scripts/CodeMirror/mode/ecl/ecl.js (view raw)
1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: https://codemirror.net/LICENSE
3
4(function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11})(function(CodeMirror) {
12"use strict";
13
14CodeMirror.defineMode("ecl", function(config) {
15
16 function words(str) {
17 var obj = {}, words = str.split(" ");
18 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
19 return obj;
20 }
21
22 function metaHook(stream, state) {
23 if (!state.startOfLine) return false;
24 stream.skipToEnd();
25 return "meta";
26 }
27
28 var indentUnit = config.indentUnit;
29 var keyword = words("abs acos allnodes ascii asin asstring atan atan2 ave case choose choosen choosesets clustersize combine correlation cos cosh count covariance cron dataset dedup define denormalize distribute distributed distribution ebcdic enth error evaluate event eventextra eventname exists exp failcode failmessage fetch fromunicode getisvalid global graph group hash hash32 hash64 hashcrc hashmd5 having if index intformat isvalid iterate join keyunicode length library limit ln local log loop map matched matchlength matchposition matchtext matchunicode max merge mergejoin min nolocal nonempty normalize parse pipe power preload process project pull random range rank ranked realformat recordof regexfind regexreplace regroup rejected rollup round roundup row rowdiff sample set sin sinh sizeof soapcall sort sorted sqrt stepped stored sum table tan tanh thisnode topn tounicode transfer trim truncate typeof ungroup unicodeorder variance which workunit xmldecode xmlencode xmltext xmlunicode");
30 var variable = words("apply assert build buildindex evaluate fail keydiff keypatch loadxml nothor notify output parallel sequential soapcall wait");
31 var variable_2 = words("__compressed__ all and any as atmost before beginc++ best between case const counter csv descend encrypt end endc++ endmacro except exclusive expire export extend false few first flat from full function group header heading hole ifblock import in interface joined keep keyed last left limit load local locale lookup macro many maxcount maxlength min skew module named nocase noroot noscan nosort not of only opt or outer overwrite packed partition penalty physicallength pipe quote record relationship repeat return right scan self separator service shared skew skip sql store terminator thor threshold token transform trim true type unicodeorder unsorted validate virtual whole wild within xml xpath");
32 var variable_3 = words("ascii big_endian boolean data decimal ebcdic integer pattern qstring real record rule set of string token udecimal unicode unsigned varstring varunicode");
33 var builtin = words("checkpoint deprecated failcode failmessage failure global independent onwarning persist priority recovery stored success wait when");
34 var blockKeywords = words("catch class do else finally for if switch try while");
35 var atoms = words("true false null");
36 var hooks = {"#": metaHook};
37 var isOperatorChar = /[+\-*&%=<>!?|\/]/;
38
39 var curPunc;
40
41 function tokenBase(stream, state) {
42 var ch = stream.next();
43 if (hooks[ch]) {
44 var result = hooks[ch](stream, state);
45 if (result !== false) return result;
46 }
47 if (ch == '"' || ch == "'") {
48 state.tokenize = tokenString(ch);
49 return state.tokenize(stream, state);
50 }
51 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
52 curPunc = ch;
53 return null;
54 }
55 if (/\d/.test(ch)) {
56 stream.eatWhile(/[\w\.]/);
57 return "number";
58 }
59 if (ch == "/") {
60 if (stream.eat("*")) {
61 state.tokenize = tokenComment;
62 return tokenComment(stream, state);
63 }
64 if (stream.eat("/")) {
65 stream.skipToEnd();
66 return "comment";
67 }
68 }
69 if (isOperatorChar.test(ch)) {
70 stream.eatWhile(isOperatorChar);
71 return "operator";
72 }
73 stream.eatWhile(/[\w\$_]/);
74 var cur = stream.current().toLowerCase();
75 if (keyword.propertyIsEnumerable(cur)) {
76 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
77 return "keyword";
78 } else if (variable.propertyIsEnumerable(cur)) {
79 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
80 return "variable";
81 } else if (variable_2.propertyIsEnumerable(cur)) {
82 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
83 return "variable-2";
84 } else if (variable_3.propertyIsEnumerable(cur)) {
85 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
86 return "variable-3";
87 } else if (builtin.propertyIsEnumerable(cur)) {
88 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
89 return "builtin";
90 } else { //Data types are of from KEYWORD##
91 var i = cur.length - 1;
92 while(i >= 0 && (!isNaN(cur[i]) || cur[i] == '_'))
93 --i;
94
95 if (i > 0) {
96 var cur2 = cur.substr(0, i + 1);
97 if (variable_3.propertyIsEnumerable(cur2)) {
98 if (blockKeywords.propertyIsEnumerable(cur2)) curPunc = "newstatement";
99 return "variable-3";
100 }
101 }
102 }
103 if (atoms.propertyIsEnumerable(cur)) return "atom";
104 return null;
105 }
106
107 function tokenString(quote) {
108 return function(stream, state) {
109 var escaped = false, next, end = false;
110 while ((next = stream.next()) != null) {
111 if (next == quote && !escaped) {end = true; break;}
112 escaped = !escaped && next == "\\";
113 }
114 if (end || !escaped)
115 state.tokenize = tokenBase;
116 return "string";
117 };
118 }
119
120 function tokenComment(stream, state) {
121 var maybeEnd = false, ch;
122 while (ch = stream.next()) {
123 if (ch == "/" && maybeEnd) {
124 state.tokenize = tokenBase;
125 break;
126 }
127 maybeEnd = (ch == "*");
128 }
129 return "comment";
130 }
131
132 function Context(indented, column, type, align, prev) {
133 this.indented = indented;
134 this.column = column;
135 this.type = type;
136 this.align = align;
137 this.prev = prev;
138 }
139 function pushContext(state, col, type) {
140 return state.context = new Context(state.indented, col, type, null, state.context);
141 }
142 function popContext(state) {
143 var t = state.context.type;
144 if (t == ")" || t == "]" || t == "}")
145 state.indented = state.context.indented;
146 return state.context = state.context.prev;
147 }
148
149 // Interface
150
151 return {
152 startState: function(basecolumn) {
153 return {
154 tokenize: null,
155 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
156 indented: 0,
157 startOfLine: true
158 };
159 },
160
161 token: function(stream, state) {
162 var ctx = state.context;
163 if (stream.sol()) {
164 if (ctx.align == null) ctx.align = false;
165 state.indented = stream.indentation();
166 state.startOfLine = true;
167 }
168 if (stream.eatSpace()) return null;
169 curPunc = null;
170 var style = (state.tokenize || tokenBase)(stream, state);
171 if (style == "comment" || style == "meta") return style;
172 if (ctx.align == null) ctx.align = true;
173
174 if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
175 else if (curPunc == "{") pushContext(state, stream.column(), "}");
176 else if (curPunc == "[") pushContext(state, stream.column(), "]");
177 else if (curPunc == "(") pushContext(state, stream.column(), ")");
178 else if (curPunc == "}") {
179 while (ctx.type == "statement") ctx = popContext(state);
180 if (ctx.type == "}") ctx = popContext(state);
181 while (ctx.type == "statement") ctx = popContext(state);
182 }
183 else if (curPunc == ctx.type) popContext(state);
184 else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
185 pushContext(state, stream.column(), "statement");
186 state.startOfLine = false;
187 return style;
188 },
189
190 indent: function(state, textAfter) {
191 if (state.tokenize != tokenBase && state.tokenize != null) return 0;
192 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
193 if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
194 var closing = firstChar == ctx.type;
195 if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
196 else if (ctx.align) return ctx.column + (closing ? 0 : 1);
197 else return ctx.indented + (closing ? 0 : indentUnit);
198 },
199
200 electricChars: "{}"
201 };
202});
203
204CodeMirror.defineMIME("text/x-ecl", "ecl");
205
206});