scc

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

commit bce263baaa569ae0a2eaa83e6483e456e172e56d
parent 323563334c17544e1c9134dc8cd8e3cbdb33c1c9
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 11 Apr 2014 16:04:53 +0200

Add logical bit operation

Diffstat:
Mcc.h | 2+-
Mcode.c | 3++-
Mexpr.c | 52++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 43 insertions(+), 14 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, OLT, OGT, OGE, OLE, OEQ, ONE + OSHR, OLT, OGT, OGE, OLE, OEQ, ONE, OBAND }; extern void diff --git a/code.c b/code.c @@ -23,7 +23,8 @@ char *opcodes[] = { [OGE] = "]", [OLE] = "[", [OEQ] = "=", - [ONE] = "!" + [ONE] = "!", + [OBAND] = "&" }; Node * diff --git a/expr.c b/expr.c @@ -36,12 +36,17 @@ primary(void) return np; } -void +static Node * +promote(Node *np) +{ +} + +static void intconv(Node **np1, Node **np2) { } -void +static void floatconv(Node **np1, Node **np2) { } @@ -57,9 +62,6 @@ arithmetic(char op, Node *np1, Node *np2) tp1 = UNQUAL(np1->type), tp2 = UNQUAL(np2->type); t1 = tp1->op, t2 = tp2->op; - if ((op == OSHL || op == OSHR) && (t1 != INT || t2 != INT)) - goto bad_shift; - switch (t1) { case INT: switch (t2) { @@ -105,10 +107,11 @@ pointer: tp2 = mktype(tp2->type, PTR, NULL, 0); else if (t2 != PTR) goto incorrect; + /* FIX: result of comparisions is integer type */ break; case OADD: OSUB: - tp3 = tp1->type; - if (!tp3->defined) + tp3 = tp1->type; /* TODO: I think tp3 is not needed */ + if (!tp1->defined) goto nocomplete; if (t1 == ARY) tp1 = mktype(tp1->type, PTR, NULL, 0); @@ -128,9 +131,6 @@ pointer: return bincode(op, tp1, np1, np2); -bad_shift: - err = "invalid operands to shift operator"; - goto error; nocomplete: err = "invalid use of indefined type"; goto error; @@ -307,6 +307,21 @@ add(void) } static Node * +bitlogic(char op, Node *np1, Node *np2) +{ + Type *tp1, *tp2; + uint8_t t1, t2; + + tp1 = UNQUAL(np1->type), tp2 = UNQUAL(np2->type); + t1 = tp1->op, t2 = tp2->op; + + if (t1 != INT || t2 != INT) + error("No integer operand in bit logical operation"); + intconv(&np1, &np2); + return bincode(op, np1->type, np1, np2); +} + +static Node * shift(void) { register char op; @@ -320,7 +335,7 @@ shift(void) default: return np; } next(); - np = arithmetic(op, np, add()); + np = bitlogic(op, np, add()); } } @@ -362,13 +377,26 @@ eq(void) } } +static Node * +bit_and(void) +{ + register Node *np; + + np = eq(); + while (yytoken == '&') { + next(); + np = bitlogic(OBAND, np, eq()); + } + return np; +} + Node * expr(void) { register Node *np; do - np = eq(); + np = bit_and(); while (yytoken == ','); return np; }