aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c44
1 files changed, 24 insertions, 20 deletions
diff --git a/lparser.c b/lparser.c
index 0ebb1ee3..ffbe49d9 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.207 2003/02/28 17:19:47 roberto Exp roberto $ 2** $Id: lparser.c,v 1.208 2003/04/03 13:35:34 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*/
@@ -1027,30 +1027,34 @@ static int exp1 (LexState *ls) {
1027 1027
1028 1028
1029static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { 1029static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1030 /* forbody -> DO block */
1030 BlockCnt bl; 1031 BlockCnt bl;
1031 FuncState *fs = ls->fs; 1032 FuncState *fs = ls->fs;
1032 int prep, endfor; 1033 int prep, endfor;
1033 adjustlocalvars(ls, nvars); /* scope for all variables */ 1034 adjustlocalvars(ls, 3); /* control variables */
1034 check(ls, TK_DO); 1035 check(ls, TK_DO);
1035 enterblock(fs, &bl, 1); /* loop block */ 1036 prep = luaK_codeAsBx(fs, (isnum ? OP_FORPREP : OP_TFORPREP), base, NO_JUMP);
1036 prep = luaK_getlabel(fs); 1037 enterblock(fs, &bl, 0); /* scope for declared variables */
1038 adjustlocalvars(ls, nvars);
1039 luaK_reserveregs(fs, nvars);
1037 block(ls); 1040 block(ls);
1038 luaK_patchtohere(fs, prep-1); 1041 leaveblock(fs); /* end of scope for declared variables */
1042 luaK_patchtohere(fs, prep);
1039 endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : 1043 endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
1040 luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); 1044 luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
1041 luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ 1045 luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
1042 luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep); 1046 luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
1043 leaveblock(fs);
1044} 1047}
1045 1048
1046 1049
1047static void fornum (LexState *ls, TString *varname, int line) { 1050static void fornum (LexState *ls, TString *varname, int line) {
1048 /* fornum -> NAME = exp1,exp1[,exp1] DO body */ 1051 /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1049 FuncState *fs = ls->fs; 1052 FuncState *fs = ls->fs;
1050 int base = fs->freereg; 1053 int base = fs->freereg;
1051 new_localvar(ls, varname, 0); 1054 new_localvarstr(ls, "(for index)", 0);
1052 new_localvarstr(ls, "(for limit)", 1); 1055 new_localvarstr(ls, "(for limit)", 1);
1053 new_localvarstr(ls, "(for step)", 2); 1056 new_localvarstr(ls, "(for step)", 2);
1057 new_localvar(ls, varname, 3);
1054 check(ls, '='); 1058 check(ls, '=');
1055 exp1(ls); /* initial value */ 1059 exp1(ls); /* initial value */
1056 check(ls, ','); 1060 check(ls, ',');
@@ -1061,39 +1065,39 @@ static void fornum (LexState *ls, TString *varname, int line) {
1061 luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); 1065 luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
1062 luaK_reserveregs(fs, 1); 1066 luaK_reserveregs(fs, 1);
1063 } 1067 }
1064 luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1); 1068 forbody(ls, base, line, 1, 1);
1065 luaK_jump(fs);
1066 forbody(ls, base, line, 3, 1);
1067} 1069}
1068 1070
1069 1071
1070static void forlist (LexState *ls, TString *indexname) { 1072static void forlist (LexState *ls, TString *indexname) {
1071 /* forlist -> NAME {,NAME} IN explist1 DO body */ 1073 /* forlist -> NAME {,NAME} IN explist1 forbody */
1072 FuncState *fs = ls->fs; 1074 FuncState *fs = ls->fs;
1073 expdesc e; 1075 expdesc e;
1074 int nvars = 0; 1076 int nvars = 0;
1075 int line; 1077 int line;
1076 int base = fs->freereg; 1078 int base = fs->freereg;
1079 /* create control variables */
1077 new_localvarstr(ls, "(for generator)", nvars++); 1080 new_localvarstr(ls, "(for generator)", nvars++);
1078 new_localvarstr(ls, "(for state)", nvars++); 1081 new_localvarstr(ls, "(for state)", nvars++);
1082 new_localvarstr(ls, "(for control)", nvars++);
1083 /* create declared variables */
1079 new_localvar(ls, indexname, nvars++); 1084 new_localvar(ls, indexname, nvars++);
1080 while (testnext(ls, ',')) 1085 while (testnext(ls, ','))
1081 new_localvar(ls, str_checkname(ls), nvars++); 1086 new_localvar(ls, str_checkname(ls), nvars++);
1082 check(ls, TK_IN); 1087 check(ls, TK_IN);
1083 line = ls->linenumber; 1088 line = ls->linenumber;
1084 adjust_assign(ls, nvars, explist1(ls, &e), &e); 1089 adjust_assign(ls, 3, explist1(ls, &e), &e);
1085 luaK_checkstack(fs, 3); /* extra space to call generator */ 1090 luaK_checkstack(fs, 3); /* extra space to call generator */
1086 luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP); 1091 forbody(ls, base, line, nvars - 3, 0);
1087 forbody(ls, base, line, nvars, 0);
1088} 1092}
1089 1093
1090 1094
1091static void forstat (LexState *ls, int line) { 1095static void forstat (LexState *ls, int line) {
1092 /* forstat -> fornum | forlist */ 1096 /* forstat -> FOR (fornum | forlist) END */
1093 FuncState *fs = ls->fs; 1097 FuncState *fs = ls->fs;
1094 TString *varname; 1098 TString *varname;
1095 BlockCnt bl; 1099 BlockCnt bl;
1096 enterblock(fs, &bl, 0); /* block to control variable scope */ 1100 enterblock(fs, &bl, 1); /* scope for loop and control variables */
1097 next(ls); /* skip `for' */ 1101 next(ls); /* skip `for' */
1098 varname = str_checkname(ls); /* first variable name */ 1102 varname = str_checkname(ls); /* first variable name */
1099 switch (ls->t.token) { 1103 switch (ls->t.token) {
@@ -1102,7 +1106,7 @@ static void forstat (LexState *ls, int line) {
1102 default: luaX_syntaxerror(ls, "`=' or `in' expected"); 1106 default: luaX_syntaxerror(ls, "`=' or `in' expected");
1103 } 1107 }
1104 check_match(ls, TK_END, TK_FOR, line); 1108 check_match(ls, TK_END, TK_FOR, line);
1105 leaveblock(fs); 1109 leaveblock(fs); /* loop scope (`break' jumps to this point) */
1106} 1110}
1107 1111
1108 1112