diff options
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 86 |
1 files changed, 38 insertions, 48 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.11 1999/02/01 18:52:05 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.12 1999/02/02 13:47:31 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -153,24 +153,19 @@ static void deltastack (LexState *ls, int delta) { | |||
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | 155 | ||
| 156 | static int code_oparg_at (LexState *ls, int pc, OpCode op, int builtin, | 156 | static int code_oparg_at (LexState *ls, int pc, OpCode op, int arg, int delta) { |
| 157 | int arg, int delta) { | ||
| 158 | Byte *code = ls->fs->f->code; | 157 | Byte *code = ls->fs->f->code; |
| 159 | deltastack(ls, delta); | 158 | deltastack(ls, delta); |
| 160 | if (arg < builtin) { | 159 | if (arg <= 255) { |
| 161 | code[pc] = (Byte)(op+1+arg); | ||
| 162 | return 1; | ||
| 163 | } | ||
| 164 | else if (arg <= 255) { | ||
| 165 | code[pc] = (Byte)op; | 160 | code[pc] = (Byte)op; |
| 166 | code[pc+1] = (Byte)arg; | 161 | code[pc+1] = (Byte)arg; |
| 167 | return 2; | 162 | return 2; /* code size (opcode + 1 byte) */ |
| 168 | } | 163 | } |
| 169 | else if (arg <= MAX_WORD) { | 164 | else if (arg <= MAX_WORD) { |
| 170 | code[pc] = (Byte)(op+1+builtin); | 165 | code[pc] = (Byte)(op+1); |
| 171 | code[pc+1] = (Byte)(arg>>8); | 166 | code[pc+1] = (Byte)(arg>>8); |
| 172 | code[pc+2] = (Byte)(arg&0xFF); | 167 | code[pc+2] = (Byte)(arg&0xFF); |
| 173 | return 3; | 168 | return 3; /* code size (opcode + 1 word) */ |
| 174 | } | 169 | } |
| 175 | else luaX_error(ls, "code too long " MES_LIM("64K") | 170 | else luaX_error(ls, "code too long " MES_LIM("64K") |
| 176 | " (try turning off debug mode)"); | 171 | " (try turning off debug mode)"); |
| @@ -178,25 +173,21 @@ static int code_oparg_at (LexState *ls, int pc, OpCode op, int builtin, | |||
| 178 | } | 173 | } |
| 179 | 174 | ||
| 180 | 175 | ||
| 181 | static int fix_opcode (LexState *ls, int pc, OpCode op, int builtin, int arg) { | 176 | static int fix_opcode (LexState *ls, int pc, OpCode op, int arg) { |
| 182 | FuncState *fs = ls->fs; | 177 | FuncState *fs = ls->fs; |
| 183 | TProtoFunc *f = fs->f; | 178 | TProtoFunc *f = fs->f; |
| 184 | if (arg < builtin) { /* close space */ | 179 | if (arg > 255) { /* open space */ |
| 185 | luaO_memdown(f->code+pc+1, f->code+pc+2, fs->pc-(pc+2)); | ||
| 186 | fs->pc--; | ||
| 187 | } | ||
| 188 | else if (arg > 255) { /* open space */ | ||
| 189 | check_pc(fs, 1); | 180 | check_pc(fs, 1); |
| 190 | luaO_memup(f->code+pc+1, f->code+pc, fs->pc-pc); | 181 | luaO_memup(f->code+pc+1, f->code+pc, fs->pc-pc); |
| 191 | fs->pc++; | 182 | fs->pc++; |
| 192 | } | 183 | } |
| 193 | return code_oparg_at(ls, pc, op, builtin, arg, 0) - 2; | 184 | return code_oparg_at(ls, pc, op, arg, 0) - 2; |
| 194 | } | 185 | } |
| 195 | 186 | ||
| 196 | static void code_oparg (LexState *ls, OpCode op, int builtin, int arg, | 187 | |
| 197 | int delta) { | 188 | static void code_oparg (LexState *ls, OpCode op, int arg, int delta) { |
| 198 | check_pc(ls->fs, 3); /* maximum code size */ | 189 | check_pc(ls->fs, 3); /* maximum code size */ |
| 199 | ls->fs->pc += code_oparg_at(ls, ls->fs->pc, op, builtin, arg, delta); | 190 | ls->fs->pc += code_oparg_at(ls, ls->fs->pc, op, arg, delta); |
| 200 | } | 191 | } |
| 201 | 192 | ||
| 202 | 193 | ||
| @@ -207,7 +198,7 @@ static void code_opcode (LexState *ls, OpCode op, int delta) { | |||
| 207 | 198 | ||
| 208 | 199 | ||
| 209 | static void code_constant (LexState *ls, int c) { | 200 | static void code_constant (LexState *ls, int c) { |
| 210 | code_oparg(ls, PUSHCONSTANT, 8, c, 1); | 201 | code_oparg(ls, PUSHCONSTANT, c, 1); |
| 211 | } | 202 | } |
| 212 | 203 | ||
| 213 | 204 | ||
| @@ -261,8 +252,9 @@ static int real_constant (FuncState *fs, real r) { | |||
| 261 | 252 | ||
| 262 | static void code_number (LexState *ls, real f) { | 253 | static void code_number (LexState *ls, real f) { |
| 263 | int i; | 254 | int i; |
| 264 | if (0 <= f && f <= (real)MAX_WORD && (real)(i=(int)f) == f) | 255 | if (0 <= f+NUMOFFSET && f+NUMOFFSET <= (real)MAX_WORD && |
| 265 | code_oparg(ls, PUSHNUMBER, 3, i, 1); /* f has a short integer value */ | 256 | (real)(i=(int)f) == f) /* f+NUMOFFSET has a short integer value? */ |
| 257 | code_oparg(ls, PUSHNUMBER, i+NUMOFFSET, 1); | ||
| 266 | else | 258 | else |
| 267 | code_constant(ls, real_constant(ls->fs, f)); | 259 | code_constant(ls, real_constant(ls->fs, f)); |
| 268 | } | 260 | } |
| @@ -270,13 +262,13 @@ static void code_number (LexState *ls, real f) { | |||
| 270 | 262 | ||
| 271 | static void flush_record (LexState *ls, int n) { | 263 | static void flush_record (LexState *ls, int n) { |
| 272 | if (n > 0) | 264 | if (n > 0) |
| 273 | code_oparg(ls, SETMAP, 1, n-1, -2*n); | 265 | code_oparg(ls, SETMAP, n-1, -2*n); |
| 274 | } | 266 | } |
| 275 | 267 | ||
| 276 | 268 | ||
| 277 | static void flush_list (LexState *ls, int m, int n) { | 269 | static void flush_list (LexState *ls, int m, int n) { |
| 278 | if (n == 0) return; | 270 | if (n == 0) return; |
| 279 | code_oparg(ls, SETLIST, 1, m, -n); | 271 | code_oparg(ls, SETLIST, m, -n); |
| 280 | code_byte(ls->fs, (Byte)n); | 272 | code_byte(ls->fs, (Byte)n); |
| 281 | } | 273 | } |
| 282 | 274 | ||
| @@ -285,14 +277,12 @@ static void luaI_registerlocalvar (FuncState *fs, TaggedString *varname, | |||
| 285 | int line) { | 277 | int line) { |
| 286 | if (fs->maxvars != -1) { /* debug information? */ | 278 | if (fs->maxvars != -1) { /* debug information? */ |
| 287 | TProtoFunc *f = fs->f; | 279 | TProtoFunc *f = fs->f; |
| 288 | if (fs->nvars+2 > fs->maxvars) | 280 | if (fs->nvars+1 > fs->maxvars) |
| 289 | fs->maxvars = luaM_growvector(&f->locvars, fs->maxvars+2, | 281 | fs->maxvars = luaM_growvector(&f->locvars, fs->maxvars+1, |
| 290 | LocVar, "", MAX_WORD); | 282 | LocVar, "", MAX_WORD); |
| 291 | f->locvars[fs->nvars].varname = varname; | 283 | f->locvars[fs->nvars].varname = varname; |
| 292 | f->locvars[fs->nvars].line = line; | 284 | f->locvars[fs->nvars].line = line; |
| 293 | fs->nvars++; | 285 | fs->nvars++; |
| 294 | f->locvars[fs->nvars].line = -1; /* flag end of vector */ | ||
| 295 | |||
| 296 | } | 286 | } |
| 297 | } | 287 | } |
| 298 | 288 | ||
| @@ -369,14 +359,14 @@ static void pushupvalue (LexState *ls, TaggedString *n) { | |||
| 369 | if (aux_localname(ls->fs, n) >= 0) | 359 | if (aux_localname(ls->fs, n) >= 0) |
| 370 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); | 360 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); |
| 371 | i = indexupvalue(ls, n); | 361 | i = indexupvalue(ls, n); |
| 372 | code_oparg(ls, PUSHUPVALUE, 2, i, 1); | 362 | code_oparg(ls, PUSHUPVALUE, i, 1); |
| 373 | } | 363 | } |
| 374 | 364 | ||
| 375 | 365 | ||
| 376 | 366 | ||
| 377 | static void check_debugline (LexState *ls) { | 367 | static void check_debugline (LexState *ls) { |
| 378 | if (lua_debug && ls->linenumber != ls->fs->lastsetline) { | 368 | if (lua_debug && ls->linenumber != ls->fs->lastsetline) { |
| 379 | code_oparg(ls, SETLINE, 0, ls->linenumber, 0); | 369 | code_oparg(ls, SETLINE, ls->linenumber, 0); |
| 380 | ls->fs->lastsetline = ls->linenumber; | 370 | ls->fs->lastsetline = ls->linenumber; |
| 381 | } | 371 | } |
| 382 | } | 372 | } |
| @@ -384,9 +374,9 @@ static void check_debugline (LexState *ls) { | |||
| 384 | 374 | ||
| 385 | static void adjuststack (LexState *ls, int n) { | 375 | static void adjuststack (LexState *ls, int n) { |
| 386 | if (n > 0) | 376 | if (n > 0) |
| 387 | code_oparg(ls, POP, 2, n-1, -n); | 377 | code_oparg(ls, POP, n-1, -n); |
| 388 | else if (n < 0) | 378 | else if (n < 0) |
| 389 | code_oparg(ls, PUSHNIL, 1, (-n)-1, -n); | 379 | code_oparg(ls, PUSHNIL, (-n)-1, -n); |
| 390 | } | 380 | } |
| 391 | 381 | ||
| 392 | 382 | ||
| @@ -394,7 +384,7 @@ static void close_exp (LexState *ls, int pc, int nresults) { | |||
| 394 | if (pc > 0) { /* expression is an open function call */ | 384 | if (pc > 0) { /* expression is an open function call */ |
| 395 | Byte *code = ls->fs->f->code; | 385 | Byte *code = ls->fs->f->code; |
| 396 | Byte nparams = code[pc]; /* save nparams */ | 386 | Byte nparams = code[pc]; /* save nparams */ |
| 397 | pc += fix_opcode(ls, pc-2, CALLFUNC, 2, nresults); | 387 | pc += fix_opcode(ls, pc-2, CALLFUNC, nresults); |
| 398 | code[pc] = nparams; /* restore nparams */ | 388 | code[pc] = nparams; /* restore nparams */ |
| 399 | if (nresults != MULT_RET) | 389 | if (nresults != MULT_RET) |
| 400 | deltastack(ls, nresults); /* "push" results */ | 390 | deltastack(ls, nresults); /* "push" results */ |
| @@ -442,13 +432,13 @@ static void code_args (LexState *ls, int nparams, int dots) { | |||
| 442 | static void lua_pushvar (LexState *ls, vardesc *var) { | 432 | static void lua_pushvar (LexState *ls, vardesc *var) { |
| 443 | switch (var->k) { | 433 | switch (var->k) { |
| 444 | case VLOCAL: | 434 | case VLOCAL: |
| 445 | code_oparg(ls, PUSHLOCAL, 8, var->info, 1); | 435 | code_oparg(ls, PUSHLOCAL, var->info, 1); |
| 446 | break; | 436 | break; |
| 447 | case VGLOBAL: | 437 | case VGLOBAL: |
| 448 | code_oparg(ls, GETGLOBAL, 8, var->info, 1); | 438 | code_oparg(ls, GETGLOBAL, var->info, 1); |
| 449 | break; | 439 | break; |
| 450 | case VDOT: | 440 | case VDOT: |
| 451 | code_oparg(ls, GETDOTTED, 8, var->info, 0); | 441 | code_oparg(ls, GETDOTTED, var->info, 0); |
| 452 | break; | 442 | break; |
| 453 | case VINDEXED: | 443 | case VINDEXED: |
| 454 | code_opcode(ls, GETTABLE, -1); | 444 | code_opcode(ls, GETTABLE, -1); |
| @@ -465,10 +455,10 @@ static void lua_pushvar (LexState *ls, vardesc *var) { | |||
| 465 | static void storevar (LexState *ls, vardesc *var) { | 455 | static void storevar (LexState *ls, vardesc *var) { |
| 466 | switch (var->k) { | 456 | switch (var->k) { |
| 467 | case VLOCAL: | 457 | case VLOCAL: |
| 468 | code_oparg(ls, SETLOCAL, 8, var->info, -1); | 458 | code_oparg(ls, SETLOCAL, var->info, -1); |
| 469 | break; | 459 | break; |
| 470 | case VGLOBAL: | 460 | case VGLOBAL: |
| 471 | code_oparg(ls, SETGLOBAL, 8, var->info, -1); | 461 | code_oparg(ls, SETGLOBAL, var->info, -1); |
| 472 | break; | 462 | break; |
| 473 | case VINDEXED: | 463 | case VINDEXED: |
| 474 | code_opcode(ls, SETTABLE0, -3); | 464 | code_opcode(ls, SETTABLE0, -3); |
| @@ -481,14 +471,14 @@ static void storevar (LexState *ls, vardesc *var) { | |||
| 481 | 471 | ||
| 482 | static int fix_jump (LexState *ls, int pc, OpCode op, int n) { | 472 | static int fix_jump (LexState *ls, int pc, OpCode op, int n) { |
| 483 | /* jump is relative to position following jump instruction */ | 473 | /* jump is relative to position following jump instruction */ |
| 484 | return fix_opcode(ls, pc, op, 0, n-(pc+JMPSIZE)); | 474 | return fix_opcode(ls, pc, op, n-(pc+JMPSIZE)); |
| 485 | } | 475 | } |
| 486 | 476 | ||
| 487 | 477 | ||
| 488 | static void fix_upjmp (LexState *ls, OpCode op, int pos) { | 478 | static void fix_upjmp (LexState *ls, OpCode op, int pos) { |
| 489 | int delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */ | 479 | int delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */ |
| 490 | if (delta > 255) delta++; | 480 | if (delta > 255) delta++; |
| 491 | code_oparg(ls, op, 0, delta, 0); | 481 | code_oparg(ls, op, delta, 0); |
| 492 | } | 482 | } |
| 493 | 483 | ||
| 494 | 484 | ||
| @@ -516,7 +506,7 @@ static void func_onstack (LexState *ls, FuncState *func) { | |||
| 516 | else { | 506 | else { |
| 517 | for (i=0; i<func->nupvalues; i++) | 507 | for (i=0; i<func->nupvalues; i++) |
| 518 | lua_pushvar(ls, &func->upvalues[i]); | 508 | lua_pushvar(ls, &func->upvalues[i]); |
| 519 | code_oparg(ls, CLOSURE, 0, c, -func->nupvalues+1); | 509 | code_oparg(ls, CLOSURE, c, -func->nupvalues+1); |
| 520 | code_byte(fs, (Byte)func->nupvalues); | 510 | code_byte(fs, (Byte)func->nupvalues); |
| 521 | } | 511 | } |
| 522 | } | 512 | } |
| @@ -862,7 +852,7 @@ static void ifpart (LexState *ls, int isexp, int line) { | |||
| 862 | } | 852 | } |
| 863 | else { /* is exp */ | 853 | else { /* is exp */ |
| 864 | if (elsepart) exp1(ls); | 854 | if (elsepart) exp1(ls); |
| 865 | else code_oparg(ls, PUSHNIL, 1, 0, 1); /* empty else exp */ | 855 | else adjuststack(ls, -1); /* empty else exp -> push nil */ |
| 866 | } | 856 | } |
| 867 | check_match(ls, END, IF, line); | 857 | check_match(ls, END, IF, line); |
| 868 | } | 858 | } |
| @@ -878,7 +868,7 @@ static void ret (LexState *ls) { | |||
| 878 | next(ls); | 868 | next(ls); |
| 879 | explist(ls, &e); | 869 | explist(ls, &e); |
| 880 | close_exp(ls, e.pc, MULT_RET); | 870 | close_exp(ls, e.pc, MULT_RET); |
| 881 | code_oparg(ls, RETCODE, 0, ls->fs->nlocalvar, 0); | 871 | code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0); |
| 882 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ | 872 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ |
| 883 | optional(ls, ';'); | 873 | optional(ls, ';'); |
| 884 | } | 874 | } |
| @@ -1078,7 +1068,7 @@ static void var_or_func_tail (LexState *ls, vardesc *v) { | |||
| 1078 | case ':': /* var_or_func_tail -> ':' NAME funcparams */ | 1068 | case ':': /* var_or_func_tail -> ':' NAME funcparams */ |
| 1079 | next(ls); | 1069 | next(ls); |
| 1080 | lua_pushvar(ls, v); /* 'v' must be on stack */ | 1070 | lua_pushvar(ls, v); /* 'v' must be on stack */ |
| 1081 | code_oparg(ls, PUSHSELF, 8, checkname(ls), 1); | 1071 | code_oparg(ls, PUSHSELF, checkname(ls), 1); |
| 1082 | v->k = VEXP; | 1072 | v->k = VEXP; |
| 1083 | v->info = funcparams(ls, 1); | 1073 | v->info = funcparams(ls, 1); |
| 1084 | break; | 1074 | break; |
| @@ -1242,7 +1232,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars) { | |||
| 1242 | storevar(ls, v); | 1232 | storevar(ls, v); |
| 1243 | } | 1233 | } |
| 1244 | else { /* indexed var with values in between*/ | 1234 | else { /* indexed var with values in between*/ |
| 1245 | code_oparg(ls, SETTABLE, 0, left+(nvars-1), -1); | 1235 | code_oparg(ls, SETTABLE, left+(nvars-1), -1); |
| 1246 | left += 2; /* table/index are not popped, because they aren't on top */ | 1236 | left += 2; /* table/index are not popped, because they aren't on top */ |
| 1247 | } | 1237 | } |
| 1248 | return left; | 1238 | return left; |
| @@ -1267,7 +1257,7 @@ static void constructor (LexState *ls) { | |||
| 1267 | nelems += other_cd.n; | 1257 | nelems += other_cd.n; |
| 1268 | } | 1258 | } |
| 1269 | check_match(ls, '}', '{', line); | 1259 | check_match(ls, '}', '{', line); |
| 1270 | fix_opcode(ls, pc, CREATEARRAY, 2, nelems); | 1260 | fix_opcode(ls, pc, CREATEARRAY, nelems); |
| 1271 | } | 1261 | } |
| 1272 | 1262 | ||
| 1273 | static void part (LexState *ls, constdesc *cd) { | 1263 | static void part (LexState *ls, constdesc *cd) { |
