diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-03-18 11:49:46 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-03-18 11:49:46 -0300 |
commit | 58badbab9933e0a50d9b9f3fec78ac50d15d5414 (patch) | |
tree | 61b07a66b33f0ac201af0376c65694d651d7496d | |
parent | da81845cd5924627a3c00fca6bec683144493cbe (diff) | |
download | lua-58badbab9933e0a50d9b9f3fec78ac50d15d5414.tar.gz lua-58badbab9933e0a50d9b9f3fec78ac50d15d5414.tar.bz2 lua-58badbab9933e0a50d9b9f3fec78ac50d15d5414.zip |
special treatment for 'global in nil'
-rw-r--r-- | lopcodes.h | 5 | ||||
-rw-r--r-- | lparser.c | 46 |
2 files changed, 29 insertions, 22 deletions
@@ -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 | /* |
@@ -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 | ||
990 | static void exp1 (LexState *ls) { | 992 | static 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) { | |||
1126 | static void globalstat (LexState *ls) { | 1131 | static 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 | ||