Subversion-Projekte lars-tiefland.ci

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
776 lars 1
// CodeMirror, copyright (c) by Marijn Haverbeke and others
2
// Distributed under an MIT license: http://codemirror.net/LICENSE
3
 
4
// Modelica support for CodeMirror, copyright (c) by Lennart Ochel
5
 
6
(function(mod) {
7
  if (typeof exports == "object" && typeof module == "object") // CommonJS
8
    mod(require("../../lib/codemirror"));
9
  else if (typeof define == "function" && define.amd) // AMD
10
    define(["../../lib/codemirror"], mod);
11
  else // Plain browser env
12
    mod(CodeMirror);
13
})
14
 
15
(function(CodeMirror) {
16
  "use strict";
17
 
18
  CodeMirror.defineMode("modelica", function(config, parserConfig) {
19
 
20
    var indentUnit = config.indentUnit;
21
    var keywords = parserConfig.keywords || {};
22
    var builtin = parserConfig.builtin || {};
23
    var atoms = parserConfig.atoms || {};
24
 
25
    var isSingleOperatorChar = /[;=\(:\),{}.*<>+\-\/^\[\]]/;
26
    var isDoubleOperatorChar = /(:=|<=|>=|==|<>|\.\+|\.\-|\.\*|\.\/|\.\^)/;
27
    var isDigit = /[0-9]/;
28
    var isNonDigit = /[_a-zA-Z]/;
29
 
30
    function tokenLineComment(stream, state) {
31
      stream.skipToEnd();
32
      state.tokenize = null;
33
      return "comment";
34
    }
35
 
36
    function tokenBlockComment(stream, state) {
37
      var maybeEnd = false, ch;
38
      while (ch = stream.next()) {
39
        if (maybeEnd && ch == "/") {
40
          state.tokenize = null;
41
          break;
42
        }
43
        maybeEnd = (ch == "*");
44
      }
45
      return "comment";
46
    }
47
 
48
    function tokenString(stream, state) {
49
      var escaped = false, ch;
50
      while ((ch = stream.next()) != null) {
51
        if (ch == '"' && !escaped) {
52
          state.tokenize = null;
53
          state.sol = false;
54
          break;
55
        }
56
        escaped = !escaped && ch == "\\";
57
      }
58
 
59
      return "string";
60
    }
61
 
62
    function tokenIdent(stream, state) {
63
      stream.eatWhile(isDigit);
64
      while (stream.eat(isDigit) || stream.eat(isNonDigit)) { }
65
 
66
 
67
      var cur = stream.current();
68
 
69
      if(state.sol && (cur == "package" || cur == "model" || cur == "when" || cur == "connector")) state.level++;
70
      else if(state.sol && cur == "end" && state.level > 0) state.level--;
71
 
72
      state.tokenize = null;
73
      state.sol = false;
74
 
75
      if (keywords.propertyIsEnumerable(cur)) return "keyword";
76
      else if (builtin.propertyIsEnumerable(cur)) return "builtin";
77
      else if (atoms.propertyIsEnumerable(cur)) return "atom";
78
      else return "variable";
79
    }
80
 
81
    function tokenQIdent(stream, state) {
82
      while (stream.eat(/[^']/)) { }
83
 
84
      state.tokenize = null;
85
      state.sol = false;
86
 
87
      if(stream.eat("'"))
88
        return "variable";
89
      else
90
        return "error";
91
    }
92
 
93
    function tokenUnsignedNuber(stream, state) {
94
      stream.eatWhile(isDigit);
95
      if (stream.eat('.')) {
96
        stream.eatWhile(isDigit);
97
      }
98
      if (stream.eat('e') || stream.eat('E')) {
99
        if (!stream.eat('-'))
100
          stream.eat('+');
101
        stream.eatWhile(isDigit);
102
      }
103
 
104
      state.tokenize = null;
105
      state.sol = false;
106
      return "number";
107
    }
108
 
109
    // Interface
110
    return {
111
      startState: function() {
112
        return {
113
          tokenize: null,
114
          level: 0,
115
          sol: true
116
        };
117
      },
118
 
119
      token: function(stream, state) {
120
        if(state.tokenize != null) {
121
          return state.tokenize(stream, state);
122
        }
123
 
124
        if(stream.sol()) {
125
          state.sol = true;
126
        }
127
 
128
        // WHITESPACE
129
        if(stream.eatSpace()) {
130
          state.tokenize = null;
131
          return null;
132
        }
133
 
134
        var ch = stream.next();
135
 
136
        // LINECOMMENT
137
        if(ch == '/' && stream.eat('/')) {
138
          state.tokenize = tokenLineComment;
139
        }
140
        // BLOCKCOMMENT
141
        else if(ch == '/' && stream.eat('*')) {
142
          state.tokenize = tokenBlockComment;
143
        }
144
        // TWO SYMBOL TOKENS
145
        else if(isDoubleOperatorChar.test(ch+stream.peek())) {
146
          stream.next();
147
          state.tokenize = null;
148
          return "operator";
149
        }
150
        // SINGLE SYMBOL TOKENS
151
        else if(isSingleOperatorChar.test(ch)) {
152
          state.tokenize = null;
153
          return "operator";
154
        }
155
        // IDENT
156
        else if(isNonDigit.test(ch)) {
157
          state.tokenize = tokenIdent;
158
        }
159
        // Q-IDENT
160
        else if(ch == "'" && stream.peek() && stream.peek() != "'") {
161
          state.tokenize = tokenQIdent;
162
        }
163
        // STRING
164
        else if(ch == '"') {
165
          state.tokenize = tokenString;
166
        }
167
        // UNSIGNED_NUBER
168
        else if(isDigit.test(ch)) {
169
          state.tokenize = tokenUnsignedNuber;
170
        }
171
        // ERROR
172
        else {
173
          state.tokenize = null;
174
          return "error";
175
        }
176
 
177
        return state.tokenize(stream, state);
178
      },
179
 
180
      indent: function(state, textAfter) {
181
        if (state.tokenize != null) return CodeMirror.Pass;
182
 
183
        var level = state.level;
184
        if(/(algorithm)/.test(textAfter)) level--;
185
        if(/(equation)/.test(textAfter)) level--;
186
        if(/(initial algorithm)/.test(textAfter)) level--;
187
        if(/(initial equation)/.test(textAfter)) level--;
188
        if(/(end)/.test(textAfter)) level--;
189
 
190
        if(level > 0)
191
          return indentUnit*level;
192
        else
193
          return 0;
194
      },
195
 
196
      blockCommentStart: "/*",
197
      blockCommentEnd: "*/",
198
      lineComment: "//"
199
    };
200
  });
201
 
202
  function words(str) {
203
    var obj = {}, words = str.split(" ");
204
    for (var i=0; i<words.length; ++i)
205
      obj[words[i]] = true;
206
    return obj;
207
  }
208
 
209
  var modelicaKeywords = "algorithm and annotation assert block break class connect connector constant constrainedby der discrete each else elseif elsewhen encapsulated end enumeration equation expandable extends external false final flow for function if import impure in initial inner input loop model not operator or outer output package parameter partial protected public pure record redeclare replaceable return stream then true type when while within";
210
  var modelicaBuiltin = "abs acos actualStream asin atan atan2 cardinality ceil cos cosh delay div edge exp floor getInstanceName homotopy inStream integer log log10 mod pre reinit rem semiLinear sign sin sinh spatialDistribution sqrt tan tanh";
211
  var modelicaAtoms = "Real Boolean Integer String";
212
 
213
  function def(mimes, mode) {
214
    if (typeof mimes == "string")
215
      mimes = [mimes];
216
 
217
    var words = [];
218
 
219
    function add(obj) {
220
      if (obj)
221
        for (var prop in obj)
222
          if (obj.hasOwnProperty(prop))
223
            words.push(prop);
224
    }
225
 
226
    add(mode.keywords);
227
    add(mode.builtin);
228
    add(mode.atoms);
229
 
230
    if (words.length) {
231
      mode.helperType = mimes[0];
232
      CodeMirror.registerHelper("hintWords", mimes[0], words);
233
    }
234
 
235
    for (var i=0; i<mimes.length; ++i)
236
      CodeMirror.defineMIME(mimes[i], mode);
237
  }
238
 
239
  def(["text/x-modelica"], {
240
    name: "modelica",
241
    keywords: words(modelicaKeywords),
242
    builtin: words(modelicaBuiltin),
243
    atoms: words(modelicaAtoms)
244
  });
245
});