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){ assert(kind == DECL_Struct || kind == DECL_Union); Decl *result = decl_new(p, kind, pos, name); 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 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); } 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 void decl_pass_notes(Decl *a, Note *b){ a->first_note = b->first; a->last_note = b->last; } 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_struct(Parser *p, Token *pos, Decl *aggregate){ Typespec *result = typespec_new(p, TS_Struct, pos); result->struct_spec = aggregate; 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); }