diff options
| -rw-r--r-- | src/llex.js | 176 | 
1 files changed, 106 insertions, 70 deletions
| diff --git a/src/llex.js b/src/llex.js index 646f8f6..c61981f 100644 --- a/src/llex.js +++ b/src/llex.js @@ -30,50 +30,86 @@ const FIRST_RESERVED = 257;  const LUA_ENV = to_luastring("_ENV", true); +/* terminal symbols denoted by reserved words */ +const TK_AND      = FIRST_RESERVED; +const TK_BREAK    = FIRST_RESERVED + 1; +const TK_DO       = FIRST_RESERVED + 2; +const TK_ELSE     = FIRST_RESERVED + 3; +const TK_ELSEIF   = FIRST_RESERVED + 4; +const TK_END      = FIRST_RESERVED + 5; +const TK_FALSE    = FIRST_RESERVED + 6; +const TK_FOR      = FIRST_RESERVED + 7; +const TK_FUNCTION = FIRST_RESERVED + 8; +const TK_GOTO     = FIRST_RESERVED + 9; +const TK_IF       = FIRST_RESERVED + 10; +const TK_IN       = FIRST_RESERVED + 11; +const TK_LOCAL    = FIRST_RESERVED + 12; +const TK_NIL      = FIRST_RESERVED + 13; +const TK_NOT      = FIRST_RESERVED + 14; +const TK_OR       = FIRST_RESERVED + 15; +const TK_REPEAT   = FIRST_RESERVED + 16; +const TK_RETURN   = FIRST_RESERVED + 17; +const TK_THEN     = FIRST_RESERVED + 18; +const TK_TRUE     = FIRST_RESERVED + 19; +const TK_UNTIL    = FIRST_RESERVED + 20; +const TK_WHILE    = FIRST_RESERVED + 21; +/* other terminal symbols */ +const TK_IDIV     = FIRST_RESERVED + 22; +const TK_CONCAT   = FIRST_RESERVED + 23; +const TK_DOTS     = FIRST_RESERVED + 24; +const TK_EQ       = FIRST_RESERVED + 25; +const TK_GE       = FIRST_RESERVED + 26; +const TK_LE       = FIRST_RESERVED + 27; +const TK_NE       = FIRST_RESERVED + 28; +const TK_SHL      = FIRST_RESERVED + 29; +const TK_SHR      = FIRST_RESERVED + 30; +const TK_DBCOLON  = FIRST_RESERVED + 31; +const TK_EOS      = FIRST_RESERVED + 32; +const TK_FLT      = FIRST_RESERVED + 33; +const TK_INT      = FIRST_RESERVED + 34; +const TK_NAME     = FIRST_RESERVED + 35; +const TK_STRING   = FIRST_RESERVED + 36; +  const RESERVED = { -    /* terminal symbols denoted by reserved words */ -    TK_AND:      FIRST_RESERVED, -    TK_BREAK:    FIRST_RESERVED + 1, -    TK_DO:       FIRST_RESERVED + 2, -    TK_ELSE:     FIRST_RESERVED + 3, -    TK_ELSEIF:   FIRST_RESERVED + 4, -    TK_END:      FIRST_RESERVED + 5, -    TK_FALSE:    FIRST_RESERVED + 6, -    TK_FOR:      FIRST_RESERVED + 7, -    TK_FUNCTION: FIRST_RESERVED + 8, -    TK_GOTO:     FIRST_RESERVED + 9, -    TK_IF:       FIRST_RESERVED + 10, -    TK_IN:       FIRST_RESERVED + 11, -    TK_LOCAL:    FIRST_RESERVED + 12, -    TK_NIL:      FIRST_RESERVED + 13, -    TK_NOT:      FIRST_RESERVED + 14, -    TK_OR:       FIRST_RESERVED + 15, -    TK_REPEAT:   FIRST_RESERVED + 16, -    TK_RETURN:   FIRST_RESERVED + 17, -    TK_THEN:     FIRST_RESERVED + 18, -    TK_TRUE:     FIRST_RESERVED + 19, -    TK_UNTIL:    FIRST_RESERVED + 20, -    TK_WHILE:    FIRST_RESERVED + 21, -    /* other terminal symbols */ -    TK_IDIV:     FIRST_RESERVED + 22, -    TK_CONCAT:   FIRST_RESERVED + 23, -    TK_DOTS:     FIRST_RESERVED + 24, -    TK_EQ:       FIRST_RESERVED + 25, -    TK_GE:       FIRST_RESERVED + 26, -    TK_LE:       FIRST_RESERVED + 27, -    TK_NE:       FIRST_RESERVED + 28, -    TK_SHL:      FIRST_RESERVED + 29, -    TK_SHR:      FIRST_RESERVED + 30, -    TK_DBCOLON:  FIRST_RESERVED + 31, -    TK_EOS:      FIRST_RESERVED + 32, -    TK_FLT:      FIRST_RESERVED + 33, -    TK_INT:      FIRST_RESERVED + 34, -    TK_NAME:     FIRST_RESERVED + 35, -    TK_STRING:   FIRST_RESERVED + 36 +    "TK_AND":      TK_AND, +    "TK_BREAK":    TK_BREAK, +    "TK_DO":       TK_DO, +    "TK_ELSE":     TK_ELSE, +    "TK_ELSEIF":   TK_ELSEIF, +    "TK_END":      TK_END, +    "TK_FALSE":    TK_FALSE, +    "TK_FOR":      TK_FOR, +    "TK_FUNCTION": TK_FUNCTION, +    "TK_GOTO":     TK_GOTO, +    "TK_IF":       TK_IF, +    "TK_IN":       TK_IN, +    "TK_LOCAL":    TK_LOCAL, +    "TK_NIL":      TK_NIL, +    "TK_NOT":      TK_NOT, +    "TK_OR":       TK_OR, +    "TK_REPEAT":   TK_REPEAT, +    "TK_RETURN":   TK_RETURN, +    "TK_THEN":     TK_THEN, +    "TK_TRUE":     TK_TRUE, +    "TK_UNTIL":    TK_UNTIL, +    "TK_WHILE":    TK_WHILE, +    "TK_IDIV":     TK_IDIV, +    "TK_CONCAT":   TK_CONCAT, +    "TK_DOTS":     TK_DOTS, +    "TK_EQ":       TK_EQ, +    "TK_GE":       TK_GE, +    "TK_LE":       TK_LE, +    "TK_NE":       TK_NE, +    "TK_SHL":      TK_SHL, +    "TK_SHR":      TK_SHR, +    "TK_DBCOLON":  TK_DBCOLON, +    "TK_EOS":      TK_EOS, +    "TK_FLT":      TK_FLT, +    "TK_INT":      TK_INT, +    "TK_NAME":     TK_NAME, +    "TK_STRING":   TK_STRING  }; -const R = RESERVED; -  const luaX_tokens = [      "and", "break", "do", "else", "elseif",      "end", "false", "for", "function", "goto", "if", @@ -135,7 +171,7 @@ const luaX_token2str = function(ls, token) {          return lobject.luaO_pushfstring(ls.L, to_luastring("'%c'", true), token);      } else {          let s = luaX_tokens[token - FIRST_RESERVED]; -        if (token < R.TK_EOS)  /* fixed format (symbols and reserved words)? */ +        if (token < TK_EOS)  /* fixed format (symbols and reserved words)? */              return lobject.luaO_pushfstring(ls.L, to_luastring("'%s'", true), to_luastring(s));          else  /* names, strings, and numerals */              return to_luastring(s); @@ -197,7 +233,7 @@ const luaX_setinput = function(L, ls, z, source, firstchar) {      ls.L = L;      ls.current = firstchar;      ls.lookahead = { -        token: R.TK_EOS, +        token: TK_EOS,          seminfo: new SemInfo()      };      ls.z = z; @@ -253,21 +289,21 @@ const read_numeral = function(ls, seminfo) {      let obj = new lobject.TValue();      if (lobject.luaO_str2num(luaZ_buffer(ls.buff), obj) === 0)  /* format error? */ -        lexerror(ls, to_luastring("malformed number", true), R.TK_FLT); +        lexerror(ls, to_luastring("malformed number", true), TK_FLT);      if (obj.ttisinteger()) {          seminfo.i = obj.value; -        return R.TK_INT; +        return TK_INT;      } else {          lua_assert(obj.ttisfloat());          seminfo.r = obj.value; -        return R.TK_FLT; +        return TK_FLT;      }  };  const txtToken = function(ls, token) {      switch (token) { -        case R.TK_NAME: case R.TK_STRING: -        case R.TK_FLT: case R.TK_INT: +        case TK_NAME: case TK_STRING: +        case TK_FLT: case TK_INT:              // save(ls, 0);              return lobject.luaO_pushfstring(ls.L, to_luastring("'%s'", true), luaZ_buffer(ls.buff));          default: @@ -316,7 +352,7 @@ const read_long_string = function(ls, seminfo, sep) {              case EOZ: {  /* error */                  let what = seminfo ? "string" : "comment";                  let msg = `unfinished long ${what} (starting at line ${line})`; -                lexerror(ls, to_luastring(msg), R.TK_EOS); +                lexerror(ls, to_luastring(msg), TK_EOS);                  break;              }              case 93 /* (']').charCodeAt(0) */: { @@ -348,7 +384,7 @@ const esccheck = function(ls, c, msg) {      if (!c) {          if (ls.current !== EOZ)              save_and_next(ls);  /* add current to buffer for error message */ -        lexerror(ls, msg, R.TK_STRING); +        lexerror(ls, msg, TK_STRING);      }  }; @@ -409,11 +445,11 @@ const read_string = function(ls, del, seminfo) {      while (ls.current !== del) {          switch (ls.current) {              case EOZ: -                lexerror(ls, to_luastring("unfinished string", true), R.TK_EOS); +                lexerror(ls, to_luastring("unfinished string", true), TK_EOS);                  break;              case 10 /* ('\n').charCodeAt(0) */:              case 13 /* ('\r').charCodeAt(0) */: -                lexerror(ls, to_luastring("unfinished string", true), R.TK_STRING); +                lexerror(ls, to_luastring("unfinished string", true), TK_STRING);                  break;              case 92 /* ('\\').charCodeAt(0) */: {  /* escape sequences */                  save_and_next(ls);  /* keep '\\' for error messages */ @@ -521,54 +557,54 @@ const llex = function(ls, seminfo) {                  let sep = skip_sep(ls);                  if (sep >= 0) {                      read_long_string(ls, seminfo, sep); -                    return R.TK_STRING; +                    return TK_STRING;                  } else if (sep !== -1)  /* '[=...' missing second bracket */ -                    lexerror(ls, to_luastring("invalid long string delimiter", true), R.TK_STRING); +                    lexerror(ls, to_luastring("invalid long string delimiter", true), TK_STRING);                  return 91 /* ('[').charCodeAt(0) */;              }              case 61 /* ('=').charCodeAt(0) */: {                  next(ls); -                if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return R.TK_EQ; +                if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return TK_EQ;                  else return 61 /* ('=').charCodeAt(0) */;              }              case 60 /* ('<').charCodeAt(0) */: {                  next(ls); -                if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return R.TK_LE; -                else if (check_next1(ls, 60 /* ('<').charCodeAt(0) */)) return R.TK_SHL; +                if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return TK_LE; +                else if (check_next1(ls, 60 /* ('<').charCodeAt(0) */)) return TK_SHL;                  else return 60 /* ('<').charCodeAt(0) */;              }              case 62 /* ('>').charCodeAt(0) */: {                  next(ls); -                if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return R.TK_GE; -                else if (check_next1(ls, 62 /* ('>').charCodeAt(0) */)) return R.TK_SHR; +                if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return TK_GE; +                else if (check_next1(ls, 62 /* ('>').charCodeAt(0) */)) return TK_SHR;                  else return 62 /* ('>').charCodeAt(0) */;              }              case 47 /* ('/').charCodeAt(0) */: {                  next(ls); -                if (check_next1(ls, 47 /* ('/').charCodeAt(0) */)) return R.TK_IDIV; +                if (check_next1(ls, 47 /* ('/').charCodeAt(0) */)) return TK_IDIV;                  else return 47 /* ('/').charCodeAt(0) */;              }              case 126 /* ('~').charCodeAt(0) */: {                  next(ls); -                if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return R.TK_NE; +                if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return TK_NE;                  else return 126 /* ('~').charCodeAt(0) */;              }              case 58 /* (':').charCodeAt(0) */: {                  next(ls); -                if (check_next1(ls, 58 /* (':').charCodeAt(0) */)) return R.TK_DBCOLON; +                if (check_next1(ls, 58 /* (':').charCodeAt(0) */)) return TK_DBCOLON;                  else return 58 /* (':').charCodeAt(0) */;              }              case 34 /* ('"').charCodeAt(0) */:              case 39 /* ('\'').charCodeAt(0) */: {  /* short literal strings */                  read_string(ls, ls.current, seminfo); -                return R.TK_STRING; +                return TK_STRING;              }              case 46 /* ('.').charCodeAt(0) */: {  /* '.', '..', '...', or number */                  save_and_next(ls);                  if (check_next1(ls, 46 /* ('.').charCodeAt(0) */)) {                      if (check_next1(ls, 46 /* ('.').charCodeAt(0) */)) -                        return R.TK_DOTS;   /* '...' */ -                    else return R.TK_CONCAT;   /* '..' */ +                        return TK_DOTS;   /* '...' */ +                    else return TK_CONCAT;   /* '..' */                  }                  else if (!ljstype.lisdigit(ls.current)) return 46 /* ('.').charCodeAt(0) */;                  else return read_numeral(ls, seminfo); @@ -578,7 +614,7 @@ const llex = function(ls, seminfo) {                  return read_numeral(ls, seminfo);              }              case EOZ: { -                return R.TK_EOS; +                return TK_EOS;              }              default: {                  if (ljstype.lislalpha(ls.current)) {  /* identifier or reserved word? */ @@ -591,7 +627,7 @@ const llex = function(ls, seminfo) {                      if (kidx !== void 0 && kidx <= 22)  /* reserved word? */                          return kidx + FIRST_RESERVED;                      else -                        return R.TK_NAME; +                        return TK_NAME;                  } else {  /* single-char tokens (+ - / ...) */                      let c = ls.current;                      next(ls); @@ -604,18 +640,18 @@ const llex = function(ls, seminfo) {  const luaX_next = function(ls) {      ls.lastline = ls.linenumber; -    if (ls.lookahead.token !== R.TK_EOS) {  /* is there a look-ahead token? */ +    if (ls.lookahead.token !== TK_EOS) {  /* is there a look-ahead token? */          ls.t.token = ls.lookahead.token;  /* use this one */          ls.t.seminfo.i = ls.lookahead.seminfo.i;          ls.t.seminfo.r = ls.lookahead.seminfo.r;          ls.t.seminfo.ts = ls.lookahead.seminfo.ts; // TODO ? -        ls.lookahead.token = R.TK_EOS;  /* and discharge it */ +        ls.lookahead.token = TK_EOS;  /* and discharge it */      } else          ls.t.token = llex(ls, ls.t.seminfo);  /* read next token */  };  const luaX_lookahead = function(ls) { -    lua_assert(ls.lookahead.token === R.TK_EOS); +    lua_assert(ls.lookahead.token === TK_EOS);      ls.lookahead.token = llex(ls, ls.lookahead.seminfo);      return ls.lookahead.token;  }; | 
