New approach, new lexer
This commit is contained in:
295
new_ast.c
Normal file
295
new_ast.c
Normal file
@@ -0,0 +1,295 @@
|
||||
|
||||
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(){
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user