244 lines
5.0 KiB
C
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);
|
|
}
|