topical media & game development

talk show tell print

mobile-query-three-www-live-playground-vendor-CodeMirror2-mode-smalltalk-smalltalk.js / js



  CodeMirror.defineMode('smalltalk', function(config, modeConfig) {
  
          var specialChars = /[+\-/\\*~<>=@%|&?!.:;^]/;
          var keywords = /true|false|nil|self|super|thisContext/;
  
          var Context = function(tokenizer, parent) {
                  this.next = tokenizer;
                  this.parent = parent;
          };
  
          var Token = function(name, context, eos) {
                  this.name = name;
                  this.context = context;
                  this.eos = eos;
          };
  
          var State = function() {
                  this.context = new Context(next, null);
                  this.expectVariable = true;
                  this.indentation = 0;
                  this.userIndentationDelta = 0;
          };
  
          State.prototype.userIndent = function(indentation) {
                  this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0;
          };
  
          var next = function(stream, context, state) {
                  var token = new Token(null, context, false);
                  var aChar = stream.next();
  
                  if (aChar === '"') {
                          token = nextComment(stream, new Context(nextComment, context));
  
                  } else if (aChar === '\'') {
                          token = nextString(stream, new Context(nextString, context));
  
                  } else if (aChar === '#') {
                          stream.eatWhile(/[^ .]/);
                          token.name = 'string-2';
  
                  } else if (aChar === '') {
                          stream.eatWhile(/[^ ]/);
                          token.name = 'string-2';
  
                  } else if (aChar === '|' && state.expectVariable) {
                          token.context = new Context(nextTemporaries, context);
  
                  } else if (/[\[\]{}()]/.test(aChar)) {
                          token.name = 'bracket';
                          token.eos = /[\[{(]/.test(aChar);
  
                          if (aChar === '[') {
                                  state.indentation++;
                          } else if (aChar === ']') {
                                  state.indentation = Math.max(0, state.indentation - 1);
                          }
  
                  } else if (specialChars.test(aChar)) {
                          stream.eatWhile(specialChars);
                          token.name = 'operator';
                          token.eos = aChar !== ';'; // ; cascaded message expression
  
                  } else if (/\d/.test(aChar)) {
                          stream.eatWhile(/[\w\d]/);
                          token.name = 'number'
  
                  } else if (/[\w_]/.test(aChar)) {
                          stream.eatWhile(/[\w\d_]/);
                          token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null;
  
                  } else {
                          token.eos = state.expectVariable;
                  }
  
                  return token;
          };
  
          var nextComment = function(stream, context) {
                  stream.eatWhile(/[^"]/);
                  return new Token('comment', stream.eat('"') ? context.parent : context, true);
          };
  
          var nextString = function(stream, context) {
                  stream.eatWhile(/[^']/);
                  return new Token('string', stream.eat('\'') ? context.parent : context, false);
          };
  
          var nextTemporaries = function(stream, context, state) {
                  var token = new Token(null, context, false);
                  var aChar = stream.next();
  
                  if (aChar === '|') {
                          token.context = context.parent;
                          token.eos = true;
  
                  } else {
                          stream.eatWhile(/[^|]/);
                          token.name = 'variable';
                  }
  
                  return token;
          }
  
          return {
                  startState: function() {
                          return new State;
                  },
  
                  token: function(stream, state) {
                          state.userIndent(stream.indentation());
  
                          if (stream.eatSpace()) {
                                  return null;
                          }
  
                          var token = state.context.next(stream, state.context, state);
                          state.context = token.context;
                          state.expectVariable = token.eos;
  
                          state.lastToken = token;
                          return token.name;
                  },
  
                  blankLine: function(state) {
                          state.userIndent(0);
                  },
  
                  indent: function(state, textAfter) {
                          var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta;
                          return (state.indentation + i) * config.indentUnit;
                  },
  
                  electricChars: ']'
          };
  
  });
  
  CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'});


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.