aboutsummaryrefslogblamecommitdiff
path: root/ast.c
blob: fa3f4976ce3c870afbe082541ad33417b6482662 (plain) (tree)
























                                                                          
                                


                                           
                  
                                     
      





                                

                                                    
     
                   

                    
                       













































































                                                               
                       




                                                           



                                      
                      


                             




                                                                                      





                                     
                          
                      
                     







                                                            



                                
                                  
                            






                                                                   



                                    
                        
                       






                                                                



                                    
                             
                       




                            





                                               


                                         

                             



                                             

                                                  




                                                     



                                                   






                                            





                               
















































































































                                                     
#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) {
    CNode *func = NEW_CNODE;
#ifdef CNODE_DEBUG
    assert(type->next == NULL);
    assert(plain_decl->next == NULL);
    assert(params->next == NULL);
    assert(stmt->next == NULL