Forráskód Böngészése

Merge branch 'master' of https://github.com/Madzi/oberonjs into Madzi-master

Vladislav Folts 12 éve
szülő
commit
2a08319bb0
1 módosított fájl, 224 hozzáadás és 87 törlés
  1. 224 87
      codemirror/oberon07.js

+ 224 - 87
codemirror/oberon07.js

@@ -1,95 +1,232 @@
 CodeMirror.defineMode("oberon07", function() {
-  function words(str) {
-    var obj = {}, words = str.split(" ");
-    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
-    return obj;
-  }
-  var keywords = words("ARRAY IMPORT THEN BEGIN IN TO BY IS TRUE CASE MOD TYPE " +
-                       "CONST MODULE UNTIL DIV NIL VAR DO OF WHILE ELSE OR " +
-                       "ELSIF POINTER END PROCEDURE FALSE RECORD FOR REPEAT IF RETURN");
-
-  var atoms = {'null': true};
-
-  var isOperatorChar = /[+\-*&%=<>^~#!?\|\/]/;
-
-  function tokenBase(stream, state) {
-    var ch = stream.next();
-    if (ch == "#" && state.startOfLine) {
-      stream.skipToEnd();
-      return "meta";
-    }
-    if (ch == '"' || ch == "'") {
-      state.tokenize = tokenString(ch);
-      return state.tokenize(stream, state);
-    }
-    if (ch == "(" && stream.eat("*")) {
-      state.tokenize = tokenComment;
-      return tokenComment(stream, state);
-    }
-    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
-      return null;
-    }
-    if (/\d/.test(ch)) {
-      stream.eatWhile(/[\w\.]/);
-      return "number";
-    }
-    if (ch == "/") {
-      if (stream.eat("/")) {
-        stream.skipToEnd();
-        return "comment";
-      }
-    }
-    if (isOperatorChar.test(ch)) {
-      stream.eatWhile(isOperatorChar);
-      return "operator";
-    }
-    stream.eatWhile(/[\w\$_]/);
-    var cur = stream.current();
-    if (keywords.propertyIsEnumerable(cur)) return "keyword";
-    if (atoms.propertyIsEnumerable(cur)) return "atom";
-    return "variable";
-  }
-
-  function tokenString(quote) {
-    return function(stream, state) {
-      var escaped = false, next, end = false;
-      while ((next = stream.next()) != null) {
-        if (next == quote && !escaped) {end = true; break;}
-        escaped = !escaped && next == "\\";
-      }
-      if (end || !escaped) state.tokenize = null;
-      return "string";
-    };
-  }
-
-  function tokenComment(stream, state) {
-    var maybeEnd = false, ch;
-    while (ch = stream.next()) {
-      if (ch == ")" && maybeEnd) {
-        state.tokenize = null;
-        break;
-      }
-      maybeEnd = (ch == "*");
-    }
-    return "comment";
-  }
+/**
+ * Possible styles:
+ *
+ * keyword   * atom        * number      * def
+ * variable  * variable-2  * variable-3  * property
+ * operator  * comment     * string      * string-2
+ * meta      * error       * qualifier   * builtin
+ * bracket   * tag         * attribute   * header
+ * quote     * hr          * link
+ *
+ * OR & ~ < logic operator
+ * + - * / DIV MOD < arithmetic operator
+ * = # < > IS IN < relation operator
+ */
 
-  // Interface
+    var DEF = 'def',
+        ATOM = 'atom',
+        CHAR = 'string-2',
+        META = 'meta',
+        IDENT = 'variable',
+        ERROR = 'error',
+        STRING = 'string',
+        COMMENT = 'comment',
+        BRACKET = 'bracket',
+        KEYWORD = 'keyword',
+        OPERATOR = 'operator',
+        QUALIFIER = 'qualifier',
+
+        _words = {
+            'ABS' : DEF, 'ASR'  : DEF, 'ASSERT': DEF,
+            'CHR' : DEF, 'COPY' : DEF, 'DEC'   : DEF,
+            'EXCL': DEF, 'FLOOR': DEF, 'FLT'   : DEF,
+            'INC' : DEF, 'INCL' : DEF, 'LEN'   : DEF,
+            'LSL' : DEF, 'LONG' : DEF, 'NEW'   : DEF,
+            'ODD' : DEF, 'ORD'  : DEF, 'PACK'  : DEF,
+            'ROR' : DEF, 'SHORT': DEF, 'UNPK'  : DEF,
+
+            'BOOLEAN' : ATOM, 'CHAR': ATOM, 'INTEGER': ATOM,
+            'LONGREAL': ATOM, 'REAL': ATOM, 'SET'    : ATOM,
+
+            'ADR': META, 'SIZE': META, 'BIT': META,
+            'GET': META, 'PUT' : META,
+
+            'ARRAY'    : KEYWORD, 'BEGIN'    : KEYWORD,
+            'BY'       : KEYWORD, 'CASE'     : KEYWORD,
+            'CONST'    : KEYWORD, 'DO'       : KEYWORD,
+            'ELSE'     : KEYWORD, 'ELSIF'    : KEYWORD,
+            'END'      : KEYWORD, 'FALSE'    : KEYWORD,
+            'FOR'      : KEYWORD, 'IF'       : KEYWORD,
+            'IMPORT'   : KEYWORD, 'MODULE'   : KEYWORD,
+            'NIL'      : KEYWORD, 'OF'       : KEYWORD,
+            'POINTER'  : KEYWORD, 'PROCEDURE': KEYWORD,
+            'RECORD'   : KEYWORD, 'REPEAT'   : KEYWORD,
+            'RETURN'   : KEYWORD, 'THEN'     : KEYWORD,
+            'TO'       : KEYWORD, 'TRUE'     : KEYWORD,
+            'TYPE'     : KEYWORD, 'UNTIL'    : KEYWORD,
+            'VAR'      : KEYWORD, 'WHILE'    : KEYWORD,
+
+            'DIV': OPERATOR, 'IN' : OPERATOR, 'IS' : OPERATOR,
+            'MOD': OPERATOR, 'OR' : OPERATOR
+        };
+
+        _alphaREX = /[a-zA-Z_]/,
+        _alphaDigitREX = /[0-9a-zA-Z_]/,
+
+        _isAlpha = function (ch) {
+            return _alphaREX.test(ch);
+        },
+
+        _isAlphaOrDigit = function (ch) {
+            return _alphaDigitREX.test(ch);
+        },
+
+        _startState = function () {
+            return {
+                stack: [],
+                state: null,
+                ch: null,
+                scope: 0,
+                level: 0,
+                error: null,
+                name: null,
+            };
+        },
+
+        _token = function (stream, state) {
+            var _state = state.state;
+
+                _ident = function (sym) {
+                    var _token = IDENT,
+                        _str = sym,
+                        _ch = stream.next();
+
+                    while (_ch && _isAlphaOrDigit(_ch) && !stream.eol()) {
+                        _str += _ch;
+                        _ch = stream.next();
+                    }
+
+                    state.name = _str;
+                    if (_ch === '.' || _ch === '[') {
+                        _token = QUALIFIER;
+                    }
+
+                    if (_words[_str]) {
+                        _token = _words[_str];
+                    }
+
+                    if (!stream.eol()) {
+                        stream.backUp(1);
+                    }
+
+                    return _token;
+                },
+
+                _number = function () {},
 
-  return {
-    startState: function() {
-      return {tokenize: null};
-    },
+                _string = function (sym) {
+                    var _str,
+                        _ch = stream.next();
 
-    token: function(stream, state) {
-      if (stream.eatSpace()) return null;
-      var style = (state.tokenize || tokenBase)(stream, state);
-      if (style == "comment" || style == "meta") return style;
-      return style;
-    },
+                    while (_ch && _ch != sym && !stream.eol()) {
+                        _str += _ch;
+                        _ch = stream.next();
+                    }
+                    if (stream.eol()) {
+                        state.error = 'string.not.close';
+                        return ERROR;
+                    }
+                    state.name = _str;
+                    return STRING;
+                },
+
+                _comment = function () {
+                    var mode = '?',
+                        _ch;
+
+                    while (state.level > 0 && !stream.eol()) {
+                        _ch = stream.next();
+                        switch (_ch) {
+                            case '(':
+                                mode = '(';
+                                break;
+
+                            case '*':
+                                if (mode === '(') {
+                                    state.level += 1;
+                                }
+                                mode = '*';
+                                break;
+
+                            case ')':
+                                if (mode === '*') {
+                                    state.level -= 1;
+                                }
+                                mode = ')';
+                                break;
+
+                            default:
+                                mode = '?';
+                        }
+                    }
+                    return COMMENT;
+                },
+
+                _ch = stream.next();
+
+            if (state.level > 0) {
+                return _comment();
+            }
+
+            if (_isAlpha(_ch)) {
+                return _ident(_ch);
+            }
+
+            switch (_ch) {
+                case '"':
+                case "'":
+                    return _string(_ch);
+
+                case '[':
+                case ']':
+                case '{':
+                case '}':
+                case ')':
+                    return BRACKET;
+
+                case '(':
+                    if (stream.peek() === '*') {
+                        state.level += 1;
+                        return _comment();
+                    }
+                    return BRACKET;
+
+                case ':':
+                    if (stream.peek() === '=') {
+                        _ch = stream.next();
+                        return KEYWORD;
+                    }
+                    return OPERATOR;
+
+                case '<':
+                case '>':
+
+                case '#':
+                case '&':
+                case '+':
+                case '-':
+                case '*':
+                case '/':
+                case '~':
+                case '|':
+                case '^':
+                case ',':
+                case ';':
+                    return OPERATOR;
+            }
+
+            return null;
+        };
+
+  // Interface
+
+    return {
+        startState: _startState,
+        token: _token,
+        electricChars: null
+    };
 
-    electricChars: "{}"
-  };
 });
 
 CodeMirror.defineMIME("text/x-oberon07", "oberon07");