diff options
-rw-r--r-- | lparser.c | 48 |
1 files changed, 14 insertions, 34 deletions
@@ -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) { | |||
126 | static void check_match (LexState *ls, int what, int who, int where) { | 126 | static 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 | |||
832 | static void whilestat (LexState *ls, int line) { | 826 | static 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); |