aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-20 16:15:37 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-20 16:15:37 -0300
commit1157c2a7e43f690ec470b70a07dd142a93b7a412 (patch)
tree2d1dce4d1b3c74a9caeb7e4d266201ebeae38474 /lparser.c
parent374cc888f4f1e1adf2311dc7fb296e443533ccbb (diff)
downloadlua-1157c2a7e43f690ec470b70a07dd142a93b7a412.tar.gz
lua-1157c2a7e43f690ec470b70a07dd142a93b7a412.tar.bz2
lua-1157c2a7e43f690ec470b70a07dd142a93b7a412.zip
better(?) treatment for SETLINE + while optimization is too complex for
only 3% of maximum improvement.
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c48
1 files changed, 14 insertions, 34 deletions
diff --git a/lparser.c b/lparser.c
index 5e8157f2..a8783be2 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.69 2000/03/13 20:37:16 roberto Exp roberto $ 2** $Id: lparser.c,v 1.70 2000/03/15 20:50:33 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*/
@@ -126,7 +126,6 @@ static void check_debugline (LexState *ls) {
126static void check_match (LexState *ls, int what, int who, int where) { 126static void check_match (LexState *ls, int what, int who, int where) {
127 if (ls->token != what) 127 if (ls->token != what)
128 error_unmatched(ls, what, who, where); 128 error_unmatched(ls, what, who, where);
129 check_debugline(ls); /* to `mark' the `what' */
130 next(ls); 129 next(ls);
131} 130}
132 131
@@ -824,43 +823,20 @@ static int assignment (LexState *ls, expdesc *v, int nvars) {
824} 823}
825 824
826 825
827/* maximum size of a while condition */
828#ifndef MAX_WHILE_EXP
829#define MAX_WHILE_EXP 200 /* arbitrary limit */
830#endif
831
832static void whilestat (LexState *ls, int line) { 826static void whilestat (LexState *ls, int line) {
833 /* whilestat -> WHILE exp1 DO block END */ 827 /* whilestat -> WHILE exp1 DO block END */
834 Instruction buffer[MAX_WHILE_EXP];
835 FuncState *fs = ls->fs; 828 FuncState *fs = ls->fs;
836 int while_init = luaK_getlabel(fs); 829 int while_init = luaK_getlabel(fs);
837 int loopentry; /* point to jump to repeat the loop */
838 int cond_init; /* init of condition, after the move */
839 int cond_size;
840 expdesc v; 830 expdesc v;
841 int i;
842 next(ls); /* skip WHILE */ 831 next(ls); /* skip WHILE */
843 expr(ls, &v); /* read condition */ 832 expr(ls, &v); /* read condition */
844 luaK_goiffalse(fs, &v, 0); 833 luaK_goiftrue(fs, &v, 0);
845 cond_size = fs->pc - while_init;
846 /* save condition (to move it to after body) */
847 if (cond_size > MAX_WHILE_EXP)
848 luaK_error(ls, "while condition too complex");
849 for (i=0; i<cond_size; i++) buffer[i] = fs->f->code[while_init+i];
850 /* go back to state prior condition */
851 fs->pc = while_init;
852 luaK_S(fs, OP_JMP, 0, 0); /* initial jump to condition */
853 check(ls, TK_DO); 834 check(ls, TK_DO);
854 loopentry = luaK_getlabel(fs);
855 block(ls); 835 block(ls);
836 luaK_fixjump(fs, luaK_S(fs, OP_JMP, 0, 0), while_init);
837 luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
838 check_debugline(ls); /* trace `end' when loop finish */
856 check_match(ls, TK_END, TK_WHILE, line); 839 check_match(ls, TK_END, TK_WHILE, line);
857 cond_init = luaK_getlabel(fs);
858 luaK_fixjump(fs, while_init, cond_init);
859 /* correct `v' and copy condition to new position */
860 if (v.u.l.t != NO_JUMP) v.u.l.t += cond_init-while_init;
861 for (i=0; i<cond_size; i++) luaK_code(fs, buffer[i], 0);
862 luaK_patchlist(fs, v.u.l.t, loopentry);
863 luaK_getlabel(fs); /* mark possible jump to this point */
864} 840}
865 841
866 842
@@ -869,6 +845,7 @@ static void repeatstat (LexState *ls, int line) {
869 FuncState *fs = ls->fs; 845 FuncState *fs = ls->fs;
870 int repeat_init = luaK_getlabel(fs); 846 int repeat_init = luaK_getlabel(fs);
871 expdesc v; 847 expdesc v;
848 check_debugline(ls); /* trace `repeat' when looping */
872 next(ls); 849 next(ls);
873 block(ls); 850 block(ls);
874 check_match(ls, TK_UNTIL, TK_REPEAT, line); 851 check_match(ls, TK_UNTIL, TK_REPEAT, line);
@@ -936,8 +913,8 @@ static int funcstat (LexState *ls, int line) {
936 expdesc v; 913 expdesc v;
937 if (ls->fs->prev) /* inside other function? */ 914 if (ls->fs->prev) /* inside other function? */
938 return 0; 915 return 0;
939 check_debugline(ls);
940 next(ls); 916 next(ls);
917 check_debugline(ls);
941 needself = funcname(ls, &v); 918 needself = funcname(ls, &v);
942 body(ls, needself, line); 919 body(ls, needself, line);
943 luaK_storevar(ls, &v); 920 luaK_storevar(ls, &v);
@@ -975,6 +952,7 @@ static void ifpart (LexState *ls, int line) {
975 block(ls); /* `then' part */ 952 block(ls); /* `then' part */
976 luaK_S(fs, OP_JMP, 0, 0); /* 2nd jump: over `else' part */ 953 luaK_S(fs, OP_JMP, 0, 0); /* 2nd jump: over `else' part */
977 elseinit = luaK_getlabel(fs); /* address of 2nd jump == elseinit-1 */ 954 elseinit = luaK_getlabel(fs); /* address of 2nd jump == elseinit-1 */
955 check_debugline(ls); /* trace `else' (or `elseif') */
978 if (ls->token == TK_ELSEIF) 956 if (ls->token == TK_ELSEIF)
979 ifpart(ls, line); 957 ifpart(ls, line);
980 else { 958 else {
@@ -997,11 +975,11 @@ static int stat (LexState *ls) {
997 int line = ls->linenumber; /* may be needed for error messages */ 975 int line = ls->linenumber; /* may be needed for error messages */
998 switch (ls->token) { 976 switch (ls->token) {
999 case TK_IF: /* stat -> IF ifpart END */ 977 case TK_IF: /* stat -> IF ifpart END */
1000 ifpart(ls, line); 978 ifpart(ls, line); /* condition will set debug line */
1001 return 1; 979 return 1;
1002 980
1003 case TK_WHILE: /* stat -> whilestat */ 981 case TK_WHILE: /* stat -> whilestat */
1004 whilestat(ls, line); 982 whilestat(ls, line); /* debug line only after 1st jump */
1005 return 1; 983 return 1;
1006 984
1007 case TK_DO: { /* stat -> DO block END */ 985 case TK_DO: { /* stat -> DO block END */
@@ -1026,8 +1004,8 @@ static int stat (LexState *ls) {
1026 namestat(ls); 1004 namestat(ls);
1027 return 1; 1005 return 1;
1028 1006
1029 case TK_RETURN: case ';': case TK_ELSE: case TK_ELSEIF: 1007 case TK_RETURN: case TK_END: case TK_UNTIL:
1030 case TK_END: case TK_UNTIL: case TK_EOS: /* `stat' follow */ 1008 case ';': case TK_ELSE: case TK_ELSEIF: case TK_EOS: /* `stat' follow */
1031 return 0; 1009 return 0;
1032 1010
1033 default: 1011 default:
@@ -1082,8 +1060,10 @@ static void body (LexState *ls, int needself, int line) {
1082 if (needself) 1060 if (needself)
1083 add_localvar(ls, luaS_newfixed(ls->L, "self")); 1061 add_localvar(ls, luaS_newfixed(ls->L, "self"));
1084 parlist(ls); 1062 parlist(ls);
1063 check_debugline(ls); /* trace function header */
1085 check(ls, ')'); 1064 check(ls, ')');
1086 chunk(ls); 1065 chunk(ls);
1066 check_debugline(ls); /* trace `end' when finish */
1087 check_match(ls, TK_END, TK_FUNCTION, line); 1067 check_match(ls, TK_END, TK_FUNCTION, line);
1088 close_func(ls); 1068 close_func(ls);
1089 func_onstack(ls, &new_fs); 1069 func_onstack(ls, &new_fs);