nctref/src/ast.h

384 lines
6.3 KiB
C
Raw Permalink Normal View History

2023-08-27 19:48:06 +03:00
#ifndef NCTREF_AST_H
#define NCTREF_AST_H
#include"types.h"
#include"lexer.h"
#include"vartable.h"
2024-02-13 21:33:49 +02:00
#pragma pack(push, 1)
#ifdef __GNUC__
#define ENUMPAK __attribute__((packed))
#else
#define ENUMPAK
#endif
2024-11-20 16:36:17 +02:00
#define GEN_ENUM(x) x,
#define GEN_STRI(x) #x,
#define AST_KINDS(K) \
K(AST_CHUNK) \
K(AST_STMT_DECL) \
K(AST_TYPE_IDENTIFIER) \
K(AST_EXPR_PRIMITIVE) \
K(AST_STMT_IF) \
K(AST_EXPR_BINARY_OP) \
K(AST_EXPR_VAR) \
K(AST_EXPR_STACK_POINTER) \
K(AST_TYPE_POINTER) \
K(AST_EXPR_UNARY_OP) \
K(AST_STMT_LOOP) \
K(AST_STMT_BREAK) \
K(AST_STMT_CONTINUE) \
K(AST_EXPR_CALL) \
K(AST_STMT_EXPR) \
K(AST_STMT_ASSIGN) \
K(AST_STMT_EXT_ALIGN) \
K(AST_EXPR_STRING_LITERAL) \
K(AST_EXPR_CAST) \
K(AST_EXPR_ARRAY) \
2024-11-26 18:42:20 +02:00
K(AST_EXPR_FUNC) \
2024-11-20 16:36:17 +02:00
K(AST_STMT_EXT_ORG) \
2024-11-28 21:40:03 +02:00
K(AST_STMT_EXT_SECTION) \
2025-02-27 20:10:02 +02:00
K(AST_STMT_RETURN) \
K(AST_EXPR_EXT_SALLOC) \
K(AST_EXPR_DOT) \
K(AST_EXPR_EXT_SIZEOF)
2024-11-20 16:36:17 +02:00
typedef enum ENUMPAK { AST_KINDS(GEN_ENUM) } ASTKind;
extern const char *AST_KIND_STR[];
2023-08-27 19:48:06 +03:00
2024-02-13 21:33:49 +02:00
typedef enum ENUMPAK {
2023-08-27 19:48:06 +03:00
BINOP_ADD = 0,
BINOP_SUB = 1,
BINOP_BITWISE_AND = 2,
BINOP_BITWISE_OR = 3,
BINOP_BITWISE_XOR = 4,
2025-02-27 20:10:02 +02:00
2023-08-27 19:48:06 +03:00
BINOP_SIMPLES = 5,
2024-12-14 18:13:33 +02:00
2023-08-27 19:48:06 +03:00
BINOP_MUL = 5,
BINOP_DIV = 6,
2025-02-27 20:10:02 +02:00
BINOP_2OPS = 7,
BINOP_MULHI = 7,
BINOP_MOD = 8,
BINOP_EQUAL = 9,
BINOP_NEQUAL = 10,
BINOP_LESS = 11,
BINOP_GREATER = 12,
BINOP_LEQUAL = 13,
BINOP_GEQUAL = 14,
2023-08-27 19:48:06 +03:00
BINOP_WTF = 999,
} BinaryOp;
static inline int binop_is_comparison(BinaryOp op) {
2024-12-14 18:13:33 +02:00
return op == BINOP_EQUAL || op == BINOP_NEQUAL || op == BINOP_LESS || op == BINOP_GREATER || op == BINOP_LEQUAL || op == BINOP_GEQUAL;
2023-08-27 19:48:06 +03:00
}
static inline int binop_is_commutative(BinaryOp op) {
return op == BINOP_ADD || op == BINOP_MUL || op == BINOP_MULHI || op == BINOP_EQUAL || op == BINOP_NEQUAL || op == BINOP_BITWISE_AND || op == BINOP_BITWISE_OR || op == BINOP_BITWISE_XOR;
}
2023-08-27 19:48:06 +03:00
static inline BinaryOp binop_comp_opposite(BinaryOp op) {
if(op == BINOP_EQUAL) {
return BINOP_NEQUAL;
} else if(op == BINOP_NEQUAL) {
return BINOP_EQUAL;
2024-12-14 18:13:33 +02:00
} else if(op == BINOP_LESS) {
return BINOP_GEQUAL;
} else if(op == BINOP_GREATER) {
return BINOP_LEQUAL;
} else if(op == BINOP_LEQUAL) {
return BINOP_GREATER;
} else if(op == BINOP_GEQUAL) {
return BINOP_LESS;
2023-08-27 19:48:06 +03:00
}
return BINOP_WTF;
}
2024-02-13 21:33:49 +02:00
typedef enum ENUMPAK {
2023-08-27 19:48:06 +03:00
UNOP_DEREF = 0,
UNOP_NEGATE = 1,
UNOP_BITWISE_NOT = 2,
UNOP_REF = 3,
} UnaryOp;
union AST;
typedef struct {
ASTKind nodeKind;
2025-05-03 09:59:30 +03:00
uint16_t row;
uint16_t col;
} ASTBase;
typedef struct {
ASTBase;
2023-08-27 19:48:06 +03:00
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;
ScopeItem *thing;
2023-08-27 19:48:06 +03:00
} ASTExprVar;
typedef struct {
ASTExpr;
union AST *what;
union AST **args;
} ASTExprCall;
typedef struct {
ASTExpr;
size_t length;
char *data;
} ASTExprStringLiteral;
2024-11-20 16:36:17 +02:00
typedef struct {
ASTExpr;
} ASTExprStackPointer;
2024-11-26 18:42:20 +02:00
typedef struct {
ASTExpr;
union AST *chunk;
2025-05-03 09:59:30 +03:00
// Necessary for when the parser jumps to a generic function
Scope *scope;
2025-05-03 09:59:30 +03:00
Token *rangeTokens;
size_t startTokI;
size_t endTokI;
2024-11-26 18:42:20 +02:00
} ASTExprFunc;
2023-08-27 19:48:06 +03:00
typedef struct {
2025-05-03 09:59:30 +03:00
ASTBase;
2023-08-27 19:48:06 +03:00
size_t size;
} ASTType;
typedef struct {
ASTType;
Token identifier;
} ASTTypeIdentifier;
typedef struct {
ASTType;
union AST *child;
int levels;
} ASTTypePointer;
typedef struct {
2025-05-03 09:59:30 +03:00
ASTBase;
2023-08-27 19:48:06 +03:00
union AST *next;
} ASTStmt;
typedef struct {
ASTStmt;
ScopeItem *thing;
2023-08-27 19:48:06 +03:00
union AST *expression;
} ASTStmtDecl;
typedef struct {
2025-05-03 09:59:30 +03:00
ASTBase;
2023-08-27 19:48:06 +03:00
/* Flattened variable array for global register allocation */
size_t varCount;
ScopeItem **vars;
2023-08-27 19:48:06 +03:00
2025-05-03 09:59:30 +03:00
/* extern symbol array */
size_t externCount;
ScopeItem **externs;
2025-05-03 09:59:30 +03:00
2023-08-27 19:48:06 +03:00
union AST *statementFirst;
union AST *statementLast;
2024-11-20 16:36:17 +02:00
size_t stackReservation;
2024-12-14 18:13:33 +02:00
/* NULL unless this is a top-level chunk belonging to a function */
Type *functionType;
2023-08-27 19:48:06 +03:00
} ASTChunk;
typedef struct {
ASTStmt;
union AST *expression;
union AST *then;
} ASTStmtIf;
typedef struct {
ASTStmt;
union AST *body;
2023-08-27 19:48:06 +03:00
} 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;
2025-02-27 20:10:02 +02:00
typedef struct {
ASTExpr;
Type *size;
} ASTExprExtSalloc;
typedef struct {
ASTExpr;
union AST *a;
const char *b;
} ASTExprDot;
2023-08-27 19:48:06 +03:00
typedef struct {
ASTStmt;
size_t val;
} ASTStmtExtOrg;
typedef struct {
ASTStmt;
Token name;
} ASTStmtExtSection;
2024-11-28 21:40:03 +02:00
typedef struct {
ASTStmt;
union AST *val;
} ASTStmtReturn;
typedef struct {
ASTExpr;
// One of these will be NULL
union AST *ofExpr;
Type *ofType;
} ASTExprExtSizeOf;
2023-08-27 19:48:06 +03:00
typedef union AST {
2025-05-03 09:59:30 +03:00
ASTBase;
2023-08-27 19:48:06 +03:00
ASTChunk chunk;
ASTStmt statement;
ASTStmtDecl stmtDecl;
ASTStmtIf stmtIf;
ASTStmtLoop stmtLoop;
ASTStmtBreak stmtBreak;
ASTStmtContinue stmtContinue;
ASTStmtExpr stmtExpr;
ASTStmtAssign stmtAssign;
2024-11-28 21:40:03 +02:00
ASTStmtReturn stmtReturn;
2023-08-27 19:48:06 +03:00
ASTExpr expression;
ASTExprPrimitive exprPrim;
ASTExprBinaryOp exprBinOp;
ASTExprUnaryOp exprUnOp;
ASTExprVar exprVar;
ASTExprCall exprCall;
ASTStmtExtAlign stmtExtAlign;
ASTExprStringLiteral exprStrLit;
ASTExprCast exprCast;
ASTExprArray exprArray;
2024-11-26 18:42:20 +02:00
ASTExprFunc exprFunc;
2025-02-27 20:10:02 +02:00
ASTExprDot exprDot;
ASTExprExtSalloc exprExtSalloc;
2023-08-27 19:48:06 +03:00
ASTStmtExtOrg stmtExtOrg;
ASTStmtExtSection stmtExtSection;
ASTExprExtSizeOf exprExtSizeOf;
2023-08-27 19:48:06 +03:00
} AST;
2024-02-13 21:33:49 +02:00
#pragma pack(pop)
2025-05-03 09:59:30 +03:00
typedef void(*GenericVisitorHandler)(AST**, AST*, AST*, AST*, AST*, void*);
void generic_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *tlc, void *ud, GenericVisitorHandler preHandler, GenericVisitorHandler postHandler);
2024-12-14 18:13:33 +02:00
2023-08-27 19:48:06 +03:00
int ast_expression_equal(AST*, AST*);
int ast_stmt_is_after(const AST *chunk, const AST *s1, const AST *s2);
2024-11-20 16:36:17 +02:00
void ast_usedef_reset(AST *chu);
char *ast_dump(AST *tlc);
AST *ast_deep_copy(AST*);
2025-02-27 20:10:02 +02:00
AST *ast_cast_expr(AST *what, Type *to);
void ast_spill_to_stack(AST *tlc, ScopeItem *vte);
2025-02-27 20:10:02 +02:00
2025-05-03 09:59:30 +03:00
void ast_typecheck(AST *tlc);
void ast_grow_stack_frame(AST *tlc, size_t bytes);
2024-12-14 18:13:33 +02:00
__attribute__((format(printf, 1, 2))) char *malp(const char *fmt, ...);
2023-08-27 19:48:06 +03:00
#endif