diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-09-25 14:06:48 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-09-25 14:06:48 -0300 |
commit | 328d53e77bf53277f565944055d3dd923d9b5c46 (patch) | |
tree | 1f868845cbd85d03d8ecbecf30e1fc3fee18e0c2 /lparser.c | |
parent | c04d9b9ecb7a9dcf59ba185fc6211cb1a3ee1706 (diff) | |
download | lua-328d53e77bf53277f565944055d3dd923d9b5c46.tar.gz lua-328d53e77bf53277f565944055d3dd923d9b5c46.tar.bz2 lua-328d53e77bf53277f565944055d3dd923d9b5c46.zip |
restricted syntax for function call/table accesses prefixes
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 97 |
1 files changed, 55 insertions, 42 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.154 2001/08/27 15:16:28 roberto Exp $ | 2 | ** $Id: lparser.c,v 1.156 2001/09/07 17:39:10 roberto Exp $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -419,6 +419,8 @@ static void funcargs (LexState *ls, expdesc *f) { | |||
419 | switch (ls->t.token) { | 419 | switch (ls->t.token) { |
420 | case l_c('('): { /* funcargs -> `(' [ explist1 ] `)' */ | 420 | case l_c('('): { /* funcargs -> `(' [ explist1 ] `)' */ |
421 | int line = ls->linenumber; | 421 | int line = ls->linenumber; |
422 | if (line != ls->lastline) | ||
423 | luaK_error(ls, l_s("ambiguous syntax (function call x new statement)")); | ||
422 | next(ls); | 424 | next(ls); |
423 | if (ls->t.token == l_c(')')) /* arg list is empty? */ | 425 | if (ls->t.token == l_c(')')) /* arg list is empty? */ |
424 | args.k = VVOID; | 426 | args.k = VVOID; |
@@ -605,33 +607,10 @@ static void constructor (LexState *ls, expdesc *t) { | |||
605 | ** ======================================================================= | 607 | ** ======================================================================= |
606 | */ | 608 | */ |
607 | 609 | ||
608 | static void primaryexp (LexState *ls, expdesc *v) { | 610 | |
611 | static void prefixexp (LexState *ls, expdesc *v) { | ||
612 | /* prefixexp -> NAME | '(' expr ')' */ | ||
609 | switch (ls->t.token) { | 613 | switch (ls->t.token) { |
610 | case TK_NUMBER: { | ||
611 | init_exp(v, VNUMBER, 0); | ||
612 | v->u.n = ls->t.seminfo.r; | ||
613 | next(ls); /* must use `seminfo' before `next' */ | ||
614 | break; | ||
615 | } | ||
616 | case TK_STRING: { | ||
617 | codestring(ls, v, ls->t.seminfo.ts); | ||
618 | next(ls); /* must use `seminfo' before `next' */ | ||
619 | break; | ||
620 | } | ||
621 | case TK_NIL: { | ||
622 | init_exp(v, VNIL, 0); | ||
623 | next(ls); | ||
624 | break; | ||
625 | } | ||
626 | case l_c('{'): { /* constructor */ | ||
627 | constructor(ls, v); | ||
628 | break; | ||
629 | } | ||
630 | case TK_FUNCTION: { | ||
631 | next(ls); | ||
632 | body(ls, v, 0, ls->linenumber); | ||
633 | break; | ||
634 | } | ||
635 | case l_c('('): { | 614 | case l_c('('): { |
636 | next(ls); | 615 | next(ls); |
637 | expr(ls, v); | 616 | expr(ls, v); |
@@ -651,7 +630,6 @@ static void primaryexp (LexState *ls, expdesc *v) { | |||
651 | next(ls); | 630 | next(ls); |
652 | return; | 631 | return; |
653 | } | 632 | } |
654 | |||
655 | default: { | 633 | default: { |
656 | luaK_error(ls, l_s("unexpected symbol")); | 634 | luaK_error(ls, l_s("unexpected symbol")); |
657 | return; | 635 | return; |
@@ -660,11 +638,11 @@ static void primaryexp (LexState *ls, expdesc *v) { | |||
660 | } | 638 | } |
661 | 639 | ||
662 | 640 | ||
663 | static void simpleexp (LexState *ls, expdesc *v) { | 641 | static void primaryexp (LexState *ls, expdesc *v) { |
664 | /* simpleexp -> | 642 | /* primaryexp -> |
665 | primaryexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ | 643 | prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ |
666 | FuncState *fs = ls->fs; | 644 | FuncState *fs = ls->fs; |
667 | primaryexp(ls, v); | 645 | prefixexp(ls, v); |
668 | for (;;) { | 646 | for (;;) { |
669 | switch (ls->t.token) { | 647 | switch (ls->t.token) { |
670 | case l_c('.'): { /* field */ | 648 | case l_c('.'): { /* field */ |
@@ -691,12 +669,51 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
691 | funcargs(ls, v); | 669 | funcargs(ls, v); |
692 | break; | 670 | break; |
693 | } | 671 | } |
694 | default: return; /* should be follow... */ | 672 | default: return; |
695 | } | 673 | } |
696 | } | 674 | } |
697 | } | 675 | } |
698 | 676 | ||
699 | 677 | ||
678 | static void simpleexp (LexState *ls, expdesc *v) { | ||
679 | /* simpleexp -> NUMBER | STRING | NIL | constructor | FUNCTION body | ||
680 | | primaryexp */ | ||
681 | switch (ls->t.token) { | ||
682 | case TK_NUMBER: { | ||
683 | init_exp(v, VNUMBER, 0); | ||
684 | v->u.n = ls->t.seminfo.r; | ||
685 | next(ls); /* must use `seminfo' before `next' */ | ||
686 | break; | ||
687 | } | ||
688 | case TK_STRING: { | ||
689 | codestring(ls, v, ls->t.seminfo.ts); | ||
690 | next(ls); /* must use `seminfo' before `next' */ | ||
691 | break; | ||
692 | } | ||
693 | case TK_NIL: { | ||
694 | init_exp(v, VNIL, 0); | ||
695 | next(ls); | ||
696 | break; | ||
697 | } | ||
698 | case l_c('{'): { /* constructor */ | ||
699 | constructor(ls, v); | ||
700 | break; | ||
701 | } | ||
702 | case TK_FUNCTION: { | ||
703 | next(ls); | ||
704 | body(ls, v, 0, ls->linenumber); | ||
705 | break; | ||
706 | } | ||
707 | default: { | ||
708 | primaryexp(ls, v); | ||
709 | break; | ||
710 | } | ||
711 | } | ||
712 | } | ||
713 | |||
714 | |||
715 | |||
716 | |||
700 | static UnOpr getunopr (int op) { | 717 | static UnOpr getunopr (int op) { |
701 | switch (op) { | 718 | switch (op) { |
702 | case TK_NOT: return OPR_NOT; | 719 | case TK_NOT: return OPR_NOT; |
@@ -846,12 +863,12 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | |||
846 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | 863 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { |
847 | expdesc e; | 864 | expdesc e; |
848 | check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, | 865 | check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, |
849 | l_s("syntax error!!")); | 866 | l_s("syntax error!")); |
850 | if (ls->t.token == l_c(',')) { /* assignment -> `,' simpleexp assignment */ | 867 | if (ls->t.token == l_c(',')) { /* assignment -> `,' primaryexp assignment */ |
851 | struct LHS_assign nv; | 868 | struct LHS_assign nv; |
852 | nv.prev = lh; | 869 | nv.prev = lh; |
853 | next(ls); | 870 | next(ls); |
854 | simpleexp(ls, &nv.v); | 871 | primaryexp(ls, &nv.v); |
855 | if (nv.v.k == VLOCAL) | 872 | if (nv.v.k == VLOCAL) |
856 | check_conflict(ls, lh, &nv.v); | 873 | check_conflict(ls, lh, &nv.v); |
857 | assignment(ls, &nv, nvars+1); | 874 | assignment(ls, &nv, nvars+1); |
@@ -1079,7 +1096,7 @@ static void exprstat (LexState *ls) { | |||
1079 | /* stat -> func | assignment */ | 1096 | /* stat -> func | assignment */ |
1080 | FuncState *fs = ls->fs; | 1097 | FuncState *fs = ls->fs; |
1081 | struct LHS_assign v; | 1098 | struct LHS_assign v; |
1082 | simpleexp(ls, &v.v); | 1099 | primaryexp(ls, &v.v); |
1083 | if (v.v.k == VCALL) { /* stat -> func */ | 1100 | if (v.v.k == VCALL) { /* stat -> func */ |
1084 | luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */ | 1101 | luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */ |
1085 | } | 1102 | } |
@@ -1155,11 +1172,7 @@ static int statement (LexState *ls) { | |||
1155 | return 0; | 1172 | return 0; |
1156 | } | 1173 | } |
1157 | case TK_FUNCTION: { | 1174 | case TK_FUNCTION: { |
1158 | lookahead(ls); | 1175 | funcstat(ls, line); /* stat -> funcstat */ |
1159 | if (ls->lookahead.token == '(') | ||
1160 | exprstat(ls); | ||
1161 | else | ||
1162 | funcstat(ls, line); /* stat -> funcstat */ | ||
1163 | return 0; | 1176 | return 0; |
1164 | } | 1177 | } |
1165 | case TK_LOCAL: { /* stat -> localstat */ | 1178 | case TK_LOCAL: { /* stat -> localstat */ |