#pragma once #include #include #include #include "lexer.h" enum StoreSize { STORE_SIZE_NONE, STORE_SIZE_BYTE, STORE_SIZE_WORD, STORE_SIZE_DWORD, STORE_SIZE_QWORD, }; struct ConstDecl { struct Token name; struct Expr* value; }; struct DataDecl { struct Token name; struct Token value; }; struct EnumDecl { struct Token name; struct Token* members; size_t member_count; size_t member_capacity; }; struct StructField { struct Token name; enum StoreSize size; }; struct StructDecl { struct Token name; struct StructField* fields; size_t field_count; size_t field_capacity; }; struct Param { struct Token name; struct Token reg; }; enum ExprKind { EXPR_PRIMARY, EXPR_UNARY, EXPR_BINARY, EXPR_MEMBER, EXPR_DEREF, }; struct PrimaryExpr { struct Token token; }; struct UnaryExpr { struct Token op; struct Expr* operand; }; struct BinaryExpr { struct Expr* left; struct Token op; struct Expr* right; }; struct MemberExpr { struct Expr* object; struct Token member; }; struct DerefExpr { bool is_signed; enum StoreSize size; struct Expr* address; }; struct Expr { enum ExprKind kind; union { struct PrimaryExpr primary; struct UnaryExpr unary; struct BinaryExpr binary; struct MemberExpr member; struct DerefExpr deref; }; }; enum StatementKind { STATEMENT_ASSIGN, STATEMENT_LABEL, STATEMENT_GOTO, STATEMENT_SYSCALL, STATEMENT_IF, STATEMENT_WHILE, STATEMENT_CALL, STATEMENT_STACK, }; struct AssignStatement { bool target_deref; enum StoreSize store_size; struct Token target; struct Token op; struct Expr* value; }; struct LabelStatement { struct Token name; }; struct GotoStatement { struct Token label; }; struct IfStatement { struct Expr* left; struct Token comparison; struct Expr* right; struct Statement* body; size_t body_count; struct Statement* else_body; size_t else_count; }; struct WhileStatement { bool named; struct Token name; struct Expr* left; struct Token comparison; struct Expr* right; struct Statement* body; size_t body_count; }; struct CallStatement { struct Token name; struct Expr** args; size_t arg_count; size_t arg_capacity; }; struct StackStatement { struct Token name; struct Expr* size; }; struct Statement { enum StatementKind kind; union { struct AssignStatement assign; struct LabelStatement label; struct GotoStatement jump; struct IfStatement branch; struct WhileStatement loop; struct CallStatement call; struct StackStatement stack; }; }; struct ProcDecl { struct Token name; struct Param* params; size_t param_count; size_t param_capacity; struct Statement* body; size_t body_count; size_t body_capacity; }; struct Config { uint32_t bits; bool has_entry; struct Token entry; bool logical_registers; }; struct Program { struct Config config; struct ConstDecl* consts; size_t const_count; size_t const_capacity; struct DataDecl* data_decls; size_t data_count; size_t data_capacity; struct EnumDecl* enums; size_t enum_count; size_t enum_capacity; struct StructDecl* structs; size_t struct_count; size_t struct_capacity; struct ProcDecl* procs; size_t proc_count; size_t proc_capacity; }; struct Program create_program(void); void free_program(struct Program* program); void add_const(struct Program* program, struct ConstDecl decl); void add_data(struct Program* program, struct DataDecl decl); struct EnumDecl create_enum(void); void add_enum_member(struct EnumDecl* decl, struct Token member); void add_enum(struct Program* program, struct EnumDecl decl); struct StructDecl create_struct(void); void add_struct_field(struct StructDecl* decl, struct StructField field); void add_struct(struct Program* program, struct StructDecl decl); struct ProcDecl create_proc(void); void free_proc(struct ProcDecl* proc); void add_param(struct ProcDecl* proc, struct Param param); void add_statement(struct ProcDecl* proc, struct Statement statement); void add_proc(struct Program* program, struct ProcDecl decl); void free_expr(struct Expr* expr); void free_statement(struct Statement* statement);