diff options
Diffstat (limited to 'llex.c')
-rw-r--r-- | llex.c | 372 |
1 files changed, 178 insertions, 194 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 1.4 1997/11/04 15:27:53 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.5 1997/11/07 15:09:49 roberto Exp roberto $ |
3 | ** Lexical Analizer | 3 | ** Lexical Analizer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -12,35 +12,32 @@ | |||
12 | #include "lmem.h" | 12 | #include "lmem.h" |
13 | #include "lobject.h" | 13 | #include "lobject.h" |
14 | #include "lparser.h" | 14 | #include "lparser.h" |
15 | #include "lstate.h" | ||
15 | #include "lstring.h" | 16 | #include "lstring.h" |
16 | #include "lstx.h" | 17 | #include "lstx.h" |
17 | #include "luadebug.h" | 18 | #include "luadebug.h" |
18 | #include "lzio.h" | 19 | #include "lzio.h" |
19 | 20 | ||
20 | 21 | ||
21 | static int current; /* look ahead character */ | ||
22 | static ZIO *lex_z; | ||
23 | 22 | ||
24 | |||
25 | int luaX_linenumber; | ||
26 | int lua_debug=0; | 23 | int lua_debug=0; |
27 | 24 | ||
28 | 25 | ||
29 | #define next() (current = zgetc(lex_z)) | 26 | #define next(LL) (LL->current = zgetc(LL->lex_z)) |
30 | 27 | ||
31 | 28 | ||
29 | static struct { | ||
30 | char *name; | ||
31 | int token; | ||
32 | } reserved [] = { | ||
33 | {"and", AND}, {"do", DO}, {"else", ELSE}, {"elseif", ELSEIF}, | ||
34 | {"end", END}, {"function", FUNCTION}, {"if", IF}, {"local", LOCAL}, | ||
35 | {"nil", NIL}, {"not", NOT}, {"or", OR}, {"repeat", REPEAT}, | ||
36 | {"return", RETURN}, {"then", THEN}, {"until", UNTIL}, {"while", WHILE} | ||
37 | }; | ||
32 | 38 | ||
33 | void luaX_init (void) | 39 | void luaX_init (void) |
34 | { | 40 | { |
35 | static struct { | ||
36 | char *name; | ||
37 | int token; | ||
38 | } reserved [] = { | ||
39 | {"and", AND}, {"do", DO}, {"else", ELSE}, {"elseif", ELSEIF}, | ||
40 | {"end", END}, {"function", FUNCTION}, {"if", IF}, {"local", LOCAL}, | ||
41 | {"nil", NIL}, {"not", NOT}, {"or", OR}, {"repeat", REPEAT}, | ||
42 | {"return", RETURN}, {"then", THEN}, {"until", UNTIL}, {"while", WHILE} | ||
43 | }; | ||
44 | int i; | 41 | int i; |
45 | for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) { | 42 | for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) { |
46 | TaggedString *ts = luaS_new(reserved[i].name); | 43 | TaggedString *ts = luaS_new(reserved[i].name); |
@@ -49,47 +46,29 @@ void luaX_init (void) | |||
49 | } | 46 | } |
50 | 47 | ||
51 | 48 | ||
52 | 49 | static void firstline (LexState *LL) | |
53 | #define MAX_IFS 5 | ||
54 | |||
55 | /* "ifstate" keeps the state of each nested $if the lexical is dealing with. */ | ||
56 | |||
57 | static struct { | ||
58 | int elsepart; /* true if its in the $else part */ | ||
59 | int condition; /* true if $if condition is true */ | ||
60 | int skip; /* true if part must be skiped */ | ||
61 | } ifstate[MAX_IFS]; | ||
62 | |||
63 | static int iflevel; /* level of nested $if's */ | ||
64 | |||
65 | |||
66 | static struct textbuff { | ||
67 | char *text; | ||
68 | int tokensize; | ||
69 | int buffsize; | ||
70 | } textbuff; | ||
71 | |||
72 | |||
73 | static void firstline (void) | ||
74 | { | 50 | { |
75 | int c = zgetc(lex_z); | 51 | int c = zgetc(LL->lex_z); |
76 | if (c == '#') | 52 | if (c == '#') |
77 | while((c=zgetc(lex_z)) != '\n' && c != EOZ) /* skip first line */; | 53 | while((c=zgetc(LL->lex_z)) != '\n' && c != EOZ) /* skip first line */; |
78 | zungetc(lex_z); | 54 | zungetc(LL->lex_z); |
79 | } | 55 | } |
80 | 56 | ||
81 | 57 | ||
82 | void luaX_setinput (ZIO *z) | 58 | void luaX_setinput (ZIO *z) |
83 | { | 59 | { |
84 | current = '\n'; | 60 | LexState *LL = L->lexstate; |
85 | luaX_linenumber = 0; | 61 | LL->current = '\n'; |
86 | iflevel = 0; | 62 | LL->linelasttoken = 0; |
87 | ifstate[0].skip = 0; | 63 | LL->lastline = 0; |
88 | ifstate[0].elsepart = 1; /* to avoid a free $else */ | 64 | LL->linenumber = 0; |
89 | lex_z = z; | 65 | LL->iflevel = 0; |
90 | firstline(); | 66 | LL->ifstate[0].skip = 0; |
91 | textbuff.buffsize = 20; | 67 | LL->ifstate[0].elsepart = 1; /* to avoid a free $else */ |
92 | textbuff.text = luaM_buffer(textbuff.buffsize); | 68 | LL->lex_z = z; |
69 | firstline(LL); | ||
70 | LL->textbuff.buffsize = 20; | ||
71 | LL->textbuff.text = luaM_buffer(LL->textbuff.buffsize); | ||
93 | } | 72 | } |
94 | 73 | ||
95 | 74 | ||
@@ -102,9 +81,9 @@ void luaX_setinput (ZIO *z) | |||
102 | 81 | ||
103 | #define PRAGMASIZE 20 | 82 | #define PRAGMASIZE 20 |
104 | 83 | ||
105 | static void skipspace (void) | 84 | static void skipspace (LexState *LL) |
106 | { | 85 | { |
107 | while (current == ' ' || current == '\t') next(); | 86 | while (LL->current == ' ' || LL->current == '\t') next(LL); |
108 | } | 87 | } |
109 | 88 | ||
110 | 89 | ||
@@ -122,49 +101,49 @@ static int checkcond (char *buff) | |||
122 | } | 101 | } |
123 | 102 | ||
124 | 103 | ||
125 | static void readname (char *buff) | 104 | static void readname (LexState *LL, char *buff) |
126 | { | 105 | { |
127 | int i = 0; | 106 | int i = 0; |
128 | skipspace(); | 107 | skipspace(LL); |
129 | while (isalnum(current) || current == '_') { | 108 | while (isalnum(LL->current) || LL->current == '_') { |
130 | if (i >= PRAGMASIZE) { | 109 | if (i >= PRAGMASIZE) { |
131 | buff[PRAGMASIZE] = 0; | 110 | buff[PRAGMASIZE] = 0; |
132 | luaY_syntaxerror("pragma too long", buff); | 111 | luaY_syntaxerror("pragma too long", buff); |
133 | } | 112 | } |
134 | buff[i++] = current; | 113 | buff[i++] = LL->current; |
135 | next(); | 114 | next(LL); |
136 | } | 115 | } |
137 | buff[i] = 0; | 116 | buff[i] = 0; |
138 | } | 117 | } |
139 | 118 | ||
140 | 119 | ||
141 | static void inclinenumber (void); | 120 | static void inclinenumber (LexState *LL); |
142 | 121 | ||
143 | 122 | ||
144 | static void ifskip (void) | 123 | static void ifskip (LexState *LL) |
145 | { | 124 | { |
146 | while (ifstate[iflevel].skip) { | 125 | while (LL->ifstate[LL->iflevel].skip) { |
147 | if (current == '\n') | 126 | if (LL->current == '\n') |
148 | inclinenumber(); | 127 | inclinenumber(LL); |
149 | else if (current == EOZ) | 128 | else if (LL->current == EOZ) |
150 | luaY_syntaxerror("input ends inside a $if", ""); | 129 | luaY_syntaxerror("input ends inside a $if", ""); |
151 | else next(); | 130 | else next(LL); |
152 | } | 131 | } |
153 | } | 132 | } |
154 | 133 | ||
155 | 134 | ||
156 | static void inclinenumber (void) | 135 | static void inclinenumber (LexState *LL) |
157 | { | 136 | { |
158 | static char *pragmas [] = | 137 | static char *pragmas [] = |
159 | {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL}; | 138 | {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL}; |
160 | next(); /* skip '\n' */ | 139 | next(LL); /* skip '\n' */ |
161 | ++luaX_linenumber; | 140 | ++LL->linenumber; |
162 | if (current == '$') { /* is a pragma? */ | 141 | if (LL->current == '$') { /* is a pragma? */ |
163 | char buff[PRAGMASIZE+1]; | 142 | char buff[PRAGMASIZE+1]; |
164 | int ifnot = 0; | 143 | int ifnot = 0; |
165 | int skip = ifstate[iflevel].skip; | 144 | int skip = LL->ifstate[LL->iflevel].skip; |
166 | next(); /* skip $ */ | 145 | next(LL); /* skip $ */ |
167 | readname(buff); | 146 | readname(LL, buff); |
168 | switch (luaO_findstring(buff, pragmas)) { | 147 | switch (luaO_findstring(buff, pragmas)) { |
169 | case 0: /* debug */ | 148 | case 0: /* debug */ |
170 | if (!skip) lua_debug = 1; | 149 | if (!skip) lua_debug = 1; |
@@ -174,42 +153,42 @@ static void inclinenumber (void) | |||
174 | break; | 153 | break; |
175 | case 2: /* endinput */ | 154 | case 2: /* endinput */ |
176 | if (!skip) { | 155 | if (!skip) { |
177 | current = EOZ; | 156 | LL->current = EOZ; |
178 | iflevel = 0; /* to allow $endinput inside a $if */ | 157 | LL->iflevel = 0; /* to allow $endinput inside a $if */ |
179 | } | 158 | } |
180 | break; | 159 | break; |
181 | case 3: /* end */ | 160 | case 3: /* end */ |
182 | if (iflevel-- == 0) | 161 | if (LL->iflevel-- == 0) |
183 | luaY_syntaxerror("unmatched $end", "$end"); | 162 | luaY_syntaxerror("unmatched $end", "$end"); |
184 | break; | 163 | break; |
185 | case 4: /* ifnot */ | 164 | case 4: /* ifnot */ |
186 | ifnot = 1; | 165 | ifnot = 1; |
187 | /* go through */ | 166 | /* go through */ |
188 | case 5: /* if */ | 167 | case 5: /* if */ |
189 | if (iflevel == MAX_IFS-1) | 168 | if (LL->iflevel == MAX_IFS-1) |
190 | luaY_syntaxerror("too many nested `$ifs'", "$if"); | 169 | luaY_syntaxerror("too many nested `$ifs'", "$if"); |
191 | readname(buff); | 170 | readname(LL, buff); |
192 | iflevel++; | 171 | LL->iflevel++; |
193 | ifstate[iflevel].elsepart = 0; | 172 | LL->ifstate[LL->iflevel].elsepart = 0; |
194 | ifstate[iflevel].condition = checkcond(buff) ? !ifnot : ifnot; | 173 | LL->ifstate[LL->iflevel].condition = checkcond(buff) ? !ifnot : ifnot; |
195 | ifstate[iflevel].skip = skip || !ifstate[iflevel].condition; | 174 | LL->ifstate[LL->iflevel].skip = skip || !LL->ifstate[LL->iflevel].condition; |
196 | break; | 175 | break; |
197 | case 6: /* else */ | 176 | case 6: /* else */ |
198 | if (ifstate[iflevel].elsepart) | 177 | if (LL->ifstate[LL->iflevel].elsepart) |
199 | luaY_syntaxerror("unmatched $else", "$else"); | 178 | luaY_syntaxerror("unmatched $else", "$else"); |
200 | ifstate[iflevel].elsepart = 1; | 179 | LL->ifstate[LL->iflevel].elsepart = 1; |
201 | ifstate[iflevel].skip = | 180 | LL->ifstate[LL->iflevel].skip = LL->ifstate[LL->iflevel-1].skip || |
202 | ifstate[iflevel-1].skip || ifstate[iflevel].condition; | 181 | LL->ifstate[LL->iflevel].condition; |
203 | break; | 182 | break; |
204 | default: | 183 | default: |
205 | luaY_syntaxerror("invalid pragma", buff); | 184 | luaY_syntaxerror("invalid pragma", buff); |
206 | } | 185 | } |
207 | skipspace(); | 186 | skipspace(LL); |
208 | if (current == '\n') /* pragma must end with a '\n' ... */ | 187 | if (LL->current == '\n') /* pragma must end with a '\n' ... */ |
209 | inclinenumber(); | 188 | inclinenumber(LL); |
210 | else if (current != EOZ) /* or eof */ | 189 | else if (LL->current != EOZ) /* or eof */ |
211 | luaY_syntaxerror("invalid pragma format", buff); | 190 | luaY_syntaxerror("invalid pragma format", buff); |
212 | ifskip(); | 191 | ifskip(LL); |
213 | } | 192 | } |
214 | } | 193 | } |
215 | 194 | ||
@@ -222,162 +201,167 @@ static void inclinenumber (void) | |||
222 | 201 | ||
223 | 202 | ||
224 | 203 | ||
225 | static void save (int c) | 204 | static void save (LexState *LL, int c) |
226 | { | 205 | { |
227 | if (textbuff.tokensize >= textbuff.buffsize) | 206 | if (LL->textbuff.tokensize >= LL->textbuff.buffsize) |
228 | textbuff.text = luaM_buffer(textbuff.buffsize *= 2); | 207 | LL->textbuff.text = luaM_buffer(LL->textbuff.buffsize *= 2); |
229 | textbuff.text[textbuff.tokensize++] = c; | 208 | LL->textbuff.text[LL->textbuff.tokensize++] = c; |
230 | } | 209 | } |
231 | 210 | ||
232 | 211 | ||
233 | char *luaX_lasttoken (void) | 212 | char *luaX_lasttoken (void) |
234 | { | 213 | { |
235 | save(0); | 214 | save(L->lexstate, 0); |
236 | return textbuff.text; | 215 | return L->lexstate->textbuff.text; |
237 | } | 216 | } |
238 | 217 | ||
239 | 218 | ||
240 | #define save_and_next() (save(current), next()) | 219 | #define save_and_next(LL) (save(LL, LL->current), next(LL)) |
241 | 220 | ||
242 | 221 | ||
243 | static int read_long_string (void) | 222 | static int read_long_string (LexState *LL, YYSTYPE *l) |
244 | { | 223 | { |
245 | int cont = 0; | 224 | int cont = 0; |
246 | while (1) { | 225 | while (1) { |
247 | switch (current) { | 226 | switch (LL->current) { |
248 | case EOZ: | 227 | case EOZ: |
249 | save(0); | 228 | save(LL, 0); |
250 | return WRONGTOKEN; | 229 | return WRONGTOKEN; |
251 | case '[': | 230 | case '[': |
252 | save_and_next(); | 231 | save_and_next(LL); |
253 | if (current == '[') { | 232 | if (LL->current == '[') { |
254 | cont++; | 233 | cont++; |
255 | save_and_next(); | 234 | save_and_next(LL); |
256 | } | 235 | } |
257 | continue; | 236 | continue; |
258 | case ']': | 237 | case ']': |
259 | save_and_next(); | 238 | save_and_next(LL); |
260 | if (current == ']') { | 239 | if (LL->current == ']') { |
261 | if (cont == 0) goto endloop; | 240 | if (cont == 0) goto endloop; |
262 | cont--; | 241 | cont--; |
263 | save_and_next(); | 242 | save_and_next(LL); |
264 | } | 243 | } |
265 | continue; | 244 | continue; |
266 | case '\n': | 245 | case '\n': |
267 | save('\n'); | 246 | save(LL, '\n'); |
268 | inclinenumber(); | 247 | inclinenumber(LL); |
269 | continue; | 248 | continue; |
270 | default: | 249 | default: |
271 | save_and_next(); | 250 | save_and_next(LL); |
272 | } | 251 | } |
273 | } endloop: | 252 | } endloop: |
274 | save_and_next(); /* pass the second ']' */ | 253 | save_and_next(LL); /* pass the second ']' */ |
275 | textbuff.text[textbuff.tokensize-2] = 0; /* erases ']]' */ | 254 | LL->textbuff.text[LL->textbuff.tokensize-2] = 0; /* erases ']]' */ |
276 | luaY_lval.pTStr = luaS_new(textbuff.text+2); | 255 | l->pTStr = luaS_new(LL->textbuff.text+2); |
277 | textbuff.text[textbuff.tokensize-2] = ']'; /* restores ']]' */ | 256 | LL->textbuff.text[LL->textbuff.tokensize-2] = ']'; /* restores ']]' */ |
278 | return STRING; | 257 | return STRING; |
279 | } | 258 | } |
280 | 259 | ||
281 | 260 | ||
282 | int luaY_lex (void) | 261 | /* to avoid warnings; this declaration cannot be public since YYSTYPE |
262 | ** cannot be visible in llex.h (otherwise there is an error, since | ||
263 | ** the parser body redefines it!) | ||
264 | */ | ||
265 | int luaY_lex (YYSTYPE *l); | ||
266 | int luaY_lex (YYSTYPE *l) | ||
283 | { | 267 | { |
284 | static int linelasttoken = 0; | 268 | LexState *LL = L->lexstate; |
285 | double a; | 269 | double a; |
286 | textbuff.tokensize = 0; | 270 | LL->textbuff.tokensize = 0; |
287 | if (lua_debug) | 271 | if (lua_debug) |
288 | luaY_codedebugline(linelasttoken); | 272 | luaY_codedebugline(LL->linelasttoken); |
289 | linelasttoken = luaX_linenumber; | 273 | LL->linelasttoken = LL->linenumber; |
290 | while (1) { | 274 | while (1) { |
291 | switch (current) { | 275 | switch (LL->current) { |
292 | case '\n': | 276 | case '\n': |
293 | inclinenumber(); | 277 | inclinenumber(LL); |
294 | linelasttoken = luaX_linenumber; | 278 | LL->linelasttoken = LL->linenumber; |
295 | continue; | 279 | continue; |
296 | 280 | ||
297 | case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */ | 281 | case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */ |
298 | next(); | 282 | next(LL); |
299 | continue; | 283 | continue; |
300 | 284 | ||
301 | case '-': | 285 | case '-': |
302 | save_and_next(); | 286 | save_and_next(LL); |
303 | if (current != '-') return '-'; | 287 | if (LL->current != '-') return '-'; |
304 | do { next(); } while (current != '\n' && current != EOZ); | 288 | do { next(LL); } while (LL->current != '\n' && LL->current != EOZ); |
305 | textbuff.tokensize = 0; | 289 | LL->textbuff.tokensize = 0; |
306 | continue; | 290 | continue; |
307 | 291 | ||
308 | case '[': | 292 | case '[': |
309 | save_and_next(); | 293 | save_and_next(LL); |
310 | if (current != '[') return '['; | 294 | if (LL->current != '[') return '['; |
311 | else { | 295 | else { |
312 | save_and_next(); /* pass the second '[' */ | 296 | save_and_next(LL); /* pass the second '[' */ |
313 | return read_long_string(); | 297 | return read_long_string(LL, l); |
314 | } | 298 | } |
315 | 299 | ||
316 | case '=': | 300 | case '=': |
317 | save_and_next(); | 301 | save_and_next(LL); |
318 | if (current != '=') return '='; | 302 | if (LL->current != '=') return '='; |
319 | else { save_and_next(); return EQ; } | 303 | else { save_and_next(LL); return EQ; } |
320 | 304 | ||
321 | case '<': | 305 | case '<': |
322 | save_and_next(); | 306 | save_and_next(LL); |
323 | if (current != '=') return '<'; | 307 | if (LL->current != '=') return '<'; |
324 | else { save_and_next(); return LE; } | 308 | else { save_and_next(LL); return LE; } |
325 | 309 | ||
326 | case '>': | 310 | case '>': |
327 | save_and_next(); | 311 | save_and_next(LL); |
328 | if (current != '=') return '>'; | 312 | if (LL->current != '=') return '>'; |
329 | else { save_and_next(); return GE; } | 313 | else { save_and_next(LL); return GE; } |
330 | 314 | ||
331 | case '~': | 315 | case '~': |
332 | save_and_next(); | 316 | save_and_next(LL); |
333 | if (current != '=') return '~'; | 317 | if (LL->current != '=') return '~'; |
334 | else { save_and_next(); return NE; } | 318 | else { save_and_next(LL); return NE; } |
335 | 319 | ||
336 | case '"': | 320 | case '"': |
337 | case '\'': { | 321 | case '\'': { |
338 | int del = current; | 322 | int del = LL->current; |
339 | save_and_next(); | 323 | save_and_next(LL); |
340 | while (current != del) { | 324 | while (LL->current != del) { |
341 | switch (current) { | 325 | switch (LL->current) { |
342 | case EOZ: | 326 | case EOZ: |
343 | case '\n': | 327 | case '\n': |
344 | save(0); | 328 | save(LL, 0); |
345 | return WRONGTOKEN; | 329 | return WRONGTOKEN; |
346 | case '\\': | 330 | case '\\': |
347 | next(); /* do not save the '\' */ | 331 | next(LL); /* do not save the '\' */ |
348 | switch (current) { | 332 | switch (LL->current) { |
349 | case 'n': save('\n'); next(); break; | 333 | case 'n': save(LL, '\n'); next(LL); break; |
350 | case 't': save('\t'); next(); break; | 334 | case 't': save(LL, '\t'); next(LL); break; |
351 | case 'r': save('\r'); next(); break; | 335 | case 'r': save(LL, '\r'); next(LL); break; |
352 | case '\n': save('\n'); inclinenumber(); break; | 336 | case '\n': save(LL, '\n'); inclinenumber(LL); break; |
353 | default : save_and_next(); break; | 337 | default : save_and_next(LL); break; |
354 | } | 338 | } |
355 | break; | 339 | break; |
356 | default: | 340 | default: |
357 | save_and_next(); | 341 | save_and_next(LL); |
358 | } | 342 | } |
359 | } | 343 | } |
360 | next(); /* skip delimiter */ | 344 | next(LL); /* skip delimiter */ |
361 | save(0); | 345 | save(LL, 0); |
362 | luaY_lval.pTStr = luaS_new(textbuff.text+1); | 346 | l->pTStr = luaS_new(LL->textbuff.text+1); |
363 | textbuff.text[textbuff.tokensize-1] = del; /* restore delimiter */ | 347 | LL->textbuff.text[LL->textbuff.tokensize-1] = del; /* restore delimiter */ |
364 | return STRING; | 348 | return STRING; |
365 | } | 349 | } |
366 | 350 | ||
367 | case '.': | 351 | case '.': |
368 | save_and_next(); | 352 | save_and_next(LL); |
369 | if (current == '.') | 353 | if (LL->current == '.') |
370 | { | 354 | { |
371 | save_and_next(); | 355 | save_and_next(LL); |
372 | if (current == '.') | 356 | if (LL->current == '.') |
373 | { | 357 | { |
374 | save_and_next(); | 358 | save_and_next(LL); |
375 | return DOTS; /* ... */ | 359 | return DOTS; /* ... */ |
376 | } | 360 | } |
377 | else return CONC; /* .. */ | 361 | else return CONC; /* .. */ |
378 | } | 362 | } |
379 | else if (!isdigit(current)) return '.'; | 363 | else if (!isdigit(LL->current)) return '.'; |
380 | /* current is a digit: goes through to number */ | 364 | /* LL->current is a digit: goes through to number */ |
381 | a=0.0; | 365 | a=0.0; |
382 | goto fraction; | 366 | goto fraction; |
383 | 367 | ||
@@ -385,69 +369,69 @@ int luaY_lex (void) | |||
385 | case '5': case '6': case '7': case '8': case '9': | 369 | case '5': case '6': case '7': case '8': case '9': |
386 | a=0.0; | 370 | a=0.0; |
387 | do { | 371 | do { |
388 | a=10.0*a+(current-'0'); | 372 | a=10.0*a+(LL->current-'0'); |
389 | save_and_next(); | 373 | save_and_next(LL); |
390 | } while (isdigit(current)); | 374 | } while (isdigit(LL->current)); |
391 | if (current == '.') { | 375 | if (LL->current == '.') { |
392 | save_and_next(); | 376 | save_and_next(LL); |
393 | if (current == '.') { | 377 | if (LL->current == '.') { |
394 | save(0); | 378 | save(LL, 0); |
395 | luaY_error( | 379 | luaY_error( |
396 | "ambiguous syntax (decimal point x string concatenation)"); | 380 | "ambiguous syntax (decimal point x string concatenation)"); |
397 | } | 381 | } |
398 | } | 382 | } |
399 | fraction: | 383 | fraction: |
400 | { double da=0.1; | 384 | { double da=0.1; |
401 | while (isdigit(current)) | 385 | while (isdigit(LL->current)) |
402 | { | 386 | { |
403 | a+=(current-'0')*da; | 387 | a+=(LL->current-'0')*da; |
404 | da/=10.0; | 388 | da/=10.0; |
405 | save_and_next(); | 389 | save_and_next(LL); |
406 | } | 390 | } |
407 | if (toupper(current) == 'E') { | 391 | if (toupper(LL->current) == 'E') { |
408 | int e=0; | 392 | int e=0; |
409 | int neg; | 393 | int neg; |
410 | double ea; | 394 | double ea; |
411 | save_and_next(); | 395 | save_and_next(LL); |
412 | neg=(current=='-'); | 396 | neg=(LL->current=='-'); |
413 | if (current == '+' || current == '-') save_and_next(); | 397 | if (LL->current == '+' || LL->current == '-') save_and_next(LL); |
414 | if (!isdigit(current)) { | 398 | if (!isdigit(LL->current)) { |
415 | save(0); return WRONGTOKEN; } | 399 | save(LL, 0); return WRONGTOKEN; } |
416 | do { | 400 | do { |
417 | e=10.0*e+(current-'0'); | 401 | e=10.0*e+(LL->current-'0'); |
418 | save_and_next(); | 402 | save_and_next(LL); |
419 | } while (isdigit(current)); | 403 | } while (isdigit(LL->current)); |
420 | for (ea=neg?0.1:10.0; e>0; e>>=1) | 404 | for (ea=neg?0.1:10.0; e>0; e>>=1) |
421 | { | 405 | { |
422 | if (e & 1) a*=ea; | 406 | if (e & 1) a*=ea; |
423 | ea*=ea; | 407 | ea*=ea; |
424 | } | 408 | } |
425 | } | 409 | } |
426 | luaY_lval.vReal = a; | 410 | l->vReal = a; |
427 | return NUMBER; | 411 | return NUMBER; |
428 | } | 412 | } |
429 | 413 | ||
430 | case EOZ: | 414 | case EOZ: |
431 | save(0); | 415 | save(LL, 0); |
432 | if (iflevel > 0) | 416 | if (LL->iflevel > 0) |
433 | luaY_error("missing $endif"); | 417 | luaY_error("missing $endif"); |
434 | return 0; | 418 | return 0; |
435 | 419 | ||
436 | default: | 420 | default: |
437 | if (current != '_' && !isalpha(current)) { | 421 | if (LL->current != '_' && !isalpha(LL->current)) { |
438 | save_and_next(); | 422 | save_and_next(LL); |
439 | return textbuff.text[0]; | 423 | return LL->textbuff.text[0]; |
440 | } | 424 | } |
441 | else { /* identifier or reserved word */ | 425 | else { /* identifier or reserved word */ |
442 | TaggedString *ts; | 426 | TaggedString *ts; |
443 | do { | 427 | do { |
444 | save_and_next(); | 428 | save_and_next(LL); |
445 | } while (isalnum(current) || current == '_'); | 429 | } while (isalnum(LL->current) || LL->current == '_'); |
446 | save(0); | 430 | save(LL, 0); |
447 | ts = luaS_new(textbuff.text); | 431 | ts = luaS_new(LL->textbuff.text); |
448 | if (ts->head.marked > 255) | 432 | if (ts->head.marked > 255) |
449 | return ts->head.marked; /* reserved word */ | 433 | return ts->head.marked; /* reserved word */ |
450 | luaY_lval.pTStr = ts; | 434 | l->pTStr = ts; |
451 | return NAME; | 435 | return NAME; |
452 | } | 436 | } |
453 | } | 437 | } |