aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-04-10 16:21:14 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-04-10 16:21:14 -0300
commit0810bc707f98f05a2d598e6a00cb33280d16cf89 (patch)
tree5fefa71b4f7427eb3b1a1a65e679997d1e3deff3
parentc3b73cbeb8c1f5588b0f516264ae34778975e6d6 (diff)
downloadlua-0810bc707f98f05a2d598e6a00cb33280d16cf89.tar.gz
lua-0810bc707f98f05a2d598e6a00cb33280d16cf89.tar.bz2
lua-0810bc707f98f05a2d598e6a00cb33280d16cf89.zip
new syntax: |label|
-rw-r--r--lparser.c143
1 files changed, 94 insertions, 49 deletions
diff --git a/lparser.c b/lparser.c
index f49d6135..61882800 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.78 2000/04/07 13:13:11 roberto Exp roberto $ 2** $Id: lparser.c,v 1.79 2000/04/07 19:35:20 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*/
@@ -36,6 +36,7 @@ typedef struct Constdesc {
36 36
37typedef struct Breaklabel { 37typedef struct Breaklabel {
38 struct Breaklabel *previous; /* chain */ 38 struct Breaklabel *previous; /* chain */
39 TString *label;
39 int breaklist; 40 int breaklist;
40 int stacklevel; 41 int stacklevel;
41} Breaklabel; 42} Breaklabel;
@@ -171,6 +172,14 @@ static TString *str_checkname (LexState *ls) {
171} 172}
172 173
173 174
175static TString *optionalname (LexState *ls) {
176 if (ls->token == TK_NAME)
177 return str_checkname(ls);
178 else
179 return NULL;
180}
181
182
174static void luaI_registerlocalvar (LexState *ls, TString *varname, 183static void luaI_registerlocalvar (LexState *ls, TString *varname,
175 int line) { 184 int line) {
176 FuncState *fs = ls->fs; 185 FuncState *fs = ls->fs;
@@ -317,6 +326,7 @@ static int getvarname (LexState *ls, expdesc *var) {
317 326
318static void enterbreak (FuncState *fs, Breaklabel *bl) { 327static void enterbreak (FuncState *fs, Breaklabel *bl) {
319 bl->stacklevel = fs->stacklevel; 328 bl->stacklevel = fs->stacklevel;
329 bl->label = NULL;
320 bl->breaklist = NO_JUMP; 330 bl->breaklist = NO_JUMP;
321 bl->previous = fs->bl; 331 bl->previous = fs->bl;
322 fs->bl = bl; 332 fs->bl = bl;
@@ -330,6 +340,20 @@ static void leavebreak (FuncState *fs, Breaklabel *bl) {
330} 340}
331 341
332 342
343static Breaklabel *findlabel (FuncState *fs, TString *name) {
344 Breaklabel *bl;
345 for (bl=fs->bl; bl; bl=bl->previous) {
346 if (bl->label == name)
347 return bl;
348 }
349 if (name) /* label not found: choose appropriate error message */
350 luaX_syntaxerror(fs->ls, "break not inside given label", name->str);
351 else
352 luaK_error(fs->ls, "break not inside while or repeat loop");
353 return NULL; /* to avoid warnings */
354}
355
356
333static void func_onstack (LexState *ls, FuncState *func) { 357static void func_onstack (LexState *ls, FuncState *func) {
334 FuncState *fs = ls->fs; 358 FuncState *fs = ls->fs;
335 Proto *f = fs->f; 359 Proto *f = fs->f;
@@ -419,7 +443,7 @@ static int explist1 (LexState *ls) {
419 expr(ls, &v); 443 expr(ls, &v);
420 n++; 444 n++;
421 } 445 }
422 luaK_tostack(ls, &v, 0); 446 luaK_tostack(ls, &v, 0); /* keep open number of values of last expression */
423 return n; 447 return n;
424} 448}
425 449
@@ -427,12 +451,12 @@ static int explist1 (LexState *ls) {
427static int explist (LexState *ls) { 451static int explist (LexState *ls) {
428 /* explist -> [ explist1 ] */ 452 /* explist -> [ explist1 ] */
429 switch (ls->token) { 453 switch (ls->token) {
430 case TK_ELSE: case TK_ELSEIF: case TK_END: case TK_UNTIL: 454 case TK_NUMBER: case TK_STRING: case TK_NIL: case '{':
431 case TK_EOS: case ';': case ')': 455 case TK_FUNCTION: case '(': case TK_NAME: case '%':
432 return 0; /* empty list */ 456 case TK_NOT: case '-': /* first `expr' */
433
434 default:
435 return explist1(ls); 457 return explist1(ls);
458 default:
459 return 0; /* empty list */
436 } 460 }
437} 461}
438 462
@@ -998,44 +1022,73 @@ static void namestat (LexState *ls) {
998} 1022}
999 1023
1000 1024
1025static void retstat (LexState *ls) {
1026 /* stat -> RETURN explist */
1027 FuncState *fs = ls->fs;
1028 setline_and_next(ls); /* skip RETURN */
1029 explist(ls);
1030 luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar);
1031 fs->stacklevel = fs->nlocalvar; /* removes all temp values */
1032}
1033
1034
1035static void breakstat (LexState *ls) {
1036 /* stat -> BREAK [NAME] */
1037 FuncState *fs = ls->fs;
1038 Breaklabel *bl;
1039 int currentlevel = fs->stacklevel;
1040 setline_and_next(ls); /* skip BREAK */
1041 bl = findlabel(fs, optionalname(ls));
1042 luaK_adjuststack(fs, currentlevel - bl->stacklevel);
1043 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
1044 fs->stacklevel = currentlevel;
1045}
1046
1047
1001static int stat (LexState *ls) { 1048static int stat (LexState *ls) {
1002 int line = ls->linenumber; /* may be needed for error messages */ 1049 int line = ls->linenumber; /* may be needed for error messages */
1003 switch (ls->token) { 1050 switch (ls->token) {
1004 case TK_IF: /* stat -> ifstat */ 1051 case TK_IF: /* stat -> ifstat */
1005 ifstat(ls, line); 1052 ifstat(ls, line);
1006 break; 1053 return 1;
1007 1054
1008 case TK_WHILE: /* stat -> whilestat */ 1055 case TK_WHILE: /* stat -> whilestat */
1009 whilestat(ls, line); 1056 whilestat(ls, line);
1010 break; 1057 return 1;
1011 1058
1012 case TK_DO: { /* stat -> DO block END */ 1059 case TK_DO: /* stat -> DO block END */
1013 setline_and_next(ls); /* skip DO */ 1060 setline_and_next(ls); /* skip DO */
1014 block(ls); 1061 block(ls);
1015 check_END(ls, TK_DO, line); 1062 check_END(ls, TK_DO, line);
1016 break; 1063 return 1;
1017 }
1018 1064
1019 case TK_REPEAT: /* stat -> repeatstat */ 1065 case TK_REPEAT: /* stat -> repeatstat */
1020 repeatstat(ls, line); 1066 repeatstat(ls, line);
1021 break; 1067 return 1;
1022 1068
1023 case TK_FUNCTION: /* stat -> funcstat */ 1069 case TK_FUNCTION: /* stat -> funcstat */
1024 funcstat(ls, line); 1070 funcstat(ls, line);
1025 break; 1071 return 1;
1026 1072
1027 case TK_LOCAL: /* stat -> localstat */ 1073 case TK_LOCAL: /* stat -> localstat */
1028 localstat(ls); 1074 localstat(ls);
1029 break; 1075 return 1;
1030 1076
1031 case TK_NAME: case '%': /* stat -> namestat */ 1077 case TK_NAME: case '%': /* stat -> namestat */
1032 namestat(ls); 1078 namestat(ls);
1033 break; 1079 return 1;
1080
1081 case TK_RETURN: /* stat -> retstat */
1082 retstat(ls);
1083 return 2; /* must be last statement */
1084
1085 case TK_BREAK: /* stat -> breakstat */
1086 breakstat(ls);
1087 return 2; /* must be last statement */
1034 1088
1035 default: 1089 default:
1036 return 0; /* no statement */ 1090 return 0; /* no statement */
1037 } 1091 }
1038 return 1;
1039} 1092}
1040 1093
1041 1094
@@ -1092,44 +1145,36 @@ static void body (LexState *ls, int needself, int line) {
1092} 1145}
1093 1146
1094 1147
1095static void ret (LexState *ls) { 1148/* }====================================================================== */
1096 /* ret -> [RETURN explist sc | BREAK sc] */ 1149
1097 FuncState *fs = ls->fs; 1150
1098 switch (ls->token) { 1151static void label (LexState *ls, Breaklabel *bl) {
1099 case TK_RETURN: { 1152 /* label -> [ '|' NAME '|' ] */
1100 setline_and_next(ls); /* skip RETURN */ 1153 if (optional(ls, '|')) {
1101 explist(ls); 1154 enterbreak(ls->fs, bl);
1102 luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar); 1155 bl->label = str_checkname(ls);
1103 fs->stacklevel = fs->nlocalvar; /* removes all temp values */ 1156 check(ls, '|');
1104 optional(ls, ';');
1105 break;
1106 }
1107 case TK_BREAK: {
1108 Breaklabel *bl = fs->bl;
1109 int currentlevel = fs->stacklevel;
1110 if (bl == NULL)
1111 luaK_error(ls, "break not inside while or repeat loop");
1112
1113 setline_and_next(ls); /* skip BREAK */
1114 luaK_adjuststack(fs, currentlevel - bl->stacklevel);
1115 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
1116 optional(ls, ';');
1117 fs->stacklevel = currentlevel;
1118 break;
1119 }
1120 } 1157 }
1158 else
1159 bl->label = NULL; /* there is no label */
1121} 1160}
1122 1161
1123/* }====================================================================== */
1124
1125 1162
1126static void chunk (LexState *ls) { 1163static void chunk (LexState *ls) {
1127 /* chunk -> { stat [;] } ret */ 1164 /* chunk -> { [label] stat [';'] } */
1128 while (stat(ls)) { 1165 Breaklabel bl;
1166 int a;
1167 do {
1168 label(ls, &bl);
1169 a = stat(ls);
1170 if (a != 0)
1171 optional(ls, ';');
1172 else if (bl.label)
1173 luaK_error(ls, "label without a statement");
1129 LUA_ASSERT(ls->L, ls->fs->stacklevel == ls->fs->nlocalvar, 1174 LUA_ASSERT(ls->L, ls->fs->stacklevel == ls->fs->nlocalvar,
1130 "stack size != # local vars"); 1175 "stack size != # local vars");
1131 optional(ls, ';'); 1176 if (bl.label)
1132 } 1177 leavebreak(ls->fs, &bl);
1133 ret(ls); /* optional return */ 1178 } while (a == 1);
1134} 1179}
1135 1180