diff options
| -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 | ||
