diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-06-06 14:29:53 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-06-06 14:29:53 -0300 |
| commit | 65d66ba27592271cda71caefe231f9ee2d909d5c (patch) | |
| tree | a21eab5485f97334b9288df090fc012647826f1a | |
| parent | cff22f57ddb6ff65edc7d8bac323f8c7af10c668 (diff) | |
| download | lua-65d66ba27592271cda71caefe231f9ee2d909d5c.tar.gz lua-65d66ba27592271cda71caefe231f9ee2d909d5c.tar.bz2 lua-65d66ba27592271cda71caefe231f9ee2d909d5c.zip | |
new "local function"
| -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 */ |
