scc

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

commit 2d30362df693b46f67f1515e9d23e56e237410a5
parent 08c42cdfaea4d0cc3bf0bc00ee3e7cf2e5a9664a
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 10 Apr 2014 07:29:53 +0200

Add shift operators

Diffstat:
Mcc.h | 3++-
Mcode.c | 4+++-
Mexpr.c | 34+++++++++++++++++++++++++++++++---
3 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/cc.h b/cc.h @@ -219,7 +219,8 @@ typedef void (*Inst)(Node *); enum { OCAST, OPTR, OADD, OARY, OSIZE, OMUL, OSUB, - OINC, ODEC, OPINC, OPDEC, ODIV, OMOD + OINC, ODEC, OPINC, OPDEC, ODIV, OMOD, OSHL, + OSHR }; extern void diff --git a/code.c b/code.c @@ -15,7 +15,9 @@ char *opcodes[] = { [OSIZE] = "#", [OPTR] = "@", [OMOD] = "*", - [ODIV] = "/'" + [ODIV] = "/'", + [OSHL] = "l", + [OSHR] = "r" }; Node * diff --git a/expr.c b/expr.c @@ -49,6 +49,7 @@ floatconv(Node **np1, Node **np2) static Node * arithmetic(char op, Node *np1, Node *np2) { + char *err; Node *naux; Type *tp1, *tp2, *tp3; uint8_t t1, t2, taux, lvalue = 0; @@ -56,6 +57,9 @@ 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) { @@ -112,10 +116,16 @@ pointer: np1->b.lvalue = lvalue; return np1; +bad_shift: + err = "invalid operands to shift operator"; + goto error; nocomplete: - error("invalid use of indefined type"); + err = "invalid use of indefined type"; + goto error; incorrect: - error("incorrect arithmetic operands"); + err = "incorrect arithmetic operands"; +error: + error(err); } static Node * @@ -283,13 +293,31 @@ add(void) } } +static struct node * +shift(void) +{ + register char op; + register Node *np; + + np = add(); + for (;;) { + switch (yytoken) { + case SHL: op = OSHL; break; + case SHR: op = OSHR; break; + default: return np; + } + next(); + np = arithmetic(op, np, add()); + } +} + Node * expr(void) { register Node *np; do - np = add(); + np = shift(); while (yytoken == ','); return np; }