Mercurial
comparison .cms/lib/codemirror/mode/mumps/mumps.js @ 0:78edf6b517a0 draft
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Fri, 11 Oct 2024 22:40:23 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78edf6b517a0 |
---|---|
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others | |
2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE | |
3 | |
4 /* | |
5 This MUMPS Language script was constructed using vbscript.js as a template. | |
6 */ | |
7 | |
8 (function(mod) { | |
9 if (typeof exports == "object" && typeof module == "object") // CommonJS | |
10 mod(require("../../lib/codemirror")); | |
11 else if (typeof define == "function" && define.amd) // AMD | |
12 define(["../../lib/codemirror"], mod); | |
13 else // Plain browser env | |
14 mod(CodeMirror); | |
15 })(function(CodeMirror) { | |
16 "use strict"; | |
17 | |
18 CodeMirror.defineMode("mumps", function() { | |
19 function wordRegexp(words) { | |
20 return new RegExp("^((" + words.join(")|(") + "))\\b", "i"); | |
21 } | |
22 | |
23 var singleOperators = new RegExp("^[\\+\\-\\*/&#!_?\\\\<>=\\'\\[\\]]"); | |
24 var doubleOperators = new RegExp("^(('=)|(<=)|(>=)|('>)|('<)|([[)|(]])|(^$))"); | |
25 var singleDelimiters = new RegExp("^[\\.,:]"); | |
26 var brackets = new RegExp("[()]"); | |
27 var identifiers = new RegExp("^[%A-Za-z][A-Za-z0-9]*"); | |
28 var commandKeywords = ["break","close","do","else","for","goto", "halt", "hang", "if", "job","kill","lock","merge","new","open", "quit", "read", "set", "tcommit", "trollback", "tstart", "use", "view", "write", "xecute", "b","c","d","e","f","g", "h", "i", "j","k","l","m","n","o", "q", "r", "s", "tc", "tro", "ts", "u", "v", "w", "x"]; | |
29 // The following list includes intrinsic functions _and_ special variables | |
30 var intrinsicFuncsWords = ["\\$ascii", "\\$char", "\\$data", "\\$ecode", "\\$estack", "\\$etrap", "\\$extract", "\\$find", "\\$fnumber", "\\$get", "\\$horolog", "\\$io", "\\$increment", "\\$job", "\\$justify", "\\$length", "\\$name", "\\$next", "\\$order", "\\$piece", "\\$qlength", "\\$qsubscript", "\\$query", "\\$quit", "\\$random", "\\$reverse", "\\$select", "\\$stack", "\\$test", "\\$text", "\\$translate", "\\$view", "\\$x", "\\$y", "\\$a", "\\$c", "\\$d", "\\$e", "\\$ec", "\\$es", "\\$et", "\\$f", "\\$fn", "\\$g", "\\$h", "\\$i", "\\$j", "\\$l", "\\$n", "\\$na", "\\$o", "\\$p", "\\$q", "\\$ql", "\\$qs", "\\$r", "\\$re", "\\$s", "\\$st", "\\$t", "\\$tr", "\\$v", "\\$z"]; | |
31 var intrinsicFuncs = wordRegexp(intrinsicFuncsWords); | |
32 var command = wordRegexp(commandKeywords); | |
33 | |
34 function tokenBase(stream, state) { | |
35 if (stream.sol()) { | |
36 state.label = true; | |
37 state.commandMode = 0; | |
38 } | |
39 | |
40 // The <space> character has meaning in MUMPS. Ignoring consecutive | |
41 // spaces would interfere with interpreting whether the next non-space | |
42 // character belongs to the command or argument context. | |
43 | |
44 // Examine each character and update a mode variable whose interpretation is: | |
45 // >0 => command 0 => argument <0 => command post-conditional | |
46 var ch = stream.peek(); | |
47 | |
48 if (ch == " " || ch == "\t") { // Pre-process <space> | |
49 state.label = false; | |
50 if (state.commandMode == 0) | |
51 state.commandMode = 1; | |
52 else if ((state.commandMode < 0) || (state.commandMode == 2)) | |
53 state.commandMode = 0; | |
54 } else if ((ch != ".") && (state.commandMode > 0)) { | |
55 if (ch == ":") | |
56 state.commandMode = -1; // SIS - Command post-conditional | |
57 else | |
58 state.commandMode = 2; | |
59 } | |
60 | |
61 // Do not color parameter list as line tag | |
62 if ((ch === "(") || (ch === "\u0009")) | |
63 state.label = false; | |
64 | |
65 // MUMPS comment starts with ";" | |
66 if (ch === ";") { | |
67 stream.skipToEnd(); | |
68 return "comment"; | |
69 } | |
70 | |
71 // Number Literals // SIS/RLM - MUMPS permits canonic number followed by concatenate operator | |
72 if (stream.match(/^[-+]?\d+(\.\d+)?([eE][-+]?\d+)?/)) | |
73 return "number"; | |
74 | |
75 // Handle Strings | |
76 if (ch == '"') { | |
77 if (stream.skipTo('"')) { | |
78 stream.next(); | |
79 return "string"; | |
80 } else { | |
81 stream.skipToEnd(); | |
82 return "error"; | |
83 } | |
84 } | |
85 | |
86 // Handle operators and Delimiters | |
87 if (stream.match(doubleOperators) || stream.match(singleOperators)) | |
88 return "operator"; | |
89 | |
90 // Prevents leading "." in DO block from falling through to error | |
91 if (stream.match(singleDelimiters)) | |
92 return null; | |
93 | |
94 if (brackets.test(ch)) { | |
95 stream.next(); | |
96 return "bracket"; | |
97 } | |
98 | |
99 if (state.commandMode > 0 && stream.match(command)) | |
100 return "variable-2"; | |
101 | |
102 if (stream.match(intrinsicFuncs)) | |
103 return "builtin"; | |
104 | |
105 if (stream.match(identifiers)) | |
106 return "variable"; | |
107 | |
108 // Detect dollar-sign when not a documented intrinsic function | |
109 // "^" may introduce a GVN or SSVN - Color same as function | |
110 if (ch === "$" || ch === "^") { | |
111 stream.next(); | |
112 return "builtin"; | |
113 } | |
114 | |
115 // MUMPS Indirection | |
116 if (ch === "@") { | |
117 stream.next(); | |
118 return "string-2"; | |
119 } | |
120 | |
121 if (/[\w%]/.test(ch)) { | |
122 stream.eatWhile(/[\w%]/); | |
123 return "variable"; | |
124 } | |
125 | |
126 // Handle non-detected items | |
127 stream.next(); | |
128 return "error"; | |
129 } | |
130 | |
131 return { | |
132 startState: function() { | |
133 return { | |
134 label: false, | |
135 commandMode: 0 | |
136 }; | |
137 }, | |
138 | |
139 token: function(stream, state) { | |
140 var style = tokenBase(stream, state); | |
141 if (state.label) return "tag"; | |
142 return style; | |
143 } | |
144 }; | |
145 }); | |
146 | |
147 CodeMirror.defineMIME("text/x-mumps", "mumps"); | |
148 }); |