Decl *new_decl_note(SrcPos pos, Note note) { Decl *d = new_decl(DECL_NOTE, pos, null); d->note = note; return(d); }
Stmt *new_stmt_decl(SrcPos pos, Decl *decl) { var s = new_stmt(STMT_DECL, pos); s->decl = decl; return(s); }
Decl *new_decl_aggregate(SrcPos pos, DeclKind kind, char *name, Aggregate *aggregate) { assert(kind == DECL_STRUCT || kind == DECL_UNION); Decl *d = new_decl(kind, pos, name); d->aggregate = aggregate; return(d); }
void print_aggregate_decl(Decl *decl) { // var d = decl; // for (var it = d->aggregate.items; it != d->aggregate.items + d->aggregate.num_items; it++) // { // print_newline(); // printf("("); // for (var name = it->names; name != it->names + it->num_names; name++) printf("{0} ", *name); // print_typespec(it->type); // printf(")"); // } }
Decl *new_decl_import(SrcPos pos, char *rename_name, bool is_relative, char **names, int num_names, bool import_all, ImportItem *items, int num_items) { Decl *d = new_decl(DECL_IMPORT, pos, null); d->name = rename_name; d->import.is_relative = is_relative; d->import.names = names; d->import.num_names = num_names; d->import.import_all = import_all; d->import.items = items; d->import.num_items = num_items; return(d); }
Note *get_decl_note(Decl *decl, char *name) { if (decl == null) { return(null); } for (int i = 0; i < decl->notes.num_notes; i++) { Note *note = decl->notes.notes + i; if (note->name == name) { return(note); } } return(null); }
Decl *parse_decl_aggregate(SrcPos pos, DeclKind kind) { assert(kind == DECL_STRUCT || kind == DECL_UNION); var name = parse_name(); AggregateKind aggregate_kind = kind == DECL_STRUCT ? AGGREGATE_STRUCT : AGGREGATE_UNION; if (match_token(TOKEN_SEMICOLON)) { Decl *decl = new_decl_aggregate(pos, kind, name, new_aggregate(pos, aggregate_kind, null, 0)); decl->is_incomplete = true; return(decl); } else { return(new_decl_aggregate(pos, kind, name, parse_aggregate(aggregate_kind))); } }
bool is_decl_foreign(Decl *decl) { return(decl != null && get_decl_note(decl, foreign_name) != null); }
bool is_decl_threadlocal(Decl *decl) { return(decl != null && get_decl_note(decl, _I("threadlocal")) != null); }
void print_decl(Decl *decl) { var d = decl; switch (d->kind) { case DECL_ENUM: printf("(enum {0}", d->name); _indent++; for (var it = d->enum_decl.items; it != d->enum_decl.items + d->enum_decl.num_items; it++) { print_newline(); printf("({0} ", it->name); if (it->init != null) { print_expr(it->init); } else { printf("nil"); } printf(")"); } _indent--; printf(")"); break; case DECL_STRUCT: printf("(struct {0}", d->name); _indent++; print_aggregate_decl(d); _indent--; printf(")"); break; case DECL_UNION: printf("(union {0}", d->name); _indent++; print_aggregate_decl(d); _indent--; printf(")"); break; case DECL_VAR: printf("(var {0} ", d->name); if (d->var.type != null) { print_typespec(d->var.type); } else { printf("nil"); } printf(" "); if (d->var.expr != null) { print_expr(d->var.expr); } else { printf("nil"); } printf(")"); break; case DECL_CONST: printf("(const {0} ", d->name); print_expr(d->const_decl.expr); printf(")"); break; case DECL_TYPEDEF: printf("(typedef {0} ", d->name); print_typespec(d->typedef_decl.type); printf(")"); break; case DECL_FUNC: printf("(func {0} ", d->name); printf("("); for (var it = d->func.@params; it != d->func.@params + d->func.num_params; it++) { printf(" {0} ", it->name); print_typespec(it->type); } printf(" ) "); if (d->func.ret_type != null) { print_typespec(d->func.ret_type); } else { printf("nil"); } _indent++; print_newline(); print_stmt_block(d->func.block); _indent--; printf(")"); break; default: assert(false); break; } }