scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit d56d3ae24cffaad777fcb4607e623e5bd5d34f8d
parent a13c8cf6f4209b766a9491c57179647762756c19
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 10 Apr 2014 08:31:02 +0200

Add relational and equality operands

Diffstat:
Mcc.h | 2+-
Mcode.c | 8+++++++-
Mexpr.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
3 files changed, 74 insertions(+), 16 deletions(-)

diff --git a/cc.h b/cc.h @@ -220,7 +220,7 @@ typedef void (*Inst)(Node *); enum { OCAST, OPTR, OADD, OARY, OSIZE, OMUL, OSUB, OINC, ODEC, OPINC, OPDEC, ODIV, OMOD, OSHL, - OSHR + OSHR, OLT, OGT, OGE, OLE, OEQ, ONE }; extern void diff --git a/code.c b/code.c @@ -17,7 +17,13 @@ char *opcodes[] = { [OMOD] = "*", [ODIV] = "/'", [OSHL] = "l", - [OSHR] = "r" + [OSHR] = "r", + [OLT] = "<", + [OGT] = ">", + [OGE] = "]", + [OLE] = "[", + [OEQ] = "=", + [ONE] = "!" }; Node * diff --git a/expr.c b/expr.c @@ -94,19 +94,33 @@ int_float: break; case PTR: case ARY: pointer: - if (!tp1->defined) - goto nocomplete; - if (op != OADD && op != OSUB) - goto incorrect; - tp3 = tp1->type; - if (t1 == ARY) - tp1 = mktype(tp1->type, PTR, NULL, 0); - if (t2 != INT) + switch (op) { + case OEQ: case ONE: + if (t1 == ARY) + tp1 = mktype(tp1->type, PTR, NULL, 0); + else if (t1 != PTR) + goto incorrect; + if (t2 == ARY) + tp2 = mktype(tp2->type, PTR, NULL, 0); + else if (t2 != PTR) + goto incorrect; + break; + case OADD: OSUB: + tp3 = tp1->type; + if (!tp3->defined) + goto nocomplete; + if (t1 == ARY) + tp1 = mktype(tp1->type, PTR, NULL, 0); + if (t2 != INT) + goto incorrect; + np2 = bincode(OMUL, tp1, + castcode(np2, tp1), + sizeofcode(tp3)); + lvalue = 1; + break; + default: goto incorrect; - np2 = bincode(OMUL, tp1, - castcode(np2, tp1), - sizeofcode(tp3)); - lvalue = 1; + } break; default: goto incorrect; @@ -293,7 +307,7 @@ add(void) } } -static struct node * +static Node * shift(void) { register char op; @@ -311,13 +325,51 @@ shift(void) } } +static Node * +relational(void) +{ + register char op; + register Node *np; + + np = shift(); + for (;;) { + switch (yytoken) { + case '<': op = OLT; break; + case '>': op = OGT; break; + case GE: op = OGE; break; + case LE: op = OLE; break; + default: return np; + } + next(); + np = bincode(op, inttype, np, shift()); + } +} + +static Node * +eq(void) +{ + register char op; + register Node *np; + + np = relational(); + for (;;) { + switch (yytoken) { + case EQ: op = OEQ; break; + case NE: op = ONE; break; + default: return np; + } + next(); + np = arithmetic(op, np, relational()); + } +} + Node * expr(void) { register Node *np; do - np = shift(); + np = eq(); while (yytoken == ','); return np; }