diff options
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 47 |
1 files changed, 42 insertions, 5 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.80 2000/04/10 19:21:14 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.81 2000/04/11 18:37:18 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 | */ |
| @@ -884,7 +884,7 @@ static void whilestat (LexState *ls, int line) { | |||
| 884 | block(ls); | 884 | block(ls); |
| 885 | luaK_patchlist(fs, luaK_jump(fs), while_init); | 885 | luaK_patchlist(fs, luaK_jump(fs), while_init); |
| 886 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 886 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); |
| 887 | check_END(ls, TK_WHILE, line); | 887 | check_END(ls, TK_WHILE, line); /* trace END when loop ends */ |
| 888 | leavebreak(fs, &bl); | 888 | leavebreak(fs, &bl); |
| 889 | } | 889 | } |
| 890 | 890 | ||
| @@ -906,7 +906,40 @@ static void repeatstat (LexState *ls, int line) { | |||
| 906 | } | 906 | } |
| 907 | 907 | ||
| 908 | 908 | ||
| 909 | static void test_and_bock (LexState *ls, expdesc *v) { | 909 | static void forstat (LexState *ls, int line) { |
| 910 | /* forstat -> FOR NAME '=' expr1 ',' expr1 [',' expr1] DO block END */ | ||
| 911 | FuncState *fs = ls->fs; | ||
| 912 | int prep; | ||
| 913 | int blockinit; | ||
| 914 | Breaklabel bl; | ||
| 915 | enterbreak(fs, &bl); | ||
| 916 | setline_and_next(ls); /* skip for */ | ||
| 917 | store_localvar(ls, str_checkname(ls), 0); /* control variable */ | ||
| 918 | check(ls, '='); | ||
| 919 | exp1(ls); /* initial value */ | ||
| 920 | check(ls, ','); | ||
| 921 | exp1(ls); /* limit */ | ||
| 922 | if (optional(ls, ',')) | ||
| 923 | exp1(ls); /* optional step */ | ||
| 924 | else | ||
| 925 | luaK_code1(fs, OP_PUSHINT, 1); /* default step */ | ||
| 926 | adjustlocalvars(ls, 1, 0); /* init scope for control variable */ | ||
| 927 | add_localvar(ls, " limit "); | ||
| 928 | add_localvar(ls, " step "); | ||
| 929 | prep = luaK_code0(fs, OP_FORPREP); | ||
| 930 | blockinit = luaK_getlabel(fs); | ||
| 931 | check(ls, TK_DO); | ||
| 932 | block(ls); | ||
| 933 | luaK_patchlist(fs, prep, luaK_getlabel(fs)); | ||
| 934 | luaK_patchlist(fs, luaK_code0(fs, OP_FORLOOP), blockinit); | ||
| 935 | check_END(ls, TK_WHILE, line); | ||
| 936 | leavebreak(fs, &bl); | ||
| 937 | removelocalvars(ls, 3, fs->lastsetline); | ||
| 938 | } | ||
| 939 | |||
| 940 | |||
| 941 | static void test_and_block (LexState *ls, expdesc *v) { | ||
| 942 | /* test_and_block -> [IF | ELSEIF] cond THEN block */ | ||
| 910 | setline_and_next(ls); /* skip IF or ELSEIF */ | 943 | setline_and_next(ls); /* skip IF or ELSEIF */ |
| 911 | expr(ls, v); /* cond */ | 944 | expr(ls, v); /* cond */ |
| 912 | luaK_goiftrue(ls->fs, v, 0); | 945 | luaK_goiftrue(ls->fs, v, 0); |
| @@ -921,11 +954,11 @@ static void ifstat (LexState *ls, int line) { | |||
| 921 | FuncState *fs = ls->fs; | 954 | FuncState *fs = ls->fs; |
| 922 | expdesc v; | 955 | expdesc v; |
| 923 | int escapelist = NO_JUMP; | 956 | int escapelist = NO_JUMP; |
| 924 | test_and_bock(ls, &v); /* IF cond THEN block */ | 957 | test_and_block(ls, &v); /* IF cond THEN block */ |
| 925 | while (ls->token == TK_ELSEIF) { | 958 | while (ls->token == TK_ELSEIF) { |
| 926 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 959 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
| 927 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 960 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); |
| 928 | test_and_bock(ls, &v); /* ELSEIF cond THEN block */ | 961 | test_and_block(ls, &v); /* ELSEIF cond THEN block */ |
| 929 | } | 962 | } |
| 930 | if (ls->token == TK_ELSE) { | 963 | if (ls->token == TK_ELSE) { |
| 931 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 964 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
| @@ -1062,6 +1095,10 @@ static int stat (LexState *ls) { | |||
| 1062 | check_END(ls, TK_DO, line); | 1095 | check_END(ls, TK_DO, line); |
| 1063 | return 1; | 1096 | return 1; |
| 1064 | 1097 | ||
| 1098 | case TK_FOR: /* stat -> forstat */ | ||
| 1099 | forstat(ls, line); | ||
| 1100 | return 1; | ||
| 1101 | |||
| 1065 | case TK_REPEAT: /* stat -> repeatstat */ | 1102 | case TK_REPEAT: /* stat -> repeatstat */ |
| 1066 | repeatstat(ls, line); | 1103 | repeatstat(ls, line); |
| 1067 | return 1; | 1104 | return 1; |
