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