Files
corelang/ast.c
Krzosa Karol 557dde1936 C codegen
2022-05-03 20:08:13 +02:00

175 lines
5.1 KiB
C

//-----------------------------------------------------------------------------
// Decls
//-----------------------------------------------------------------------------
function Decl *
decl_new(Parser *p, Decl_Kind kind, Token *pos, Intern_String name){
Decl *result = arena_push_struct(&p->main_arena, Decl);
result->kind = kind;
result->pos = pos;
result->name = name;
return result;
}
function Decl *
decl_struct(Parser *p, Decl_Kind kind, Token *pos, Intern_String name, Decl_Struct_Kind struct_kind){
assert(kind == DECL_Struct || kind == DECL_Union);
Decl *result = decl_new(p, kind, pos, name);
result->struct_decl.kind = struct_kind;
return result;
}
function Decl *
decl_typedef(Parser *p, Token *pos, Intern_String name, Typespec *type){
Decl *result = decl_new(p, DECL_Typedef, pos, name);
result->typedef_decl.type = type;
return result;
}
function Decl *
decl_enum(Parser *p, Token *pos, Intern_String name, Typespec *typespec){
Decl *result = decl_new(p, DECL_Enum, pos, name);
result->enum_decl.typespec = typespec;
return result;
}
function Decl *
decl_variable(Parser *p, Token *pos, Intern_String name, Typespec *typespec, Expr *expr){
Decl *result = decl_new(p, DECL_Variable, pos, name);
result->variable_decl.type = typespec;
result->variable_decl.expr = expr;
return result;
}
function Decl *
decl_function(Parser *p, Token *pos, Intern_String name, Typespec *ret){
Decl *result = decl_new(p, DECL_Function, pos, name);
result->function_decl.ret = ret;
return result;
}
function void
decl_function_push(Parser *p, Decl *parent, Token *pos, Intern_String name, Typespec *type){
assert(parent->kind == DECL_Function);
Decl_Function_Arg *result = arena_push_struct(&p->main_arena, Decl_Function_Arg);
result->name = name;
result->typespec = type;
result->pos = pos;
SLLQueuePush(parent->function_decl.first, parent->function_decl.last, result);
}
function void
decl_enum_push(Parser *p, Decl *parent, Token *pos, Intern_String name, Expr *expr, Note *notes){
assert(parent->kind == DECL_Enum);
Decl_Enum_Child *child = arena_push_struct(&p->main_arena, Decl_Enum_Child);
child->pos = pos;
child->name = name;
child->expr = expr;
child->first_note = notes->first;
child->last_note = notes->last;
SLLQueuePush(parent->enum_decl.first, parent->enum_decl.last, child);
}
function void
decl_struct_push(Decl *parent, Decl *child){
assert(parent->kind == DECL_Struct || parent->kind == DECL_Union);
SLLQueuePush(parent->struct_decl.first, parent->struct_decl.last, child);
}
function void
decl_list_push(Decl *parent, Decl *child){
assert(parent->kind == DECL_List);
SLLQueuePush(parent->list.first, parent->list.last, child);
}
//-----------------------------------------------------------------------------
// Notes
//-----------------------------------------------------------------------------
function void
decl_pass_notes(Decl *a, Note *b){
a->first_note = b->first;
a->last_note = b->last;
}
function Note *
note_push_new(Parser *p, Note *parent, Token *pos, Intern_String name, Expr *expr){
Note *result = arena_push_struct(&p->main_arena, Note);
result->pos = pos;
result->name = name;
result->expr = expr;
SLLQueuePush(parent->first, parent->last, result);
return result;
}
function Note *
find_note(Note *first, String string){
for(Note *n = first; n; n=n->next){
if(string_compare(string, n->name.s)){
return n;
}
}
return 0;
}
function String
find_string_note(Note *first, String string, String default_string){
Note *note = find_note(first, string);
if(note){
return note->expr->token->intern_val.s;
}
return default_string;
}
function Note *
decl_find_note(Decl *decl, String string){
return find_note(decl->first_note, string);
}
function String
decl_find_string_note(Decl *decl, String string, String default_string){
return find_string_note(decl->first_note, string, default_string);
}
//-----------------------------------------------------------------------------
// Typespec
//-----------------------------------------------------------------------------
function Typespec *
typespec_new(Parser *p, Typespec_Kind kind, Token *pos){
Typespec *result = arena_push_struct(&p->main_arena, Typespec);
result->kind = kind;
result->pos = pos;
return result;
}
function Typespec *
typespec_name(Parser *p, Token *pos, Intern_String name){
Typespec *result = typespec_new(p, TS_Name, pos);
result->name = name;
return result;
}
function Typespec *
typespec_pointer(Parser *p, Token *pos, Typespec *base){
Typespec *result = typespec_new(p, TS_Pointer, pos);
result->base = base;
return result;
}
function Typespec *
typespec_array(Parser *p, Token *pos, Typespec *base, Expr *size){
Typespec *result = typespec_new(p, TS_Array, pos);
result->array_spec.base = base;
result->array_spec.size = size;
return result;
}
function Typespec *
typespec_function(Parser *p, Token *pos, Typespec *ret){
Typespec *result = typespec_new(p, TS_Function, pos);
result->function_spec.ret = ret;
return result;
}
function void
typespec_function_push(Typespec *func, Typespec *arg){
SLLQueuePush(func->function_spec.first, func->function_spec.last, arg);
}