diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-03 15:53:17 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-03 15:53:17 -0300 |
| commit | d1ea38580ae35a3a34e7122c41682af7f9901030 (patch) | |
| tree | ce7fa1568be9eb757805966b77ea1eac2bc604f6 /lparser.c | |
| parent | 3c9d999424520c809e05bee11d81788b488434f6 (diff) | |
| download | lua-d1ea38580ae35a3a34e7122c41682af7f9901030.tar.gz lua-d1ea38580ae35a3a34e7122c41682af7f9901030.tar.bz2 lua-d1ea38580ae35a3a34e7122c41682af7f9901030.zip | |
change of code generation design (independent functions for each opcode)
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 85 |
1 files changed, 43 insertions, 42 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.61 2000/03/03 12:33:59 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.62 2000/03/03 14:58:26 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 | */ |
| @@ -23,15 +23,13 @@ | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | /* | 25 | /* |
| 26 | ** Expression List descriptor: | 26 | ** check whether arbitrary limits fit in respective opcode types |
| 27 | ** tells number of expressions in the list, | ||
| 28 | ** and, if last expression is open (a function call), | ||
| 29 | ** where is the call pc index. | ||
| 30 | */ | 27 | */ |
| 31 | typedef struct listdesc { | 28 | #if MAXLOCALS>MAXARG_U || MAXUPVALUES>MAXARG_B || MAXVARSLH>MAXARG_B || \ |
| 32 | int n; | 29 | MAXPARAMS>MAXLOCALS || MAXSTACK>MAXARG_A || LFIELDS_PER_FLUSH>MAXARG_B |
| 33 | int pc; /* 0 if last expression is closed */ | 30 | #error invalid limits |
| 34 | } listdesc; | 31 | #endif |
| 32 | |||
| 35 | 33 | ||
| 36 | 34 | ||
| 37 | /* | 35 | /* |
| @@ -51,11 +49,11 @@ typedef struct constdesc { | |||
| 51 | /* | 49 | /* |
| 52 | ** prototypes for recursive non-terminal functions | 50 | ** prototypes for recursive non-terminal functions |
| 53 | */ | 51 | */ |
| 54 | static int body (LexState *ls, int needself, int line); | 52 | static void body (LexState *ls, int needself, int line); |
| 55 | static void chunk (LexState *ls); | 53 | static void chunk (LexState *ls); |
| 56 | static int constructor (LexState *ls); | 54 | static void constructor (LexState *ls); |
| 57 | static void expr (LexState *ls, expdesc *v); | 55 | static void expr (LexState *ls, expdesc *v); |
| 58 | static void exp1 (LexState *ls); | 56 | static int exp1 (LexState *ls); |
| 59 | 57 | ||
| 60 | 58 | ||
| 61 | static void next (LexState *ls) { | 59 | static void next (LexState *ls) { |
| @@ -145,8 +143,8 @@ static int string_constant (LexState *ls, FuncState *fs, TaggedString *s) { | |||
| 145 | } | 143 | } |
| 146 | 144 | ||
| 147 | 145 | ||
| 148 | static int code_string (LexState *ls, TaggedString *s) { | 146 | static void code_string (LexState *ls, TaggedString *s) { |
| 149 | return luaK_kstr(ls, string_constant(ls, ls->fs, s)); | 147 | luaK_kstr(ls, string_constant(ls, ls->fs, s)); |
| 150 | } | 148 | } |
| 151 | 149 | ||
| 152 | 150 | ||
| @@ -249,18 +247,18 @@ static int indexupvalue (LexState *ls, TaggedString *n) { | |||
| 249 | } | 247 | } |
| 250 | 248 | ||
| 251 | 249 | ||
| 252 | static int pushupvalue (LexState *ls, TaggedString *n) { | 250 | static void pushupvalue (LexState *ls, TaggedString *n) { |
| 253 | if (ls->fs->prev == NULL) | 251 | if (ls->fs->prev == NULL) |
| 254 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); | 252 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); |
| 255 | if (aux_localname(ls->fs, n) >= 0) | 253 | if (aux_localname(ls->fs, n) >= 0) |
| 256 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); | 254 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); |
| 257 | return luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); | 255 | luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); |
| 258 | } | 256 | } |
| 259 | 257 | ||
| 260 | 258 | ||
| 261 | static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { | 259 | static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { |
| 262 | int diff = d->n - nvars; | 260 | int diff = d->n - nvars; |
| 263 | if (d->n == 0 || !luaK_iscall(ls, d->pc)) { /* list is empty or closed */ | 261 | if (d->n == 0 || !luaK_iscall(ls, d->info)) { /* list is empty or closed */ |
| 264 | /* push or pop eventual difference between list lengths */ | 262 | /* push or pop eventual difference between list lengths */ |
| 265 | luaK_adjuststack(ls, diff); | 263 | luaK_adjuststack(ls, diff); |
| 266 | } | 264 | } |
| @@ -268,10 +266,10 @@ static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { | |||
| 268 | diff--; /* do not count function call itself */ | 266 | diff--; /* do not count function call itself */ |
| 269 | if (diff <= 0) { /* more variables than values? */ | 267 | if (diff <= 0) { /* more variables than values? */ |
| 270 | /* function call must provide extra values */ | 268 | /* function call must provide extra values */ |
| 271 | luaK_setcallreturns(ls, d->pc, -diff); | 269 | luaK_setcallreturns(ls, d->info, -diff); |
| 272 | } | 270 | } |
| 273 | else { /* more values than variables */ | 271 | else { /* more values than variables */ |
| 274 | luaK_setcallreturns(ls, d->pc, 0); /* call should provide no value */ | 272 | luaK_setcallreturns(ls, d->info, 0); /* call should provide no value */ |
| 275 | luaK_adjuststack(ls, diff); /* pop eventual extra values */ | 273 | luaK_adjuststack(ls, diff); /* pop eventual extra values */ |
| 276 | } | 274 | } |
| 277 | } | 275 | } |
| @@ -308,7 +306,7 @@ static int getvarname (LexState *ls, expdesc *var) { | |||
| 308 | } | 306 | } |
| 309 | 307 | ||
| 310 | 308 | ||
| 311 | static int func_onstack (LexState *ls, FuncState *func) { | 309 | static void func_onstack (LexState *ls, FuncState *func) { |
| 312 | TProtoFunc *f = ls->fs->f; | 310 | TProtoFunc *f = ls->fs->f; |
| 313 | int i; | 311 | int i; |
| 314 | for (i=0; i<func->nupvalues; i++) | 312 | for (i=0; i<func->nupvalues; i++) |
| @@ -317,7 +315,7 @@ static int func_onstack (LexState *ls, FuncState *func) { | |||
| 317 | constantEM, MAXARG_A); | 315 | constantEM, MAXARG_A); |
| 318 | f->kproto[f->nkproto++] = func->f; | 316 | f->kproto[f->nkproto++] = func->f; |
| 319 | luaK_deltastack(ls, 1); /* CLOSURE puts one extra element before popping */ | 317 | luaK_deltastack(ls, 1); /* CLOSURE puts one extra element before popping */ |
| 320 | return luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues); | 318 | luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues); |
| 321 | } | 319 | } |
| 322 | 320 | ||
| 323 | 321 | ||
| @@ -333,7 +331,6 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) { | |||
| 333 | fs->f = f; | 331 | fs->f = f; |
| 334 | f->source = source; | 332 | f->source = source; |
| 335 | fs->pc = 0; | 333 | fs->pc = 0; |
| 336 | fs->last_pc = -1; /* invalid index to signal no last instruction */ | ||
| 337 | f->code = NULL; | 334 | f->code = NULL; |
| 338 | f->maxstacksize = 0; | 335 | f->maxstacksize = 0; |
| 339 | f->numparams = 0; /* default for main chunk */ | 336 | f->numparams = 0; /* default for main chunk */ |
| @@ -395,7 +392,7 @@ static void explist1 (LexState *ls, listdesc *d) { | |||
| 395 | } | 392 | } |
| 396 | luaK_2stack(ls, &v); | 393 | luaK_2stack(ls, &v); |
| 397 | luaK_setcallreturns(ls, v.info, MULT_RET); /* default for explists */ | 394 | luaK_setcallreturns(ls, v.info, MULT_RET); /* default for explists */ |
| 398 | d->pc = v.info; | 395 | d->info = v.info; |
| 399 | } | 396 | } |
| 400 | 397 | ||
| 401 | 398 | ||
| @@ -412,7 +409,7 @@ static void explist (LexState *ls, listdesc *d) { | |||
| 412 | } | 409 | } |
| 413 | 410 | ||
| 414 | 411 | ||
| 415 | static int funcparams (LexState *ls, int slf) { | 412 | static void funcparams (LexState *ls, int slf) { |
| 416 | FuncState *fs = ls->fs; | 413 | FuncState *fs = ls->fs; |
| 417 | int slevel = fs->stacksize - slf - 1; /* where is func in the stack */ | 414 | int slevel = fs->stacksize - slf - 1; /* where is func in the stack */ |
| 418 | switch (ls->token) { | 415 | switch (ls->token) { |
| @@ -443,7 +440,7 @@ static int funcparams (LexState *ls, int slf) { | |||
| 443 | break; | 440 | break; |
| 444 | } | 441 | } |
| 445 | fs->stacksize = slevel; /* call will remove func and params */ | 442 | fs->stacksize = slevel; /* call will remove func and params */ |
| 446 | return luaK_AB(ls, CALL, slevel, 0, 0); | 443 | luaK_AB(ls, CALL, slevel, 0, 0); |
| 447 | } | 444 | } |
| 448 | 445 | ||
| 449 | 446 | ||
| @@ -455,14 +452,15 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { | |||
| 455 | luaK_2stack(ls, v); /* `v' must be on stack */ | 452 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 456 | luaK_kstr(ls, checkname(ls)); | 453 | luaK_kstr(ls, checkname(ls)); |
| 457 | v->k = VINDEXED; | 454 | v->k = VINDEXED; |
| 455 | v->info = NOJUMPS; | ||
| 458 | break; | 456 | break; |
| 459 | 457 | ||
| 460 | case '[': /* var_or_func_tail -> '[' exp1 ']' */ | 458 | case '[': /* var_or_func_tail -> '[' exp1 ']' */ |
| 461 | next(ls); | 459 | next(ls); |
| 462 | luaK_2stack(ls, v); /* `v' must be on stack */ | 460 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 463 | exp1(ls); | ||
| 464 | check(ls, ']'); | ||
| 465 | v->k = VINDEXED; | 461 | v->k = VINDEXED; |
| 462 | v->info = exp1(ls); | ||
| 463 | check(ls, ']'); | ||
| 466 | break; | 464 | break; |
| 467 | 465 | ||
| 468 | case ':': { /* var_or_func_tail -> ':' NAME funcparams */ | 466 | case ':': { /* var_or_func_tail -> ':' NAME funcparams */ |
| @@ -471,15 +469,17 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { | |||
| 471 | name = checkname(ls); | 469 | name = checkname(ls); |
| 472 | luaK_2stack(ls, v); /* `v' must be on stack */ | 470 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 473 | luaK_U(ls, PUSHSELF, name, 1); | 471 | luaK_U(ls, PUSHSELF, name, 1); |
| 472 | funcparams(ls, 1); | ||
| 474 | v->k = VEXP; | 473 | v->k = VEXP; |
| 475 | v->info = funcparams(ls, 1); | 474 | v->info = NOJUMPS; |
| 476 | break; | 475 | break; |
| 477 | } | 476 | } |
| 478 | 477 | ||
| 479 | case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ | 478 | case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ |
| 480 | luaK_2stack(ls, v); /* `v' must be on stack */ | 479 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 480 | funcparams(ls, 0); | ||
| 481 | v->k = VEXP; | 481 | v->k = VEXP; |
| 482 | v->info = funcparams(ls, 0); | 482 | v->info = NOJUMPS; |
| 483 | break; | 483 | break; |
| 484 | 484 | ||
| 485 | default: return; /* should be follow... */ | 485 | default: return; /* should be follow... */ |
| @@ -491,8 +491,9 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { | |||
| 491 | static void var_or_func (LexState *ls, expdesc *v) { | 491 | static void var_or_func (LexState *ls, expdesc *v) { |
| 492 | /* var_or_func -> ['%'] NAME var_or_func_tail */ | 492 | /* var_or_func -> ['%'] NAME var_or_func_tail */ |
| 493 | if (optional(ls, '%')) { /* upvalue? */ | 493 | if (optional(ls, '%')) { /* upvalue? */ |
| 494 | pushupvalue(ls, str_checkname(ls)); | ||
| 494 | v->k = VEXP; | 495 | v->k = VEXP; |
| 495 | v->info = pushupvalue(ls, str_checkname(ls)); | 496 | v->info = NOJUMPS; |
| 496 | } | 497 | } |
| 497 | else /* variable name */ | 498 | else /* variable name */ |
| 498 | singlevar(ls, str_checkname(ls), v, 0); | 499 | singlevar(ls, str_checkname(ls), v, 0); |
| @@ -614,7 +615,7 @@ static void constructor_part (LexState *ls, constdesc *cd) { | |||
| 614 | } | 615 | } |
| 615 | 616 | ||
| 616 | 617 | ||
| 617 | static int constructor (LexState *ls) { | 618 | static void constructor (LexState *ls) { |
| 618 | /* constructor -> '{' constructor_part [';' constructor_part] '}' */ | 619 | /* constructor -> '{' constructor_part [';' constructor_part] '}' */ |
| 619 | int line = ls->linenumber; | 620 | int line = ls->linenumber; |
| 620 | int pc = luaK_U(ls, CREATETABLE, 0, 1); | 621 | int pc = luaK_U(ls, CREATETABLE, 0, 1); |
| @@ -634,7 +635,6 @@ static int constructor (LexState *ls) { | |||
| 634 | check_match(ls, '}', '{', line); | 635 | check_match(ls, '}', '{', line); |
| 635 | /* set initial table size */ | 636 | /* set initial table size */ |
| 636 | ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems); | 637 | ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems); |
| 637 | return pc; | ||
| 638 | } | 638 | } |
| 639 | 639 | ||
| 640 | /* }====================================================================== */ | 640 | /* }====================================================================== */ |
| @@ -655,28 +655,27 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
| 655 | case NUMBER: { /* simpleexp -> NUMBER */ | 655 | case NUMBER: { /* simpleexp -> NUMBER */ |
| 656 | real r = ls->seminfo.r; | 656 | real r = ls->seminfo.r; |
| 657 | next(ls); | 657 | next(ls); |
| 658 | v->info = luaK_number(ls, r); | 658 | luaK_number(ls, r); |
| 659 | break; | 659 | break; |
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | case STRING: /* simpleexp -> STRING */ | 662 | case STRING: /* simpleexp -> STRING */ |
| 663 | /* must use `seminfo' before `next' */ | 663 | code_string(ls, ls->seminfo.ts); /* must use `seminfo' before `next' */ |
| 664 | v->info = code_string(ls, ls->seminfo.ts); | ||
| 665 | next(ls); | 664 | next(ls); |
| 666 | break; | 665 | break; |
| 667 | 666 | ||
| 668 | case NIL: /* simpleexp -> NIL */ | 667 | case NIL: /* simpleexp -> NIL */ |
| 669 | v->info = luaK_adjuststack(ls, -1); | 668 | luaK_adjuststack(ls, -1); |
| 670 | next(ls); | 669 | next(ls); |
| 671 | break; | 670 | break; |
| 672 | 671 | ||
| 673 | case '{': /* simpleexp -> constructor */ | 672 | case '{': /* simpleexp -> constructor */ |
| 674 | v->info = constructor(ls); | 673 | constructor(ls); |
| 675 | break; | 674 | break; |
| 676 | 675 | ||
| 677 | case FUNCTION: /* simpleexp -> FUNCTION body */ | 676 | case FUNCTION: /* simpleexp -> FUNCTION body */ |
| 678 | next(ls); | 677 | next(ls); |
| 679 | v->info = body(ls, 0, ls->linenumber); | 678 | body(ls, 0, ls->linenumber); |
| 680 | break; | 679 | break; |
| 681 | 680 | ||
| 682 | case '(': /* simpleexp -> '(' expr ')' */ | 681 | case '(': /* simpleexp -> '(' expr ')' */ |
| @@ -694,13 +693,15 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
| 694 | return; | 693 | return; |
| 695 | } | 694 | } |
| 696 | v->k = VEXP; | 695 | v->k = VEXP; |
| 696 | v->info = NOJUMPS; | ||
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | 699 | ||
| 700 | static void exp1 (LexState *ls) { | 700 | static int exp1 (LexState *ls) { |
| 701 | expdesc v; | 701 | expdesc v; |
| 702 | expr(ls, &v); | 702 | expr(ls, &v); |
| 703 | luaK_2stack(ls, &v); | 703 | luaK_2stack(ls, &v); |
| 704 | return v.info; | ||
| 704 | } | 705 | } |
| 705 | 706 | ||
| 706 | 707 | ||
| @@ -1052,7 +1053,7 @@ static void parlist (LexState *ls) { | |||
| 1052 | } | 1053 | } |
| 1053 | 1054 | ||
| 1054 | 1055 | ||
| 1055 | static int body (LexState *ls, int needself, int line) { | 1056 | static void body (LexState *ls, int needself, int line) { |
| 1056 | /* body -> '(' parlist ')' chunk END */ | 1057 | /* body -> '(' parlist ')' chunk END */ |
| 1057 | FuncState new_fs; | 1058 | FuncState new_fs; |
| 1058 | init_state(ls, &new_fs, ls->fs->f->source); | 1059 | init_state(ls, &new_fs, ls->fs->f->source); |
| @@ -1065,7 +1066,7 @@ static int body (LexState *ls, int needself, int line) { | |||
| 1065 | chunk(ls); | 1066 | chunk(ls); |
| 1066 | check_match(ls, END, FUNCTION, line); | 1067 | check_match(ls, END, FUNCTION, line); |
| 1067 | close_func(ls); | 1068 | close_func(ls); |
| 1068 | return func_onstack(ls, &new_fs); | 1069 | func_onstack(ls, &new_fs); |
| 1069 | } | 1070 | } |
| 1070 | 1071 | ||
| 1071 | 1072 | ||
| @@ -1076,7 +1077,7 @@ static void ret (LexState *ls) { | |||
| 1076 | check_debugline(ls); | 1077 | check_debugline(ls); |
| 1077 | next(ls); | 1078 | next(ls); |
| 1078 | explist(ls, &e); | 1079 | explist(ls, &e); |
| 1079 | luaK_U(ls, RETCODE, ls->fs->nlocalvar, 0); | 1080 | luaK_retcode(ls, ls->fs->nlocalvar, &e); |
| 1080 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ | 1081 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ |
| 1081 | optional(ls, ';'); | 1082 | optional(ls, ';'); |
| 1082 | } | 1083 | } |
