384 lines
6.3 KiB
C
384 lines
6.3 KiB
C
#ifndef NCTREF_AST_H
|
|
#define NCTREF_AST_H
|
|
|
|
#include"types.h"
|
|
#include"lexer.h"
|
|
#include"vartable.h"
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
#ifdef __GNUC__
|
|
#define ENUMPAK __attribute__((packed))
|
|
#else
|
|
#define ENUMPAK
|
|
#endif
|
|
|
|
#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) \
|
|
K(AST_EXPR_FUNC) \
|
|
K(AST_STMT_EXT_ORG) \
|
|
K(AST_STMT_EXT_SECTION) \
|
|
K(AST_STMT_RETURN) \
|
|
K(AST_EXPR_EXT_SALLOC) \
|
|
K(AST_EXPR_DOT) \
|
|
K(AST_EXPR_EXT_SIZEOF)
|
|
|
|
typedef enum ENUMPAK { AST_KINDS(GEN_ENUM) } ASTKind;
|
|
extern const char *AST_KIND_STR[];
|
|
|
|
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_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,
|
|
|
|
BINOP_WTF = 999,
|
|
} BinaryOp;
|
|
|
|
static inline int binop_is_comparison(BinaryOp op) {
|
|
return op == BINOP_EQUAL || op == BINOP_NEQUAL || op == BINOP_LESS || op == BINOP_GREATER || op == BINOP_LEQUAL || op == BINOP_GEQUAL;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
static inline BinaryOp binop_comp_opposite(BinaryOp op) {
|
|
if(op == BINOP_EQUAL) {
|
|
return BINOP_NEQUAL;
|
|
} else if(op == BINOP_NEQUAL) {
|
|
return BINOP_EQUAL;
|
|
} 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;
|
|
}
|
|
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;
|
|
uint16_t row;
|
|
uint16_t col;
|
|
} ASTBase;
|
|
|
|
typedef struct {
|
|
ASTBase;
|
|
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;
|
|
} ASTExprVar;
|
|
|
|
typedef struct {
|
|
ASTExpr;
|
|
|
|
union AST *what;
|
|
|
|
union AST **args;
|
|
} ASTExprCall;
|
|
|
|
typedef struct {
|
|
ASTExpr;
|
|
|
|
size_t length;
|
|
char *data;
|
|
} ASTExprStringLiteral;
|
|
|
|
typedef struct {
|
|
ASTExpr;
|
|
} ASTExprStackPointer;
|
|
|
|
typedef struct {
|
|
ASTExpr;
|
|
|
|
union AST *chunk;
|
|
|
|
// Necessary for when the parser jumps to a generic function
|
|
Scope *scope;
|
|
Token *rangeTokens;
|
|
size_t startTokI;
|
|
size_t endTokI;
|
|
} ASTExprFunc;
|
|
|
|
typedef struct {
|
|
ASTBase;
|
|
|
|
size_t size;
|
|
} ASTType;
|
|
|
|
typedef struct {
|
|
ASTType;
|
|
|
|
Token identifier;
|
|
} ASTTypeIdentifier;
|
|
|
|
typedef struct {
|
|
ASTType;
|
|
|
|
union AST *child;
|
|
int levels;
|
|
} ASTTypePointer;
|
|
|
|
typedef struct {
|
|
ASTBase;
|
|
union AST *next;
|
|
} ASTStmt;
|
|
|
|
typedef struct {
|
|
ASTStmt;
|
|
|
|
ScopeItem *thing;
|
|
|
|
union AST *expression;
|
|
} ASTStmtDecl;
|
|
|
|
typedef struct {
|
|
ASTBase;
|
|
|
|
/* Flattened variable array for global register allocation */
|
|
size_t varCount;
|
|
ScopeItem **vars;
|
|
|
|
/* extern symbol array */
|
|
size_t externCount;
|
|
ScopeItem **externs;
|
|
|
|
union AST *statementFirst;
|
|
union AST *statementLast;
|
|
|
|
size_t stackReservation;
|
|
|
|
/* NULL unless this is a top-level chunk belonging to a function */
|
|
Type *functionType;
|
|
} 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 {
|
|
ASTExpr;
|
|
|
|
Type *size;
|
|
} ASTExprExtSalloc;
|
|
|
|
typedef struct {
|
|
ASTExpr;
|
|
|
|
union AST *a;
|
|
const char *b;
|
|
} ASTExprDot;
|
|
|
|
typedef struct {
|
|
ASTStmt;
|
|
|
|
size_t val;
|
|
} ASTStmtExtOrg;
|
|
|
|
typedef struct {
|
|
ASTStmt;
|
|
|
|
Token name;
|
|
} ASTStmtExtSection;
|
|
|
|
typedef struct {
|
|
ASTStmt;
|
|
|
|
union AST *val;
|
|
} ASTStmtReturn;
|
|
|
|
typedef struct {
|
|
ASTExpr;
|
|
|
|
// One of these will be NULL
|
|
union AST *ofExpr;
|
|
Type *ofType;
|
|
} ASTExprExtSizeOf;
|
|
|
|
typedef union AST {
|
|
ASTBase;
|
|
|
|
ASTChunk chunk;
|
|
ASTStmt statement;
|
|
ASTStmtDecl stmtDecl;
|
|
ASTStmtIf stmtIf;
|
|
ASTStmtLoop stmtLoop;
|
|
ASTStmtBreak stmtBreak;
|
|
ASTStmtContinue stmtContinue;
|
|
ASTStmtExpr stmtExpr;
|
|
ASTStmtAssign stmtAssign;
|
|
ASTStmtReturn stmtReturn;
|
|
ASTExpr expression;
|
|
ASTExprPrimitive exprPrim;
|
|
ASTExprBinaryOp exprBinOp;
|
|
ASTExprUnaryOp exprUnOp;
|
|
ASTExprVar exprVar;
|
|
ASTExprCall exprCall;
|
|
ASTStmtExtAlign stmtExtAlign;
|
|
ASTExprStringLiteral exprStrLit;
|
|
ASTExprCast exprCast;
|
|
ASTExprArray exprArray;
|
|
ASTExprFunc exprFunc;
|
|
ASTExprDot exprDot;
|
|
ASTExprExtSalloc exprExtSalloc;
|
|
ASTStmtExtOrg stmtExtOrg;
|
|
ASTStmtExtSection stmtExtSection;
|
|
ASTExprExtSizeOf exprExtSizeOf;
|
|
} AST;
|
|
|
|
#pragma pack(pop)
|
|
|
|
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);
|
|
|
|
int ast_expression_equal(AST*, AST*);
|
|
|
|
int ast_stmt_is_after(const AST *chunk, const AST *s1, const AST *s2);
|
|
|
|
void ast_usedef_reset(AST *chu);
|
|
|
|
char *ast_dump(AST *tlc);
|
|
|
|
AST *ast_deep_copy(AST*);
|
|
|
|
AST *ast_cast_expr(AST *what, Type *to);
|
|
|
|
void ast_spill_to_stack(AST *tlc, ScopeItem *vte);
|
|
|
|
void ast_typecheck(AST *tlc);
|
|
|
|
void ast_grow_stack_frame(AST *tlc, size_t bytes);
|
|
|
|
__attribute__((format(printf, 1, 2))) char *malp(const char *fmt, ...);
|
|
|
|
#endif
|