aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-01-29 11:48:58 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-01-29 11:48:58 -0200
commit68267ed878a2ea668aa97b40c5d9cacbe0e57831 (patch)
tree5cc3b833ef1561482818b51131f5510c1b15d5b0 /lparser.c
parentfd25d4ad85302a84551ac6ed915435c035a978e4 (diff)
downloadlua-68267ed878a2ea668aa97b40c5d9cacbe0e57831.tar.gz
lua-68267ed878a2ea668aa97b40c5d9cacbe0e57831.tar.bz2
lua-68267ed878a2ea668aa97b40c5d9cacbe0e57831.zip
negative numerals do not need a MINUSOPeration; go directly to contant
table.
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c95
1 files changed, 51 insertions, 44 deletions
diff --git a/lparser.c b/lparser.c
index a9f04128..4c9de9e2 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.8 1999/01/15 11:38:33 roberto Exp roberto $ 2** $Id: lparser.c,v 1.9 1999/01/21 18:38:39 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*/
@@ -123,7 +123,6 @@ static void parlist (LexState *ls);
123static void part (LexState *ls, constdesc *cd); 123static void part (LexState *ls, constdesc *cd);
124static void recfield (LexState *ls); 124static void recfield (LexState *ls);
125static void ret (LexState *ls); 125static void ret (LexState *ls);
126static void simpleexp (LexState *ls, vardesc *v);
127static void statlist (LexState *ls); 126static void statlist (LexState *ls);
128static void var_or_func (LexState *ls, vardesc *v); 127static void var_or_func (LexState *ls, vardesc *v);
129static void var_or_func_tail (LexState *ls, vardesc *v); 128static void var_or_func_tail (LexState *ls, vardesc *v);
@@ -262,7 +261,7 @@ static int real_constant (FuncState *fs, real r) {
262 261
263static void code_number (LexState *ls, real f) { 262static void code_number (LexState *ls, real f) {
264 int i; 263 int i;
265 if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(int)f) == f) 264 if (0 <= f && f <= (real)MAX_WORD && (real)(i=(int)f) == f)
266 code_oparg(ls, PUSHNUMBER, 3, i, 1); /* f has a short integer value */ 265 code_oparg(ls, PUSHNUMBER, 3, i, 1); /* f has a short integer value */
267 else 266 else
268 code_constant(ls, real_constant(ls->fs, f)); 267 code_constant(ls, real_constant(ls->fs, f));
@@ -900,6 +899,9 @@ static int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6};
900static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP, 899static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP,
901 LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP}; 900 LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP};
902 901
902#define INDNOT 0
903#define INDMINUS 1
904
903#define MAXOPS 20 905#define MAXOPS 20
904 906
905typedef struct { 907typedef struct {
@@ -941,7 +943,7 @@ static void push (LexState *ls, stack_op *s, int op) {
941 943
942static void prefix (LexState *ls, stack_op *s) { 944static void prefix (LexState *ls, stack_op *s) {
943 while (ls->token == NOT || ls->token == '-') { 945 while (ls->token == NOT || ls->token == '-') {
944 push(ls, s, ls->token==NOT?0:1); 946 push(ls, s, ls->token==NOT?INDNOT:INDMINUS);
945 next(ls); 947 next(ls);
946 } 948 }
947} 949}
@@ -954,80 +956,85 @@ static void pop_to (LexState *ls, stack_op *s, int prio) {
954 } 956 }
955} 957}
956 958
957static void exp2 (LexState *ls, vardesc *v) { 959static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
958 stack_op s;
959 int op;
960 s.top = 0;
961 prefix(ls, &s);
962 simpleexp(ls, v);
963 while ((op = is_in(ls->token, binop)) >= 0) {
964 op += FIRSTBIN;
965 lua_pushvar(ls, v);
966 /* '^' is right associative, so must 'simulate' a higher priority */
967 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
968 push(ls, &s, op);
969 next(ls);
970 prefix(ls, &s);
971 simpleexp(ls, v);
972 lua_pushvar(ls, v);
973 }
974 if (s.top > 0) {
975 lua_pushvar(ls, v);
976 pop_to(ls, &s, 0);
977 }
978}
979
980
981static void simpleexp (LexState *ls, vardesc *v) {
982 check_debugline(ls); 960 check_debugline(ls);
983 switch (ls->token) { 961 switch (ls->token) {
984 case '(': /* simpleexp -> '(' exp0 ')' */ 962 case NUMBER: { /* simpleexp -> NUMBER */
963 real r = ls->seminfo.r;
985 next(ls); 964 next(ls);
986 exp0(ls, v); 965 /* dirty trick: check whether is a -NUMBER not followed by "^" */
987 check(ls, ')'); 966 /* (because the priority of "^" is closer than "-"...) */
988 break; 967 if (s->top > 0 && s->ops[s->top-1] == INDMINUS && ls->token != '^') {
989 968 s->top--;
990 case NUMBER: /* simpleexp -> NUMBER */ 969 r = -r;
991 code_number(ls, ls->seminfo.r); 970 }
992 next(ls); 971 code_number(ls, r);
993 v->k = VEXP; v->info = 0;
994 break; 972 break;
973 }
995 974
996 case STRING: /* simpleexp -> STRING */ 975 case STRING: /* simpleexp -> STRING */
997 code_string(ls, ls->seminfo.ts); /* must use before "next" */ 976 code_string(ls, ls->seminfo.ts); /* must use before "next" */
998 next(ls); 977 next(ls);
999 v->k = VEXP; v->info = 0;
1000 break; 978 break;
1001 979
1002 case NIL: /* simpleexp -> NIL */ 980 case NIL: /* simpleexp -> NIL */
1003 adjuststack(ls, -1); 981 adjuststack(ls, -1);
1004 next(ls); 982 next(ls);
1005 v->k = VEXP; v->info = 0;
1006 break; 983 break;
1007 984
1008 case '{': /* simpleexp -> constructor */ 985 case '{': /* simpleexp -> constructor */
1009 constructor(ls); 986 constructor(ls);
1010 v->k = VEXP; v->info = 0;
1011 break; 987 break;
1012 988
1013 case FUNCTION: { /* simpleexp -> FUNCTION body */ 989 case FUNCTION: { /* simpleexp -> FUNCTION body */
1014 int line = ls->linenumber; 990 int line = ls->linenumber;
1015 next(ls); 991 next(ls);
1016 body(ls, 0, line); 992 body(ls, 0, line);
1017 v->k = VEXP; v->info = 0;
1018 break; 993 break;
1019 } 994 }
1020 995
996 case '(': /* simpleexp -> '(' exp0 ')' */
997 next(ls);
998 exp0(ls, v);
999 check(ls, ')');
1000 return;
1001
1021 case NAME: case '%': 1002 case NAME: case '%':
1022 var_or_func(ls, v); 1003 var_or_func(ls, v);
1023 break; 1004 return;
1024 1005
1025 default: 1006 default:
1026 luaX_error(ls, "<expression> expected"); 1007 luaX_error(ls, "<expression> expected");
1027 break; 1008 return;
1009 }
1010 v->k = VEXP; v->info = 0;
1011}
1012
1013
1014static void exp2 (LexState *ls, vardesc *v) {
1015 stack_op s;
1016 int op;
1017 s.top = 0;
1018 prefix(ls, &s);
1019 simpleexp(ls, v, &s);
1020 while ((op = is_in(ls->token, binop)) >= 0) {
1021 op += FIRSTBIN;
1022 lua_pushvar(ls, v);
1023 /* '^' is right associative, so must 'simulate' a higher priority */
1024 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
1025 push(ls, &s, op);
1026 next(ls);
1027 prefix(ls, &s);
1028 simpleexp(ls, v, &s);
1029 lua_pushvar(ls, v);
1030 }
1031 if (s.top > 0) {
1032 lua_pushvar(ls, v);
1033 pop_to(ls, &s, 0);
1028 } 1034 }
1029} 1035}
1030 1036
1037
1031static void var_or_func (LexState *ls, vardesc *v) { 1038static void var_or_func (LexState *ls, vardesc *v) {
1032 /* var_or_func -> ['%'] NAME var_or_func_tail */ 1039 /* var_or_func -> ['%'] NAME var_or_func_tail */
1033 if (optional(ls, '%')) { /* upvalue? */ 1040 if (optional(ls, '%')) { /* upvalue? */