aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c22
-rw-r--r--lparser.c36
-rw-r--r--lparser.h3
3 files changed, 38 insertions, 23 deletions
diff --git a/lcode.c b/lcode.c
index de4c3623..750def9a 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.19 2000/04/04 20:48:44 roberto Exp roberto $ 2** $Id: lcode.c,v 1.20 2000/04/05 17:51:58 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -171,7 +171,12 @@ static void luaK_neq (FuncState *fs) {
171 171
172 172
173int luaK_jump (FuncState *fs) { 173int luaK_jump (FuncState *fs) {
174 return luaK_S(fs, OP_JMP, NO_JUMP, 0); 174 int j = luaK_S(fs, OP_JMP, NO_JUMP, 0);
175 if (j == fs->lasttarget) { /* possible jumps to this jump? */
176 luaK_concat(fs, &j, fs->jlt); /* keep them on hold */
177 fs->jlt = NO_JUMP;
178 }
179 return j;
175} 180}
176 181
177 182
@@ -220,11 +225,17 @@ static int luaK_getjump (FuncState *fs, int pc) {
220 225
221 226
222/* 227/*
228** discharge list of jumps to last target.
223** returns current `pc' and marks it as a jump target (to avoid wrong 229** returns current `pc' and marks it as a jump target (to avoid wrong
224** optimizations with consecutive instructions not in the same basic block). 230** optimizations with consecutive instructions not in the same basic block).
225*/ 231*/
226int luaK_getlabel (FuncState *fs) { 232int luaK_getlabel (FuncState *fs) {
227 fs->lasttarget = fs->pc; 233 if (fs->pc != fs->lasttarget) {
234 int lasttarget = fs->lasttarget;
235 fs->lasttarget = fs->pc;
236 luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */
237 fs->jlt = NO_JUMP; /* nobody jumps to this new label (till now) */
238 }
228 return fs->pc; 239 return fs->pc;
229} 240}
230 241
@@ -394,7 +405,10 @@ static void luaK_patchlistaux (FuncState *fs, int list, int target,
394 405
395 406
396void luaK_patchlist (FuncState *fs, int list, int target) { 407void luaK_patchlist (FuncState *fs, int list, int target) {
397 luaK_patchlistaux(fs, list, target, OP_END, 0); 408 if (target == fs->lasttarget) /* same target that list `jlt'? */
409 luaK_concat(fs, &fs->jlt, list); /* delay fixing */
410 else
411 luaK_patchlistaux(fs, list, target, OP_END, 0);
398} 412}
399 413
400 414
diff --git a/lparser.c b/lparser.c
index 1bb0c0cc..3fbffb05 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.75 2000/04/03 13:44:55 roberto Exp roberto $ 2** $Id: lparser.c,v 1.76 2000/04/05 17:51:58 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*/
@@ -71,20 +71,6 @@ static void error_unexpected (LexState *ls) {
71} 71}
72 72
73 73
74static void error_unmatched (LexState *ls, int what, int who, int where) {
75 if (where == ls->linenumber)
76 error_expected(ls, what);
77 else {
78 char buff[100];
79 char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
80 luaX_token2str(what, t_what);
81 luaX_token2str(who, t_who);
82 sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
83 t_what, t_who, where);
84 luaK_error(ls, buff);
85 }
86}
87
88static void check (LexState *ls, int c) { 74static void check (LexState *ls, int c) {
89 if (ls->token != c) 75 if (ls->token != c)
90 error_expected(ls, c); 76 error_expected(ls, c);
@@ -121,8 +107,19 @@ static int optional (LexState *ls, int c) {
121 107
122 108
123static void check_match (LexState *ls, int what, int who, int where) { 109static void check_match (LexState *ls, int what, int who, int where) {
124 if (ls->token != what) 110 if (ls->token != what) {
125 error_unmatched(ls, what, who, where); 111 if (where == ls->linenumber)
112 error_expected(ls, what);
113 else {
114 char buff[100];
115 char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
116 luaX_token2str(what, t_what);
117 luaX_token2str(who, t_who);
118 sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
119 t_what, t_who, where);
120 luaK_error(ls, buff);
121 }
122 }
126 next(ls); 123 next(ls);
127} 124}
128 125
@@ -363,6 +360,7 @@ static void init_state (LexState *ls, FuncState *fs, TString *source) {
363 f->source = source; 360 f->source = source;
364 fs->pc = 0; 361 fs->pc = 0;
365 fs->lasttarget = 0; 362 fs->lasttarget = 0;
363 fs->jlt = NO_JUMP;
366 f->code = NULL; 364 f->code = NULL;
367 f->maxstacksize = 0; 365 f->maxstacksize = 0;
368 f->numparams = 0; /* default for main chunk */ 366 f->numparams = 0; /* default for main chunk */
@@ -376,6 +374,7 @@ static void close_func (LexState *ls) {
376 FuncState *fs = ls->fs; 374 FuncState *fs = ls->fs;
377 Proto *f = fs->f; 375 Proto *f = fs->f;
378 luaK_0(fs, OP_END, 0); 376 luaK_0(fs, OP_END, 0);
377 luaK_getlabel(fs); /* close eventual list of pending jumps */
379 luaM_reallocvector(L, f->code, fs->pc, Instruction); 378 luaM_reallocvector(L, f->code, fs->pc, Instruction);
380 luaM_reallocvector(L, f->kstr, f->nkstr, TString *); 379 luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
381 luaM_reallocvector(L, f->knum, f->nknum, Number); 380 luaM_reallocvector(L, f->knum, f->nknum, Number);
@@ -1114,7 +1113,8 @@ static void ret (LexState *ls) {
1114 Breaklabel *bl = fs->bl; 1113 Breaklabel *bl = fs->bl;
1115 int currentlevel = fs->stacklevel; 1114 int currentlevel = fs->stacklevel;
1116 if (bl == NULL) 1115 if (bl == NULL)
1117 luaK_error(ls, "no breakable structure to break"); 1116 luaK_error(ls, "break not inside while or repeat loop");
1117
1118 setline_and_next(ls); /* skip BREAK */ 1118 setline_and_next(ls); /* skip BREAK */
1119 luaK_adjuststack(fs, currentlevel - bl->stacklevel); 1119 luaK_adjuststack(fs, currentlevel - bl->stacklevel);
1120 luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); 1120 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
diff --git a/lparser.h b/lparser.h
index 64214861..edfa2a06 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.14 2000/03/24 17:26:08 roberto Exp roberto $ 2** $Id: lparser.h,v 1.15 2000/04/05 17:51:58 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*/
@@ -43,6 +43,7 @@ typedef struct FuncState {
43 struct lua_State *L; /* copy of the Lua state */ 43 struct lua_State *L; /* copy of the Lua state */
44 int pc; /* next position to code */ 44 int pc; /* next position to code */
45 int lasttarget; /* `pc' of last `jump target' */ 45 int lasttarget; /* `pc' of last `jump target' */
46 int jlt; /* list of jumps to `lasttarged' */
46 int stacklevel; /* number of values on activation register */ 47 int stacklevel; /* number of values on activation register */
47 int nlocalvar; /* number of active local variables */ 48 int nlocalvar; /* number of active local variables */
48 int nupvalues; /* number of upvalues */ 49 int nupvalues; /* number of upvalues */