scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 7c5b9f6272a0b8868bf5844a0a064c8aa881e595
parent f591b0538b54090ee276e05118a94e2d8451709a
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 25 Jan 2018 14:51:19 +0000

[as] Create unary() function

This unary function implements unary + and -.

Diffstat:
Mas/as.h | 1+
Mas/expr.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++------------------------
2 files changed, 50 insertions(+), 24 deletions(-)

diff --git a/as/as.h b/as/as.h @@ -56,6 +56,7 @@ enum tokens { NUMBER, REG, STRING, + MINUS, SHL, SHR, GE, diff --git a/as/expr.c b/as/expr.c @@ -143,13 +143,32 @@ binary(int op, Node *l, Node *r) } static Node * -unary(int op, Node *np) +unaryop(int op, Node *np) { - if (op != '!') + TUINT val; + + if (np->addr != ANUMBER) + error("invalid argument for unary operator"); + if (np->op != NUMBER) { + np = node(op, np, NULL); + np->addr = ANUMBER; + return np; + } + + val = np->sym->value; + switch (op) { + case '!': + val = !val; + case '+': + break; + case '-': + val = -val; + break; + default: abort(); - if (np->op != NUMBER) - return node(op, np, NULL); - np->sym->value = ~np->sym->value; + } + np->sym->value = val; + return np; } @@ -359,7 +378,7 @@ content(Node *np) /* grammar functions */ /*************************************************************************/ -static Node *or(void); +static Node *expr(void); static Node * primary(void) @@ -384,12 +403,12 @@ primary(void) next(); break; case '(': - np = or(); + np = expr(); expect(')'); break; case '[': next(); - np = or(); + np = expr(); expect(']'); np = content(np); break; @@ -401,12 +420,29 @@ primary(void) } static Node * +unary(void) +{ + int op, tok; + Node *np; + + switch (tok = yytoken) { + case '!': + case '-': + case '+': + next(); + return unaryop(tok, primary()); + default: + return primary(); + } +} + +static Node * mul(void) { int op; Node *np; - np = primary(); + np = unary(); for (;;) { switch (op = yytoken) { case '*': @@ -467,30 +503,19 @@ relational(void) } static Node * -not(void) -{ - Node *np; - - np = relational(); - while (accept('!')) - np = unary('!', relational()); - return np; -} - -static Node * and(void) { int op; Node *np; - np = not(); + np = relational(); while (accept('&')) - np = binary('&', np, not()); + np = binary('&', np, relational()); return np; } static Node * -or(void) +expr(void) { int op; Node *np; @@ -529,7 +554,7 @@ operand(char **strp) textp++; default: next(); - np = or(); + np = expr(); if (imm) np->addr = AIMM; if (yytoken != ',' && yytoken != EOS)