diff options
-rw-r--r-- | lparser.c | 58 |
1 files changed, 32 insertions, 26 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.186 2002/06/06 13:16:02 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.187 2002/06/06 13:52:37 roberto Exp roberto $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -73,16 +73,6 @@ static void error_expected (LexState *ls, int token) { | |||
73 | } | 73 | } |
74 | 74 | ||
75 | 75 | ||
76 | static void check (LexState *ls, int c) { | ||
77 | if (ls->t.token != c) | ||
78 | error_expected(ls, c); | ||
79 | next(ls); | ||
80 | } | ||
81 | |||
82 | |||
83 | #define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } | ||
84 | |||
85 | |||
86 | static int testnext (LexState *ls, int c) { | 76 | static int testnext (LexState *ls, int c) { |
87 | if (ls->t.token == c) { | 77 | if (ls->t.token == c) { |
88 | next(ls); | 78 | next(ls); |
@@ -92,8 +82,18 @@ static int testnext (LexState *ls, int c) { | |||
92 | } | 82 | } |
93 | 83 | ||
94 | 84 | ||
85 | static void check (LexState *ls, int c) { | ||
86 | if (!testnext(ls, c)) | ||
87 | error_expected(ls, c); | ||
88 | } | ||
89 | |||
90 | |||
91 | #define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } | ||
92 | |||
93 | |||
94 | |||
95 | static void check_match (LexState *ls, int what, int who, int where) { | 95 | static void check_match (LexState *ls, int what, int who, int where) { |
96 | if (ls->t.token != what) { | 96 | if (!testnext(ls, what)) { |
97 | if (where == ls->linenumber) | 97 | if (where == ls->linenumber) |
98 | error_expected(ls, what); | 98 | error_expected(ls, what); |
99 | else { | 99 | else { |
@@ -102,7 +102,6 @@ static void check_match (LexState *ls, int what, int who, int where) { | |||
102 | luaX_token2str(ls, what), luaX_token2str(ls, who), where)); | 102 | luaX_token2str(ls, what), luaX_token2str(ls, who), where)); |
103 | } | 103 | } |
104 | } | 104 | } |
105 | next(ls); | ||
106 | } | 105 | } |
107 | 106 | ||
108 | 107 | ||
@@ -400,8 +399,7 @@ static int explist1 (LexState *ls, expdesc *v) { | |||
400 | /* explist1 -> expr { `,' expr } */ | 399 | /* explist1 -> expr { `,' expr } */ |
401 | int n = 1; /* at least one expression */ | 400 | int n = 1; /* at least one expression */ |
402 | expr(ls, v); | 401 | expr(ls, v); |
403 | while (ls->t.token == ',') { | 402 | while (testnext(ls, ',')) { |
404 | next(ls); /* skip comma */ | ||
405 | luaK_exp2nextreg(ls->fs, v); | 403 | luaK_exp2nextreg(ls->fs, v); |
406 | expr(ls, v); | 404 | expr(ls, v); |
407 | n++; | 405 | n++; |
@@ -544,7 +542,7 @@ static void constructor (LexState *ls, expdesc *t) { | |||
544 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ | 542 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ |
545 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ | 543 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ |
546 | check(ls, '{'); | 544 | check(ls, '{'); |
547 | for (;;) { | 545 | do { |
548 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); | 546 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); |
549 | testnext(ls, ';'); /* compatibility only */ | 547 | testnext(ls, ';'); /* compatibility only */ |
550 | if (ls->t.token == '}') break; | 548 | if (ls->t.token == '}') break; |
@@ -567,11 +565,7 @@ static void constructor (LexState *ls, expdesc *t) { | |||
567 | break; | 565 | break; |
568 | } | 566 | } |
569 | } | 567 | } |
570 | if (ls->t.token == ',' || ls->t.token == ';') | 568 | } while (testnext(ls, ',') || testnext(ls, ';')); |
571 | next(ls); | ||
572 | else | ||
573 | break; | ||
574 | } | ||
575 | check_match(ls, '}', '{', line); | 569 | check_match(ls, '}', '{', line); |
576 | lastlistfield(fs, &cc); | 570 | lastlistfield(fs, &cc); |
577 | if (cc.na > 0) | 571 | if (cc.na > 0) |
@@ -857,10 +851,9 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | |||
857 | expdesc e; | 851 | expdesc e; |
858 | check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, | 852 | check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, |
859 | "syntax error"); | 853 | "syntax error"); |
860 | if (ls->t.token == ',') { /* assignment -> `,' primaryexp assignment */ | 854 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ |
861 | struct LHS_assign nv; | 855 | struct LHS_assign nv; |
862 | nv.prev = lh; | 856 | nv.prev = lh; |
863 | next(ls); | ||
864 | primaryexp(ls, &nv.v); | 857 | primaryexp(ls, &nv.v); |
865 | if (nv.v.k == VLOCAL) | 858 | if (nv.v.k == VLOCAL) |
866 | check_conflict(ls, lh, &nv.v); | 859 | check_conflict(ls, lh, &nv.v); |
@@ -1083,7 +1076,7 @@ static void ifstat (LexState *ls, int line) { | |||
1083 | if (ls->t.token == TK_ELSE) { | 1076 | if (ls->t.token == TK_ELSE) { |
1084 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 1077 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
1085 | luaK_patchtohere(fs, v.f); | 1078 | luaK_patchtohere(fs, v.f); |
1086 | next(ls); /* skip ELSE */ | 1079 | next(ls); /* skip ELSE (after patch, for correct line info) */ |
1087 | block(ls); /* `else' part */ | 1080 | block(ls); /* `else' part */ |
1088 | } | 1081 | } |
1089 | else | 1082 | else |
@@ -1093,12 +1086,21 @@ static void ifstat (LexState *ls, int line) { | |||
1093 | } | 1086 | } |
1094 | 1087 | ||
1095 | 1088 | ||
1089 | static void localfunc (LexState *ls) { | ||
1090 | expdesc v, b; | ||
1091 | new_localvar(ls, str_checkname(ls), 0); | ||
1092 | init_exp(&v, VLOCAL, ls->fs->freereg++); | ||
1093 | adjustlocalvars(ls, 1); | ||
1094 | body(ls, &b, 0, ls->linenumber); | ||
1095 | luaK_storevar(ls->fs, &v, &b); | ||
1096 | } | ||
1097 | |||
1098 | |||
1096 | static void localstat (LexState *ls) { | 1099 | static void localstat (LexState *ls) { |
1097 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ | 1100 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ |
1098 | int nvars = 0; | 1101 | int nvars = 0; |
1099 | int nexps; | 1102 | int nexps; |
1100 | expdesc e; | 1103 | expdesc e; |
1101 | next(ls); /* skip LOCAL */ | ||
1102 | do { | 1104 | do { |
1103 | new_localvar(ls, str_checkname(ls), nvars++); | 1105 | new_localvar(ls, str_checkname(ls), nvars++); |
1104 | } while (testnext(ls, ',')); | 1106 | } while (testnext(ls, ',')); |
@@ -1234,7 +1236,11 @@ static int statement (LexState *ls) { | |||
1234 | return 0; | 1236 | return 0; |
1235 | } | 1237 | } |
1236 | case TK_LOCAL: { /* stat -> localstat */ | 1238 | case TK_LOCAL: { /* stat -> localstat */ |
1237 | localstat(ls); | 1239 | next(ls); /* skip LOCAL */ |
1240 | if (testnext(ls, TK_FUNCTION)) /* local function? */ | ||
1241 | localfunc(ls); | ||
1242 | else | ||
1243 | localstat(ls); | ||
1238 | return 0; | 1244 | return 0; |
1239 | } | 1245 | } |
1240 | case TK_RETURN: { /* stat -> retstat */ | 1246 | case TK_RETURN: { /* stat -> retstat */ |