#pragma once #include "common/arch.h" #include "lex.h" #include "report.h" #include #include typedef struct PLabel PLabel; struct PLabel { PLabel* next; char* ident; Loc loc; bool sub_label; }; PLabel* plabel_new(PLabel* next, char* ident, bool sub_label, Loc loc); void plabel_free(PLabel* label); typedef enum { PoTy_Reg, PoTy_Imm, PoTy_Ident, PoTy_SubLabel, PoTy_Str, PoTy_Mem8, PoTy_Mem16, PoTy_Not, PoTy_Negate, PoTy_Or, PoTy_Xor, PoTy_And, PoTy_Shl, PoTy_Shr, PoTy_Add, PoTy_Sub, PoTy_Mul, PoTy_Div, PoTy_Mod, } POperandTy; typedef struct POperand POperand; struct POperand { POperandTy ty; Loc loc; union { Reg reg; uint16_t imm; struct { char* str; size_t str_len; }; POperand* operand; struct { POperand* left; POperand* right; }; }; }; POperand* poperand_new_reg(Reg reg, Loc loc); POperand* poperand_new_imm(uint16_t imm, Loc loc); POperand* poperand_new_str(POperandTy ty, char* str, size_t str_len, Loc loc); POperand* poperand_new_unary(POperandTy ty, POperand* inner, Loc loc); POperand* poperand_new_binary( POperandTy ty, POperand* left, POperand* right, Loc loc); void poperand_free(POperand* operand); typedef struct { PLabel* labels; char* op; Loc loc; size_t ops_size; POperand* ops[]; } PLine; PLine* pline_new( char* op, PLabel* labels, Loc loc, size_t ops_size, POperand** ops); void pline_free(PLine* pline); typedef enum { PStmtTy_Line, PStmtTy_Global, PStmtTy_Extern, PStmtTy_Const, } PStmtTy; typedef struct { PStmtTy ty; Loc loc; union { PLine* line; struct { char* ident; POperand* value; }; }; } PStmt; PStmt* pstmt_new_line(Loc loc, PLine* line); PStmt* pstmt_new_ident(PStmtTy ty, Loc loc, char* ident); PStmt* pstmt_new_const(PStmtTy ty, Loc loc, char* ident, POperand* value); void pstmt_free(PStmt* stmt); typedef struct { Lexer lexer; Tok tok; Tok eaten; bool error_occured; } Parser; void parser_construct(Parser* parser, const char* filename, const char* text); bool parser_done(const Parser* parser); bool parser_error_occured(const Parser* parser); PLine* parser_next_line(Parser* parser); PStmt* parser_next_stmt(Parser* parser);