scc

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

commit f0bad0d420fc126fa86c3e8a95f1783cc7032ed6
parent 3f1579403feed901243196776461d5f02035fac7
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 11 Apr 2014 19:01:24 +0200

Add ternary operator

Diffstat:
Mcc.h | 3++-
Mcode.c | 27+++++++++++++++++++++++++--
Mexpr.c | 19++++++++++++++++++-
3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/cc.h b/cc.h @@ -235,7 +235,8 @@ extern Node *unarycode(char op, Type *tp, Node *child), *bincode(char op, Type *tp, Node *np1, Node *np2), *castcode(Node *child, Type *tp), - *sizeofcode(Type *tp); + *sizeofcode(Type *tp), + *ternarycode(Node *cond, Node *ifyes, Node *ifno); #define SYM(s) ((union unode) {.sym = s}) #define OP(s) ((union unode) {.op = s}) diff --git a/code.c b/code.c @@ -104,6 +104,20 @@ emitbin(Node *np) } void +emitternary(Node *np) +{ + Node *cond, *ifyes, *ifno; + + cond = np->childs[0]; + ifyes = np->childs[1]; + ifno = np->childs[2]; + (*cond->code)(cond); + (*ifyes->code)(ifyes); + (*ifno->code)(ifno); + printf("\t?%c", np->type->letter); +} + +void emitsizeof(Node *np) { printf("\t#%c", np->u.type->letter); @@ -164,4 +178,14 @@ Node * sizeofcode(Type *tp) { return node(emitsizeof, inttype, TYP(tp), 0); -} -\ No newline at end of file +} + +Node * +ternarycode(Node *cond, Node *ifyes, Node *ifno) +{ + Node *np= node(emitternary, ifyes->type, OP(0), 3); + np->childs[0] = cond; + np->childs[1] = ifyes; + np->childs[2] = ifno; + return np; +} diff --git a/expr.c b/expr.c @@ -445,9 +445,25 @@ bit_or(void) } static Node * +ternary(void) +{ + register Node *cond, *ifyes, *ifno; + + cond = bit_or(); + while (accept('?')) { + ifyes = expr(); + expect(':'); + ifno = expr(); + /* TODO: check the types of ifno and ifyes */ + cond = ternarycode(cond, ifyes, ifno); + } + return cond; +} + +static Node * assign(void) { - register Node *np1 = bit_or(), *np2; + register Node *np1 = ternary(), *np2; char *err; for (;;) { @@ -471,6 +487,7 @@ assign(void) np2 = assign(); if (!np1->b.lvalue) goto nolvalue; + /* TODO: if it necessary a 0 comparision? */ if ((np2 = convert(np1, np2)) == NULL) goto incompatibles; np1 = bincode(op, np1->type, np1, np2);