// CodeMirror, copyright (c) by Marijn Haverbeke and others // Distributed under an MIT license: https://codemirror.net/LICENSE // Author: Aliaksei Chapyzhenka ;(function (mod) { if (typeof exports == 'object' && typeof module == 'object') // CommonJS mod(require('../../lib/codemirror')) else if (typeof define == 'function' && define.amd) // AMD define(['../../lib/codemirror'], mod) // Plain browser env else mod(CodeMirror) })(function (CodeMirror) { 'use strict' function toWordList(words) { var ret = [] words.split(' ').forEach(function (e) { ret.push({ name: e }) }) return ret } var coreWordList = toWordList( 'INVERT AND OR XOR\ 2* 2/ LSHIFT RSHIFT\ 0= = 0< < > U< MIN MAX\ 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP\ >R R> R@\ + - 1+ 1- ABS NEGATE\ S>D * M* UM*\ FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD\ HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2!\ ALIGN ALIGNED +! ALLOT\ CHAR [CHAR] [ ] BL\ FIND EXECUTE IMMEDIATE COUNT LITERAL STATE\ ; DOES> >BODY\ EVALUATE\ SOURCE >IN\ <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL\ FILL MOVE\ . CR EMIT SPACE SPACES TYPE U. .R U.R\ ACCEPT\ TRUE FALSE\ <> U> 0<> 0>\ NIP TUCK ROLL PICK\ 2>R 2R@ 2R>\ WITHIN UNUSED MARKER\ I J\ TO\ COMPILE, [COMPILE]\ SAVE-INPUT RESTORE-INPUT\ PAD ERASE\ 2LITERAL DNEGATE\ D- D+ D0< D0= D2* D2/ D< D= DMAX DMIN D>S DABS\ M+ M*/ D. D.R 2ROT DU<\ CATCH THROW\ FREE RESIZE ALLOCATE\ CS-PICK CS-ROLL\ GET-CURRENT SET-CURRENT FORTH-WORDLIST GET-ORDER SET-ORDER\ PREVIOUS SEARCH-WORDLIST WORDLIST FIND ALSO ONLY FORTH DEFINITIONS ORDER\ -TRAILING /STRING SEARCH COMPARE CMOVE CMOVE> BLANK SLITERAL' ) 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') CodeMirror.defineMode('forth', function () { function searchWordList(wordList, word) { var i for (i = wordList.length - 1; i >= 0; i--) { if (wordList[i].name === word.toUpperCase()) { return wordList[i] } } return undefined } return { startState: function () { return { state: '', base: 10, coreWordList: coreWordList, immediateWordList: immediateWordList, wordList: [], } }, token: function (stream, stt) { var mat if (stream.eatSpace()) { return null } if (stt.state === '') { // interpretation if (stream.match(/^(\]|:NONAME)(\s|$)/i)) { stt.state = ' compilation' return 'builtin compilation' } mat = stream.match(/^(\:)\s+(\S+)(\s|$)+/) if (mat) { stt.wordList.push({ name: mat[2].toUpperCase() }) stt.state = ' compilation' return 'def' + stt.state } mat = stream.match(/^(VARIABLE|2VARIABLE|CONSTANT|2CONSTANT|CREATE|POSTPONE|VALUE|WORD)\s+(\S+)(\s|$)+/i) if (mat) { stt.wordList.push({ name: mat[2].toUpperCase() }) return 'def' + stt.state } mat = stream.match(/^(\'|\[\'\])\s+(\S+)(\s|$)+/) if (mat) { return 'builtin' + stt.state } } else { // compilation // ; [ if (stream.match(/^(\;|\[)(\s)/)) { stt.state = '' stream.backUp(1) return 'builtin compilation' } if (stream.match(/^(\;|\[)($)/)) { stt.state = '' return 'builtin compilation' } if (stream.match(/^(POSTPONE)\s+\S+(\s|$)+/)) { return 'builtin' } } // dynamic wordlist mat = stream.match(/^(\S+)(\s+|$)/) if (mat) { if (searchWordList(stt.wordList, mat[1]) !== undefined) { return 'variable' + stt.state } // comments if (mat[1] === '\\') { stream.skipToEnd() return 'comment' + stt.state } // core words if (searchWordList(stt.coreWordList, mat[1]) !== undefined) { return 'builtin' + stt.state } if (searchWordList(stt.immediateWordList, mat[1]) !== undefined) { return 'keyword' + stt.state } if (mat[1] === '(') { stream.eatWhile(function (s) { return s !== ')' }) stream.eat(')') return 'comment' + stt.state } // // strings if (mat[1] === '.(') { stream.eatWhile(function (s) { return s !== ')' }) stream.eat(')') return 'string' + stt.state } if (mat[1] === 'S"' || mat[1] === '."' || mat[1] === 'C"') { stream.eatWhile(function (s) { return s !== '"' }) stream.eat('"') return 'string' + stt.state } // numbers if (mat[1] - 0xfffffffff) { return 'number' + stt.state } // if (mat[1].match(/^[-+]?[0-9]+\.[0-9]*/)) { // return 'number' + stt.state; // } return 'atom' + stt.state } }, } }) CodeMirror.defineMIME('text/x-forth', 'forth') })