typedef
struct expr expr; struct expr {
int e_op;
union
{
expr *e__branch[2];
char *e__string;
int e__int;
double e__double;
symbol *e__symbol;
} e_u; };
expr *expr_alloc(int op); void expr_free(expr *ep); char
*expr_text(expr *ep); int expr_is_constant(expr *ep); expr
*expr_optimize(expr *ep); void expr_generate_code(expr *ep);
etc etc etc
#define INT_CONST 1 #define CHAR_CONST 2 #define DOUBLE_CONST 3
#define PLUS 4 #define UNARY_MINUS 5 etc etc etc
#define e_branch e_u.e__branch #define e_string e_u.e__string
#define e_int e_u.e__int #define e_double e_u.e__double #define
e_symbol e_u.e__symbol |
#include "expr.h"
expr * expr_alloc(int op) {
expr *result;
result = new(expr);
result->e_op = op;
return result; }
void expr_generate_code(expr *e) {
switch(e->e_op)
{
case PLUS:
expr_generate_code(e->e_branch[0]);
expr_generate_code(e->e_branch[1]);
emit(OP_ADI);
break;
case IDENT:
gen_emit_address(e->e_symbol->address);
break;
case INT_CONST:
gen_emit_int(e->e_int);
break;
case DOUBLE_CONST:
gen_emit_double(e->e_double);
break;
case CHAR_STRING:
gen_emit_string(e->e_string);
break;
} }
expression * expr_optimize(expr *e) {
if (!expr_is_constant(e))
return e;
switch(e->e_op)
{
case AND:
{
int n1;
int n2;
expr *result;
n1 = expr_generate_code(e->e_branch[0]);
n2 = expr_generate_code(e->e_branch[1]);
result = expr_alloc(INT_CONST);
result->e_int = (n1 & n2);
return result;
}
case INT_CONST:
return e;
etc etc etc
} }
void expr_free(expr *ep) {
if (!ep)
return;
switch(ep->e_op)
{
case INT_CONST:
case DOUBLE_CONST:
case CHAR_CONST:
break;
case IDENT:
case CHAR_STRING:
free(ep->e_string);
break;
case PLUS:
etc etc etc
expr_free(ep->e_branch[1]);
/* fall through... */
case UNARY_MINUS:
etc etc etc
expr_free(ep->e_branch[0]);
break;
}
free(ep); } |