Mercurial
comparison .cms/lib/codemirror/mode/forth/forth.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 // Author: Aliaksei Chapyzhenka | |
5 | |
6 (function(mod) { | |
7 if (typeof exports == "object" && typeof module == "object") // CommonJS | |
8 mod(require("../../lib/codemirror")); | |
9 else if (typeof define == "function" && define.amd) // AMD | |
10 define(["../../lib/codemirror"], mod); | |
11 else // Plain browser env | |
12 mod(CodeMirror); | |
13 })(function(CodeMirror) { | |
14 "use strict"; | |
15 | |
16 function toWordList(words) { | |
17 var ret = []; | |
18 words.split(' ').forEach(function(e){ | |
19 ret.push({name: e}); | |
20 }); | |
21 return ret; | |
22 } | |
23 | |
24 var coreWordList = toWordList( | |
25 'INVERT AND OR XOR\ | |
26 2* 2/ LSHIFT RSHIFT\ | |
27 0= = 0< < > U< MIN MAX\ | |
28 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP\ | |
29 >R R> R@\ | |
30 + - 1+ 1- ABS NEGATE\ | |
31 S>D * M* UM*\ | |
32 FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD\ | |
33 HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2!\ | |
34 ALIGN ALIGNED +! ALLOT\ | |
35 CHAR [CHAR] [ ] BL\ | |
36 FIND EXECUTE IMMEDIATE COUNT LITERAL STATE\ | |
37 ; DOES> >BODY\ | |
38 EVALUATE\ | |
39 SOURCE >IN\ | |
40 <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL\ | |
41 FILL MOVE\ | |
42 . CR EMIT SPACE SPACES TYPE U. .R U.R\ | |
43 ACCEPT\ | |
44 TRUE FALSE\ | |
45 <> U> 0<> 0>\ | |
46 NIP TUCK ROLL PICK\ | |
47 2>R 2R@ 2R>\ | |
48 WITHIN UNUSED MARKER\ | |
49 I J\ | |
50 TO\ | |
51 COMPILE, [COMPILE]\ | |
52 SAVE-INPUT RESTORE-INPUT\ | |
53 PAD ERASE\ | |
54 2LITERAL DNEGATE\ | |
55 D- D+ D0< D0= D2* D2/ D< D= DMAX DMIN D>S DABS\ | |
56 M+ M*/ D. D.R 2ROT DU<\ | |
57 CATCH THROW\ | |
58 FREE RESIZE ALLOCATE\ | |
59 CS-PICK CS-ROLL\ | |
60 GET-CURRENT SET-CURRENT FORTH-WORDLIST GET-ORDER SET-ORDER\ | |
61 PREVIOUS SEARCH-WORDLIST WORDLIST FIND ALSO ONLY FORTH DEFINITIONS ORDER\ | |
62 -TRAILING /STRING SEARCH COMPARE CMOVE CMOVE> BLANK SLITERAL'); | |
63 | |
64 var immediateWordList = toWordList('IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE [IF] [ELSE] [THEN] ?DO DO LOOP +LOOP UNLOOP LEAVE EXIT AGAIN CASE OF ENDOF ENDCASE'); | |
65 | |
66 CodeMirror.defineMode('forth', function() { | |
67 function searchWordList (wordList, word) { | |
68 var i; | |
69 for (i = wordList.length - 1; i >= 0; i--) { | |
70 if (wordList[i].name === word.toUpperCase()) { | |
71 return wordList[i]; | |
72 } | |
73 } | |
74 return undefined; | |
75 } | |
76 return { | |
77 startState: function() { | |
78 return { | |
79 state: '', | |
80 base: 10, | |
81 coreWordList: coreWordList, | |
82 immediateWordList: immediateWordList, | |
83 wordList: [] | |
84 }; | |
85 }, | |
86 token: function (stream, stt) { | |
87 var mat; | |
88 if (stream.eatSpace()) { | |
89 return null; | |
90 } | |
91 if (stt.state === '') { // interpretation | |
92 if (stream.match(/^(\]|:NONAME)(\s|$)/i)) { | |
93 stt.state = ' compilation'; | |
94 return 'builtin compilation'; | |
95 } | |
96 mat = stream.match(/^(\:)\s+(\S+)(\s|$)+/); | |
97 if (mat) { | |
98 stt.wordList.push({name: mat[2].toUpperCase()}); | |
99 stt.state = ' compilation'; | |
100 return 'def' + stt.state; | |
101 } | |
102 mat = stream.match(/^(VARIABLE|2VARIABLE|CONSTANT|2CONSTANT|CREATE|POSTPONE|VALUE|WORD)\s+(\S+)(\s|$)+/i); | |
103 if (mat) { | |
104 stt.wordList.push({name: mat[2].toUpperCase()}); | |
105 return 'def' + stt.state; | |
106 } | |
107 mat = stream.match(/^(\'|\[\'\])\s+(\S+)(\s|$)+/); | |
108 if (mat) { | |
109 return 'builtin' + stt.state; | |
110 } | |
111 } else { // compilation | |
112 // ; [ | |
113 if (stream.match(/^(\;|\[)(\s)/)) { | |
114 stt.state = ''; | |
115 stream.backUp(1); | |
116 return 'builtin compilation'; | |
117 } | |
118 if (stream.match(/^(\;|\[)($)/)) { | |
119 stt.state = ''; | |
120 return 'builtin compilation'; | |
121 } | |
122 if (stream.match(/^(POSTPONE)\s+\S+(\s|$)+/)) { | |
123 return 'builtin'; | |
124 } | |
125 } | |
126 | |
127 // dynamic wordlist | |
128 mat = stream.match(/^(\S+)(\s+|$)/); | |
129 if (mat) { | |
130 if (searchWordList(stt.wordList, mat[1]) !== undefined) { | |
131 return 'variable' + stt.state; | |
132 } | |
133 | |
134 // comments | |
135 if (mat[1] === '\\') { | |
136 stream.skipToEnd(); | |
137 return 'comment' + stt.state; | |
138 } | |
139 | |
140 // core words | |
141 if (searchWordList(stt.coreWordList, mat[1]) !== undefined) { | |
142 return 'builtin' + stt.state; | |
143 } | |
144 if (searchWordList(stt.immediateWordList, mat[1]) !== undefined) { | |
145 return 'keyword' + stt.state; | |
146 } | |
147 | |
148 if (mat[1] === '(') { | |
149 stream.eatWhile(function (s) { return s !== ')'; }); | |
150 stream.eat(')'); | |
151 return 'comment' + stt.state; | |
152 } | |
153 | |
154 // // strings | |
155 if (mat[1] === '.(') { | |
156 stream.eatWhile(function (s) { return s !== ')'; }); | |
157 stream.eat(')'); | |
158 return 'string' + stt.state; | |
159 } | |
160 if (mat[1] === 'S"' || mat[1] === '."' || mat[1] === 'C"') { | |
161 stream.eatWhile(function (s) { return s !== '"'; }); | |
162 stream.eat('"'); | |
163 return 'string' + stt.state; | |
164 } | |
165 | |
166 // numbers | |
167 if (mat[1] - 0xfffffffff) { | |
168 return 'number' + stt.state; | |
169 } | |
170 // if (mat[1].match(/^[-+]?[0-9]+\.[0-9]*/)) { | |
171 // return 'number' + stt.state; | |
172 // } | |
173 | |
174 return 'atom' + stt.state; | |
175 } | |
176 } | |
177 }; | |
178 }); | |
179 CodeMirror.defineMIME("text/x-forth", "forth"); | |
180 }); |