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 | } |