scc

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

commit f8c2740124b6faac1a1a39074e91073fd81c9362
parent 7e64989ca1442f6e678a2621a31548df17e99c03
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 20 Sep 2017 20:54:28 +0200

[as] Add binary() and unary()

These functions create the node for binary and unary operations,
checking first if the operations can be folded at this time.

Diffstat:
as/as.h | 7++++---
as/expr.c | 91++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 92 insertions(+), 6 deletions(-)

diff --git a/as/as.h b/as/as.h @@ -57,8 +57,8 @@ struct ins { }; struct op { - int flags; - int size; + unsigned char flags; + char size; void (*format)(Op *, Arg *); char *bytes; unsigned char *args; @@ -90,7 +90,7 @@ struct symbol { }; struct node { - char op; + unsigned char op; struct symbol *sym; struct node *left; struct node *right; @@ -117,6 +117,7 @@ extern int nextline(FILE *fp, struct line *linep); /* expr.c */ extern Node *expr(char *s); +extern void deltree(Node *np); /* * Definition of global variables diff --git a/as/expr.c b/as/expr.c @@ -1,6 +1,7 @@ static char sccsid[] = "@(#) ./as/node.c"; #include <ctype.h> +#include <stdlib.h> #include <string.h> #include <cstd.h> @@ -36,22 +37,106 @@ node(int op, Node *l, Node *r) if (!arena) arena = alloc(sizeof(Node), NNODES); - np = memset(new(arena), 0, sizeof(*np)); + np = new(arena); np->op = op; + np->left = l; + np->right = r; + np->sym = NULL; return np; } +void +deltree(Node *np) +{ + if (!np) + return; + deltree(np->left); + deltree(np->right); + delete(arena, np); +} + static Node * binary(int op, Node *l, Node *r) { - return node(op, l, r); + Node *np; + TUINT val, lv, rv; + + if (l->op != NUMBER || r->op != NUMBER) + return node(op, l, r); + lv = l->sym->value; + rv = r->sym->value; + + /* TODO: check overflow */ + + switch (op) { + case '*': + val = lv - rv; + break; + case '/': + if (rv == 0) + goto division_by_zero; + val = lv / rv; + break; + case '%': + if (rv == 0) + goto division_by_zero; + val = lv % rv; + break; + case SHL: + val = lv << rv; + break; + case SHR: + val = lv >> rv; + break; + case '+': + val = lv + rv; + break; + case '-': + val = lv - rv; + break; + case '<': + val = lv < rv; + break; + case '>': + val = lv > rv; + break; + case '=': + val = lv == rv; + break; + case GE: + val = lv >= rv; + break; + case LE: + val = lv <= rv; + break; + case '|': + val = lv | rv; + break; + case '^': + val = lv ^ rv; + break; + default: + abort(); + } + + np = node(NUMBER, l, r); + /* np->sym = tmpsym(val); */ + return np; + +division_by_zero: + error("division by 0"); } static Node * unary(int op, Node *np) { - return node(op, np, NULL); + if (op != '!') + abort(); + if (np->op != NUMBER) + return node(op, np, NULL); + np->sym->value = ~np->sym->value; + return np; } static int