aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-01-25 16:44:21 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-01-25 16:44:21 -0200
commitd83c2a84550221c30a48647fde9c433c65af1802 (patch)
treeea525b29eaabb7cacd54bf7d42ab9e57533e4b5a /lparser.c
parentd11e5adf55b11a446671775a6c7803e066fc94e8 (diff)
downloadlua-d83c2a84550221c30a48647fde9c433c65af1802.tar.gz
lua-d83c2a84550221c30a48647fde9c433c65af1802.tar.bz2
lua-d83c2a84550221c30a48647fde9c433c65af1802.zip
performance details.
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c87
1 files changed, 47 insertions, 40 deletions
diff --git a/lparser.c b/lparser.c
index 664795c6..ec655a99 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.54 2000/01/12 16:24:39 roberto Exp roberto $ 2** $Id: lparser.c,v 1.55 2000/01/25 13:57: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*/
@@ -119,11 +119,16 @@ static void exp1 (LexState *ls);
119 119
120 120
121 121
122static void luaY_error (LexState *ls, const char *msg) {
123 luaX_error(ls, msg, ls->token);
124}
125
126
122static void checklimit (LexState *ls, int val, int limit, const char *msg) { 127static void checklimit (LexState *ls, int val, int limit, const char *msg) {
123 if (val > limit) { 128 if (val > limit) {
124 char buff[100]; 129 char buff[100];
125 sprintf(buff, "too many %.50s (limit=%d)", msg, limit); 130 sprintf(buff, "too many %.50s (limit=%d)", msg, limit);
126 luaX_error(ls, buff); 131 luaY_error(ls, buff);
127 } 132 }
128} 133}
129 134
@@ -145,7 +150,7 @@ static void deltastack (LexState *ls, int delta) {
145 fs->stacksize += delta; 150 fs->stacksize += delta;
146 if (fs->stacksize > fs->maxstacksize) { 151 if (fs->stacksize > fs->maxstacksize) {
147 if (fs->stacksize > MAX_BYTE) 152 if (fs->stacksize > MAX_BYTE)
148 luaX_error(ls, "function/expression too complex"); 153 luaY_error(ls, "function/expression too complex");
149 fs->maxstacksize = fs->stacksize; 154 fs->maxstacksize = fs->stacksize;
150 } 155 }
151} 156}
@@ -160,7 +165,7 @@ static void code_oparg_at (LexState *ls, int pc, OpCode op,
160 code[pc+1] = (Byte)arg; 165 code[pc+1] = (Byte)arg;
161 } 166 }
162 else if (arg > MAX_ARG) 167 else if (arg > MAX_ARG)
163 luaX_error(ls, "code too long"); 168 luaY_error(ls, "code too long");
164 else { /* MAX_BYTE < arg < MAX_ARG */ 169 else { /* MAX_BYTE < arg < MAX_ARG */
165 if (arg > MAX_WORD) { 170 if (arg > MAX_WORD) {
166 code[pc] = (Byte)LONGARG; 171 code[pc] = (Byte)LONGARG;
@@ -599,20 +604,6 @@ static void close_func (LexState *ls) {
599} 604}
600 605
601 606
602
603static const int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT,
604 DO, NAME, LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';',
605 EOS, ',', 0};
606
607
608static int is_in (int tok, const int *toks) {
609 const int *t;
610 for (t=toks; *t; t++)
611 if (*t == tok) return t-toks;
612 return -1;
613}
614
615
616static void next (LexState *ls) { 607static void next (LexState *ls) {
617 ls->token = luaX_lex(ls); 608 ls->token = luaX_lex(ls);
618} 609}
@@ -622,12 +613,12 @@ static void error_expected (LexState *ls, int token) {
622 char buff[100], t[TOKEN_LEN]; 613 char buff[100], t[TOKEN_LEN];
623 luaX_token2str(token, t); 614 luaX_token2str(token, t);
624 sprintf(buff, "`%.20s' expected", t); 615 sprintf(buff, "`%.20s' expected", t);
625 luaX_error(ls, buff); 616 luaY_error(ls, buff);
626} 617}
627 618
628 619
629static void error_unexpected (LexState *ls) { 620static void error_unexpected (LexState *ls) {
630 luaX_error(ls, "unexpected token"); 621 luaY_error(ls, "unexpected token");
631} 622}
632 623
633 624
@@ -641,7 +632,7 @@ static void error_unmatched (LexState *ls, int what, int who, int where) {
641 luaX_token2str(who, t_who); 632 luaX_token2str(who, t_who);
642 sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", 633 sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
643 t_what, t_who, where); 634 t_what, t_who, where);
644 luaX_error(ls, buff); 635 luaY_error(ls, buff);
645 } 636 }
646} 637}
647 638
@@ -661,7 +652,7 @@ static void check_match (LexState *ls, int what, int who, int where) {
661static int checkname (LexState *ls) { 652static int checkname (LexState *ls) {
662 int sc; 653 int sc;
663 if (ls->token != NAME) 654 if (ls->token != NAME)
664 luaX_error(ls, "<name> expected"); 655 luaY_error(ls, "<name> expected");
665 sc = string_constant(ls, ls->fs, ls->seminfo.ts); 656 sc = string_constant(ls, ls->fs, ls->seminfo.ts);
666 next(ls); 657 next(ls);
667 return sc; 658 return sc;
@@ -691,7 +682,7 @@ TProtoFunc *luaY_parser (lua_State *L, ZIO *z) {
691 next(&lexstate); /* read first token */ 682 next(&lexstate); /* read first token */
692 chunk(&lexstate); 683 chunk(&lexstate);
693 if (lexstate.token != EOS) 684 if (lexstate.token != EOS)
694 luaX_error(&lexstate, "<eof> expected"); 685 luaY_error(&lexstate, "<eof> expected");
695 close_func(&lexstate); 686 close_func(&lexstate);
696 return funcstate.f; 687 return funcstate.f;
697} 688}
@@ -782,7 +773,7 @@ static int funcparams (LexState *ls, int slf, vardesc *v) {
782 break; 773 break;
783 774
784 default: 775 default:
785 luaX_error(ls, "function arguments expected"); 776 luaY_error(ls, "function arguments expected");
786 break; 777 break;
787 } 778 }
788 code_setname(ls, v); 779 code_setname(ls, v);
@@ -871,7 +862,7 @@ static void recfield (LexState *ls) {
871 check(ls, ']'); 862 check(ls, ']');
872 break; 863 break;
873 864
874 default: luaX_error(ls, "<name> or `[' expected"); 865 default: luaY_error(ls, "<name> or `[' expected");
875 } 866 }
876 check(ls, '='); 867 check(ls, '=');
877 exp1(ls); 868 exp1(ls);
@@ -977,7 +968,7 @@ static void constructor (LexState *ls) {
977 next(ls); 968 next(ls);
978 constructor_part(ls, &other_cd); 969 constructor_part(ls, &other_cd);
979 if (cd.k == other_cd.k) /* repeated parts? */ 970 if (cd.k == other_cd.k) /* repeated parts? */
980 luaX_error(ls, "invalid constructor syntax"); 971 luaY_error(ls, "invalid constructor syntax");
981 nelems += other_cd.n; 972 nelems += other_cd.n;
982 } 973 }
983 check_match(ls, '}', '{', line); 974 check_match(ls, '}', '{', line);
@@ -992,8 +983,8 @@ static void constructor (LexState *ls) {
992/* 983/*
993** {====================================================================== 984** {======================================================================
994** For parsing expressions, we use a classic stack with priorities. 985** For parsing expressions, we use a classic stack with priorities.
995** Each binary operator is represented by its index in `binop' + FIRSTBIN 986** Each binary operator is represented by an index: EQ=2, NE=3, ... '^'=13.
996** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1. 987** The unary NOT is 0 and UNMINUS is 1.
997** ======================================================================= 988** =======================================================================
998*/ 989*/
999 990
@@ -1008,8 +999,6 @@ static void constructor (LexState *ls) {
1008*/ 999*/
1009#define POW 13 1000#define POW 13
1010 1001
1011static const int binop [] = {EQ, NE, '>', '<', LE, GE, CONC,
1012 '+', '-', '*', '/', '^', 0};
1013 1002
1014static const int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6}; 1003static const int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6};
1015 1004
@@ -1024,10 +1013,31 @@ typedef struct stack_op {
1024} stack_op; 1013} stack_op;
1025 1014
1026 1015
1016/*
1017** returns the index of a binary operator
1018*/
1019static int binop (int op) {
1020 switch (op) {
1021 case EQ: return FIRSTBIN;
1022 case NE: return FIRSTBIN+1;
1023 case '>': return FIRSTBIN+2;
1024 case '<': return FIRSTBIN+3;
1025 case LE: return FIRSTBIN+4;
1026 case GE: return FIRSTBIN+5;
1027 case CONC: return FIRSTBIN+6;
1028 case '+': return FIRSTBIN+7;
1029 case '-': return FIRSTBIN+8;
1030 case '*': return FIRSTBIN+9;
1031 case '/': return FIRSTBIN+10;
1032 case '^': return FIRSTBIN+11;
1033 default: return -1;
1034 }
1035}
1036
1027 1037
1028static void push (LexState *ls, stack_op *s, int op) { 1038static void push (LexState *ls, stack_op *s, int op) {
1029 if (s->top >= MAXOPS) 1039 if (s->top >= MAXOPS)
1030 luaX_error(ls, "expression too complex"); 1040 luaY_error(ls, "expression too complex");
1031 s->ops[s->top++] = op; 1041 s->ops[s->top++] = op;
1032} 1042}
1033 1043
@@ -1086,7 +1096,7 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
1086 return; 1096 return;
1087 1097
1088 default: 1098 default:
1089 luaX_error(ls, "<expression> expected"); 1099 luaY_error(ls, "<expression> expected");
1090 return; 1100 return;
1091 } 1101 }
1092 v->k = VEXP; v->info = 0; 1102 v->k = VEXP; v->info = 0;
@@ -1108,8 +1118,7 @@ static void arith_exp (LexState *ls, vardesc *v) {
1108 int op; 1118 int op;
1109 s.top = 0; 1119 s.top = 0;
1110 prefixexp(ls, v, &s); 1120 prefixexp(ls, v, &s);
1111 while ((op = is_in(ls->token, binop)) >= 0) { 1121 while ((op = binop(ls->token)) >= 0) {
1112 op += FIRSTBIN;
1113 lua_pushvar(ls, v); 1122 lua_pushvar(ls, v);
1114 /* '^' is right associative, so must 'simulate' a higher priority */ 1123 /* '^' is right associative, so must 'simulate' a higher priority */
1115 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); 1124 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
@@ -1129,8 +1138,6 @@ static void exp1 (LexState *ls) {
1129 vardesc v; 1138 vardesc v;
1130 expr(ls, &v); 1139 expr(ls, &v);
1131 lua_pushvar(ls, &v); 1140 lua_pushvar(ls, &v);
1132 if (is_in(ls->token, expfollow) < 0)
1133 luaX_error(ls, "malformed expression");
1134} 1141}
1135 1142
1136 1143
@@ -1180,7 +1187,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars) {
1180 next(ls); 1187 next(ls);
1181 var_or_func(ls, &nv); 1188 var_or_func(ls, &nv);
1182 if (nv.k == VEXP) 1189 if (nv.k == VEXP)
1183 luaX_error(ls, "syntax error"); 1190 luaY_error(ls, "syntax error");
1184 left = assignment(ls, &nv, nvars+1); 1191 left = assignment(ls, &nv, nvars+1);
1185 } 1192 }
1186 else { /* assignment -> '=' explist1 */ 1193 else { /* assignment -> '=' explist1 */
@@ -1313,7 +1320,7 @@ static void namestat (LexState *ls) {
1313 var_or_func(ls, &v); 1320 var_or_func(ls, &v);
1314 if (v.k == VEXP) { /* stat -> func */ 1321 if (v.k == VEXP) { /* stat -> func */
1315 if (v.info == 0) /* is just an upper value? */ 1322 if (v.info == 0) /* is just an upper value? */
1316 luaX_error(ls, "syntax error"); 1323 luaY_error(ls, "syntax error");
1317 close_exp(ls, v.info, 0); 1324 close_exp(ls, v.info, 0);
1318 } 1325 }
1319 else { /* stat -> ['%'] NAME assignment */ 1326 else { /* stat -> ['%'] NAME assignment */
@@ -1410,14 +1417,14 @@ static void parlist (LexState *ls) {
1410 case NAME: /* tailparlist -> NAME [',' tailparlist] */ 1417 case NAME: /* tailparlist -> NAME [',' tailparlist] */
1411 goto init; 1418 goto init;
1412 1419
1413 default: luaX_error(ls, "<name> or `...' expected"); 1420 default: luaY_error(ls, "<name> or `...' expected");
1414 } 1421 }
1415 } 1422 }
1416 break; 1423 break;
1417 1424
1418 case ')': break; /* parlist -> empty */ 1425 case ')': break; /* parlist -> empty */
1419 1426
1420 default: luaX_error(ls, "<name> or `...' expected"); 1427 default: luaY_error(ls, "<name> or `...' expected");
1421 } 1428 }
1422 code_args(ls, nparams, dots); 1429 code_args(ls, nparams, dots);
1423} 1430}