openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

forth.js (5230B)


      1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
      2 // Distributed under an MIT license: http://codemirror.net/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 });