openrat-cms

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

smalltalk.js (4543B)


      1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
      2 // Distributed under an MIT license: http://codemirror.net/LICENSE
      3 
      4 (function(mod) {
      5   if (typeof exports == "object" && typeof module == "object") // CommonJS
      6     mod(require("../../lib/codemirror"));
      7   else if (typeof define == "function" && define.amd) // AMD
      8     define(["../../lib/codemirror"], mod);
      9   else // Plain browser env
     10     mod(CodeMirror);
     11 })(function(CodeMirror) {
     12 "use strict";
     13 
     14 CodeMirror.defineMode('smalltalk', function(config) {
     15 
     16   var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/;
     17   var keywords = /true|false|nil|self|super|thisContext/;
     18 
     19   var Context = function(tokenizer, parent) {
     20     this.next = tokenizer;
     21     this.parent = parent;
     22   };
     23 
     24   var Token = function(name, context, eos) {
     25     this.name = name;
     26     this.context = context;
     27     this.eos = eos;
     28   };
     29 
     30   var State = function() {
     31     this.context = new Context(next, null);
     32     this.expectVariable = true;
     33     this.indentation = 0;
     34     this.userIndentationDelta = 0;
     35   };
     36 
     37   State.prototype.userIndent = function(indentation) {
     38     this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0;
     39   };
     40 
     41   var next = function(stream, context, state) {
     42     var token = new Token(null, context, false);
     43     var aChar = stream.next();
     44 
     45     if (aChar === '"') {
     46       token = nextComment(stream, new Context(nextComment, context));
     47 
     48     } else if (aChar === '\'') {
     49       token = nextString(stream, new Context(nextString, context));
     50 
     51     } else if (aChar === '#') {
     52       if (stream.peek() === '\'') {
     53         stream.next();
     54         token = nextSymbol(stream, new Context(nextSymbol, context));
     55       } else {
     56         if (stream.eatWhile(/[^\s.{}\[\]()]/))
     57           token.name = 'string-2';
     58         else
     59           token.name = 'meta';
     60       }
     61 
     62     } else if (aChar === '$') {
     63       if (stream.next() === '<') {
     64         stream.eatWhile(/[^\s>]/);
     65         stream.next();
     66       }
     67       token.name = 'string-2';
     68 
     69     } else if (aChar === '|' && state.expectVariable) {
     70       token.context = new Context(nextTemporaries, context);
     71 
     72     } else if (/[\[\]{}()]/.test(aChar)) {
     73       token.name = 'bracket';
     74       token.eos = /[\[{(]/.test(aChar);
     75 
     76       if (aChar === '[') {
     77         state.indentation++;
     78       } else if (aChar === ']') {
     79         state.indentation = Math.max(0, state.indentation - 1);
     80       }
     81 
     82     } else if (specialChars.test(aChar)) {
     83       stream.eatWhile(specialChars);
     84       token.name = 'operator';
     85       token.eos = aChar !== ';'; // ; cascaded message expression
     86 
     87     } else if (/\d/.test(aChar)) {
     88       stream.eatWhile(/[\w\d]/);
     89       token.name = 'number';
     90 
     91     } else if (/[\w_]/.test(aChar)) {
     92       stream.eatWhile(/[\w\d_]/);
     93       token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null;
     94 
     95     } else {
     96       token.eos = state.expectVariable;
     97     }
     98 
     99     return token;
    100   };
    101 
    102   var nextComment = function(stream, context) {
    103     stream.eatWhile(/[^"]/);
    104     return new Token('comment', stream.eat('"') ? context.parent : context, true);
    105   };
    106 
    107   var nextString = function(stream, context) {
    108     stream.eatWhile(/[^']/);
    109     return new Token('string', stream.eat('\'') ? context.parent : context, false);
    110   };
    111 
    112   var nextSymbol = function(stream, context) {
    113     stream.eatWhile(/[^']/);
    114     return new Token('string-2', stream.eat('\'') ? context.parent : context, false);
    115   };
    116 
    117   var nextTemporaries = function(stream, context) {
    118     var token = new Token(null, context, false);
    119     var aChar = stream.next();
    120 
    121     if (aChar === '|') {
    122       token.context = context.parent;
    123       token.eos = true;
    124 
    125     } else {
    126       stream.eatWhile(/[^|]/);
    127       token.name = 'variable';
    128     }
    129 
    130     return token;
    131   };
    132 
    133   return {
    134     startState: function() {
    135       return new State;
    136     },
    137 
    138     token: function(stream, state) {
    139       state.userIndent(stream.indentation());
    140 
    141       if (stream.eatSpace()) {
    142         return null;
    143       }
    144 
    145       var token = state.context.next(stream, state.context, state);
    146       state.context = token.context;
    147       state.expectVariable = token.eos;
    148 
    149       return token.name;
    150     },
    151 
    152     blankLine: function(state) {
    153       state.userIndent(0);
    154     },
    155 
    156     indent: function(state, textAfter) {
    157       var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta;
    158       return (state.indentation + i) * config.indentUnit;
    159     },
    160 
    161     electricChars: ']'
    162   };
    163 
    164 });
    165 
    166 CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'});
    167 
    168 });