Path: blob/master/web-gui/buildyourownbotnet/assets/js/codemirror/mode/haxe/haxe.js
1294 views
CodeMirror.defineMode("haxe", function(config, parserConfig) {1var indentUnit = config.indentUnit;23// Tokenizer45var keywords = function(){6function kw(type) {return {type: type, style: "keyword"};}7var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");8var operator = kw("operator"), atom = {type: "atom", style: "atom"}, attribute = {type:"attribute", style: "attribute"};9var type = kw("typedef");10return {11"if": A, "while": A, "else": B, "do": B, "try": B,12"return": C, "break": C, "continue": C, "new": C, "throw": C,13"var": kw("var"), "inline":attribute, "static": attribute, "using":kw("import"),14"public": attribute, "private": attribute, "cast": kw("cast"), "import": kw("import"), "macro": kw("macro"),15"function": kw("function"), "catch": kw("catch"), "untyped": kw("untyped"), "callback": kw("cb"),16"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),17"in": operator, "never": kw("property_access"), "trace":kw("trace"),18"class": type, "enum":type, "interface":type, "typedef":type, "extends":type, "implements":type, "dynamic":type,19"true": atom, "false": atom, "null": atom20};21}();2223var isOperatorChar = /[+\-*&%=<>!?|]/;2425function chain(stream, state, f) {26state.tokenize = f;27return f(stream, state);28}2930function nextUntilUnescaped(stream, end) {31var escaped = false, next;32while ((next = stream.next()) != null) {33if (next == end && !escaped)34return false;35escaped = !escaped && next == "\\";36}37return escaped;38}3940// Used as scratch variables to communicate multiple values without41// consing up tons of objects.42var type, content;43function ret(tp, style, cont) {44type = tp; content = cont;45return style;46}4748function haxeTokenBase(stream, state) {49var ch = stream.next();50if (ch == '"' || ch == "'")51return chain(stream, state, haxeTokenString(ch));52else if (/[\[\]{}\(\),;\:\.]/.test(ch))53return ret(ch);54else if (ch == "0" && stream.eat(/x/i)) {55stream.eatWhile(/[\da-f]/i);56return ret("number", "number");57}58else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {59stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);60return ret("number", "number");61}62else if (state.reAllowed && (ch == "~" && stream.eat(/\//))) {63nextUntilUnescaped(stream, "/");64stream.eatWhile(/[gimsu]/);65return ret("regexp", "string-2");66}67else if (ch == "/") {68if (stream.eat("*")) {69return chain(stream, state, haxeTokenComment);70}71else if (stream.eat("/")) {72stream.skipToEnd();73return ret("comment", "comment");74}75else {76stream.eatWhile(isOperatorChar);77return ret("operator", null, stream.current());78}79}80else if (ch == "#") {81stream.skipToEnd();82return ret("conditional", "meta");83}84else if (ch == "@") {85stream.eat(/:/);86stream.eatWhile(/[\w_]/);87return ret ("metadata", "meta");88}89else if (isOperatorChar.test(ch)) {90stream.eatWhile(isOperatorChar);91return ret("operator", null, stream.current());92}93else {94var word;95if(/[A-Z]/.test(ch))96{97stream.eatWhile(/[\w_<>]/);98word = stream.current();99return ret("type", "variable-3", word);100}101else102{103stream.eatWhile(/[\w_]/);104var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];105return (known && state.kwAllowed) ? ret(known.type, known.style, word) :106ret("variable", "variable", word);107}108}109}110111function haxeTokenString(quote) {112return function(stream, state) {113if (!nextUntilUnescaped(stream, quote))114state.tokenize = haxeTokenBase;115return ret("string", "string");116};117}118119function haxeTokenComment(stream, state) {120var maybeEnd = false, ch;121while (ch = stream.next()) {122if (ch == "/" && maybeEnd) {123state.tokenize = haxeTokenBase;124break;125}126maybeEnd = (ch == "*");127}128return ret("comment", "comment");129}130131// Parser132133var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};134135function HaxeLexical(indented, column, type, align, prev, info) {136this.indented = indented;137this.column = column;138this.type = type;139this.prev = prev;140this.info = info;141if (align != null) this.align = align;142}143144function inScope(state, varname) {145for (var v = state.localVars; v; v = v.next)146if (v.name == varname) return true;147}148149function parseHaxe(state, style, type, content, stream) {150var cc = state.cc;151// Communicate our context to the combinators.152// (Less wasteful than consing up a hundred closures on every call.)153cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;154155if (!state.lexical.hasOwnProperty("align"))156state.lexical.align = true;157158while(true) {159var combinator = cc.length ? cc.pop() : statement;160if (combinator(type, content)) {161while(cc.length && cc[cc.length - 1].lex)162cc.pop()();163if (cx.marked) return cx.marked;164if (type == "variable" && inScope(state, content)) return "variable-2";165if (type == "variable" && imported(state, content)) return "variable-3";166return style;167}168}169}170171function imported(state, typename)172{173if (/[a-z]/.test(typename.charAt(0)))174return false;175var len = state.importedtypes.length;176for (var i = 0; i<len; i++)177if(state.importedtypes[i]==typename) return true;178}179180181function registerimport(importname) {182var state = cx.state;183for (var t = state.importedtypes; t; t = t.next)184if(t.name == importname) return;185state.importedtypes = { name: importname, next: state.importedtypes };186}187// Combinator utils188189var cx = {state: null, column: null, marked: null, cc: null};190function pass() {191for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);192}193function cont() {194pass.apply(null, arguments);195return true;196}197function register(varname) {198var state = cx.state;199if (state.context) {200cx.marked = "def";201for (var v = state.localVars; v; v = v.next)202if (v.name == varname) return;203state.localVars = {name: varname, next: state.localVars};204}205}206207// Combinators208209var defaultVars = {name: "this", next: null};210function pushcontext() {211if (!cx.state.context) cx.state.localVars = defaultVars;212cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};213}214function popcontext() {215cx.state.localVars = cx.state.context.vars;216cx.state.context = cx.state.context.prev;217}218function pushlex(type, info) {219var result = function() {220var state = cx.state;221state.lexical = new HaxeLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);222};223result.lex = true;224return result;225}226function poplex() {227var state = cx.state;228if (state.lexical.prev) {229if (state.lexical.type == ")")230state.indented = state.lexical.indented;231state.lexical = state.lexical.prev;232}233}234poplex.lex = true;235236function expect(wanted) {237return function(type) {238if (type == wanted) return cont();239else if (wanted == ";") return pass();240else return cont(arguments.callee);241};242}243244function statement(type) {245if (type == "@") return cont(metadef);246if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);247if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);248if (type == "keyword b") return cont(pushlex("form"), statement, poplex);249if (type == "{") return cont(pushlex("}"), pushcontext, block, poplex, popcontext);250if (type == ";") return cont();251if (type == "attribute") return cont(maybeattribute);252if (type == "function") return cont(functiondef);253if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),254poplex, statement, poplex);255if (type == "variable") return cont(pushlex("stat"), maybelabel);256if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),257block, poplex, poplex);258if (type == "case") return cont(expression, expect(":"));259if (type == "default") return cont(expect(":"));260if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),261statement, poplex, popcontext);262if (type == "import") return cont(importdef, expect(";"));263if (type == "typedef") return cont(typedef);264return pass(pushlex("stat"), expression, expect(";"), poplex);265}266function expression(type) {267if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);268if (type == "function") return cont(functiondef);269if (type == "keyword c") return cont(maybeexpression);270if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);271if (type == "operator") return cont(expression);272if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);273if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);274return cont();275}276function maybeexpression(type) {277if (type.match(/[;\}\)\],]/)) return pass();278return pass(expression);279}280281function maybeoperator(type, value) {282if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);283if (type == "operator" || type == ":") return cont(expression);284if (type == ";") return;285if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);286if (type == ".") return cont(property, maybeoperator);287if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);288}289290function maybeattribute(type) {291if (type == "attribute") return cont(maybeattribute);292if (type == "function") return cont(functiondef);293if (type == "var") return cont(vardef1);294}295296function metadef(type) {297if(type == ":") return cont(metadef);298if(type == "variable") return cont(metadef);299if(type == "(") return cont(pushlex(")"), commasep(metaargs, ")"), poplex, statement);300}301function metaargs(type) {302if(type == "variable") return cont();303}304305function importdef (type, value) {306if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }307else if(type == "variable" || type == "property" || type == ".") return cont(importdef);308}309310function typedef (type, value)311{312if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }313}314315function maybelabel(type) {316if (type == ":") return cont(poplex, statement);317return pass(maybeoperator, expect(";"), poplex);318}319function property(type) {320if (type == "variable") {cx.marked = "property"; return cont();}321}322function objprop(type) {323if (type == "variable") cx.marked = "property";324if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);325}326function commasep(what, end) {327function proceed(type) {328if (type == ",") return cont(what, proceed);329if (type == end) return cont();330return cont(expect(end));331}332return function(type) {333if (type == end) return cont();334else return pass(what, proceed);335};336}337function block(type) {338if (type == "}") return cont();339return pass(statement, block);340}341function vardef1(type, value) {342if (type == "variable"){register(value); return cont(typeuse, vardef2);}343return cont();344}345function vardef2(type, value) {346if (value == "=") return cont(expression, vardef2);347if (type == ",") return cont(vardef1);348}349function forspec1(type, value) {350if (type == "variable") {351register(value);352}353return cont(pushlex(")"), pushcontext, forin, expression, poplex, statement, popcontext);354}355function forin(_type, value) {356if (value == "in") return cont();357}358function functiondef(type, value) {359if (type == "variable") {register(value); return cont(functiondef);}360if (value == "new") return cont(functiondef);361if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, typeuse, statement, popcontext);362}363function typeuse(type) {364if(type == ":") return cont(typestring);365}366function typestring(type) {367if(type == "type") return cont();368if(type == "variable") return cont();369if(type == "{") return cont(pushlex("}"), commasep(typeprop, "}"), poplex);370}371function typeprop(type) {372if(type == "variable") return cont(typeuse);373}374function funarg(type, value) {375if (type == "variable") {register(value); return cont(typeuse);}376}377378// Interface379380return {381startState: function(basecolumn) {382var defaulttypes = ["Int", "Float", "String", "Void", "Std", "Bool", "Dynamic", "Array"];383return {384tokenize: haxeTokenBase,385reAllowed: true,386kwAllowed: true,387cc: [],388lexical: new HaxeLexical((basecolumn || 0) - indentUnit, 0, "block", false),389localVars: parserConfig.localVars,390importedtypes: defaulttypes,391context: parserConfig.localVars && {vars: parserConfig.localVars},392indented: 0393};394},395396token: function(stream, state) {397if (stream.sol()) {398if (!state.lexical.hasOwnProperty("align"))399state.lexical.align = false;400state.indented = stream.indentation();401}402if (stream.eatSpace()) return null;403var style = state.tokenize(stream, state);404if (type == "comment") return style;405state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));406state.kwAllowed = type != '.';407return parseHaxe(state, style, type, content, stream);408},409410indent: function(state, textAfter) {411if (state.tokenize != haxeTokenBase) return 0;412var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;413if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;414var type = lexical.type, closing = firstChar == type;415if (type == "vardef") return lexical.indented + 4;416else if (type == "form" && firstChar == "{") return lexical.indented;417else if (type == "stat" || type == "form") return lexical.indented + indentUnit;418else if (lexical.info == "switch" && !closing)419return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);420else if (lexical.align) return lexical.column + (closing ? 0 : 1);421else return lexical.indented + (closing ? 0 : indentUnit);422},423424electricChars: "{}"425};426});427428CodeMirror.defineMIME("text/x-haxe", "haxe");429430431