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_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_name(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_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(){ }