Code coverage report for sc/lang/compiler/lexer/string.js

Statements: 100% (66 / 66)      Branches: 100% (28 / 28)      Functions: 100% (11 / 11)      Lines: 100% (66 / 66)      Ignored: none     

All files » sc/lang/compiler/lexer/ » string.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 1281     1   1 1   1 60     1 60 60     1 60           1 60     1 9 9   9 1     8   8     1 60   60 54     6   6     1 54 54   54 40     14 14 14 51 51 11   40 1   39 1   38       3     1 40 40   40 9     31 31 31 132 132 30 102 1 1 1 101 1   100       1     1 55               1 4                
(function(sc) {
  "use strict";
 
  require("./lexer");
 
  var Token = sc.lang.compiler.Token;
  var Lexer = sc.lang.compiler.Lexer;
 
  Lexer.addLexMethod("String", function(source, index) {
    return new StringLexer(source, index).scan();
  });
 
  function StringLexer(source, index) {
    this.source = source;
    this.index = index;
  }
 
  StringLexer.prototype.scan = function() {
    return this.scanSymbolLiteral() ||
      this.scanQuotedSymbolLiteral() ||
      this.scanStringLiteral() ||
      this.scanCharLiteral();
  };
 
  StringLexer.prototype.match = function(re) {
    return re.exec(this.source.slice(this.index));
  };
 
  StringLexer.prototype.scanCharLiteral = function() {
    var source = this.source;
    var index  = this.index;
 
    if (source.charAt(index) !== "$") {
      return;
    }
 
    var value = source.charAt(index + 1) || "";
 
    return makeStringToken(Token.CharLiteral, value, 1);
  };
 
  StringLexer.prototype.scanSymbolLiteral = function() {
    var items = this.match(/^\\([a-zA-Z_]\w*|\d+)?/);
 
    if (!items) {
      return;
    }
 
    var value = items[1] || "";
 
    return makeStringToken(Token.SymbolLiteral, value, 1);
  };
 
  StringLexer.prototype.scanQuotedSymbolLiteral = function() {
    var source = this.source;
    var index  = this.index;
 
    if (source.charAt(index) !== "'") {
      return;
    }
 
    var value = "";
    var pad = 2;
    for (var i = index + 1, imax = source.length; i < imax; ++i) {
      var ch = source.charAt(i);
      if (ch === "'") {
        return makeStringToken(Token.SymbolLiteral, value, pad);
      }
      if (ch === "\n") {
        break;
      }
      if (ch === "\\") {
        pad += 1;
      } else {
        value += ch;
      }
    }
 
    return makeErrorToken("'" + value);
  };
 
  StringLexer.prototype.scanStringLiteral = function() {
    var source = this.source;
    var index  = this.index;
 
    if (source.charAt(index) !== '"') {
      return;
    }
 
    var value = "";
    var pad = 2, line = 0;
    for (var i = index + 1, imax = source.length; i < imax; ++i) {
      var ch = source.charAt(i);
      if (ch === '"') {
        return makeStringToken(Token.StringLiteral, value, pad, line);
      } else if (ch === "\n") {
        line += 1;
        value += "\\n";
        pad -= 1;
      } else if (ch === "\\") {
        value += "\\" + source.charAt(++i);
      } else {
        value += ch;
      }
    }
 
    return makeErrorToken('"' + value, line);
  };
 
  function makeStringToken(type, value, pad, line) {
    return {
      type: type,
      value: value,
      length: value.length + pad,
      line: line|0
    };
  }
 
  function makeErrorToken(value, line) {
    return {
      error: true,
      value: value,
      length: value.length,
      line: line|0
    };
  }
})(sc);