#ifndef NCTREF_AST_H #define NCTREF_AST_H #include"types.h" #include"lexer.h" #include"vartable.h" // VISITORS APPEAR IN varify_change_usedefs,ast_expr_is_equal,ast_stmt_is_after, // dumben_chunk, cg_go, loop_second_pass AND OTHERS // // THEY ***MUST*** BE CHANGED ACCORDINGLY IF AST IS ALTERED #pragma pack(push, 1) #ifdef __GNUC__ #define ENUMPAK __attribute__((packed)) #else #define ENUMPAK #endif typedef enum ENUMPAK { AST_CHUNK, AST_STMT_DECL, AST_TYPE_IDENTIFIER, AST_EXPR_PRIMITIVE, AST_STMT_IF, AST_EXPR_BINARY_OP, AST_EXPR_VAR, AST_TYPE_POINTER, AST_EXPR_UNARY_OP, AST_STMT_LOOP, AST_STMT_BREAK, AST_STMT_CONTINUE, AST_EXPR_CALL, AST_STMT_EXPR, AST_STMT_ASSIGN, AST_STMT_EXT_ALIGN, AST_EXPR_STRING_LITERAL, AST_EXPR_CAST, AST_EXPR_ARRAY, AST_STMT_EXT_ORG, AST_STMT_EXT_SECTION, } ASTKind; typedef enum ENUMPAK { BINOP_ADD = 0, BINOP_SUB = 1, BINOP_BITWISE_AND = 2, BINOP_BITWISE_OR = 3, BINOP_BITWISE_XOR = 4, BINOP_SIMPLES = 5, BINOP_MUL = 5, BINOP_DIV = 6, BINOP_EQUAL = 7, BINOP_NEQUAL = 8, BINOP_WTF = 999, } BinaryOp; static inline int binop_is_comparison(BinaryOp op) { return op == BINOP_EQUAL || op == BINOP_NEQUAL; } static inline BinaryOp binop_comp_opposite(BinaryOp op) { if(op == BINOP_EQUAL) { return BINOP_NEQUAL; } else if(op == BINOP_NEQUAL) { return BINOP_EQUAL; } return BINOP_WTF; } typedef enum ENUMPAK { UNOP_DEREF = 0, UNOP_NEGATE = 1, UNOP_BITWISE_NOT = 2, UNOP_REF = 3, } UnaryOp; union AST; typedef struct { ASTKind nodeKind; Type *type; } ASTExpr; typedef struct { ASTExpr; int val; } ASTExprPrimitive; typedef struct { ASTExpr; union AST *operands[2]; BinaryOp operator; } ASTExprBinaryOp; typedef struct { ASTExpr; UnaryOp operator; union AST *operand; } ASTExprUnaryOp; typedef struct { ASTExpr; VarTableEntry *thing; } ASTExprVar; typedef struct { ASTExpr; union AST *what; union AST **args; } ASTExprCall; typedef struct { ASTExpr; size_t length; char *data; } ASTExprStringLiteral; typedef struct { ASTKind nodeKind; size_t size; } ASTType; typedef struct { ASTType; Token identifier; } ASTTypeIdentifier; typedef struct { ASTType; union AST *child; int levels; } ASTTypePointer; typedef struct { ASTKind nodeKind; union AST *next; } ASTStmt; typedef struct { ASTStmt; VarTableEntry *thing; union AST *expression; } ASTStmtDecl; typedef struct { ASTKind nodeKind; /* Flattened variable array for global register allocation */ size_t varCount; VarTableEntry **vars; union AST *statementFirst; union AST *statementLast; } ASTChunk; typedef struct { ASTStmt; union AST *expression; union AST *then; } ASTStmtIf; typedef struct { ASTStmt; union AST *body; } ASTStmtLoop; typedef struct { ASTStmt; } ASTStmtBreak; typedef struct { ASTStmt; } ASTStmtContinue; typedef struct { ASTStmt; union AST *expr; } ASTStmtExpr; typedef struct { ASTStmt; union AST *what; union AST *to; } ASTStmtAssign; typedef struct { ASTStmt; int val; } ASTStmtExtAlign; typedef struct { ASTExpr; union AST *what; Type *to; char reinterpretation; /* 1 = as, 0 = to */ } ASTExprCast; typedef struct { ASTExpr; union AST **items; } ASTExprArray; typedef struct { ASTStmt; size_t val; } ASTStmtExtOrg; typedef struct { ASTStmt; Token name; } ASTStmtExtSection; typedef union AST { ASTKind nodeKind; ASTChunk chunk; ASTStmt statement; ASTStmtDecl stmtDecl; ASTStmtIf stmtIf; ASTStmtLoop stmtLoop; ASTStmtBreak stmtBreak; ASTStmtContinue stmtContinue; ASTStmtExpr stmtExpr; ASTStmtAssign stmtAssign; ASTExpr expression; ASTExprPrimitive exprPrim; ASTExprBinaryOp exprBinOp; ASTExprUnaryOp exprUnOp; ASTExprVar exprVar; ASTExprCall exprCall; ASTStmtExtAlign stmtExtAlign; ASTExprStringLiteral exprStrLit; ASTExprCast exprCast; ASTExprArray exprArray; ASTStmtExtOrg stmtExtOrg; ASTStmtExtSection stmtExtSection; } AST; #pragma pack(pop) AST *ast_expression_optimize(AST*); int ast_expression_equal(AST*, AST*); int ast_stmt_is_after(const AST *chunk, const AST *s1, const AST *s2); #endif