//----------------------------------------------------------------------------- // 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); }