#ifndef AST_H #define AST_H #include "collection.h" #include typedef struct { int line; int col; } Loc; typedef struct AstStmt AstStmt; typedef struct AstDecl AstDecl; typedef struct AstDeclar AstDeclar; typedef struct AstExpr AstExpr; typedef struct AstStmtBlock AstStmtBlock; struct AstStmtBlock { ARRAY_FIELD(AstStmt*, stmts); Loc loc; }; typedef struct AstDeclBlock AstDeclBlock; struct AstDeclBlock { ARRAY_FIELD(AstDecl*, decls); Loc loc; }; typedef enum { AstStmt_Decl, AstStmt_Expr, } AstStmtTy; struct AstStmt { AstStmtTy ty; Loc loc; union { AstDecl* decl; AstExpr* expr; }; }; typedef enum : unsigned int { AstSpec_Int = 1 << 0, AstSpec_Char = 1 << 1, AstSpec_Void = 1 << 2, AstSpec_DefTy = 1 << 6, AstSpec_Unsigned = 1 << 7, AstSpec_Static = 1 << 8, AstSpec_Const = 1 << 9, AstSpec_Inline = 1 << 10, AstSpec_Typedef = 1 << 11, AstSpec_Enum = 1 << 12, AstSpec_Struct = 1 << 13, AstSpec_Union = 1 << 14, } AstSpec; struct AstDecl { AstSpec spec; char* type_ident; ARRAY_FIELD(AstDeclar*, declars); AstStmtBlock* function_body; Loc loc; }; typedef enum { AstDeclar_Ident, AstDeclar_Pointer, AstDeclar_Array, AstDeclar_Function, } AstDeclarTy; struct AstDeclar { AstDeclarTy ty; Loc loc; AstExpr* init_expr; union { char* ident; struct { AstDeclar* declar; AstSpec spec; } pointer; struct { AstDeclar* declar; AstExpr* expr; } array; struct { AstDeclar* declar; ARRAY_FIELD(AstDecl*, params); } function; }; }; typedef enum { AstExpr_Ident, AstExpr_Str, AstExpr_Call, } AstExprTy; struct AstExpr { AstExprTy ty; Loc loc; union { char* ident; char* str_val; struct { AstExpr* expr; ARRAY_FIELD(AstExpr*, args); } call; }; }; void ast_stmt_block_print(FILE* f, const AstStmtBlock* node, int depth); void ast_stmt_print(FILE* f, const AstStmt* node, int depth); void ast_decl_print(FILE* f, const AstDecl* node, int depth); void ast_declar_print(FILE* f, const AstDeclar* node, int depth); void ast_expr_print(FILE* f, const AstExpr* node, int depth); typedef struct AstVisitor AstVisitor; typedef enum { AstVisitor_Continue, AstVisitor_Break, } AstVisitorResult; struct AstVisitor { AstVisitorResult (*visit_stmt_block)(AstVisitor* v, AstStmtBlock* node); AstVisitorResult (*visit_stmt)(AstVisitor* v, AstStmt* node); AstVisitorResult (*visit_decl)(AstVisitor* v, AstDecl* node); AstVisitorResult (*visit_declar)(AstVisitor* v, AstDeclar* node); AstVisitorResult (*visit_expr)(AstVisitor* v, AstExpr* node); void* op; }; void ast_stmt_block_visit(AstVisitor* v, AstStmtBlock* node); void ast_stmt_block_visit_body(AstVisitor* v, AstStmtBlock* node); void ast_stmt_visit(AstVisitor* v, AstStmt* node); void ast_stmt_visit_body(AstVisitor* v, AstStmt* node); void ast_decl_visit(AstVisitor* v, AstDecl* node); void ast_decl_visit_body(AstVisitor* v, AstDecl* node); void ast_declar_visit(AstVisitor* v, AstDeclar* node); void ast_declar_visit_body(AstVisitor* v, AstDeclar* node); void ast_expr_visit(AstVisitor* v, AstExpr* node); void ast_expr_visit_body(AstVisitor* v, AstExpr* node); #endif