diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-04-12 15:57:19 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-04-12 15:57:19 -0300 |
commit | f9cf402fbd1ba2ab00f5aa5f7d0ff5c9c0580dd5 (patch) | |
tree | 7bed49a7ff5c730cdfdef7c3a43b71e039d4442b /lparser.c | |
parent | 0c3fe2c44be155b11b52230e36f45e688bae5ce2 (diff) | |
download | lua-f9cf402fbd1ba2ab00f5aa5f7d0ff5c9c0580dd5.tar.gz lua-f9cf402fbd1ba2ab00f5aa5f7d0ff5c9c0580dd5.tar.bz2 lua-f9cf402fbd1ba2ab00f5aa5f7d0ff5c9c0580dd5.zip |
first implementation of FOR
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; |