From 68267ed878a2ea668aa97b40c5d9cacbe0e57831 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 29 Jan 1999 11:48:58 -0200 Subject: negative numerals do not need a MINUSOPeration; go directly to contant table. --- lparser.c | 95 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 51 insertions(+), 44 deletions(-) (limited to 'lparser.c') diff --git a/lparser.c b/lparser.c index a9f04128..4c9de9e2 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.8 1999/01/15 11:38:33 roberto Exp roberto $ +** $Id: lparser.c,v 1.9 1999/01/21 18:38:39 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -123,7 +123,6 @@ static void parlist (LexState *ls); static void part (LexState *ls, constdesc *cd); static void recfield (LexState *ls); static void ret (LexState *ls); -static void simpleexp (LexState *ls, vardesc *v); static void statlist (LexState *ls); static void var_or_func (LexState *ls, vardesc *v); static void var_or_func_tail (LexState *ls, vardesc *v); @@ -262,7 +261,7 @@ static int real_constant (FuncState *fs, real r) { static void code_number (LexState *ls, real f) { int i; - if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(int)f) == f) + if (0 <= f && f <= (real)MAX_WORD && (real)(i=(int)f) == f) code_oparg(ls, PUSHNUMBER, 3, i, 1); /* f has a short integer value */ else 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}; static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP, LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP}; +#define INDNOT 0 +#define INDMINUS 1 + #define MAXOPS 20 typedef struct { @@ -941,7 +943,7 @@ static void push (LexState *ls, stack_op *s, int op) { static void prefix (LexState *ls, stack_op *s) { while (ls->token == NOT || ls->token == '-') { - push(ls, s, ls->token==NOT?0:1); + push(ls, s, ls->token==NOT?INDNOT:INDMINUS); next(ls); } } @@ -954,80 +956,85 @@ static void pop_to (LexState *ls, stack_op *s, int prio) { } } -static void exp2 (LexState *ls, vardesc *v) { - stack_op s; - int op; - s.top = 0; - prefix(ls, &s); - simpleexp(ls, v); - while ((op = is_in(ls->token, binop)) >= 0) { - op += FIRSTBIN; - lua_pushvar(ls, v); - /* '^' is right associative, so must 'simulate' a higher priority */ - pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); - push(ls, &s, op); - next(ls); - prefix(ls, &s); - simpleexp(ls, v); - lua_pushvar(ls, v); - } - if (s.top > 0) { - lua_pushvar(ls, v); - pop_to(ls, &s, 0); - } -} - - -static void simpleexp (LexState *ls, vardesc *v) { +static void simpleexp (LexState *ls, vardesc *v, stack_op *s) { check_debugline(ls); switch (ls->token) { - case '(': /* simpleexp -> '(' exp0 ')' */ + case NUMBER: { /* simpleexp -> NUMBER */ + real r = ls->seminfo.r; next(ls); - exp0(ls, v); - check(ls, ')'); - break; - - case NUMBER: /* simpleexp -> NUMBER */ - code_number(ls, ls->seminfo.r); - next(ls); - v->k = VEXP; v->info = 0; + /* dirty trick: check whether is a -NUMBER not followed by "^" */ + /* (because the priority of "^" is closer than "-"...) */ + if (s->top > 0 && s->ops[s->top-1] == INDMINUS && ls->token != '^') { + s->top--; + r = -r; + } + code_number(ls, r); break; + } case STRING: /* simpleexp -> STRING */ code_string(ls, ls->seminfo.ts); /* must use before "next" */ next(ls); - v->k = VEXP; v->info = 0; break; case NIL: /* simpleexp -> NIL */ adjuststack(ls, -1); next(ls); - v->k = VEXP; v->info = 0; break; case '{': /* simpleexp -> constructor */ constructor(ls); - v->k = VEXP; v->info = 0; break; case FUNCTION: { /* simpleexp -> FUNCTION body */ int line = ls->linenumber; next(ls); body(ls, 0, line); - v->k = VEXP; v->info = 0; break; } + case '(': /* simpleexp -> '(' exp0 ')' */ + next(ls); + exp0(ls, v); + check(ls, ')'); + return; + case NAME: case '%': var_or_func(ls, v); - break; + return; default: luaX_error(ls, " expected"); - break; + return; + } + v->k = VEXP; v->info = 0; +} + + +static void exp2 (LexState *ls, vardesc *v) { + stack_op s; + int op; + s.top = 0; + prefix(ls, &s); + simpleexp(ls, v, &s); + while ((op = is_in(ls->token, binop)) >= 0) { + op += FIRSTBIN; + lua_pushvar(ls, v); + /* '^' is right associative, so must 'simulate' a higher priority */ + pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); + push(ls, &s, op); + next(ls); + prefix(ls, &s); + simpleexp(ls, v, &s); + lua_pushvar(ls, v); + } + if (s.top > 0) { + lua_pushvar(ls, v); + pop_to(ls, &s, 0); } } + static void var_or_func (LexState *ls, vardesc *v) { /* var_or_func -> ['%'] NAME var_or_func_tail */ if (optional(ls, '%')) { /* upvalue? */ -- cgit v1.2.3-55-g6feb