aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-04-12 15:57:19 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-04-12 15:57:19 -0300
commitf9cf402fbd1ba2ab00f5aa5f7d0ff5c9c0580dd5 (patch)
tree7bed49a7ff5c730cdfdef7c3a43b71e039d4442b /lparser.c
parent0c3fe2c44be155b11b52230e36f45e688bae5ce2 (diff)
downloadlua-f9cf402fbd1ba2ab00f5aa5f7d0ff5c9c0580dd5.tar.gz
lua-f9cf402fbd1ba2ab00f5aa5f7d0ff5c9c0580dd5.tar.bz2
lua-f9cf402fbd1ba2ab00f5aa5f7d0ff5c9c0580dd5.zip
first implementation of FOR
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/lparser.c b/lparser.c
index 39127e2a..df4aeecf 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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
909static void test_and_bock (LexState *ls, expdesc *v) { 909static 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
941static 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;