diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-24 09:17:53 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-24 09:17:53 -0300 |
| commit | 415ee1a24f59136b735eb78e864a934ea534e5ff (patch) | |
| tree | fa557ab19ef1cfd583ee57ed669a2a182f56a82f | |
| parent | 5f3c5ace959ac6e9cc53d93258af89f134083ce5 (diff) | |
| download | lua-415ee1a24f59136b735eb78e864a934ea534e5ff.tar.gz lua-415ee1a24f59136b735eb78e864a934ea534e5ff.tar.bz2 lua-415ee1a24f59136b735eb78e864a934ea534e5ff.zip | |
SETLINEs for reserved words, too.
| -rw-r--r-- | lparser.c | 84 |
1 files changed, 45 insertions, 39 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.70 2000/03/15 20:50:33 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.71 2000/03/20 19:15:37 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 | */ |
| @@ -96,15 +96,6 @@ static void check (LexState *ls, int c) { | |||
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | 98 | ||
| 99 | static int optional (LexState *ls, int c) { | ||
| 100 | if (ls->token == c) { | ||
| 101 | next(ls); | ||
| 102 | return 1; | ||
| 103 | } | ||
| 104 | else return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | |||
| 108 | static void checklimit (LexState *ls, int val, int limit, const char *msg) { | 99 | static void checklimit (LexState *ls, int val, int limit, const char *msg) { |
| 109 | if (val > limit) { | 100 | if (val > limit) { |
| 110 | char buff[100]; | 101 | char buff[100]; |
| @@ -114,15 +105,25 @@ static void checklimit (LexState *ls, int val, int limit, const char *msg) { | |||
| 114 | } | 105 | } |
| 115 | 106 | ||
| 116 | 107 | ||
| 117 | static void check_debugline (LexState *ls) { | 108 | static void setline (LexState *ls) { |
| 118 | FuncState *fs = ls->fs; | 109 | FuncState *fs = ls->fs; |
| 119 | if (ls->L->debug && ls->linenumber != fs->lastsetline) { | 110 | if (ls->L->debug && ls->linenumber != fs->lastsetline) { |
| 111 | checklimit(ls, ls->linenumber, MAXARG_U, "lines in a chunk"); | ||
| 120 | luaK_U(fs, OP_SETLINE, ls->linenumber, 0); | 112 | luaK_U(fs, OP_SETLINE, ls->linenumber, 0); |
| 121 | fs->lastsetline = ls->linenumber; | 113 | fs->lastsetline = ls->linenumber; |
| 122 | } | 114 | } |
| 123 | } | 115 | } |
| 124 | 116 | ||
| 125 | 117 | ||
| 118 | static int optional (LexState *ls, int c) { | ||
| 119 | if (ls->token == c) { | ||
| 120 | next(ls); | ||
| 121 | return 1; | ||
| 122 | } | ||
| 123 | else return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | |||
| 126 | static void check_match (LexState *ls, int what, int who, int where) { | 127 | static void check_match (LexState *ls, int what, int who, int where) { |
| 127 | if (ls->token != what) | 128 | if (ls->token != what) |
| 128 | error_unmatched(ls, what, who, where); | 129 | error_unmatched(ls, what, who, where); |
| @@ -130,6 +131,18 @@ static void check_match (LexState *ls, int what, int who, int where) { | |||
| 130 | } | 131 | } |
| 131 | 132 | ||
| 132 | 133 | ||
| 134 | static void setline_and_next (LexState *ls) { | ||
| 135 | setline(ls); | ||
| 136 | next(ls); | ||
| 137 | } | ||
| 138 | |||
| 139 | |||
| 140 | static void check_END (LexState *ls, int who, int where) { | ||
| 141 | setline(ls); /* setline for END */ | ||
| 142 | check_match(ls, TK_END, who, where); | ||
| 143 | } | ||
| 144 | |||
| 145 | |||
| 133 | static int string_constant (FuncState *fs, TString *s) { | 146 | static int string_constant (FuncState *fs, TString *s) { |
| 134 | Proto *f = fs->f; | 147 | Proto *f = fs->f; |
| 135 | int c = s->constindex; | 148 | int c = s->constindex; |
| @@ -661,7 +674,7 @@ static void constructor (LexState *ls) { | |||
| 661 | 674 | ||
| 662 | static void simpleexp (LexState *ls, expdesc *v) { | 675 | static void simpleexp (LexState *ls, expdesc *v) { |
| 663 | FuncState *fs = ls->fs; | 676 | FuncState *fs = ls->fs; |
| 664 | check_debugline(ls); | 677 | setline(ls); |
| 665 | switch (ls->token) { | 678 | switch (ls->token) { |
| 666 | case TK_NUMBER: { /* simpleexp -> NUMBER */ | 679 | case TK_NUMBER: { /* simpleexp -> NUMBER */ |
| 667 | Number r = ls->seminfo.r; | 680 | Number r = ls->seminfo.r; |
| @@ -828,15 +841,14 @@ static void whilestat (LexState *ls, int line) { | |||
| 828 | FuncState *fs = ls->fs; | 841 | FuncState *fs = ls->fs; |
| 829 | int while_init = luaK_getlabel(fs); | 842 | int while_init = luaK_getlabel(fs); |
| 830 | expdesc v; | 843 | expdesc v; |
| 831 | next(ls); /* skip WHILE */ | 844 | setline_and_next(ls); /* trace WHILE when looping */ |
| 832 | expr(ls, &v); /* read condition */ | 845 | expr(ls, &v); /* read condition */ |
| 833 | luaK_goiftrue(fs, &v, 0); | 846 | luaK_goiftrue(fs, &v, 0); |
| 834 | check(ls, TK_DO); | 847 | check(ls, TK_DO); |
| 835 | block(ls); | 848 | block(ls); |
| 836 | luaK_fixjump(fs, luaK_S(fs, OP_JMP, 0, 0), while_init); | 849 | luaK_fixjump(fs, luaK_S(fs, OP_JMP, 0, 0), while_init); |
| 837 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 850 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); |
| 838 | check_debugline(ls); /* trace `end' when loop finish */ | 851 | check_END(ls, TK_WHILE, line); |
| 839 | check_match(ls, TK_END, TK_WHILE, line); | ||
| 840 | } | 852 | } |
| 841 | 853 | ||
| 842 | 854 | ||
| @@ -845,8 +857,7 @@ static void repeatstat (LexState *ls, int line) { | |||
| 845 | FuncState *fs = ls->fs; | 857 | FuncState *fs = ls->fs; |
| 846 | int repeat_init = luaK_getlabel(fs); | 858 | int repeat_init = luaK_getlabel(fs); |
| 847 | expdesc v; | 859 | expdesc v; |
| 848 | check_debugline(ls); /* trace `repeat' when looping */ | 860 | setline_and_next(ls); /* trace REPEAT when looping */ |
| 849 | next(ls); | ||
| 850 | block(ls); | 861 | block(ls); |
| 851 | check_match(ls, TK_UNTIL, TK_REPEAT, line); | 862 | check_match(ls, TK_UNTIL, TK_REPEAT, line); |
| 852 | expr(ls, &v); | 863 | expr(ls, &v); |
| @@ -883,8 +894,7 @@ static void localstat (LexState *ls) { | |||
| 883 | FuncState *fs = ls->fs; | 894 | FuncState *fs = ls->fs; |
| 884 | int nvars; | 895 | int nvars; |
| 885 | int nexps; | 896 | int nexps; |
| 886 | check_debugline(ls); | 897 | setline_and_next(ls); /* skip LOCAL */ |
| 887 | next(ls); | ||
| 888 | nvars = localnamelist(ls); | 898 | nvars = localnamelist(ls); |
| 889 | nexps = decinit(ls); | 899 | nexps = decinit(ls); |
| 890 | adjustlocalvars(ls, nvars, fs->lastsetline); | 900 | adjustlocalvars(ls, nvars, fs->lastsetline); |
| @@ -913,8 +923,7 @@ static int funcstat (LexState *ls, int line) { | |||
| 913 | expdesc v; | 923 | expdesc v; |
| 914 | if (ls->fs->prev) /* inside other function? */ | 924 | if (ls->fs->prev) /* inside other function? */ |
| 915 | return 0; | 925 | return 0; |
| 916 | next(ls); | 926 | setline_and_next(ls); /* skip FUNCTION */ |
| 917 | check_debugline(ls); | ||
| 918 | needself = funcname(ls, &v); | 927 | needself = funcname(ls, &v); |
| 919 | body(ls, needself, line); | 928 | body(ls, needself, line); |
| 920 | luaK_storevar(ls, &v); | 929 | luaK_storevar(ls, &v); |
| @@ -926,7 +935,7 @@ static void namestat (LexState *ls) { | |||
| 926 | /* stat -> func | ['%'] NAME assignment */ | 935 | /* stat -> func | ['%'] NAME assignment */ |
| 927 | FuncState *fs = ls->fs; | 936 | FuncState *fs = ls->fs; |
| 928 | expdesc v; | 937 | expdesc v; |
| 929 | check_debugline(ls); | 938 | setline(ls); |
| 930 | var_or_func(ls, &v); | 939 | var_or_func(ls, &v); |
| 931 | if (v.k == VEXP) { /* stat -> func */ | 940 | if (v.k == VEXP) { /* stat -> func */ |
| 932 | if (!luaK_lastisopen(fs)) /* is just an upvalue? */ | 941 | if (!luaK_lastisopen(fs)) /* is just an upvalue? */ |
| @@ -940,25 +949,24 @@ static void namestat (LexState *ls) { | |||
| 940 | } | 949 | } |
| 941 | 950 | ||
| 942 | 951 | ||
| 943 | static void ifpart (LexState *ls, int line) { | 952 | static void ifpart (LexState *ls) { |
| 944 | /* ifpart -> cond THEN block (ELSEIF ifpart | [ELSE block] END) */ | 953 | /* ifpart -> cond THEN block (ELSEIF ifpart | [ELSE block] END) */ |
| 945 | FuncState *fs = ls->fs; | 954 | FuncState *fs = ls->fs; |
| 946 | expdesc v; | 955 | expdesc v; |
| 947 | int elseinit; | 956 | int elseinit; |
| 948 | next(ls); /* skip IF or ELSEIF */ | 957 | setline_and_next(ls); /* skip IF or ELSEIF */ |
| 949 | expr(ls, &v); /* cond */ | 958 | expr(ls, &v); /* cond */ |
| 950 | luaK_goiftrue(fs, &v, 0); | 959 | luaK_goiftrue(fs, &v, 0); |
| 960 | setline(ls); /* to trace the THEN */ | ||
| 951 | check(ls, TK_THEN); | 961 | check(ls, TK_THEN); |
| 952 | block(ls); /* `then' part */ | 962 | block(ls); /* `then' part */ |
| 953 | luaK_S(fs, OP_JMP, 0, 0); /* 2nd jump: over `else' part */ | 963 | luaK_S(fs, OP_JMP, 0, 0); /* 2nd jump: over `else' part */ |
| 954 | elseinit = luaK_getlabel(fs); /* address of 2nd jump == elseinit-1 */ | 964 | elseinit = luaK_getlabel(fs); /* address of 2nd jump == elseinit-1 */ |
| 955 | check_debugline(ls); /* trace `else' (or `elseif') */ | ||
| 956 | if (ls->token == TK_ELSEIF) | 965 | if (ls->token == TK_ELSEIF) |
| 957 | ifpart(ls, line); | 966 | ifpart(ls); |
| 958 | else { | 967 | else if (ls->token == TK_ELSE) { |
| 959 | if (optional(ls, TK_ELSE)) | 968 | setline_and_next(ls); /* skip ELSE */ |
| 960 | block(ls); /* `else' part */ | 969 | block(ls); /* `else' part */ |
| 961 | check_match(ls, TK_END, TK_IF, line); | ||
| 962 | } | 970 | } |
| 963 | if (fs->pc > elseinit) { /* is there an `else' part? */ | 971 | if (fs->pc > elseinit) { /* is there an `else' part? */ |
| 964 | luaK_fixjump(fs, elseinit-1, luaK_getlabel(fs)); /* fix 2nd jump */ | 972 | luaK_fixjump(fs, elseinit-1, luaK_getlabel(fs)); /* fix 2nd jump */ |
| @@ -975,17 +983,18 @@ static int stat (LexState *ls) { | |||
| 975 | int line = ls->linenumber; /* may be needed for error messages */ | 983 | int line = ls->linenumber; /* may be needed for error messages */ |
| 976 | switch (ls->token) { | 984 | switch (ls->token) { |
| 977 | case TK_IF: /* stat -> IF ifpart END */ | 985 | case TK_IF: /* stat -> IF ifpart END */ |
| 978 | ifpart(ls, line); /* condition will set debug line */ | 986 | ifpart(ls); |
| 987 | check_END(ls, TK_IF, line); | ||
| 979 | return 1; | 988 | return 1; |
| 980 | 989 | ||
| 981 | case TK_WHILE: /* stat -> whilestat */ | 990 | case TK_WHILE: /* stat -> whilestat */ |
| 982 | whilestat(ls, line); /* debug line only after 1st jump */ | 991 | whilestat(ls, line); |
| 983 | return 1; | 992 | return 1; |
| 984 | 993 | ||
| 985 | case TK_DO: { /* stat -> DO block END */ | 994 | case TK_DO: { /* stat -> DO block END */ |
| 986 | next(ls); | 995 | setline_and_next(ls); /* skip DO */ |
| 987 | block(ls); | 996 | block(ls); |
| 988 | check_match(ls, TK_END, TK_DO, line); | 997 | check_END(ls, TK_DO, line); |
| 989 | return 1; | 998 | return 1; |
| 990 | } | 999 | } |
| 991 | 1000 | ||
| @@ -1060,11 +1069,9 @@ static void body (LexState *ls, int needself, int line) { | |||
| 1060 | if (needself) | 1069 | if (needself) |
| 1061 | add_localvar(ls, luaS_newfixed(ls->L, "self")); | 1070 | add_localvar(ls, luaS_newfixed(ls->L, "self")); |
| 1062 | parlist(ls); | 1071 | parlist(ls); |
| 1063 | check_debugline(ls); /* trace function header */ | ||
| 1064 | check(ls, ')'); | 1072 | check(ls, ')'); |
| 1065 | chunk(ls); | 1073 | chunk(ls); |
| 1066 | check_debugline(ls); /* trace `end' when finish */ | 1074 | check_END(ls, TK_FUNCTION, line); |
| 1067 | check_match(ls, TK_END, TK_FUNCTION, line); | ||
| 1068 | close_func(ls); | 1075 | close_func(ls); |
| 1069 | func_onstack(ls, &new_fs); | 1076 | func_onstack(ls, &new_fs); |
| 1070 | } | 1077 | } |
| @@ -1075,8 +1082,7 @@ static void ret (LexState *ls) { | |||
| 1075 | if (ls->token == TK_RETURN) { | 1082 | if (ls->token == TK_RETURN) { |
| 1076 | FuncState *fs = ls->fs; | 1083 | FuncState *fs = ls->fs; |
| 1077 | int nexps; /* number of expressions returned */ | 1084 | int nexps; /* number of expressions returned */ |
| 1078 | check_debugline(ls); | 1085 | setline_and_next(ls); /* skip RETURN */ |
| 1079 | next(ls); | ||
| 1080 | nexps = explist(ls); | 1086 | nexps = explist(ls); |
| 1081 | luaK_retcode(fs, ls->fs->nlocalvar, nexps); | 1087 | luaK_retcode(fs, ls->fs->nlocalvar, nexps); |
| 1082 | fs->stacksize = fs->nlocalvar; /* removes all temp values */ | 1088 | fs->stacksize = fs->nlocalvar; /* removes all temp values */ |
