#include <stdlib.h>
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include "ast.h"
#include "cibic.tab.h"
#define NEW_CNODE ((CNode *)malloc(sizeof(CNode)))
CNode *ast_root;
void cnode_init() {
}
CNode *cnode_create_nop() {
CNode *nop = NEW_CNODE;
nop->type = NOP;
nop->next = nop->chd = NULL;
return nop;
}
CNode *cnode_create_general(int type, int subtype, int pnum, va_list ap) {
int i;
CNode *exp = NEW_CNODE;
exp->type = type;
exp->rec.subtype = subtype;
exp->next = exp->chd = NULL;
for (i = 0; i < pnum; i++)
{
CNode *subexp = va_arg(ap, CNode*);
#ifdef CNODE_DEBUG
assert(subexp->next == NULL);
#endif
subexp->next = exp->chd;
exp->chd = subexp;
}
return exp;
}
CNode *cnode_list_append(CNode *list, CNode *tail) {
if (list->type == NOP)
{
free(list);
return tail;
}
tail->next = list;
return tail;
}
CNode *cnode_create_identifier(char *val) {
CNode *exp = NEW_CNODE;
exp->type = ID;
exp->chd = exp->next = NULL;
exp->rec.strval = val;
return exp;
}
CNode *cnode_create_int_const(int val) {
/* TODO: overflow checking */
CNode *exp = NEW_CNODE;
exp->type = INT;
exp->chd = exp->next = NULL;
exp->rec.intval = val;
return exp;
}
CNode *cnode_create_char_const(int val) {
/* TODO: overflow checking */
CNode *exp = NEW_CNODE;
exp->type = CHAR;
exp->chd = exp->next = NULL;
exp->rec.intval = val;
return exp;
}
CNode *cnode_create_str_const(char *val) {
CNode *exp = NEW_CNODE;
exp->type = STR;
exp->chd = exp->next = NULL;
exp->rec.strval = val;
return exp;
}
CNode *cnode_create_exp(int exp_type, int pnum, ...) {
CNode *ret;
va_list ap;
va_start(ap, pnum);
ret = cnode_create_general(EXP, exp_type, pnum, ap);
va_end(ap);
return ret;
}
CNode *cnode_create_type_spec(int spec_type, int pnum, ...) {
CNode *ret;
va_list ap;
va_start(ap, pnum);
ret = cnode_create_general(TYPE_SPEC, spec_type, pnum, ap);
va_end(ap);
return ret;
}
CNode *cnode_create_declr(int declr_type, int pnum, ...) {
CNode *ret;
va_list ap;
va_start(ap, pnum);
ret = cnode_create_general(DECLR, declr_type, pnum, ap);
va_end(ap);
return ret;
}
CNode *cnode_create_stmt(int stmt_type, int pnum, ...) {
CNode *ret;
va_list ap;
va_start(ap, pnum);
ret = cnode_create_general(STMT, stmt_type, pnum, ap);
va_end(ap);
return ret;
}
CNode *cnode_create_initr(int initr_type, CNode *body) {
CNode *initr = NEW_CNODE;
initr->type = INITR;
initr->rec.subtype = initr_type;
initr->chd = body;
initr->next = NULL;
return initr;
}
CNode *cnode_create_decl(CNode *type, CNode *init_declrs) {
CNode *decl = NEW_CNODE;
#ifdef CNODE_DEBUG
assert(type->next == NULL);
assert(init_declrs->next == NULL);
#endif
decl->type = DECL;
decl->next = NULL;
decl->chd = init_declrs;
init_declrs->next = type;
return decl;
}
CNode *cnode_create_func(CNode *type, CNode *plain_decl, CNode *params, CNode *stmt) {