New approach, new lexer

This commit is contained in:
Krzosa Karol
2022-05-06 10:13:16 +02:00
parent 557dde1936
commit e3b5e9b33a
33 changed files with 3331 additions and 784 deletions

455
ast.c
View File

@@ -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;
}