295 lines
6.1 KiB
C
295 lines
6.1 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_Unary,
|
|
EK_Binary,
|
|
EK_Ternary,
|
|
EK_Cast,
|
|
EK_List,
|
|
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 {
|
|
Typespec *type;
|
|
Expr* expr;
|
|
} cast;
|
|
struct {
|
|
Expr *first;
|
|
Expr *last;
|
|
} list;
|
|
struct {
|
|
Expr *atom;
|
|
Expr *list;
|
|
} call;
|
|
struct {
|
|
Expr *atom;
|
|
Expr *index;
|
|
} index;
|
|
struct {
|
|
Token_Kind op;
|
|
Expr* expr;
|
|
} 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_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 *list){
|
|
Expr *expr = expr_new(p, EK_Call, token);
|
|
expr->call.atom = atom;
|
|
expr->call.list = list;
|
|
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 Expr *
|
|
expr_list(Arena *p, Token *token){
|
|
Expr *expr = expr_new(p, EK_List, token);
|
|
return expr;
|
|
}
|
|
|
|
function void
|
|
expr_list_push(Expr *list, Expr *expr){
|
|
SLLQueuePush(list->list.first, list->list.last, expr);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
function void
|
|
token_print(Token *token){
|
|
printf("%.*s", (S32)token->len, token->str);
|
|
}
|
|
|
|
function void
|
|
expr_print(Expr *expr){
|
|
switch(expr->kind) {
|
|
case EK_Int:
|
|
case EK_String: {
|
|
token_print(expr->token);
|
|
} break;
|
|
|
|
case EK_Sizeof:{
|
|
printf("sizeof(");
|
|
if(expr->size_of.kind == SIZEOF_Expr){
|
|
expr_print(expr->size_of.expr);
|
|
}
|
|
else{
|
|
assert(expr->size_of.kind == SIZEOF_Type);
|
|
//print_typespec(expr->size_of.type);
|
|
}
|
|
printf(")");
|
|
}break;
|
|
|
|
case EK_Binary:{
|
|
printf("(");
|
|
expr_print(expr->binary.left);
|
|
token_print(expr->token);
|
|
expr_print(expr->binary.right);
|
|
printf(")");
|
|
} break;
|
|
case EK_Unary:{
|
|
printf("(");
|
|
token_print(expr->token);
|
|
expr_print(expr->unary.expr);
|
|
printf(")");
|
|
} break;
|
|
|
|
case EK_Ternary:{
|
|
printf("(");
|
|
expr_print(expr->ternary.cond);
|
|
printf("?");
|
|
expr_print(expr->ternary.on_true);
|
|
printf(":");
|
|
expr_print(expr->ternary.on_false);
|
|
printf(")");
|
|
} break;
|
|
case EK_List:{
|
|
printf("(");
|
|
for(Expr *n = expr->list.first; n; n=n->next){
|
|
expr_print(n);
|
|
if(n!=expr->list.last) printf(",");
|
|
}
|
|
printf(")");
|
|
}break;
|
|
|
|
case EK_Cast:{
|
|
printf("(");
|
|
printf("(");
|
|
//print_typespec(expr->cast.type);
|
|
printf(")");
|
|
expr_print(expr->cast.expr);
|
|
printf(")");
|
|
} break;
|
|
|
|
case EK_Index:{
|
|
expr_print(expr->index.atom);
|
|
printf("[");
|
|
expr_print(expr->index.index);
|
|
printf("]");
|
|
}break;
|
|
|
|
case EK_Call:{
|
|
expr_print(expr->call.atom);
|
|
printf("(");
|
|
expr_print(expr->call.list);
|
|
printf(")");
|
|
}break;
|
|
default: {invalid_codepath;} break;
|
|
}
|
|
}
|
|
|
|
function void
|
|
test_ast(){
|
|
|
|
} |