lua/llex.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 09 Apr 2020 02:15:46 -0400
changeset 60 a0629a9e3ee6
parent 0 d7ee4e2ed49d
permissions -rw-r--r--
otp: Some base32-decoding fixes to match what Google Authenticator expects.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     1
/*
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     2
** $Id: llex.c,v 2.63.1.2 2013/08/30 15:49:41 roberto Exp $
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     3
** Lexical Analyzer
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     4
** See Copyright Notice in lua.h
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     5
*/
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     6
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     7
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     8
#include <locale.h>
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     9
#include <string.h>
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    10
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    11
#define llex_c
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    12
#define LUA_CORE
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    13
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    14
#include "lua.h"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    15
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    16
#include "lctype.h"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    17
#include "ldo.h"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    18
#include "llex.h"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    19
#include "lobject.h"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    20
#include "lparser.h"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    21
#include "lstate.h"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    22
#include "lstring.h"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    23
#include "ltable.h"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    24
#include "lzio.h"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    25
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    26
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    27
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    28
#define next(ls) (ls->current = zgetc(ls->z))
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    29
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    30
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    31
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    32
#define currIsNewline(ls)	(ls->current == '\n' || ls->current == '\r')
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    33
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    34
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    35
/* ORDER RESERVED */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    36
static const char *const luaX_tokens [] = {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    37
    "and", "break", "do", "else", "elseif",
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    38
    "end", "false", "for", "function", "goto", "if",
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    39
    "in", "local", "nil", "not", "or", "repeat",
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    40
    "return", "then", "true", "until", "while",
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    41
    "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    42
    "<number>", "<name>", "<string>"
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    43
};
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    44
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    45
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    46
#define save_and_next(ls) (save(ls, ls->current), next(ls))
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    47
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    48
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    49
static l_noret lexerror (LexState *ls, const char *msg, int token);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    50
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    51
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    52
static void save (LexState *ls, int c) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    53
  Mbuffer *b = ls->buff;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    54
  if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    55
    size_t newsize;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    56
    if (luaZ_sizebuffer(b) >= MAX_SIZET/2)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    57
      lexerror(ls, "lexical element too long", 0);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    58
    newsize = luaZ_sizebuffer(b) * 2;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    59
    luaZ_resizebuffer(ls->L, b, newsize);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    60
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    61
  b->buffer[luaZ_bufflen(b)++] = cast(char, c);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    62
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    63
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    64
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    65
void luaX_init (lua_State *L) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    66
  int i;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    67
  for (i=0; i<NUM_RESERVED; i++) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    68
    TString *ts = luaS_new(L, luaX_tokens[i]);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    69
    luaS_fix(ts);  /* reserved words are never collected */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    70
    ts->tsv.extra = cast_byte(i+1);  /* reserved word */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    71
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    72
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    73
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    74
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    75
const char *luaX_token2str (LexState *ls, int token) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    76
  if (token < FIRST_RESERVED) {  /* single-byte symbols? */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    77
    lua_assert(token == cast(unsigned char, token));
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    78
    return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    79
                              luaO_pushfstring(ls->L, "char(%d)", token);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    80
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    81
  else {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    82
    const char *s = luaX_tokens[token - FIRST_RESERVED];
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    83
    if (token < TK_EOS)  /* fixed format (symbols and reserved words)? */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    84
      return luaO_pushfstring(ls->L, LUA_QS, s);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    85
    else  /* names, strings, and numerals */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    86
      return s;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    87
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    88
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    89
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    90
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    91
static const char *txtToken (LexState *ls, int token) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    92
  switch (token) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    93
    case TK_NAME:
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    94
    case TK_STRING:
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    95
    case TK_NUMBER:
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    96
      save(ls, '\0');
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    97
      return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    98
    default:
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    99
      return luaX_token2str(ls, token);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   100
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   101
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   102
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   103
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   104
static l_noret lexerror (LexState *ls, const char *msg, int token) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   105
  char buff[LUA_IDSIZE];
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   106
  luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   107
  msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   108
  if (token)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   109
    luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   110
  luaD_throw(ls->L, LUA_ERRSYNTAX);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   111
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   112
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   113
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   114
l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   115
  lexerror(ls, msg, ls->t.token);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   116
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   117
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   118
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   119
/*
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   120
** creates a new string and anchors it in function's table so that
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   121
** it will not be collected until the end of the function's compilation
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   122
** (by that time it should be anchored in function's prototype)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   123
*/
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   124
TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   125
  lua_State *L = ls->L;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   126
  TValue *o;  /* entry for `str' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   127
  TString *ts = luaS_newlstr(L, str, l);  /* create new string */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   128
  setsvalue2s(L, L->top++, ts);  /* temporarily anchor it in stack */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   129
  o = luaH_set(L, ls->fs->h, L->top - 1);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   130
  if (ttisnil(o)) {  /* not in use yet? (see 'addK') */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   131
    /* boolean value does not need GC barrier;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   132
       table has no metatable, so it does not need to invalidate cache */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   133
    setbvalue(o, 1);  /* t[string] = true */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   134
    luaC_checkGC(L);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   135
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   136
  else {  /* string already present */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   137
    ts = rawtsvalue(keyfromval(o));  /* re-use value previously stored */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   138
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   139
  L->top--;  /* remove string from stack */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   140
  return ts;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   141
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   142
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   143
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   144
/*
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   145
** increment line number and skips newline sequence (any of
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   146
** \n, \r, \n\r, or \r\n)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   147
*/
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   148
static void inclinenumber (LexState *ls) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   149
  int old = ls->current;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   150
  lua_assert(currIsNewline(ls));
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   151
  next(ls);  /* skip `\n' or `\r' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   152
  if (currIsNewline(ls) && ls->current != old)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   153
    next(ls);  /* skip `\n\r' or `\r\n' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   154
  if (++ls->linenumber >= MAX_INT)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   155
    luaX_syntaxerror(ls, "chunk has too many lines");
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   156
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   157
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   158
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   159
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   160
                    int firstchar) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   161
  ls->decpoint = '.';
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   162
  ls->L = L;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   163
  ls->current = firstchar;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   164
  ls->lookahead.token = TK_EOS;  /* no look-ahead token */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   165
  ls->z = z;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   166
  ls->fs = NULL;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   167
  ls->linenumber = 1;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   168
  ls->lastline = 1;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   169
  ls->source = source;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   170
  ls->envn = luaS_new(L, LUA_ENV);  /* create env name */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   171
  luaS_fix(ls->envn);  /* never collect this name */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   172
  luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   173
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   174
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   175
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   176
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   177
/*
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   178
** =======================================================
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   179
** LEXICAL ANALYZER
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   180
** =======================================================
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   181
*/
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   182
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   183
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   184
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   185
static int check_next (LexState *ls, const char *set) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   186
  if (ls->current == '\0' || !strchr(set, ls->current))
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   187
    return 0;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   188
  save_and_next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   189
  return 1;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   190
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   191
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   192
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   193
/*
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   194
** change all characters 'from' in buffer to 'to'
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   195
*/
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   196
static void buffreplace (LexState *ls, char from, char to) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   197
  size_t n = luaZ_bufflen(ls->buff);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   198
  char *p = luaZ_buffer(ls->buff);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   199
  while (n--)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   200
    if (p[n] == from) p[n] = to;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   201
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   202
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   203
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   204
#if !defined(getlocaledecpoint)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   205
#define getlocaledecpoint()	(localeconv()->decimal_point[0])
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   206
#endif
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   207
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   208
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   209
#define buff2d(b,e)	luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   210
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   211
/*
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   212
** in case of format error, try to change decimal point separator to
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   213
** the one defined in the current locale and check again
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   214
*/
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   215
static void trydecpoint (LexState *ls, SemInfo *seminfo) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   216
  char old = ls->decpoint;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   217
  ls->decpoint = getlocaledecpoint();
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   218
  buffreplace(ls, old, ls->decpoint);  /* try new decimal separator */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   219
  if (!buff2d(ls->buff, &seminfo->r)) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   220
    /* format error with correct decimal point: no more options */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   221
    buffreplace(ls, ls->decpoint, '.');  /* undo change (for error message) */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   222
    lexerror(ls, "malformed number", TK_NUMBER);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   223
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   224
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   225
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   226
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   227
/* LUA_NUMBER */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   228
/*
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   229
** this function is quite liberal in what it accepts, as 'luaO_str2d'
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   230
** will reject ill-formed numerals.
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   231
*/
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   232
static void read_numeral (LexState *ls, SemInfo *seminfo) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   233
  const char *expo = "Ee";
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   234
  int first = ls->current;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   235
  lua_assert(lisdigit(ls->current));
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   236
  save_and_next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   237
  if (first == '0' && check_next(ls, "Xx"))  /* hexadecimal? */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   238
    expo = "Pp";
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   239
  for (;;) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   240
    if (check_next(ls, expo))  /* exponent part? */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   241
      check_next(ls, "+-");  /* optional exponent sign */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   242
    if (lisxdigit(ls->current) || ls->current == '.')
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   243
      save_and_next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   244
    else  break;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   245
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   246
  save(ls, '\0');
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   247
  buffreplace(ls, '.', ls->decpoint);  /* follow locale for decimal point */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   248
  if (!buff2d(ls->buff, &seminfo->r))  /* format error? */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   249
    trydecpoint(ls, seminfo); /* try to update decimal point separator */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   250
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   251
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   252
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   253
/*
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   254
** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   255
** -1 if sequence is malformed
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   256
*/
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   257
static int skip_sep (LexState *ls) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   258
  int count = 0;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   259
  int s = ls->current;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   260
  lua_assert(s == '[' || s == ']');
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   261
  save_and_next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   262
  while (ls->current == '=') {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   263
    save_and_next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   264
    count++;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   265
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   266
  return (ls->current == s) ? count : (-count) - 1;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   267
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   268
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   269
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   270
static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   271
  save_and_next(ls);  /* skip 2nd `[' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   272
  if (currIsNewline(ls))  /* string starts with a newline? */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   273
    inclinenumber(ls);  /* skip it */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   274
  for (;;) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   275
    switch (ls->current) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   276
      case EOZ:
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   277
        lexerror(ls, (seminfo) ? "unfinished long string" :
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   278
                                 "unfinished long comment", TK_EOS);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   279
        break;  /* to avoid warnings */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   280
      case ']': {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   281
        if (skip_sep(ls) == sep) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   282
          save_and_next(ls);  /* skip 2nd `]' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   283
          goto endloop;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   284
        }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   285
        break;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   286
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   287
      case '\n': case '\r': {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   288
        save(ls, '\n');
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   289
        inclinenumber(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   290
        if (!seminfo) luaZ_resetbuffer(ls->buff);  /* avoid wasting space */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   291
        break;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   292
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   293
      default: {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   294
        if (seminfo) save_and_next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   295
        else next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   296
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   297
    }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   298
  } endloop:
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   299
  if (seminfo)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   300
    seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   301
                                     luaZ_bufflen(ls->buff) - 2*(2 + sep));
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   302
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   303
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   304
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   305
static void escerror (LexState *ls, int *c, int n, const char *msg) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   306
  int i;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   307
  luaZ_resetbuffer(ls->buff);  /* prepare error message */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   308
  save(ls, '\\');
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   309
  for (i = 0; i < n && c[i] != EOZ; i++)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   310
    save(ls, c[i]);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   311
  lexerror(ls, msg, TK_STRING);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   312
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   313
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   314
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   315
static int readhexaesc (LexState *ls) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   316
  int c[3], i;  /* keep input for error message */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   317
  int r = 0;  /* result accumulator */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   318
  c[0] = 'x';  /* for error message */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   319
  for (i = 1; i < 3; i++) {  /* read two hexadecimal digits */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   320
    c[i] = next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   321
    if (!lisxdigit(c[i]))
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   322
      escerror(ls, c, i + 1, "hexadecimal digit expected");
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   323
    r = (r << 4) + luaO_hexavalue(c[i]);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   324
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   325
  return r;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   326
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   327
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   328
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   329
static int readdecesc (LexState *ls) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   330
  int c[3], i;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   331
  int r = 0;  /* result accumulator */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   332
  for (i = 0; i < 3 && lisdigit(ls->current); i++) {  /* read up to 3 digits */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   333
    c[i] = ls->current;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   334
    r = 10*r + c[i] - '0';
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   335
    next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   336
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   337
  if (r > UCHAR_MAX)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   338
    escerror(ls, c, i, "decimal escape too large");
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   339
  return r;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   340
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   341
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   342
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   343
static void read_string (LexState *ls, int del, SemInfo *seminfo) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   344
  save_and_next(ls);  /* keep delimiter (for error messages) */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   345
  while (ls->current != del) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   346
    switch (ls->current) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   347
      case EOZ:
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   348
        lexerror(ls, "unfinished string", TK_EOS);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   349
        break;  /* to avoid warnings */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   350
      case '\n':
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   351
      case '\r':
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   352
        lexerror(ls, "unfinished string", TK_STRING);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   353
        break;  /* to avoid warnings */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   354
      case '\\': {  /* escape sequences */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   355
        int c;  /* final character to be saved */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   356
        next(ls);  /* do not save the `\' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   357
        switch (ls->current) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   358
          case 'a': c = '\a'; goto read_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   359
          case 'b': c = '\b'; goto read_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   360
          case 'f': c = '\f'; goto read_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   361
          case 'n': c = '\n'; goto read_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   362
          case 'r': c = '\r'; goto read_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   363
          case 't': c = '\t'; goto read_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   364
          case 'v': c = '\v'; goto read_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   365
          case 'x': c = readhexaesc(ls); goto read_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   366
          case '\n': case '\r':
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   367
            inclinenumber(ls); c = '\n'; goto only_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   368
          case '\\': case '\"': case '\'':
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   369
            c = ls->current; goto read_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   370
          case EOZ: goto no_save;  /* will raise an error next loop */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   371
          case 'z': {  /* zap following span of spaces */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   372
            next(ls);  /* skip the 'z' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   373
            while (lisspace(ls->current)) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   374
              if (currIsNewline(ls)) inclinenumber(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   375
              else next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   376
            }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   377
            goto no_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   378
          }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   379
          default: {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   380
            if (!lisdigit(ls->current))
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   381
              escerror(ls, &ls->current, 1, "invalid escape sequence");
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   382
            /* digital escape \ddd */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   383
            c = readdecesc(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   384
            goto only_save;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   385
          }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   386
        }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   387
       read_save: next(ls);  /* read next character */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   388
       only_save: save(ls, c);  /* save 'c' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   389
       no_save: break;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   390
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   391
      default:
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   392
        save_and_next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   393
    }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   394
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   395
  save_and_next(ls);  /* skip delimiter */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   396
  seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   397
                                   luaZ_bufflen(ls->buff) - 2);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   398
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   399
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   400
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   401
static int llex (LexState *ls, SemInfo *seminfo) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   402
  luaZ_resetbuffer(ls->buff);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   403
  for (;;) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   404
    switch (ls->current) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   405
      case '\n': case '\r': {  /* line breaks */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   406
        inclinenumber(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   407
        break;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   408
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   409
      case ' ': case '\f': case '\t': case '\v': {  /* spaces */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   410
        next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   411
        break;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   412
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   413
      case '-': {  /* '-' or '--' (comment) */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   414
        next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   415
        if (ls->current != '-') return '-';
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   416
        /* else is a comment */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   417
        next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   418
        if (ls->current == '[') {  /* long comment? */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   419
          int sep = skip_sep(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   420
          luaZ_resetbuffer(ls->buff);  /* `skip_sep' may dirty the buffer */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   421
          if (sep >= 0) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   422
            read_long_string(ls, NULL, sep);  /* skip long comment */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   423
            luaZ_resetbuffer(ls->buff);  /* previous call may dirty the buff. */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   424
            break;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   425
          }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   426
        }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   427
        /* else short comment */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   428
        while (!currIsNewline(ls) && ls->current != EOZ)
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   429
          next(ls);  /* skip until end of line (or end of file) */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   430
        break;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   431
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   432
      case '[': {  /* long string or simply '[' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   433
        int sep = skip_sep(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   434
        if (sep >= 0) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   435
          read_long_string(ls, seminfo, sep);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   436
          return TK_STRING;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   437
        }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   438
        else if (sep == -1) return '[';
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   439
        else lexerror(ls, "invalid long string delimiter", TK_STRING);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   440
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   441
      case '=': {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   442
        next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   443
        if (ls->current != '=') return '=';
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   444
        else { next(ls); return TK_EQ; }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   445
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   446
      case '<': {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   447
        next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   448
        if (ls->current != '=') return '<';
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   449
        else { next(ls); return TK_LE; }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   450
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   451
      case '>': {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   452
        next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   453
        if (ls->current != '=') return '>';
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   454
        else { next(ls); return TK_GE; }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   455
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   456
      case '~': {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   457
        next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   458
        if (ls->current != '=') return '~';
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   459
        else { next(ls); return TK_NE; }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   460
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   461
      case ':': {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   462
        next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   463
        if (ls->current != ':') return ':';
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   464
        else { next(ls); return TK_DBCOLON; }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   465
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   466
      case '"': case '\'': {  /* short literal strings */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   467
        read_string(ls, ls->current, seminfo);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   468
        return TK_STRING;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   469
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   470
      case '.': {  /* '.', '..', '...', or number */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   471
        save_and_next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   472
        if (check_next(ls, ".")) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   473
          if (check_next(ls, "."))
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   474
            return TK_DOTS;   /* '...' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   475
          else return TK_CONCAT;   /* '..' */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   476
        }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   477
        else if (!lisdigit(ls->current)) return '.';
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   478
        /* else go through */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   479
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   480
      case '0': case '1': case '2': case '3': case '4':
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   481
      case '5': case '6': case '7': case '8': case '9': {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   482
        read_numeral(ls, seminfo);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   483
        return TK_NUMBER;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   484
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   485
      case EOZ: {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   486
        return TK_EOS;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   487
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   488
      default: {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   489
        if (lislalpha(ls->current)) {  /* identifier or reserved word? */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   490
          TString *ts;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   491
          do {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   492
            save_and_next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   493
          } while (lislalnum(ls->current));
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   494
          ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   495
                                  luaZ_bufflen(ls->buff));
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   496
          seminfo->ts = ts;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   497
          if (isreserved(ts))  /* reserved word? */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   498
            return ts->tsv.extra - 1 + FIRST_RESERVED;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   499
          else {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   500
            return TK_NAME;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   501
          }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   502
        }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   503
        else {  /* single-char tokens (+ - / ...) */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   504
          int c = ls->current;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   505
          next(ls);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   506
          return c;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   507
        }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   508
      }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   509
    }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   510
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   511
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   512
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   513
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   514
void luaX_next (LexState *ls) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   515
  ls->lastline = ls->linenumber;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   516
  if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   517
    ls->t = ls->lookahead;  /* use this one */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   518
    ls->lookahead.token = TK_EOS;  /* and discharge it */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   519
  }
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   520
  else
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   521
    ls->t.token = llex(ls, &ls->t.seminfo);  /* read next token */
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   522
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   523
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   524
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   525
int luaX_lookahead (LexState *ls) {
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   526
  lua_assert(ls->lookahead.token == TK_EOS);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   527
  ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   528
  return ls->lookahead.token;
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   529
}
d7ee4e2ed49d Initial work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   530