aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-03-18 11:49:46 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-03-18 11:49:46 -0300
commit58badbab9933e0a50d9b9f3fec78ac50d15d5414 (patch)
tree61b07a66b33f0ac201af0376c65694d651d7496d
parentda81845cd5924627a3c00fca6bec683144493cbe (diff)
downloadlua-58badbab9933e0a50d9b9f3fec78ac50d15d5414.tar.gz
lua-58badbab9933e0a50d9b9f3fec78ac50d15d5414.tar.bz2
lua-58badbab9933e0a50d9b9f3fec78ac50d15d5414.zip
special treatment for 'global in nil'
-rw-r--r--lopcodes.h5
-rw-r--r--lparser.c46
2 files changed, 29 insertions, 22 deletions
diff --git a/lopcodes.h b/lopcodes.h
index 4568fe46..d6528220 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.89 2002/02/14 21:43:01 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.90 2002/03/08 19:10:32 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -112,9 +112,10 @@ enum OpMode {iABC, iABc, iAsBc}; /* basic instruction format */
112 112
113 113
114/* 114/*
115** an invalid register that fits in 8 bits 115** invalid registers that fits in 8 bits
116*/ 116*/
117#define NO_REG MAXARG_A 117#define NO_REG MAXARG_A
118#define NO_REG1 (NO_REG+1)
118 119
119 120
120/* 121/*
diff --git a/lparser.c b/lparser.c
index 78a6846f..f03475e8 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.169 2002/03/14 18:01:52 roberto Exp roberto $ 2** $Id: lparser.c,v 1.170 2002/03/14 18:32: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*/
@@ -255,6 +255,8 @@ static int singlevar_aux (FuncState *fs, TString *n, expdesc *var, int nd) {
255 int k = singlevar_aux(fs->prev, n, var, nd && fs->defaultglob == NO_REG); 255 int k = singlevar_aux(fs->prev, n, var, nd && fs->defaultglob == NO_REG);
256 if (var->k == VGLOBAL) { 256 if (var->k == VGLOBAL) {
257 if (k == VNIL && nd && fs->defaultglob != NO_REG) { 257 if (k == VNIL && nd && fs->defaultglob != NO_REG) {
258 if (fs->defaultglob == NO_REG1)
259 luaK_error(fs->ls, "undeclared global");
258 init_exp(var, VLOCAL, fs->defaultglob); 260 init_exp(var, VLOCAL, fs->defaultglob);
259 k = VGLOBAL; /* now there is a declaration */ 261 k = VGLOBAL; /* now there is a declaration */
260 } 262 }
@@ -987,10 +989,13 @@ static void repeatstat (LexState *ls, int line) {
987} 989}
988 990
989 991
990static void exp1 (LexState *ls) { 992static int exp1 (LexState *ls) {
991 expdesc e; 993 expdesc e;
994 int k;
992 expr(ls, &e); 995 expr(ls, &e);
996 k = e.k;
993 luaK_exp2nextreg(ls->fs, &e); 997 luaK_exp2nextreg(ls->fs, &e);
998 return k;
994} 999}
995 1000
996 1001
@@ -1000,8 +1005,8 @@ static void fornum (LexState *ls, TString *varname) {
1000 int prep; 1005 int prep;
1001 int base = fs->freereg; 1006 int base = fs->freereg;
1002 new_localvar(ls, varname, 0); 1007 new_localvar(ls, varname, 0);
1003 new_localvarstr(ls, "(limit)", 1); 1008 new_localvarstr(ls, "(for limit)", 1);
1004 new_localvarstr(ls, "(step)", 2); 1009 new_localvarstr(ls, "(for step)", 2);
1005 check(ls, '='); 1010 check(ls, '=');
1006 exp1(ls); /* initial value */ 1011 exp1(ls); /* initial value */
1007 check(ls, ','); 1012 check(ls, ',');
@@ -1012,11 +1017,11 @@ static void fornum (LexState *ls, TString *varname) {
1012 luaK_codeABc(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); 1017 luaK_codeABc(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
1013 luaK_reserveregs(fs, 1); 1018 luaK_reserveregs(fs, 1);
1014 } 1019 }
1020 adjustlocalvars(ls, 3); /* scope for control variables */
1015 luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1); 1021 luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1);
1016 luaK_jump(fs); 1022 luaK_jump(fs);
1017 prep = luaK_getlabel(fs); 1023 prep = luaK_getlabel(fs);
1018 check(ls, TK_DO); 1024 check(ls, TK_DO);
1019 adjustlocalvars(ls, 3); /* scope for control variables */
1020 block(ls); 1025 block(ls);
1021 luaK_patchtohere(fs, prep-1); 1026 luaK_patchtohere(fs, prep-1);
1022 luaK_patchlist(fs, luaK_codeAsBc(fs, OP_FORLOOP, base, NO_JUMP), prep); 1027 luaK_patchlist(fs, luaK_codeAsBc(fs, OP_FORLOOP, base, NO_JUMP), prep);
@@ -1029,7 +1034,7 @@ static void forlist (LexState *ls, TString *indexname) {
1029 int nvars = 0; 1034 int nvars = 0;
1030 int prep; 1035 int prep;
1031 int base = fs->freereg; 1036 int base = fs->freereg;
1032 new_localvarstr(ls, "(table)", 0); 1037 new_localvarstr(ls, "(for generator)", 0);
1033 new_localvar(ls, indexname, ++nvars); 1038 new_localvar(ls, indexname, ++nvars);
1034 while (optional(ls, ',')) { 1039 while (optional(ls, ',')) {
1035 new_localvar(ls, str_checkname(ls), ++nvars); 1040 new_localvar(ls, str_checkname(ls), ++nvars);
@@ -1126,26 +1131,27 @@ static void localstat (LexState *ls) {
1126static void globalstat (LexState *ls) { 1131static void globalstat (LexState *ls) {
1127 /* stat -> GLOBAL NAME {`,' NAME} [IN exp] | GLOBAL IN exp */ 1132 /* stat -> GLOBAL NAME {`,' NAME} [IN exp] | GLOBAL IN exp */
1128 FuncState *fs = ls->fs; 1133 FuncState *fs = ls->fs;
1134 int nvars = 0;
1129 next(ls); /* skip GLOBAL */ 1135 next(ls); /* skip GLOBAL */
1130 if (optional(ls, TK_IN)) { /* default declaration? */ 1136 if (ls->t.token == TK_NAME) {
1131 exp1(ls);
1132 fs->defaultglob = fs->freereg - 1;
1133 create_local(ls, "(global table)");
1134 }
1135 else {
1136 int nvars = 0;
1137 do { 1137 do {
1138 vardesc *v = new_var(ls, nvars++); 1138 vardesc *v = new_var(ls, nvars++);
1139 v->i = luaK_stringK(ls->fs, str_checkname(ls)); 1139 v->i = luaK_stringK(ls->fs, str_checkname(ls));
1140 next(ls); /* skip name */ 1140 next(ls); /* skip name */
1141 } while (optional(ls, ',')); 1141 } while (optional(ls, ','));
1142 if (!optional(ls, TK_IN)) 1142 }
1143 adjustglobalvars(ls, nvars, NO_REG); /* free globals */ 1143 if (!optional(ls, TK_IN)) { /* free globals? */
1144 else { 1144 if (nvars == 0) /* default - free is invalid */
1145 exp1(ls); 1145 error_expected(ls, TK_IN);
1146 adjustglobalvars(ls, nvars, ls->fs->freereg - 1); 1146 adjustglobalvars(ls, nvars, NO_REG); /* mark globals as free */
1147 create_local(ls, "(global table)"); 1147 }
1148 } 1148 else {
1149 int baselocal = fs->freereg;
1150 int k = exp1(ls);
1151 if (nvars == 0)
1152 fs->defaultglob = (k == VNIL) ? NO_REG1 : baselocal;
1153 adjustglobalvars(ls, nvars, baselocal);
1154 create_local(ls, "*");
1149 } 1155 }
1150} 1156}
1151 1157