aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-06-06 14:29:53 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-06-06 14:29:53 -0300
commit65d66ba27592271cda71caefe231f9ee2d909d5c (patch)
treea21eab5485f97334b9288df090fc012647826f1a
parentcff22f57ddb6ff65edc7d8bac323f8c7af10c668 (diff)
downloadlua-65d66ba27592271cda71caefe231f9ee2d909d5c.tar.gz
lua-65d66ba27592271cda71caefe231f9ee2d909d5c.tar.bz2
lua-65d66ba27592271cda71caefe231f9ee2d909d5c.zip
new "local function"
-rw-r--r--lparser.c58
1 files changed, 32 insertions, 26 deletions
diff --git a/lparser.c b/lparser.c
index 5e9bcc30..3ceb15e7 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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
76static 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
86static int testnext (LexState *ls, int c) { 76static 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
85static 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
95static void check_match (LexState *ls, int what, int who, int where) { 95static 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
1089static 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
1096static void localstat (LexState *ls) { 1099static 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 */