diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-14 15:19:28 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-14 15:19:28 -0200 |
commit | 40f4e931f317f56725cba0b61ed82c0688a821f6 (patch) | |
tree | a5cb02942b7471b1628bcc1d3ad3bee84484cc29 | |
parent | 29371ecfe87d546b9ffab480808640bd2ef226a1 (diff) | |
download | lua-40f4e931f317f56725cba0b61ed82c0688a821f6.tar.gz lua-40f4e931f317f56725cba0b61ed82c0688a821f6.tar.bz2 lua-40f4e931f317f56725cba0b61ed82c0688a821f6.zip |
more liberal syntax for expressions
-rw-r--r-- | lparser.c | 151 |
1 files changed, 70 insertions, 81 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.131 2001/02/09 18:37:33 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.132 2001/02/09 20:22:29 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 | */ |
@@ -352,7 +352,7 @@ static void close_func (LexState *ls) { | |||
352 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->nlineinfo+1, int); | 352 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->nlineinfo+1, int); |
353 | f->lineinfo[fs->nlineinfo++] = MAX_INT; /* end flag */ | 353 | f->lineinfo[fs->nlineinfo++] = MAX_INT; /* end flag */ |
354 | f->sizelineinfo = fs->nlineinfo; | 354 | f->sizelineinfo = fs->nlineinfo; |
355 | lua_assert(luaG_checkcode(f)); | 355 | lua_assert(luaG_checkcode(L, f)); |
356 | ls->fs = fs->prev; | 356 | ls->fs = fs->prev; |
357 | lua_assert(fs->bl == NULL); | 357 | lua_assert(fs->bl == NULL); |
358 | } | 358 | } |
@@ -433,60 +433,6 @@ static void funcargs (LexState *ls, int slf) { | |||
433 | } | 433 | } |
434 | 434 | ||
435 | 435 | ||
436 | static void var_or_func_tail (LexState *ls, expdesc *v) { | ||
437 | for (;;) { | ||
438 | switch (ls->t.token) { | ||
439 | case '.': { /* var_or_func_tail -> '.' NAME */ | ||
440 | next(ls); | ||
441 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | ||
442 | luaK_kstr(ls, checkname(ls)); | ||
443 | v->k = VINDEXED; | ||
444 | break; | ||
445 | } | ||
446 | case '[': { /* var_or_func_tail -> '[' exp1 ']' */ | ||
447 | next(ls); | ||
448 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | ||
449 | v->k = VINDEXED; | ||
450 | exp1(ls); | ||
451 | check(ls, ']'); | ||
452 | break; | ||
453 | } | ||
454 | case ':': { /* var_or_func_tail -> ':' NAME funcargs */ | ||
455 | next(ls); | ||
456 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | ||
457 | luaK_code1(ls->fs, OP_PUSHSELF, checkname(ls)); | ||
458 | funcargs(ls, 1); | ||
459 | v->k = VEXP; | ||
460 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
461 | break; | ||
462 | } | ||
463 | case '(': case TK_STRING: case '{': { /* var_or_func_tail -> funcargs */ | ||
464 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | ||
465 | funcargs(ls, 0); | ||
466 | v->k = VEXP; | ||
467 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
468 | break; | ||
469 | } | ||
470 | default: return; /* should be follow... */ | ||
471 | } | ||
472 | } | ||
473 | } | ||
474 | |||
475 | |||
476 | static void var_or_func (LexState *ls, expdesc *v) { | ||
477 | /* var_or_func -> ['%'] NAME var_or_func_tail */ | ||
478 | if (optional(ls, '%')) { /* upvalue? */ | ||
479 | pushupvalue(ls, str_checkname(ls)); | ||
480 | v->k = VEXP; | ||
481 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
482 | } | ||
483 | else /* variable name */ | ||
484 | singlevar(ls, str_checkname(ls), v); | ||
485 | var_or_func_tail(ls, v); | ||
486 | } | ||
487 | |||
488 | |||
489 | |||
490 | /* | 436 | /* |
491 | ** {====================================================================== | 437 | ** {====================================================================== |
492 | ** Rules for Constructors | 438 | ** Rules for Constructors |
@@ -615,47 +561,51 @@ static void constructor (LexState *ls) { | |||
615 | ** ======================================================================= | 561 | ** ======================================================================= |
616 | */ | 562 | */ |
617 | 563 | ||
618 | 564 | static void primaryexp (LexState *ls, expdesc *v) { | |
619 | static void simpleexp (LexState *ls, expdesc *v) { | ||
620 | FuncState *fs = ls->fs; | 565 | FuncState *fs = ls->fs; |
621 | switch (ls->t.token) { | 566 | switch (ls->t.token) { |
622 | case TK_NUMBER: { /* simpleexp -> NUMBER */ | 567 | case TK_NUMBER: { |
623 | lua_Number r = ls->t.seminfo.r; | 568 | lua_Number r = ls->t.seminfo.r; |
624 | next(ls); | 569 | next(ls); |
625 | luaK_number(fs, r); | 570 | luaK_number(fs, r); |
626 | break; | 571 | break; |
627 | } | 572 | } |
628 | case TK_STRING: { /* simpleexp -> STRING */ | 573 | case TK_STRING: { |
629 | code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ | 574 | code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ |
630 | next(ls); | 575 | next(ls); |
631 | break; | 576 | break; |
632 | } | 577 | } |
633 | case TK_NIL: { /* simpleexp -> NIL */ | 578 | case TK_NIL: { |
634 | luaK_adjuststack(fs, -1); | 579 | luaK_adjuststack(fs, -1); |
635 | next(ls); | 580 | next(ls); |
636 | break; | 581 | break; |
637 | } | 582 | } |
638 | case '{': { /* simpleexp -> constructor */ | 583 | case '{': { /* constructor */ |
639 | constructor(ls); | 584 | constructor(ls); |
640 | break; | 585 | break; |
641 | } | 586 | } |
642 | case TK_FUNCTION: { /* simpleexp -> FUNCTION body */ | 587 | case TK_FUNCTION: { |
643 | next(ls); | 588 | next(ls); |
644 | body(ls, 0, ls->linenumber); | 589 | body(ls, 0, ls->linenumber); |
645 | break; | 590 | break; |
646 | } | 591 | } |
647 | case '(': { /* simpleexp -> '(' expr ')' */ | 592 | case '(': { |
648 | next(ls); | 593 | next(ls); |
649 | expr(ls, v); | 594 | expr(ls, v); |
650 | check(ls, ')'); | 595 | check(ls, ')'); |
651 | return; | 596 | return; |
652 | } | 597 | } |
653 | case TK_NAME: case '%': { | 598 | case TK_NAME: { |
654 | var_or_func(ls, v); | 599 | singlevar(ls, str_checkname(ls), v); |
655 | return; | 600 | return; |
656 | } | 601 | } |
602 | case '%': { | ||
603 | next(ls); /* skip `%' */ | ||
604 | pushupvalue(ls, str_checkname(ls)); | ||
605 | break; | ||
606 | } | ||
657 | default: { | 607 | default: { |
658 | luaK_error(ls, "<expression> expected"); | 608 | luaK_error(ls, "unexpected symbol"); |
659 | return; | 609 | return; |
660 | } | 610 | } |
661 | } | 611 | } |
@@ -664,10 +614,46 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
664 | } | 614 | } |
665 | 615 | ||
666 | 616 | ||
667 | static void exp1 (LexState *ls) { | 617 | static void simpleexp (LexState *ls, expdesc *v) { |
668 | expdesc v; | 618 | /* simpleexp -> |
669 | expr(ls, &v); | 619 | primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ |
670 | luaK_tostack(ls, &v, 1); | 620 | primaryexp(ls, v); |
621 | for (;;) { | ||
622 | switch (ls->t.token) { | ||
623 | case '.': { /* '.' NAME */ | ||
624 | next(ls); | ||
625 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | ||
626 | luaK_kstr(ls, checkname(ls)); | ||
627 | v->k = VINDEXED; | ||
628 | break; | ||
629 | } | ||
630 | case '[': { /* '[' exp1 ']' */ | ||
631 | next(ls); | ||
632 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | ||
633 | v->k = VINDEXED; | ||
634 | exp1(ls); | ||
635 | check(ls, ']'); | ||
636 | break; | ||
637 | } | ||
638 | case ':': { /* ':' NAME funcargs */ | ||
639 | next(ls); | ||
640 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | ||
641 | luaK_code1(ls->fs, OP_PUSHSELF, checkname(ls)); | ||
642 | funcargs(ls, 1); | ||
643 | v->k = VEXP; | ||
644 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
645 | break; | ||
646 | } | ||
647 | case '(': case TK_STRING: case '{': { /* funcargs */ | ||
648 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | ||
649 | funcargs(ls, 0); | ||
650 | v->k = VEXP; | ||
651 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
652 | break; | ||
653 | } | ||
654 | default: return; /* should be follow... */ | ||
655 | } | ||
656 | } | ||
671 | } | 657 | } |
672 | 658 | ||
673 | 659 | ||
@@ -748,6 +734,13 @@ static void expr (LexState *ls, expdesc *v) { | |||
748 | subexpr(ls, v, -1); | 734 | subexpr(ls, v, -1); |
749 | } | 735 | } |
750 | 736 | ||
737 | |||
738 | static void exp1 (LexState *ls) { | ||
739 | expdesc v; | ||
740 | expr(ls, &v); | ||
741 | luaK_tostack(ls, &v, 1); | ||
742 | } | ||
743 | |||
751 | /* }==================================================================== */ | 744 | /* }==================================================================== */ |
752 | 745 | ||
753 | 746 | ||
@@ -781,10 +774,10 @@ static void block (LexState *ls) { | |||
781 | static int assignment (LexState *ls, expdesc *v, int nvars) { | 774 | static int assignment (LexState *ls, expdesc *v, int nvars) { |
782 | int left = 0; /* number of values left in the stack after assignment */ | 775 | int left = 0; /* number of values left in the stack after assignment */ |
783 | luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); | 776 | luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); |
784 | if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */ | 777 | if (ls->t.token == ',') { /* assignment -> ',' simpleexp assignment */ |
785 | expdesc nv; | 778 | expdesc nv; |
786 | next(ls); | 779 | next(ls); |
787 | var_or_func(ls, &nv); | 780 | simpleexp(ls, &nv); |
788 | check_condition(ls, (nv.k != VEXP), "syntax error"); | 781 | check_condition(ls, (nv.k != VEXP), "syntax error"); |
789 | left = assignment(ls, &nv, nvars+1); | 782 | left = assignment(ls, &nv, nvars+1); |
790 | } | 783 | } |
@@ -998,15 +991,15 @@ static void funcstat (LexState *ls, int line) { | |||
998 | 991 | ||
999 | 992 | ||
1000 | static void namestat (LexState *ls) { | 993 | static void namestat (LexState *ls) { |
1001 | /* stat -> func | ['%'] NAME assignment */ | 994 | /* stat -> func | assignment */ |
1002 | FuncState *fs = ls->fs; | 995 | FuncState *fs = ls->fs; |
1003 | expdesc v; | 996 | expdesc v; |
1004 | var_or_func(ls, &v); | 997 | simpleexp(ls, &v); |
1005 | if (v.k == VEXP) { /* stat -> func */ | 998 | if (v.k == VEXP) { /* stat -> func */ |
1006 | check_condition(ls, luaK_lastisopen(fs), "syntax error"); /* an upvalue? */ | 999 | check_condition(ls, luaK_lastisopen(fs), "syntax error"); /* an upvalue? */ |
1007 | luaK_setcallreturns(fs, 0); /* call statement uses no results */ | 1000 | luaK_setcallreturns(fs, 0); /* call statement uses no results */ |
1008 | } | 1001 | } |
1009 | else { /* stat -> ['%'] NAME assignment */ | 1002 | else { /* stat -> assignment */ |
1010 | int left = assignment(ls, &v, 1); | 1003 | int left = assignment(ls, &v, 1); |
1011 | luaK_adjuststack(fs, left); /* remove eventual garbage left on stack */ | 1004 | luaK_adjuststack(fs, left); /* remove eventual garbage left on stack */ |
1012 | } | 1005 | } |
@@ -1072,10 +1065,6 @@ static int stat (LexState *ls) { | |||
1072 | localstat(ls); | 1065 | localstat(ls); |
1073 | return 0; | 1066 | return 0; |
1074 | } | 1067 | } |
1075 | case TK_NAME: case '%': { /* stat -> namestat */ | ||
1076 | namestat(ls); | ||
1077 | return 0; | ||
1078 | } | ||
1079 | case TK_RETURN: { /* stat -> retstat */ | 1068 | case TK_RETURN: { /* stat -> retstat */ |
1080 | retstat(ls); | 1069 | retstat(ls); |
1081 | return 1; /* must be last statement */ | 1070 | return 1; /* must be last statement */ |
@@ -1085,7 +1074,7 @@ static int stat (LexState *ls) { | |||
1085 | return 1; /* must be last statement */ | 1074 | return 1; /* must be last statement */ |
1086 | } | 1075 | } |
1087 | default: { | 1076 | default: { |
1088 | luaK_error(ls, "<statement> expected"); | 1077 | namestat(ls); |
1089 | return 0; /* to avoid warnings */ | 1078 | return 0; /* to avoid warnings */ |
1090 | } | 1079 | } |
1091 | } | 1080 | } |