#ifndef AST_H #define AST_H #include "type.h" #include "scope.h" struct stmt_node; struct expr_node; struct expr_list_node { struct expr_node* expr; struct expr_list_node* next; const struct type* resolved_type; }; struct int_lit_node { integral_t val; }; struct float_lit_node { floating_t val; }; struct char_lit_node { char val; }; struct str_lit_node { char* val; }; struct var_ref_node { struct var_def* def_ref; }; struct decl_node { struct var_def* def_ref; struct expr_node* initial_value; struct decl_node* next; }; struct decl_list_node { struct type type; struct decl_node* head; }; struct assign_node { struct expr_node* lval; struct expr_node* rval; }; struct call_node { /* TODO: function pointers */ struct fn_decl_node* fn_ref; /* borrowed */ struct expr_list_node* args; }; struct unary_node { enum { UNARY_NEG, } op; struct expr_node* expr; }; struct binary_node { enum { BINARY_ADD, BINARY_SUB, BINARY_MUL, BINARY_DIV, } op; struct expr_node* lhs; struct expr_node* rhs; }; struct paren_node { struct expr_list_node* expr_list; }; struct cast_node { struct type type; struct expr_node* expr; }; struct expr_node { enum { EXPR_INT_LIT, EXPR_FLOAT_LIT, EXPR_CHAR_LIT, EXPR_STR_LIT, EXPR_VAR_REF, EXPR_ASSIGN, EXPR_CALL, EXPR_UNARY, EXPR_BINARY, EXPR_PAREN, EXPR_CAST, } type; union { struct int_lit_node int_lit; struct float_lit_node float_lit; struct char_lit_node char_lit; struct str_lit_node str_lit; struct var_ref_node var_ref; struct assign_node assign; struct call_node call; struct unary_node unary; struct binary_node binary; struct paren_node paren; struct cast_node cast; } inner; const struct type* resolved_type; }; struct group_node { struct stmt_node* head; struct scope* scope; }; struct arg_decl_node { struct type type; struct var_def* def_ref; struct arg_decl_node* next; }; struct fn_decl_node { struct type return_type; const char* name; struct arg_decl_node* args; struct group_node body; struct scope* scope; }; struct return_node { struct fn_decl_node* fn_ref; struct expr_list_node* ret_val; /* null to return void */ }; struct if_node { struct expr_list_node* cond; struct stmt_node* true_branch; struct stmt_node* false_branch; struct scope* scope; }; struct loop_init_node { enum { INIT_EXPR_LIST, INIT_DECL_LIST, } type; union { struct expr_list_node* expr_list; struct decl_list_node* decl_list; }; }; struct loop_node { struct loop_init_node* init; /* null if absent */ struct expr_list_node* cond; /* null if absent */ struct expr_list_node* incr; /* null if absent */ struct stmt_node* body; struct scope* scope; }; struct stmt_node { enum { STMT_EMPTY, STMT_EXPR_LIST, STMT_DECL_LIST, STMT_RETURN, STMT_GROUP, STMT_IF, STMT_LOOP, } type; union { struct expr_list_node expr_list; struct decl_list_node decl_list; struct return_node return_; struct group_node group; struct if_node if_; struct loop_node loop; } inner; struct stmt_node* next; }; struct root_node { enum { ROOT_FN_DECL, } type; union { struct fn_decl_node fn_decl; } inner; struct root_node* next; }; struct ast { struct root_node* root_node; struct scope* root_scope; }; void ast_destroy(struct ast* ast); #endif