Files
corelang/new_ast.c
2022-05-06 12:52:33 +02:00

244 lines
5.0 KiB
C

typedef struct Expr Expr;
typedef struct Typespec Typespec;
typedef enum Typespec_Kind{
TS_None,
TS_Name,
TS_Pointer,
TS_Array,
TS_Function,
}Typespec_Kind;
struct Typespec{
Typespec_Kind kind;
Typespec *next;
Token *pos;
union{
Intern_String name;
Typespec *base;
struct{
Typespec *first;
Typespec *last;
Typespec *ret;
}func;
struct{
Typespec *base;
Expr *size;
}arr;
};
};
//-----------------------------------------------------------------------------
// Expressions
//-----------------------------------------------------------------------------
typedef enum Expr_Sizeof_Kind{
SIZEOF_Expr,
SIZEOF_Type,
}Expr_Sizeof_Kind;
typedef enum Expr_Kind{
EK_None,
EK_Int,
EK_String,
EK_Identifier,
EK_Paren,
EK_PostfixUnary,
EK_Unary,
EK_Binary,
EK_Ternary,
EK_Cast,
EK_Field,
EK_Call,
EK_Index,
EK_Sizeof,
} Expr_Kind;
struct Expr {
Expr_Kind kind;
Token *token;
Expr *next;
union {
U64 int_val;
Intern_String intern_val;
double float_val;
struct {
Expr *expr;
} paren;
struct {
Typespec *type;
Expr* expr;
} cast;
struct{
Intern_String name;
Expr *expr;
}field;
struct {
Expr *atom;
Expr *first;
Expr *last;
} call;
struct {
Expr *atom;
Expr *index;
} index;
struct {
Token_Kind op;
Expr* expr;
} unary;
struct {
Token_Kind op;
Expr *expr;
} postfix_unary;
struct {
Token_Kind op;
Expr* left;
Expr* right;
} binary;
struct {
Expr* cond;
Expr* on_true;
Expr* on_false;
} ternary;
struct{
Expr_Sizeof_Kind kind;
union{
Typespec *type;
Expr *expr;
};
} size_of;
};
};
//-----------------------------------------------------------------------------
// Expr
//-----------------------------------------------------------------------------
function Expr *
expr_new(Arena *p, Expr_Kind kind, Token *token){
Expr *expr = arena_push_struct(p, Expr);
expr->kind = kind;
expr->token = token;
return expr;
}
function Expr *
expr_int(Arena *p, Token *token){
assert(token->kind == TK_Int);
Expr *expr = expr_new(p, EK_Int, token);
expr->int_val = token->int_val;
return expr;
}
function Expr *
expr_str(Arena *p, Token *token){
assert(token->kind == TK_StringLit);
Expr *expr = expr_new(p, EK_String, token);
expr->intern_val = token->intern_val;
return expr;
}
function Expr *
expr_identifier(Arena *p, Token *token){
assert(token->kind == TK_Identifier);
Expr *expr = expr_new(p, EK_Identifier, token);
expr->intern_val = token->intern_val;
return expr;
}
function Expr *
expr_field(Arena *p, Token *token, Expr *inexpr){
assert(token->kind == TK_Identifier);
Expr *expr = expr_new(p, EK_Field, token);
expr->field.expr = inexpr;
expr->field.name = token->intern_val;
return expr;
}
function Expr *
expr_paren(Arena *p, Token *token, Expr *inexpr){
Expr *expr = expr_new(p, EK_Paren, token);
expr->paren.expr = inexpr;
return expr;
}
function Expr *
expr_postfix_unary(Arena *p, Token *op, Expr *exp){
Expr *expr = expr_new(p, EK_PostfixUnary, op);
expr->unary.op = op->kind;
expr->unary.expr = exp;
return expr;
}
function Expr *
expr_unary(Arena *p, Token *op, Expr *exp){
Expr *expr = expr_new(p, EK_Unary, op);
expr->unary.op = op->kind;
expr->unary.expr = exp;
return expr;
}
function Expr *
expr_binary(Arena *p, Token *op, Expr *left, Expr *right){
Expr *expr = expr_new(p, EK_Binary, op);
expr->binary.op = op->kind;
expr->binary.left = left;
expr->binary.right = right;
return expr;
}
function Expr *
expr_ternary(Arena *p, Token *op, Expr *cond, Expr *on_true, Expr *on_false){
Expr *expr = expr_new(p, EK_Ternary, op);
expr->ternary.cond = cond;
expr->ternary.on_true = on_true;
expr->ternary.on_false = on_false;
return expr;
}
function Expr *
expr_call(Arena *p, Token *token, Expr *atom){
Expr *expr = expr_new(p, EK_Call, token);
expr->call.atom = atom;
return expr;
}
function Expr *
expr_index(Arena *p, Token *token, Expr *atom, Expr *index){
Expr *expr = expr_new(p, EK_Index, token);
expr->index.atom = atom;
expr->index.index = index;
return expr;
}
function Expr *
expr_cast(Arena *p, Token *token, Typespec *type, Expr *exp){
Expr *expr = expr_new(p, EK_Cast, token);
expr->cast.type = type;
expr->cast.expr = exp;
return expr;
}
function Expr *
expr_sizeof_type(Arena *p, Token *token, Typespec *type){
Expr *expr = expr_new(p, EK_Sizeof, token);
expr->size_of.kind = SIZEOF_Type;
expr->size_of.type = type;
return expr;
}
function Expr *
expr_sizeof_expr(Arena *p, Token *token, Expr *in_expr){
Expr *expr = expr_new(p, EK_Sizeof, token);
expr->size_of.kind = SIZEOF_Expr;
expr->size_of.expr = in_expr;
return expr;
}
function void
expr_call_push(Expr *list, Expr *expr){
SLLQueuePush(list->call.first, list->call.last, expr);
}