ecl.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. ;(function (mod) {
  4. if (typeof exports == 'object' && typeof module == 'object')
  5. // CommonJS
  6. mod(require('../../lib/codemirror'))
  7. else if (typeof define == 'function' && define.amd)
  8. // AMD
  9. define(['../../lib/codemirror'], mod)
  10. // Plain browser env
  11. else mod(CodeMirror)
  12. })(function (CodeMirror) {
  13. 'use strict'
  14. CodeMirror.defineMode('ecl', function (config) {
  15. function words(str) {
  16. var obj = {},
  17. words = str.split(' ')
  18. for (var i = 0; i < words.length; ++i) obj[words[i]] = true
  19. return obj
  20. }
  21. function metaHook(stream, state) {
  22. if (!state.startOfLine) return false
  23. stream.skipToEnd()
  24. return 'meta'
  25. }
  26. var indentUnit = config.indentUnit
  27. var keyword = words(
  28. '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'
  29. )
  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(
  32. '__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'
  33. )
  34. 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')
  35. var builtin = words('checkpoint deprecated failcode failmessage failure global independent onwarning persist priority recovery stored success wait when')
  36. var blockKeywords = words('catch class do else finally for if switch try while')
  37. var atoms = words('true false null')
  38. var hooks = { '#': metaHook }
  39. var isOperatorChar = /[+\-*&%=<>!?|\/]/
  40. var curPunc
  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 {
  91. //Data types are of from KEYWORD##
  92. var i = cur.length - 1
  93. while (i >= 0 && (!isNaN(cur[i]) || cur[i] == '_')) --i
  94. if (i > 0) {
  95. var cur2 = cur.substr(0, i + 1)
  96. if (variable_3.propertyIsEnumerable(cur2)) {
  97. if (blockKeywords.propertyIsEnumerable(cur2)) curPunc = 'newstatement'
  98. return 'variable-3'
  99. }
  100. }
  101. }
  102. if (atoms.propertyIsEnumerable(cur)) return 'atom'
  103. return null
  104. }
  105. function tokenString(quote) {
  106. return function (stream, state) {
  107. var escaped = false,
  108. next,
  109. end = false
  110. while ((next = stream.next()) != null) {
  111. if (next == quote && !escaped) {
  112. end = true
  113. break
  114. }
  115. escaped = !escaped && next == '\\'
  116. }
  117. if (end || !escaped) state.tokenize = tokenBase
  118. return 'string'
  119. }
  120. }
  121. function tokenComment(stream, state) {
  122. var maybeEnd = false,
  123. ch
  124. while ((ch = stream.next())) {
  125. if (ch == '/' && maybeEnd) {
  126. state.tokenize = tokenBase
  127. break
  128. }
  129. maybeEnd = ch == '*'
  130. }
  131. return 'comment'
  132. }
  133. function Context(indented, column, type, align, prev) {
  134. this.indented = indented
  135. this.column = column
  136. this.type = type
  137. this.align = align
  138. this.prev = prev
  139. }
  140. function pushContext(state, col, type) {
  141. return (state.context = new Context(state.indented, col, type, null, state.context))
  142. }
  143. function popContext(state) {
  144. var t = state.context.type
  145. if (t == ')' || t == ']' || t == '}') state.indented = state.context.indented
  146. return (state.context = state.context.prev)
  147. }
  148. // Interface
  149. return {
  150. startState: function (basecolumn) {
  151. return {
  152. tokenize: null,
  153. context: new Context((basecolumn || 0) - indentUnit, 0, 'top', false),
  154. indented: 0,
  155. startOfLine: true,
  156. }
  157. },
  158. token: function (stream, state) {
  159. var ctx = state.context
  160. if (stream.sol()) {
  161. if (ctx.align == null) ctx.align = false
  162. state.indented = stream.indentation()
  163. state.startOfLine = true
  164. }
  165. if (stream.eatSpace()) return null
  166. curPunc = null
  167. var style = (state.tokenize || tokenBase)(stream, state)
  168. if (style == 'comment' || style == 'meta') return style
  169. if (ctx.align == null) ctx.align = true
  170. if ((curPunc == ';' || curPunc == ':') && ctx.type == 'statement') popContext(state)
  171. else if (curPunc == '{') pushContext(state, stream.column(), '}')
  172. else if (curPunc == '[') pushContext(state, stream.column(), ']')
  173. else if (curPunc == '(') pushContext(state, stream.column(), ')')
  174. else if (curPunc == '}') {
  175. while (ctx.type == 'statement') ctx = popContext(state)
  176. if (ctx.type == '}') ctx = popContext(state)
  177. while (ctx.type == 'statement') ctx = popContext(state)
  178. } else if (curPunc == ctx.type) popContext(state)
  179. else if (ctx.type == '}' || ctx.type == 'top' || (ctx.type == 'statement' && curPunc == 'newstatement')) pushContext(state, stream.column(), 'statement')
  180. state.startOfLine = false
  181. return style
  182. },
  183. indent: function (state, textAfter) {
  184. if (state.tokenize != tokenBase && state.tokenize != null) return 0
  185. var ctx = state.context,
  186. firstChar = textAfter && textAfter.charAt(0)
  187. if (ctx.type == 'statement' && firstChar == '}') ctx = ctx.prev
  188. var closing = firstChar == ctx.type
  189. if (ctx.type == 'statement') return ctx.indented + (firstChar == '{' ? 0 : indentUnit)
  190. else if (ctx.align) return ctx.column + (closing ? 0 : 1)
  191. else return ctx.indented + (closing ? 0 : indentUnit)
  192. },
  193. electricChars: '{}',
  194. }
  195. })
  196. CodeMirror.defineMIME('text/x-ecl', 'ecl')
  197. })