#ifndef AST_H #define AST_H #include "scope.h" struct stmt_node; struct expr_node; struct type_ref_node { struct type_ref type; }; struct int_lit_node { long long val; }; struct float_lit_node { double val; }; struct char_lit_node { char val; }; struct str_lit_node { char* val; }; struct var_ref_node { struct var_def* def_ref; }; struct var_decl_node { struct type_ref_node type; struct var_def* def_ref; }; struct lval_node { enum { LVAL_VAR_DECL, LVAL_VAR_REF, } type; union { struct var_ref_node var_ref; struct var_decl_node var_decl; } inner; const struct type_def* resolved_type; }; struct assign_node { struct lval_node lval; struct expr_node* rval; }; struct args_eval_node { struct expr_node* expr; struct args_eval_node* next; }; struct call_node { /* TODO: eventually this could also be a function pointer */ struct fn_decl_node* called_fn_ref; /* borrowed */ struct args_eval_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 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, } 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; } inner; const struct type_def* resolved_type; }; struct group_node { struct stmt_node* head; struct scope* scope; }; struct args_decl_node { struct var_decl_node* decl; struct args_decl_node* next; }; struct fn_decl_node { struct type_ref_node return_type; char* name; struct args_decl_node* args; struct group_node body; struct scope* scope; const struct type_def* resolved_return_type; }; struct return_node { struct expr_node* ret_val; /* null to return void */ }; struct if_node { struct expr_node* cond; struct stmt_node* true_branch; struct stmt_node* false_branch; struct scope* scope; }; struct loop_node { struct expr_node* init; /* null if absent */ struct expr_node* cond; /* null if absent */ struct expr_node* incr; /* null if absent */ struct stmt_node* body; struct scope* scope; }; struct stmt_node { enum { STMT_EMPTY, STMT_EXPR, STMT_VAR_DECL, STMT_RETURN, STMT_GROUP, STMT_IF, STMT_LOOP, } type; union { struct expr_node expr; struct var_decl_node var_decl; 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; /* nice shortcuts to have */ const struct type_def* void_type; const struct type_def* char_type; const struct type_def* integral_type; const struct type_def* decimal_type; const struct type_def* pointer_type; }; void ast_destroy(struct ast* ast); #endif