New approach, new lexer
This commit is contained in:
455
ast.c
455
ast.c
@@ -81,6 +81,19 @@ decl_list_push(Decl *parent, Decl *child){
|
||||
SLLQueuePush(parent->list.first, parent->list.last, child);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Ops
|
||||
//-----------------------------------------------------------------------------
|
||||
function Decl *
|
||||
decl_struct_find_node(Decl *decl, String string){
|
||||
for(Decl *n = decl->struct_decl.first; n; n=n->next){
|
||||
if(string_compare(string, n->name.s)){
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Notes
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -172,4 +185,444 @@ typespec_function(Parser *p, Token *pos, Typespec *ret){
|
||||
function void
|
||||
typespec_function_push(Typespec *func, Typespec *arg){
|
||||
SLLQueuePush(func->function_spec.first, func->function_spec.last, arg);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
function Typespec *
|
||||
typespec_get_func(Typespec *type){
|
||||
switch(type->kind){
|
||||
case TS_Name:{return 0;} break;
|
||||
case TS_Pointer:{return typespec_get_func(type->base);} break;
|
||||
case TS_Array:{return typespec_get_func(type->array_spec.base);} break;
|
||||
case TS_Function:{return type;} break;
|
||||
default: {invalid_codepath;} break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function Typespec *
|
||||
typespec_get_name(Typespec *type){
|
||||
switch(type->kind){
|
||||
case TS_Name:{return type;} break;
|
||||
case TS_Pointer:{return typespec_get_name(type->base);} break;
|
||||
case TS_Array:{return typespec_get_name(type->array_spec.base);} break;
|
||||
case TS_Function:{return 0;} break;
|
||||
default: {invalid_codepath;} break;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function String
|
||||
typespec_require_name_string(Typespec *type){
|
||||
Typespec *result = typespec_get_name(type);
|
||||
if(result){
|
||||
if(result->kind == TS_Name){
|
||||
return result->name.s;
|
||||
}
|
||||
}
|
||||
invalid_codepath;
|
||||
return string_empty;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Statements
|
||||
//-----------------------------------------------------------------------------
|
||||
function Stmt *
|
||||
stmt_new(Parser *p, Stmt_Kind kind, Token *pos){
|
||||
Stmt *result = arena_push_struct(&p->main_arena, Stmt);
|
||||
result->kind = kind;
|
||||
result->pos = pos;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Stmt *
|
||||
stmt_decl(Parser *p, Token *pos, Decl *decl){
|
||||
Stmt *result = stmt_new(p, STMT_Decl, pos);
|
||||
result->decl = decl;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Stmt *
|
||||
stmt_expr(Parser *p, Token *pos, Expr *expr){
|
||||
Stmt *result = stmt_new(p, STMT_Expr, pos);
|
||||
result->expr = expr;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Stmt *
|
||||
stmt_list(Parser *p, Token *pos){
|
||||
Stmt *result = stmt_new(p, STMT_List, pos);
|
||||
return result;
|
||||
}
|
||||
|
||||
function Stmt *
|
||||
stmt_return(Parser *p, Token *pos, Expr *expr){
|
||||
Stmt *result = stmt_new(p, STMT_Return, pos);
|
||||
result->ret.expr = expr;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Stmt *
|
||||
stmt_if(Parser *p, Token *pos, Stmt *body, Expr *cond){
|
||||
Stmt *result = stmt_new(p, STMT_If, pos);
|
||||
result->stmt_if.cond = cond;
|
||||
result->stmt_if.body = body;
|
||||
return result;
|
||||
}
|
||||
|
||||
function void
|
||||
stmt_push(Stmt *stmt, Stmt *child){
|
||||
SLLQueuePush(stmt->list.first, stmt->list.last, child);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pointer Array
|
||||
//-----------------------------------------------------------------------------
|
||||
function Pointer_Array
|
||||
pointer_array_make(Arena *arena){
|
||||
Pointer_Array result = {
|
||||
.last = &result.first,
|
||||
.arena = arena,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
#define bucket_size (buff_cap(array->first.data))
|
||||
function void
|
||||
pointer_array_push(Pointer_Array *array, Pointer p){
|
||||
if(array->len >= bucket_size){
|
||||
Pointer_Bucket *bucket = arena_push_struct(array->arena, Pointer_Bucket);
|
||||
array->last = array->last->next = bucket;
|
||||
array->len = 0;
|
||||
array->block += 1;
|
||||
}
|
||||
array->last->data[array->len++] = p;
|
||||
}
|
||||
|
||||
function B32
|
||||
pointer_array_iter_is_end(Pointer_Array *array){
|
||||
B32 result = array->iter_len == array->len && array->iter_block == array->block;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Pointer
|
||||
pointer_array_iter_next(Pointer_Array *array){
|
||||
if(pointer_array_iter_is_end(array)){
|
||||
return (Pointer){0};
|
||||
}
|
||||
if(array->iter_len >= bucket_size){
|
||||
array->iter_len = 0;
|
||||
array->iter_block += 1;
|
||||
array->iter_bucket = array->iter_bucket->next;
|
||||
}
|
||||
Pointer result = array->iter_bucket->data[array->iter_len++];
|
||||
return result;
|
||||
}
|
||||
|
||||
function Pointer
|
||||
pointer_array_iter_begin(Pointer_Array *array){
|
||||
array->iter_len = 0;
|
||||
array->iter_block = 0;
|
||||
array->iter_bucket = &array->first;
|
||||
Pointer result = pointer_array_iter_next(array);
|
||||
return result;
|
||||
}
|
||||
|
||||
function Pointer
|
||||
pointer_typespec(Typespec *t){
|
||||
return (Pointer){.kind = PK_Typespec, .typespec = t};
|
||||
}
|
||||
function Pointer
|
||||
pointer_expr(Expr *t){
|
||||
return (Pointer){.kind = PK_Expr, .expr = t};
|
||||
}
|
||||
function Pointer
|
||||
pointer_decl(Decl *t){
|
||||
return (Pointer){.kind = PK_Decl, .decl = t};
|
||||
}
|
||||
function Pointer
|
||||
pointer_stmt(Stmt *t){
|
||||
return (Pointer){.kind = PK_Stmt, .stmt = t};
|
||||
}
|
||||
function Pointer
|
||||
pointer_enum_child(Decl_Enum_Child *t){
|
||||
return (Pointer){.kind = PK_Enum_Child, .enum_child = t};
|
||||
}
|
||||
function Pointer
|
||||
pointer_func_arg(Decl_Function_Arg *t){
|
||||
return (Pointer){.kind = PK_Func_Arg, .func_arg=t};
|
||||
}
|
||||
|
||||
function void
|
||||
pointer_array_push_typespec(Pointer_Array *array, Typespec *typespec){
|
||||
pointer_array_push(array, pointer_typespec(typespec));
|
||||
}
|
||||
function void
|
||||
pointer_array_push_decl(Pointer_Array *array, Decl *decl){
|
||||
pointer_array_push(array, pointer_decl(decl));
|
||||
}
|
||||
function void
|
||||
pointer_array_push_stmt(Pointer_Array *array, Stmt *stmt){
|
||||
pointer_array_push(array, pointer_stmt(stmt));
|
||||
}
|
||||
function void
|
||||
pointer_array_push_expr(Pointer_Array *array, Expr *expr){
|
||||
pointer_array_push(array, pointer_expr(expr));
|
||||
}
|
||||
function void
|
||||
pointer_array_push_enum_child(Pointer_Array *array, Decl_Enum_Child *enum_child){
|
||||
pointer_array_push(array, pointer_enum_child(enum_child));
|
||||
}
|
||||
function void
|
||||
pointer_array_push_func_arg(Pointer_Array *array, Decl_Function_Arg *func_arg){
|
||||
pointer_array_push(array, pointer_func_arg(func_arg));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gather
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function void
|
||||
gather_try_recurse_typespec(Pointer_Array *array, Typespec *typespec, Gather_Flag gflag, Traversal_Flag tflag);
|
||||
function void
|
||||
gather_recurse_expr(Pointer_Array *array, Expr *expr, Gather_Flag gflag, Traversal_Flag tflag){
|
||||
if(gflag & GATHER_Expr)
|
||||
pointer_array_push_expr(array, expr);
|
||||
|
||||
switch(expr->kind) {
|
||||
case EK_Atom: {} break;
|
||||
case EK_Sizeof:{
|
||||
if(expr->size_of.kind == SIZEOF_Expr){
|
||||
gather_recurse_expr(array, expr->size_of.expr, gflag, tflag);
|
||||
}
|
||||
else{
|
||||
assert(expr->size_of.kind == SIZEOF_Type);
|
||||
gather_try_recurse_typespec(array, expr->size_of.type, gflag, tflag);
|
||||
}
|
||||
}break;
|
||||
|
||||
case EK_Binary:{
|
||||
gather_recurse_expr(array, expr->binary.left, gflag, tflag);
|
||||
gather_recurse_expr(array, expr->binary.right, gflag, tflag);
|
||||
} break;
|
||||
case EK_Unary:{
|
||||
gather_recurse_expr(array, expr->unary.expr, gflag, tflag);
|
||||
} break;
|
||||
|
||||
case EK_Ternary:{
|
||||
gather_recurse_expr(array, expr->ternary.cond, gflag, tflag);
|
||||
gather_recurse_expr(array, expr->ternary.on_true, gflag, tflag);
|
||||
gather_recurse_expr(array, expr->ternary.on_false, gflag, tflag);
|
||||
} break;
|
||||
case EK_List:{
|
||||
for(Expr *n = expr->list.first; n; n=n->next){
|
||||
gather_recurse_expr(array, n, gflag, tflag);
|
||||
}
|
||||
}break;
|
||||
|
||||
case EK_Cast:{
|
||||
gather_try_recurse_typespec(array, expr->cast.type, gflag, tflag);
|
||||
gather_recurse_expr(array, expr->cast.expr, gflag, tflag);
|
||||
} break;
|
||||
|
||||
case EK_Index:{
|
||||
gather_recurse_expr(array, expr->index.atom, gflag, tflag);
|
||||
gather_recurse_expr(array, expr->index.index, gflag, tflag);
|
||||
}break;
|
||||
|
||||
case EK_Call:{
|
||||
gather_recurse_expr(array, expr->call.atom, gflag, tflag);
|
||||
gather_recurse_expr(array, expr->call.list, gflag, tflag);
|
||||
}break;
|
||||
default: {invalid_codepath;} break;
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
gather_try_recurse_expr(Pointer_Array *array, Expr *expr, Gather_Flag gflag, Traversal_Flag tflag){
|
||||
if(expr){
|
||||
if(tflag & TRAVERS_Expr){
|
||||
gather_recurse_expr(array, expr, gflag, tflag);
|
||||
}
|
||||
else if(gflag & GATHER_Expr){
|
||||
pointer_array_push_expr(array, expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
gather_recurse_decl(Pointer_Array *array, Decl *decl, Gather_Flag gflag, Traversal_Flag tflag);
|
||||
function void
|
||||
gather_try_recurse_stmt(Pointer_Array *array, Stmt *stmt, Gather_Flag gflag, Traversal_Flag tflag);
|
||||
function void
|
||||
gather_recurse_stmt(Pointer_Array *array, Stmt *stmt, Gather_Flag gflag, Traversal_Flag tflag){
|
||||
switch(stmt->kind) {
|
||||
case STMT_List: {
|
||||
for(Stmt *s = stmt->list.first; s; s=s->next){
|
||||
gather_recurse_stmt(array, s, gflag, tflag);
|
||||
}
|
||||
} break;
|
||||
case STMT_Return:{
|
||||
gather_try_recurse_expr(array, stmt->ret.expr, gflag, tflag);
|
||||
} break;
|
||||
case STMT_If:{
|
||||
gather_recurse_expr(array, stmt->stmt_if.cond, gflag, tflag);
|
||||
gather_recurse_stmt(array, stmt->stmt_if.body, gflag, tflag);
|
||||
for(Stmt_If *s = stmt->stmt_if.next; s; s=s->next){
|
||||
gather_recurse_stmt(array, s->body, gflag, tflag);
|
||||
gather_recurse_expr(array, s->cond, gflag, tflag);
|
||||
}
|
||||
} break;
|
||||
case STMT_Expr: {
|
||||
gather_recurse_expr(array, stmt->expr, gflag, tflag);
|
||||
} break;
|
||||
case STMT_Decl: {
|
||||
gather_recurse_decl(array, stmt->decl, gflag, tflag);
|
||||
} break;
|
||||
default: {invalid_codepath;} break;
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
gather_try_recurse_stmt(Pointer_Array *array, Stmt *stmt, Gather_Flag gflag, Traversal_Flag tflag){
|
||||
if(stmt){
|
||||
if(tflag & TRAVERS_Stmt){
|
||||
gather_recurse_stmt(array, stmt, gflag, tflag);
|
||||
}
|
||||
else if(gflag & GATHER_Stmt){
|
||||
pointer_array_push_stmt(array, stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
gather_recurse_typespec(Pointer_Array *array, Typespec *typespec, Gather_Flag gflag, Traversal_Flag tflag){
|
||||
if(gflag & GATHER_Typespec)
|
||||
pointer_array_push_typespec(array, typespec);
|
||||
switch(typespec->kind) {
|
||||
case TS_Name: {
|
||||
} break;
|
||||
case TS_Pointer: {
|
||||
gather_recurse_typespec(array, typespec->base, gflag, tflag);
|
||||
} break;
|
||||
case TS_Array: {
|
||||
gather_recurse_typespec(array, typespec->array_spec.base, gflag, tflag);
|
||||
gather_try_recurse_expr(array, typespec->array_spec.size, gflag, tflag);
|
||||
} break;
|
||||
case TS_Function: {
|
||||
gather_recurse_typespec(array, typespec->function_spec.ret, gflag, tflag);
|
||||
for(Typespec *n = typespec->function_spec.first; n; n=n->next){
|
||||
gather_recurse_typespec(array, n, gflag, tflag);
|
||||
}
|
||||
} break;
|
||||
default: {invalid_codepath;} break;
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
gather_try_recurse_typespec(Pointer_Array *array, Typespec *typespec, Gather_Flag gflag, Traversal_Flag tflag){
|
||||
if(typespec){
|
||||
if(tflag & TRAVERS_Typespec){
|
||||
gather_recurse_typespec(array, typespec, gflag, tflag);
|
||||
}
|
||||
else if(gflag & GATHER_Typespec){
|
||||
pointer_array_push_typespec(array, typespec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
gather_recurse_decl(Pointer_Array *array, Decl *decl, Gather_Flag gflag, Traversal_Flag tflag){
|
||||
if(gflag & GATHER_Decl) pointer_array_push_decl(array, decl);
|
||||
|
||||
switch(decl->kind){
|
||||
case DECL_Struct:
|
||||
case DECL_Union:{
|
||||
for(Decl *n = decl->struct_decl.first; n; n=n->next){
|
||||
gather_recurse_decl(array, n, gflag, tflag);
|
||||
}
|
||||
} break;
|
||||
case DECL_Enum:{
|
||||
gather_try_recurse_typespec(array, decl->enum_decl.typespec, gflag, tflag);
|
||||
for(Decl_Enum_Child *child = decl->enum_decl.first; child; child=child->next){
|
||||
if(gflag & GATHER_Enum_Child) pointer_array_push_enum_child(array, child);
|
||||
gather_try_recurse_expr(array, child->expr, gflag, tflag);
|
||||
}
|
||||
}break;
|
||||
case DECL_Variable:{
|
||||
gather_try_recurse_typespec(array, decl->variable_decl.type, gflag, tflag);
|
||||
gather_try_recurse_expr(array, decl->variable_decl.expr, gflag, tflag);
|
||||
}break;
|
||||
case DECL_Typedef:{
|
||||
gather_try_recurse_typespec(array, decl->typedef_decl.type, gflag, tflag);
|
||||
}break;
|
||||
case DECL_Function:{
|
||||
gather_try_recurse_typespec(array, decl->function_decl.ret, gflag, tflag);
|
||||
for(Decl_Function_Arg *arg = decl->function_decl.first; arg; arg=arg->next){
|
||||
if(gflag & GATHER_Func_Arg) pointer_array_push_func_arg(array, arg);
|
||||
gather_try_recurse_typespec(array, arg->typespec, gflag, tflag);
|
||||
}
|
||||
gather_try_recurse_stmt(array, decl->function_decl.body, gflag, tflag);
|
||||
}break;
|
||||
case DECL_List:{
|
||||
for(Decl *n = decl->list.first; n; n=n->next){
|
||||
gather_recurse_decl(array, n, gflag, tflag);
|
||||
}
|
||||
}break;
|
||||
default:invalid_codepath;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function Pointer_Array
|
||||
gather(Arena *arena, Decl *decl, Gather_Flag gflag, Traversal_Flag tflag){
|
||||
Pointer_Array array = pointer_array_make(arena);
|
||||
gather_recurse_decl(&array, decl, gflag, tflag);
|
||||
return array;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function Decl *
|
||||
decl_deep_copy_recurse(Arena *arena, Decl *decl){
|
||||
Decl *result = arena_push_struct(arena, Decl);
|
||||
memory_copy(result, decl, sizeof(*decl));
|
||||
switch(decl->kind) {
|
||||
case DECL_Struct:{
|
||||
|
||||
}break;
|
||||
case DECL_Union:{
|
||||
|
||||
}break;
|
||||
case DECL_Enum:{
|
||||
|
||||
}break;
|
||||
case DECL_Variable:{
|
||||
|
||||
}break;
|
||||
case DECL_Typedef:{
|
||||
|
||||
}break;
|
||||
case DECL_Function:{
|
||||
|
||||
}break;
|
||||
case DECL_List:{
|
||||
|
||||
}break;
|
||||
default: {invalid_codepath;} break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function Decl *
|
||||
decl_deep_copy(Arena *arena){
|
||||
Decl *result = decl_deep_copy_recurse(arena, decl);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user