aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c89
1 files changed, 63 insertions, 26 deletions
diff --git a/lparser.c b/lparser.c
index 9691f4d2..3fae5419 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.85 2000/05/10 16:33:20 roberto Exp roberto $ 2** $Id: lparser.c,v 1.86 2000/05/12 18:12:04 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*/
@@ -205,7 +205,8 @@ static void store_localvar (LexState *ls, TString *name, int n) {
205} 205}
206 206
207 207
208static void adjustlocalvars (LexState *ls, int nvars, int line) { 208static void adjustlocalvars (LexState *ls, int nvars) {
209 int line = ls->fs->lastsetline;
209 FuncState *fs = ls->fs; 210 FuncState *fs = ls->fs;
210 int i; 211 int i;
211 fs->nlocalvar += nvars; 212 fs->nlocalvar += nvars;
@@ -214,7 +215,8 @@ static void adjustlocalvars (LexState *ls, int nvars, int line) {
214} 215}
215 216
216 217
217static void removelocalvars (LexState *ls, int nvars, int line) { 218static void removelocalvars (LexState *ls, int nvars) {
219 int line = ls->fs->lastsetline;
218 ls->fs->nlocalvar -= nvars; 220 ls->fs->nlocalvar -= nvars;
219 while (nvars--) 221 while (nvars--)
220 luaI_unregisterlocalvar(ls, line); 222 luaI_unregisterlocalvar(ls, line);
@@ -223,7 +225,7 @@ static void removelocalvars (LexState *ls, int nvars, int line) {
223 225
224static void add_localvar (LexState *ls, const char *name) { 226static void add_localvar (LexState *ls, const char *name) {
225 store_localvar(ls, luaS_newfixed(ls->L, name), 0); 227 store_localvar(ls, luaS_newfixed(ls->L, name), 0);
226 adjustlocalvars(ls, 1, 0); 228 adjustlocalvars(ls, 1);
227} 229}
228 230
229 231
@@ -303,7 +305,7 @@ static void adjust_mult_assign (LexState *ls, int nvars, int nexps) {
303 305
304static void code_args (LexState *ls, int nparams, int dots) { 306static void code_args (LexState *ls, int nparams, int dots) {
305 FuncState *fs = ls->fs; 307 FuncState *fs = ls->fs;
306 adjustlocalvars(ls, nparams, 0); 308 adjustlocalvars(ls, nparams);
307 checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); 309 checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters");
308 nparams = fs->nlocalvar; /* `self' could be there already */ 310 nparams = fs->nlocalvar; /* `self' could be there already */
309 fs->f->numparams = nparams; 311 fs->f->numparams = nparams;
@@ -838,7 +840,7 @@ static void block (LexState *ls) {
838 int nlocalvar = fs->nlocalvar; 840 int nlocalvar = fs->nlocalvar;
839 chunk(ls); 841 chunk(ls);
840 luaK_adjuststack(fs, fs->nlocalvar - nlocalvar); /* remove local variables */ 842 luaK_adjuststack(fs, fs->nlocalvar - nlocalvar); /* remove local variables */
841 removelocalvars(ls, fs->nlocalvar - nlocalvar, fs->lastsetline); 843 removelocalvars(ls, fs->nlocalvar - nlocalvar);
842} 844}
843 845
844 846
@@ -907,15 +909,20 @@ static void repeatstat (LexState *ls, int line) {
907} 909}
908 910
909 911
910static void forstat (LexState *ls, int line) { 912static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) {
911 /* forstat -> FOR NAME '=' expr1 ',' expr1 [',' expr1] DO block END */
912 FuncState *fs = ls->fs; 913 FuncState *fs = ls->fs;
913 int prep; 914 int prep = luaK_code0(fs, prepfor);
914 int blockinit; 915 int blockinit = luaK_getlabel(fs);
915 Breaklabel bl; 916 check(ls, TK_DO);
916 enterbreak(fs, &bl); 917 block(ls);
917 setline_and_next(ls); /* skip for */ 918 luaK_patchlist(fs, prep, luaK_getlabel(fs));
918 store_localvar(ls, str_checkname(ls), 0); /* control variable */ 919 luaK_patchlist(fs, luaK_code0(fs, loopfor), blockinit);
920}
921
922
923static void fornum (LexState *ls, TString *varname) {
924 FuncState *fs = ls->fs;
925 store_localvar(ls, varname, 0);
919 check(ls, '='); 926 check(ls, '=');
920 exp1(ls); /* initial value */ 927 exp1(ls); /* initial value */
921 check(ls, ','); 928 check(ls, ',');
@@ -924,18 +931,49 @@ static void forstat (LexState *ls, int line) {
924 exp1(ls); /* optional step */ 931 exp1(ls); /* optional step */
925 else 932 else
926 luaK_code1(fs, OP_PUSHINT, 1); /* default step */ 933 luaK_code1(fs, OP_PUSHINT, 1); /* default step */
927 adjustlocalvars(ls, 1, 0); /* init scope for control variable */ 934 adjustlocalvars(ls, 1); /* scope for control variables */
928 add_localvar(ls, " limit "); 935 add_localvar(ls, "*limit*");
929 add_localvar(ls, " step "); 936 add_localvar(ls, "*step*");
930 prep = luaK_code0(fs, OP_FORPREP); 937 forbody(ls, OP_FORPREP, OP_FORLOOP);
931 blockinit = luaK_getlabel(fs); 938 removelocalvars(ls, 3);
932 check(ls, TK_DO); 939}
933 block(ls); 940
934 luaK_patchlist(fs, prep, luaK_getlabel(fs)); 941
935 luaK_patchlist(fs, luaK_code0(fs, OP_FORLOOP), blockinit); 942static void forlist (LexState *ls, TString *indexname) {
943 TString *valname;
944 check(ls, ',');
945 valname = str_checkname(ls);
946 /* next test is dirty, but avoids `in' being a reserved word */
947 if (ls->token != TK_NAME || ls->seminfo.ts != luaS_new(ls->L, "in"))
948 luaK_error(ls, "`in' expected");
949 next(ls); /* skip `in' */
950 exp1(ls); /* table */
951 add_localvar(ls, "*table*");
952 add_localvar(ls, "*counter*");
953 store_localvar(ls, indexname, 0);
954 store_localvar(ls, valname, 1);
955 adjustlocalvars(ls, 2); /* scope for control variable */
956 forbody(ls, OP_LFORPREP, OP_LFORLOOP);
957 removelocalvars(ls, 4);
958}
959
960
961static void forstat (LexState *ls, int line) {
962 /* forstat -> FOR NAME '=' expr1 ',' expr1 [',' expr1] DO block END */
963 /* forstat -> FOR NAME1, NAME2 IN expr1 DO block END */
964 FuncState *fs = ls->fs;
965 TString *varname;
966 Breaklabel bl;
967 enterbreak(fs, &bl);
968 setline_and_next(ls); /* skip `for' */
969 varname = str_checkname(ls); /* first variable name */
970 switch (ls->token) {
971 case '=': fornum(ls, varname); break;
972 case ',': forlist(ls, varname); break;
973 default: luaK_error(ls, "`=' or `,' expected");
974 }
936 check_END(ls, TK_FOR, line); 975 check_END(ls, TK_FOR, line);
937 leavebreak(fs, &bl); 976 leavebreak(fs, &bl);
938 removelocalvars(ls, 3, fs->lastsetline);
939} 977}
940 978
941 979
@@ -999,13 +1037,12 @@ static int decinit (LexState *ls) {
999 1037
1000static void localstat (LexState *ls) { 1038static void localstat (LexState *ls) {
1001 /* stat -> LOCAL localnamelist decinit */ 1039 /* stat -> LOCAL localnamelist decinit */
1002 FuncState *fs = ls->fs;
1003 int nvars; 1040 int nvars;
1004 int nexps; 1041 int nexps;
1005 setline_and_next(ls); /* skip LOCAL */ 1042 setline_and_next(ls); /* skip LOCAL */
1006 nvars = localnamelist(ls); 1043 nvars = localnamelist(ls);
1007 nexps = decinit(ls); 1044 nexps = decinit(ls);
1008 adjustlocalvars(ls, nvars, fs->lastsetline); 1045 adjustlocalvars(ls, nvars);
1009 adjust_mult_assign(ls, nvars, nexps); 1046 adjust_mult_assign(ls, nvars, nexps);
1010} 1047}
1011 1048