#ifndef AST_H #define AST_H #include "collection.h" 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_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_Str, AstExpr_Call, } AstExprTy; struct AstExpr { AstExprTy ty; Loc loc; union { char* str_val; struct { AstExpr* expr; ARRAY_FIELD(AstExpr*, args); } call; }; }; typedef struct { ARRAY_FIELD(char, string); Arena* arena; int depth; } AstStringifier; void ast_stringifier_init(AstStringifier* s, Arena* arena); void ast_stmt_block_to_string(AstStringifier* s, const AstStmtBlock* node); void ast_stmt_to_string(AstStringifier* s, const AstStmt* node); void ast_decl_to_string(AstStringifier* s, const AstDecl* node); void ast_declar_to_string(AstStringifier* s, const AstDeclar* node); void ast_expr_to_string(AstStringifier* s, const AstExpr* node); #endif