diff options
| -rw-r--r-- | lparser.c | 46 |
1 files changed, 5 insertions, 41 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.95 2000/06/12 13:52:05 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.96 2000/06/19 18:05:14 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 | */ |
| @@ -37,7 +37,6 @@ typedef struct Constdesc { | |||
| 37 | 37 | ||
| 38 | typedef struct Breaklabel { | 38 | typedef struct Breaklabel { |
| 39 | struct Breaklabel *previous; /* chain */ | 39 | struct Breaklabel *previous; /* chain */ |
| 40 | TString *label; | ||
| 41 | int breaklist; | 40 | int breaklist; |
| 42 | int stacklevel; | 41 | int stacklevel; |
| 43 | } Breaklabel; | 42 | } Breaklabel; |
| @@ -309,7 +308,6 @@ static void code_params (LexState *ls, int nparams, int dots) { | |||
| 309 | 308 | ||
| 310 | static void enterbreak (FuncState *fs, Breaklabel *bl) { | 309 | static void enterbreak (FuncState *fs, Breaklabel *bl) { |
| 311 | bl->stacklevel = fs->stacklevel; | 310 | bl->stacklevel = fs->stacklevel; |
| 312 | bl->label = NULL; | ||
| 313 | bl->breaklist = NO_JUMP; | 311 | bl->breaklist = NO_JUMP; |
| 314 | bl->previous = fs->bl; | 312 | bl->previous = fs->bl; |
| 315 | fs->bl = bl; | 313 | fs->bl = bl; |
| @@ -323,22 +321,6 @@ static void leavebreak (FuncState *fs, Breaklabel *bl) { | |||
| 323 | } | 321 | } |
| 324 | 322 | ||
| 325 | 323 | ||
| 326 | static Breaklabel *findlabel (LexState *ls) { | ||
| 327 | FuncState *fs = ls->fs; | ||
| 328 | Breaklabel *bl; | ||
| 329 | TString *label = (ls->t.token == TK_NAME) ? ls->t.seminfo.ts : NULL; | ||
| 330 | for (bl=fs->bl; bl; bl=bl->previous) { | ||
| 331 | if (bl->label == label) { | ||
| 332 | if (label) next(ls); /* no errors; can skip optional label */ | ||
| 333 | return bl; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | /* label not found */ | ||
| 337 | luaK_error(fs->ls, "invalid break"); | ||
| 338 | return NULL; /* to avoid warnings */ | ||
| 339 | } | ||
| 340 | |||
| 341 | |||
| 342 | static void pushclosure (LexState *ls, FuncState *func) { | 324 | static void pushclosure (LexState *ls, FuncState *func) { |
| 343 | FuncState *fs = ls->fs; | 325 | FuncState *fs = ls->fs; |
| 344 | Proto *f = fs->f; | 326 | Proto *f = fs->f; |
| @@ -1045,10 +1027,11 @@ static void retstat (LexState *ls) { | |||
| 1045 | static void breakstat (LexState *ls) { | 1027 | static void breakstat (LexState *ls) { |
| 1046 | /* stat -> BREAK [NAME] */ | 1028 | /* stat -> BREAK [NAME] */ |
| 1047 | FuncState *fs = ls->fs; | 1029 | FuncState *fs = ls->fs; |
| 1048 | Breaklabel *bl; | ||
| 1049 | int currentlevel = fs->stacklevel; | 1030 | int currentlevel = fs->stacklevel; |
| 1031 | Breaklabel *bl = fs->bl; | ||
| 1032 | if (!bl) | ||
| 1033 | luaK_error(ls, "no loop to break"); | ||
| 1050 | setline_and_next(ls); /* skip BREAK */ | 1034 | setline_and_next(ls); /* skip BREAK */ |
| 1051 | bl = findlabel(ls); | ||
| 1052 | luaK_adjuststack(fs, currentlevel - bl->stacklevel); | 1035 | luaK_adjuststack(fs, currentlevel - bl->stacklevel); |
| 1053 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | 1036 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); |
| 1054 | fs->stacklevel = currentlevel; | 1037 | fs->stacklevel = currentlevel; |
| @@ -1145,33 +1128,14 @@ static void body (LexState *ls, int needself, int line) { | |||
| 1145 | /* }====================================================================== */ | 1128 | /* }====================================================================== */ |
| 1146 | 1129 | ||
| 1147 | 1130 | ||
| 1148 | static TString *optional_label (LexState *ls) { | ||
| 1149 | /* label -> [ '|' NAME '|' ] */ | ||
| 1150 | if (optional(ls, '|')) { | ||
| 1151 | TString *l = str_checkname(ls); | ||
| 1152 | check(ls, '|'); | ||
| 1153 | return l; | ||
| 1154 | } | ||
| 1155 | else | ||
| 1156 | return NULL; /* there is no label */ | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | |||
| 1160 | static void chunk (LexState *ls) { | 1131 | static void chunk (LexState *ls) { |
| 1161 | /* chunk -> { [label] stat [';'] } */ | 1132 | /* chunk -> { stat [';'] } */ |
| 1162 | int islast = 0; | 1133 | int islast = 0; |
| 1163 | while (!islast && !block_follow(ls->t.token)) { | 1134 | while (!islast && !block_follow(ls->t.token)) { |
| 1164 | Breaklabel bl; | ||
| 1165 | TString *l = optional_label(ls); | ||
| 1166 | if (l) { | ||
| 1167 | enterbreak(ls->fs, &bl); | ||
| 1168 | bl.label = l; | ||
| 1169 | } | ||
| 1170 | islast = stat(ls); | 1135 | islast = stat(ls); |
| 1171 | optional(ls, ';'); | 1136 | optional(ls, ';'); |
| 1172 | LUA_ASSERT(ls->L, ls->fs->stacklevel == ls->fs->nlocalvar, | 1137 | LUA_ASSERT(ls->L, ls->fs->stacklevel == ls->fs->nlocalvar, |
| 1173 | "stack size != # local vars"); | 1138 | "stack size != # local vars"); |
| 1174 | if (l) leavebreak(ls->fs, &bl); | ||
| 1175 | } | 1139 | } |
| 1176 | } | 1140 | } |
| 1177 | 1141 | ||
