diff options
Diffstat (limited to 'llex.c')
| -rw-r--r-- | llex.c | 47 |
1 files changed, 30 insertions, 17 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.c,v 2.62 2012/12/05 19:57:00 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 2.63 2013/03/16 21:10:18 roberto Exp roberto $ |
| 3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -39,7 +39,7 @@ static const char *const luaX_tokens [] = { | |||
| 39 | "in", "local", "nil", "not", "or", "repeat", | 39 | "in", "local", "nil", "not", "or", "repeat", |
| 40 | "return", "then", "true", "until", "while", | 40 | "return", "then", "true", "until", "while", |
| 41 | "..", "...", "==", ">=", "<=", "~=", "::", "<eof>", | 41 | "..", "...", "==", ">=", "<=", "~=", "::", "<eof>", |
| 42 | "<number>", "<name>", "<string>" | 42 | "<number>", "<number>", "<name>", "<string>" |
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | 45 | ||
| @@ -90,9 +90,8 @@ const char *luaX_token2str (LexState *ls, int token) { | |||
| 90 | 90 | ||
| 91 | static const char *txtToken (LexState *ls, int token) { | 91 | static const char *txtToken (LexState *ls, int token) { |
| 92 | switch (token) { | 92 | switch (token) { |
| 93 | case TK_NAME: | 93 | case TK_NAME: case TK_STRING: |
| 94 | case TK_STRING: | 94 | case TK_FLT: case TK_INT: |
| 95 | case TK_NUMBER: | ||
| 96 | save(ls, '\0'); | 95 | save(ls, '\0'); |
| 97 | return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff)); | 96 | return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff)); |
| 98 | default: | 97 | default: |
| @@ -216,7 +215,7 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) { | |||
| 216 | if (!buff2d(ls->buff, &seminfo->r)) { | 215 | if (!buff2d(ls->buff, &seminfo->r)) { |
| 217 | /* format error with correct decimal point: no more options */ | 216 | /* format error with correct decimal point: no more options */ |
| 218 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ | 217 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ |
| 219 | lexerror(ls, "malformed number", TK_NUMBER); | 218 | lexerror(ls, "malformed number", TK_FLT); |
| 220 | } | 219 | } |
| 221 | } | 220 | } |
| 222 | 221 | ||
| @@ -224,9 +223,10 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) { | |||
| 224 | /* LUA_NUMBER */ | 223 | /* LUA_NUMBER */ |
| 225 | /* | 224 | /* |
| 226 | ** this function is quite liberal in what it accepts, as 'luaO_str2d' | 225 | ** this function is quite liberal in what it accepts, as 'luaO_str2d' |
| 227 | ** will reject ill-formed numerals. | 226 | ** will reject ill-formed numerals. 'isf' means the numeral is not |
| 227 | ** an integer (it has a dot or an exponent). | ||
| 228 | */ | 228 | */ |
| 229 | static void read_numeral (LexState *ls, SemInfo *seminfo) { | 229 | static int read_numeral (LexState *ls, SemInfo *seminfo, int isf) { |
| 230 | const char *expo = "Ee"; | 230 | const char *expo = "Ee"; |
| 231 | int first = ls->current; | 231 | int first = ls->current; |
| 232 | lua_assert(lisdigit(ls->current)); | 232 | lua_assert(lisdigit(ls->current)); |
| @@ -234,16 +234,30 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) { | |||
| 234 | if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */ | 234 | if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */ |
| 235 | expo = "Pp"; | 235 | expo = "Pp"; |
| 236 | for (;;) { | 236 | for (;;) { |
| 237 | if (check_next(ls, expo)) /* exponent part? */ | 237 | if (check_next(ls, expo)) { /* exponent part? */ |
| 238 | check_next(ls, "+-"); /* optional exponent sign */ | 238 | check_next(ls, "+-"); /* optional exponent sign */ |
| 239 | if (lisxdigit(ls->current) || ls->current == '.') | 239 | isf = 1; |
| 240 | } | ||
| 241 | if (lisxdigit(ls->current)) | ||
| 242 | save_and_next(ls); | ||
| 243 | else if (ls->current == '.') { | ||
| 240 | save_and_next(ls); | 244 | save_and_next(ls); |
| 241 | else break; | 245 | isf = 1; |
| 246 | } | ||
| 247 | else break; | ||
| 242 | } | 248 | } |
| 243 | save(ls, '\0'); | 249 | save(ls, '\0'); |
| 244 | buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ | 250 | if (!isf) { |
| 245 | if (!buff2d(ls->buff, &seminfo->r)) /* format error? */ | 251 | if (!luaO_str2int(luaZ_buffer(ls->buff), &seminfo->i)) |
| 246 | trydecpoint(ls, seminfo); /* try to update decimal point separator */ | 252 | lexerror(ls, "malformed number", TK_INT); |
| 253 | return TK_INT; | ||
| 254 | } | ||
| 255 | else { | ||
| 256 | buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ | ||
| 257 | if (!buff2d(ls->buff, &seminfo->r)) /* format error? */ | ||
| 258 | trydecpoint(ls, seminfo); /* try to update decimal point separator */ | ||
| 259 | return TK_FLT; | ||
| 260 | } | ||
| 247 | } | 261 | } |
| 248 | 262 | ||
| 249 | 263 | ||
| @@ -472,12 +486,11 @@ static int llex (LexState *ls, SemInfo *seminfo) { | |||
| 472 | else return TK_CONCAT; /* '..' */ | 486 | else return TK_CONCAT; /* '..' */ |
| 473 | } | 487 | } |
| 474 | else if (!lisdigit(ls->current)) return '.'; | 488 | else if (!lisdigit(ls->current)) return '.'; |
| 475 | /* else go through */ | 489 | else return read_numeral(ls, seminfo, 1); |
| 476 | } | 490 | } |
| 477 | case '0': case '1': case '2': case '3': case '4': | 491 | case '0': case '1': case '2': case '3': case '4': |
| 478 | case '5': case '6': case '7': case '8': case '9': { | 492 | case '5': case '6': case '7': case '8': case '9': { |
| 479 | read_numeral(ls, seminfo); | 493 | return read_numeral(ls, seminfo, 0); |
| 480 | return TK_NUMBER; | ||
| 481 | } | 494 | } |
| 482 | case EOZ: { | 495 | case EOZ: { |
| 483 | return TK_EOS; | 496 | return TK_EOS; |
