aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-04-05 14:51:58 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-04-05 14:51:58 -0300
commit22329e4cdf6c6741523099173c31b0a421825a3c (patch)
tree6448d563eaf5d8e6b3d7e792459c04f5ac740ddf /lparser.c
parent9f734094f9bbb34216ef555edf08019d5feea13b (diff)
downloadlua-22329e4cdf6c6741523099173c31b0a421825a3c.tar.gz
lua-22329e4cdf6c6741523099173c31b0a421825a3c.tar.bz2
lua-22329e4cdf6c6741523099173c31b0a421825a3c.zip
implementation of BREAK
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c169
1 files changed, 112 insertions, 57 deletions
diff --git a/lparser.c b/lparser.c
index 05832288..1bb0c0cc 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.74 2000/03/29 20:19:20 roberto Exp roberto $ 2** $Id: lparser.c,v 1.75 2000/04/03 13:44:55 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*/
@@ -28,10 +28,17 @@
28** it is a list constructor (k = 0) or a record constructor (k = 1) 28** it is a list constructor (k = 0) or a record constructor (k = 1)
29** or empty (k = ';' or '}') 29** or empty (k = ';' or '}')
30*/ 30*/
31typedef struct constdesc { 31typedef struct Constdesc {
32 int n; 32 int n;
33 int k; 33 int k;
34} constdesc; 34} Constdesc;
35
36
37typedef struct Breaklabel {
38 struct Breaklabel *previous; /* chain */
39 int breaklist;
40 int stacklevel;
41} Breaklabel;
35 42
36 43
37 44
@@ -311,6 +318,21 @@ static int getvarname (LexState *ls, expdesc *var) {
311} 318}
312 319
313 320
321static void enterbreak (FuncState *fs, Breaklabel *bl) {
322 bl->stacklevel = fs->stacklevel;
323 bl->breaklist = NO_JUMP;
324 bl->previous = fs->bl;
325 fs->bl = bl;
326}
327
328
329static void leavebreak (FuncState *fs, Breaklabel *bl) {
330 fs->bl = bl->previous;
331 LUA_ASSERT(fs->L, bl->stacklevel == fs->stacklevel, "wrong levels");
332 luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs));
333}
334
335
314static void func_onstack (LexState *ls, FuncState *func) { 336static void func_onstack (LexState *ls, FuncState *func) {
315 FuncState *fs = ls->fs; 337 FuncState *fs = ls->fs;
316 Proto *f = fs->f; 338 Proto *f = fs->f;
@@ -332,10 +354,11 @@ static void init_state (LexState *ls, FuncState *fs, TString *source) {
332 fs->ls = ls; 354 fs->ls = ls;
333 fs->L = ls->L; 355 fs->L = ls->L;
334 ls->fs = fs; 356 ls->fs = fs;
335 fs->stacksize = 0; 357 fs->stacklevel = 0;
336 fs->nlocalvar = 0; 358 fs->nlocalvar = 0;
337 fs->nupvalues = 0; 359 fs->nupvalues = 0;
338 fs->lastsetline = 0; 360 fs->lastsetline = 0;
361 fs->bl = NULL;
339 fs->f = f; 362 fs->f = f;
340 f->source = source; 363 f->source = source;
341 fs->pc = 0; 364 fs->pc = 0;
@@ -362,6 +385,7 @@ static void close_func (LexState *ls) {
362 luaM_reallocvector(L, f->locvars, fs->nvars, LocVar); 385 luaM_reallocvector(L, f->locvars, fs->nvars, LocVar);
363 } 386 }
364 ls->fs = fs->prev; 387 ls->fs = fs->prev;
388 LUA_ASSERT(L, fs->bl == NULL, "wrong list end");
365} 389}
366 390
367 391
@@ -375,6 +399,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) {
375 if (lexstate.token != TK_EOS) 399 if (lexstate.token != TK_EOS)
376 luaK_error(&lexstate, "<eof> expected"); 400 luaK_error(&lexstate, "<eof> expected");
377 close_func(&lexstate); 401 close_func(&lexstate);
402 LUA_ASSERT(L, funcstate.prev == NULL, "wrong list end");
378 return funcstate.f; 403 return funcstate.f;
379} 404}
380 405
@@ -416,7 +441,7 @@ static int explist (LexState *ls) {
416 441
417static void funcargs (LexState *ls, int slf) { 442static void funcargs (LexState *ls, int slf) {
418 FuncState *fs = ls->fs; 443 FuncState *fs = ls->fs;
419 int slevel = fs->stacksize - slf - 1; /* where is func in the stack */ 444 int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */
420 switch (ls->token) { 445 switch (ls->token) {
421 case '(': { /* funcargs -> '(' explist ')' */ 446 case '(': { /* funcargs -> '(' explist ')' */
422 int line = ls->linenumber; 447 int line = ls->linenumber;
@@ -444,7 +469,7 @@ static void funcargs (LexState *ls, int slf) {
444 luaK_error(ls, "function arguments expected"); 469 luaK_error(ls, "function arguments expected");
445 break; 470 break;
446 } 471 }
447 fs->stacksize = slevel; /* call will remove function and arguments */ 472 fs->stacklevel = slevel; /* call will remove function and arguments */
448 luaK_AB(fs, OP_CALL, slevel, MULT_RET, 0); 473 luaK_AB(fs, OP_CALL, slevel, MULT_RET, 0);
449} 474}
450 475
@@ -581,7 +606,7 @@ static int listfields (LexState *ls) {
581 606
582 607
583 608
584static void constructor_part (LexState *ls, constdesc *cd) { 609static void constructor_part (LexState *ls, Constdesc *cd) {
585 switch (ls->token) { 610 switch (ls->token) {
586 case ';': case '}': /* constructor_part -> empty */ 611 case ';': case '}': /* constructor_part -> empty */
587 cd->n = 0; 612 cd->n = 0;
@@ -627,12 +652,12 @@ static void constructor (LexState *ls) {
627 int line = ls->linenumber; 652 int line = ls->linenumber;
628 int pc = luaK_U(fs, OP_CREATETABLE, 0, 1); 653 int pc = luaK_U(fs, OP_CREATETABLE, 0, 1);
629 int nelems; 654 int nelems;
630 constdesc cd; 655 Constdesc cd;
631 check(ls, '{'); 656 check(ls, '{');
632 constructor_part(ls, &cd); 657 constructor_part(ls, &cd);
633 nelems = cd.n; 658 nelems = cd.n;
634 if (ls->token == ';') { 659 if (ls->token == ';') {
635 constdesc other_cd; 660 Constdesc other_cd;
636 next(ls); 661 next(ls);
637 constructor_part(ls, &other_cd); 662 constructor_part(ls, &other_cd);
638 if (cd.k == other_cd.k) /* repeated parts? */ 663 if (cd.k == other_cd.k) /* repeated parts? */
@@ -825,14 +850,17 @@ static void whilestat (LexState *ls, int line) {
825 FuncState *fs = ls->fs; 850 FuncState *fs = ls->fs;
826 int while_init = luaK_getlabel(fs); 851 int while_init = luaK_getlabel(fs);
827 expdesc v; 852 expdesc v;
853 Breaklabel bl;
854 enterbreak(fs, &bl);
828 setline_and_next(ls); /* trace WHILE when looping */ 855 setline_and_next(ls); /* trace WHILE when looping */
829 expr(ls, &v); /* read condition */ 856 expr(ls, &v); /* read condition */
830 luaK_goiftrue(fs, &v, 0); 857 luaK_goiftrue(fs, &v, 0);
831 check(ls, TK_DO); 858 check(ls, TK_DO);
832 block(ls); 859 block(ls);
833 luaK_fixjump(fs, luaK_S(fs, OP_JMP, 0, 0), while_init); 860 luaK_patchlist(fs, luaK_jump(fs), while_init);
834 luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); 861 luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
835 check_END(ls, TK_WHILE, line); 862 check_END(ls, TK_WHILE, line);
863 leavebreak(fs, &bl);
836} 864}
837 865
838 866
@@ -841,12 +869,55 @@ static void repeatstat (LexState *ls, int line) {
841 FuncState *fs = ls->fs; 869 FuncState *fs = ls->fs;
842 int repeat_init = luaK_getlabel(fs); 870 int repeat_init = luaK_getlabel(fs);
843 expdesc v; 871 expdesc v;
872 Breaklabel bl;
873 enterbreak(fs, &bl);
844 setline_and_next(ls); /* trace REPEAT when looping */ 874 setline_and_next(ls); /* trace REPEAT when looping */
845 block(ls); 875 block(ls);
846 check_match(ls, TK_UNTIL, TK_REPEAT, line); 876 if (ls->token == TK_END) {
847 expr(ls, &v); 877 luaK_patchlist(fs, luaK_jump(fs), repeat_init);
848 luaK_goiftrue(fs, &v, 0); 878 next(ls);
849 luaK_patchlist(fs, v.u.l.f, repeat_init); 879 }
880 else {
881 check_match(ls, TK_UNTIL, TK_REPEAT, line);
882 expr(ls, &v);
883 luaK_goiftrue(fs, &v, 0);
884 luaK_patchlist(fs, v.u.l.f, repeat_init);
885 }
886 leavebreak(fs, &bl);
887}
888
889
890static void test_and_bock (LexState *ls, expdesc *v) {
891 setline_and_next(ls); /* skip IF or ELSEIF */
892 expr(ls, v); /* cond */
893 luaK_goiftrue(ls->fs, v, 0);
894 setline(ls); /* to trace the THEN */
895 check(ls, TK_THEN);
896 block(ls); /* `then' part */
897}
898
899
900static void ifstat (LexState *ls, int line) {
901 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
902 FuncState *fs = ls->fs;
903 expdesc v;
904 int escapelist = NO_JUMP;
905 test_and_bock(ls, &v); /* IF cond THEN block */
906 while (ls->token == TK_ELSEIF) {
907 luaK_concat(fs, &escapelist, luaK_jump(fs));
908 luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
909 test_and_bock(ls, &v); /* ELSEIF cond THEN block */
910 }
911 if (ls->token == TK_ELSE) {
912 luaK_concat(fs, &escapelist, luaK_jump(fs));
913 luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
914 setline_and_next(ls); /* skip ELSE */
915 block(ls); /* `else' part */
916 }
917 else
918 luaK_concat(fs, &escapelist, v.u.l.f);
919 luaK_patchlist(fs, escapelist, luaK_getlabel(fs));
920 check_END(ls, TK_IF, line);
850} 921}
851 922
852 923
@@ -932,42 +1003,11 @@ static void namestat (LexState *ls) {
932} 1003}
933 1004
934 1005
935static void ifpart (LexState *ls) {
936 /* ifpart -> cond THEN block (ELSEIF ifpart | [ELSE block] END) */
937 FuncState *fs = ls->fs;
938 expdesc v;
939 int elseinit;
940 setline_and_next(ls); /* skip IF or ELSEIF */
941 expr(ls, &v); /* cond */
942 luaK_goiftrue(fs, &v, 0);
943 setline(ls); /* to trace the THEN */
944 check(ls, TK_THEN);
945 block(ls); /* `then' part */
946 luaK_S(fs, OP_JMP, 0, 0); /* 2nd jump: over `else' part */
947 elseinit = luaK_getlabel(fs); /* address of 2nd jump == elseinit-1 */
948 if (ls->token == TK_ELSEIF)
949 ifpart(ls);
950 else if (ls->token == TK_ELSE) {
951 setline_and_next(ls); /* skip ELSE */
952 block(ls); /* `else' part */
953 }
954 if (fs->pc > elseinit) { /* is there an `else' part? */
955 luaK_fixjump(fs, elseinit-1, luaK_getlabel(fs)); /* fix 2nd jump */
956 }
957 else { /* no else part */
958 fs->pc--; /* remove 2nd jump */
959 elseinit = luaK_getlabel(fs); /* `elseinit' points to end */
960 }
961 luaK_patchlist(fs, v.u.l.f, elseinit); /* fix 1st jump to `else' part */
962}
963
964
965static int stat (LexState *ls) { 1006static int stat (LexState *ls) {
966 int line = ls->linenumber; /* may be needed for error messages */ 1007 int line = ls->linenumber; /* may be needed for error messages */
967 switch (ls->token) { 1008 switch (ls->token) {
968 case TK_IF: /* stat -> IF ifpart END */ 1009 case TK_IF: /* stat -> ifstat */
969 ifpart(ls); 1010 ifstat(ls, line);
970 check_END(ls, TK_IF, line);
971 break; 1011 break;
972 1012
973 case TK_WHILE: /* stat -> whilestat */ 1013 case TK_WHILE: /* stat -> whilestat */
@@ -1058,15 +1098,30 @@ static void body (LexState *ls, int needself, int line) {
1058 1098
1059 1099
1060static void ret (LexState *ls) { 1100static void ret (LexState *ls) {
1061 /* ret -> [RETURN explist sc] */ 1101 /* ret -> [RETURN explist sc | BREAK sc] */
1062 if (ls->token == TK_RETURN) { 1102 FuncState *fs = ls->fs;
1063 FuncState *fs = ls->fs; 1103 switch (ls->token) {
1064 int nexps; /* number of expressions returned */ 1104 case TK_RETURN: {
1065 setline_and_next(ls); /* skip RETURN */ 1105 int nexps; /* number of expressions returned */
1066 nexps = explist(ls); 1106 setline_and_next(ls); /* skip RETURN */
1067 luaK_retcode(fs, ls->fs->nlocalvar, nexps); 1107 nexps = explist(ls);
1068 fs->stacksize = fs->nlocalvar; /* removes all temp values */ 1108 luaK_retcode(fs, ls->fs->nlocalvar, nexps);
1069 optional(ls, ';'); 1109 fs->stacklevel = fs->nlocalvar; /* removes all temp values */
1110 optional(ls, ';');
1111 break;
1112 }
1113 case TK_BREAK: {
1114 Breaklabel *bl = fs->bl;
1115 int currentlevel = fs->stacklevel;
1116 if (bl == NULL)
1117 luaK_error(ls, "no breakable structure to break");
1118 setline_and_next(ls); /* skip BREAK */
1119 luaK_adjuststack(fs, currentlevel - bl->stacklevel);
1120 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
1121 optional(ls, ';');
1122 fs->stacklevel = currentlevel;
1123 break;
1124 }
1070 } 1125 }
1071} 1126}
1072 1127
@@ -1076,7 +1131,7 @@ static void ret (LexState *ls) {
1076static void chunk (LexState *ls) { 1131static void chunk (LexState *ls) {
1077 /* chunk -> { stat [;] } ret */ 1132 /* chunk -> { stat [;] } ret */
1078 while (stat(ls)) { 1133 while (stat(ls)) {
1079 LUA_ASSERT(ls->L, ls->fs->stacksize == ls->fs->nlocalvar, 1134 LUA_ASSERT(ls->L, ls->fs->stacklevel == ls->fs->nlocalvar,
1080 "stack size != # local vars"); 1135 "stack size != # local vars");
1081 optional(ls, ';'); 1136 optional(ls, ';');
1082 } 1137 }