diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/actualize.c | 212 | ||||
| -rw-r--r-- | src/ast.c | 96 | ||||
| -rw-r--r-- | src/debug.c | 22 | ||||
| -rw-r--r-- | src/parser.y | 4 | ||||
| -rw-r--r-- | src/scope.c | 43 |
5 files changed, 323 insertions, 54 deletions
diff --git a/src/actualize.c b/src/actualize.c index 4d1d449..b25968f 100644 --- a/src/actualize.c +++ b/src/actualize.c @@ -337,6 +337,11 @@ static int analyze_file_visibility(struct scope *scope, struct ast_node *node) break; } + case AST_UNION: { + ret |= scope_add_type(scope, node); + break; + } + case AST_ENUM: { ret |= scope_add_type(scope, node); break; @@ -1251,6 +1256,11 @@ static int actualize_type(struct act_state *state, EXIT_ACT(-1); } + /* this could be more clear, maybe add into the parser some kind + * of meta class for templated types? */ + if (exists->node_type == AST_UNION) + type->_type.kind = AST_TYPE_UNION; + /* nothing to do, except maybe check that types are actually * identical? */ if (exists->node_type == AST_TYPE) @@ -1300,6 +1310,9 @@ static int actualize_type(struct act_state *state, type->_type.unio.impls = NULL; } + if (ast_flags(exists, AST_FLAG_GENERIC)) + ast_set_flags(type, AST_FLAG_GENERIC); + break; } @@ -1344,11 +1357,24 @@ static int actualize_type(struct act_state *state, break; } + case AST_TYPE_UNION: case AST_TYPE_STRUCT: { - struct ast_node *id = type->_type.struc.id; + assert(ast_flags(type, AST_FLAG_ACTUAL)); + break; + } + + case AST_TYPE_GENERIC: { + struct ast_node *id = type->_type.generic.id; struct ast_node *exists = file_scope_resolve_type(scope, id); - if (!exists || exists->node_type != AST_STRUCT) { - semantic_error(scope->fctx, type, "no such struct"); + if (!exists) { + semantic_error(scope->fctx, type, "no such type"); + EXIT_ACT(-1); + } + + if (exists->node_type != AST_UNION && + exists->node_type != AST_STRUCT) { + semantic_error(scope->fctx, type, + "type not struct or union"); EXIT_ACT(-1); } @@ -1356,7 +1382,7 @@ static int actualize_type(struct act_state *state, if (actualize(state, exists->scope, exists)) EXIT_ACT(-1); - struct ast_node *types = type->_type.struc.impls; + struct ast_node *types = type->_type.generic.args; if (actualize(state, scope, types)) EXIT_ACT(-1); @@ -1377,14 +1403,17 @@ static int actualize_type(struct act_state *state, types = types->next; } - break; - } + if (exists->node_type == AST_UNION) + type->_type.kind = AST_TYPE_UNION; + else + type->_type.kind = AST_TYPE_STRUCT; - case AST_TYPE_MEMBER: { - /* TODO */ break; } + default: + semantic_error(scope->fctx, type, "unimplemented type"); + EXIT_ACT(-1); } ast_set_flags(type, AST_FLAG_ACTUAL); @@ -1494,16 +1523,16 @@ static size_t member_count(struct ast_node *exists) return ast_list_len(body); } -static struct ast_node *lookup_struct_member_idx(struct ast_node *struc, - struct ast_node *find, - size_t *idx) +static struct ast_node *lookup_member_idx(struct ast_node *body, + struct ast_node *find, + size_t *idx) { /* micro-optimisation, likely way premature but speeds up selection * between lookup_struct_member_idx and *_name by a tiny amount */ (void)(find); - + assert(idx); size_t i = *idx; - struct ast_node *m = struc->_struct.body; + struct ast_node *m = body; while (i != 0 && m) { m = m->next; i--; @@ -1512,12 +1541,13 @@ static struct ast_node *lookup_struct_member_idx(struct ast_node *struc, return m; } -static struct ast_node *lookup_struct_member_name(struct ast_node *struc, - struct ast_node *find, - size_t *idx) +static struct ast_node *lookup_member_name(struct ast_node *body, + struct ast_node *find, + size_t *idx) { + assert(find->node_type == AST_ID); size_t i = 0; - struct ast_node *m = struc->_struct.body; + struct ast_node *m = body; while (m) { assert(m->node_type == AST_VAR); if (identical_ast_nodes(0, find, m->_var.id)) @@ -1526,7 +1556,9 @@ static struct ast_node *lookup_struct_member_name(struct ast_node *struc, i++; } - *idx = i; + if (idx) + *idx = i; + return m; } @@ -1534,9 +1566,19 @@ static struct ast_node *lookup_struct_member(struct ast_node *struc, struct ast_node *find, size_t *idx) { if (find) - return lookup_struct_member_name(struc, find, idx); + return lookup_member_name(struc->_struct.body, find, idx); + + return lookup_member_idx(struc->_struct.body, find, idx); +} + +static struct ast_node *lookup_union_member(struct ast_node *unio, + struct ast_node *find) +{ + if (find) + return lookup_member_name(unio->_union.body, find, NULL); - return lookup_struct_member_idx(struc, find, idx); + size_t idx = 0; + return lookup_member_idx(unio->_union.body, find, &idx); } static struct ast_node *lookup_enum_member(struct ast_node *enu, @@ -1555,11 +1597,53 @@ static struct ast_node *lookup_enum_member(struct ast_node *enu, return m; } +static int init_union(struct act_state *state, struct scope *scope, + struct ast_node *exists, struct ast_node *init) +{ + struct ast_node *arg = init->_init.body; + if (arg->next) { + semantic_error(scope->fctx, arg->next, + "multiple arguments in union initialization not allowed"); + return -1; + } + + if (actualize(state, scope, arg)) + return -1; + + struct ast_node *member = NULL; + if (ast_flags(arg, AST_FLAG_MEMBER)) { + member = lookup_union_member(exists, arg->_var.id); + } + else { + /* pick first element in body */ + member = exists->_union.body; + } + + if (!member) { + char *sstr = type_str(exists->type); + semantic_error(scope->fctx, arg, + "no such member in %s", + sstr); + free(sstr); + return -1; + } + + if (!implements(0, scope, arg->type, member->type)) { + char *mstr = type_str(member->type); + char *astr = type_str(arg->type); + semantic_error(scope->fctx, arg, "%s does not implement %s", + astr, mstr); + free(mstr); + free(astr); + return -1; + } + + return 0; +} + static int init_struct(struct act_state *state, struct scope *scope, struct ast_node *exists, struct ast_node *init) { - assert(ast_flags(exists, AST_FLAG_ACTUAL)); - size_t i = 0; size_t mcount = member_count(exists); @@ -1653,24 +1737,48 @@ struct ast_node *actual_type(struct ast_node *type) return type; } -static int actualize_struct_init(struct act_state *state, - struct scope *scope, struct ast_node *init, - struct ast_node *struct_type) +static int actualize_struct_init_cast(struct act_state *state, + struct scope *scope, + struct ast_node *init, + struct ast_node *actual) { - struct ast_node *actual = actual_type(struct_type); - if (actual->_type.kind != AST_TYPE_STRUCT) { - semantic_error(scope->fctx, struct_type, - "type is not a structure"); - return -1; - } - struct ast_node *id = actual->_type.struc.id; struct ast_node *exists = file_scope_resolve_type(scope, id); assert(exists); + assert(ast_flags(exists, AST_FLAG_ACTUAL)); return init_struct(state, scope, exists, init); } +static int actualize_union_init_cast(struct act_state *state, + struct scope *scope, + struct ast_node *init, + struct ast_node *actual) +{ + struct ast_node *id = actual->_type.unio.id; + struct ast_node *exists = file_scope_resolve_type(scope, id); + assert(exists); + assert(ast_flags(exists, AST_FLAG_ACTUAL)); + + return init_union(state, scope, exists, init); +} + +static int actualize_init_cast(struct act_state *state, + struct scope *scope, struct ast_node *init, + struct ast_node *type) +{ + struct ast_node *actual = actual_type(type); + if (actual->_type.kind == AST_TYPE_STRUCT) + return actualize_struct_init_cast(state, scope, init, actual); + if (actual->_type.kind == AST_TYPE_UNION) + return actualize_union_init_cast(state, scope, init, actual); + + semantic_error(scope->fctx, type, + "type is not a struct or union"); + return -1; + +} + static int proc_pointer(struct ast_node *type) { if (type->_type.kind != AST_TYPE_POINTER) @@ -1698,6 +1806,7 @@ static int proc_choice(struct ast_node *expr, struct ast_node *type) static int match_proc(struct act_state *state, struct scope *scope, struct ast_node *cast) { + (void)(state); semantic_error(scope->fctx, cast, "procedure signature casts not yet implemented"); return -1; @@ -1723,7 +1832,7 @@ static int actualize_cast(struct act_state *state, if (expr->node_type == AST_INIT) { cast->type = type; - return actualize_struct_init(state, scope, expr, type); + return actualize_init_cast(state, scope, expr, type); } if (types_match(expr->type, type)) { @@ -2068,6 +2177,8 @@ static int actualize_struct(struct act_state *state, return -1; scope_add_scope(node->scope, struct_scope); + if (generics) + ast_set_flags(node, AST_FLAG_GENERIC); /* TODO: some IDs should be handles as just placeholders, I think? */ if (actualize(state, struct_scope, generics)) @@ -2086,6 +2197,36 @@ static int actualize_struct(struct act_state *state, return 0; } +static int actualize_union(struct act_state *state, + struct scope *scope, struct ast_node *node) +{ + assert(node->node_type == AST_UNION); + ast_set_flags(node, AST_FLAG_INIT); + struct ast_node *generics = node->_union.generics; + struct scope *union_scope = create_scope(); + if (!union_scope) + return -1; + + scope_add_scope(node->scope, union_scope); + if (generics) + ast_set_flags(node, AST_FLAG_GENERIC); + + if (actualize(state, union_scope, generics)) + return -1; + + struct ast_node *body = node->_union.body; + if (actualize(state, union_scope, body)) + return -1; + + /* cloning slightly odd, but I guess it's fine? */ + struct ast_node *clone_id = clone_ast_node(node->_union.id); + node->type = gen_type(AST_TYPE_UNION, clone_id, NULL, NULL); + scope_add_scratch(scope, node->type); + + ast_set_flags(node, AST_FLAG_ACTUAL); + return 0; +} + /* could maybe be renamed, but essentially dot in copper works as either * -> or . in C, so allow structures or templates and single level pointers to * structures or templates. */ @@ -2165,7 +2306,7 @@ static int actualize_assign(struct act_state *state, struct scope *scope, if (from->node_type == AST_INIT) { node->type = to->type; - return actualize_struct_init(state, scope, from, to->type); + return actualize_init_cast(state, scope, from, to->type); } if (!types_match(to->type, from->type)) { @@ -2298,6 +2439,7 @@ static int actualize(struct act_state *state, struct scope *scope, case AST_UNOP: ret |= actualize_unop(state, scope, node); break; case AST_AS: ret |= actualize_as(state, scope, node); break; case AST_STRUCT: ret |= actualize_struct(state, scope, node); break; + case AST_UNION: ret |= actualize_union(state, scope, node); break; case AST_DOT: ret |= actualize_dot(state, scope, node); break; case AST_INIT: ret |= actualize_init(state, scope, node); break; case AST_ASSIGN: ret |= actualize_assign(state, scope, node); break; @@ -2378,6 +2520,8 @@ void replace_type(struct ast_node *type, struct ast_node *from, case AST_TYPE_TYPEOF: destroy_ast_node(type->_type.typeo.expr); break; + + default: } *type = *clone; free(clone); @@ -423,6 +423,12 @@ struct ast_node *gen_type(enum ast_type_kind kind, struct ast_node *id, n->node_type = AST_TYPE; n->_type.kind = kind; switch (kind) { + case AST_TYPE_GENERIC: + n->_type.generic.id = id; + n->_type.generic.args = expr; + n->loc = id->loc; + break; + case AST_TYPE_MEMBER: n->_type.member.id = id; n->_type.member.expr = expr; @@ -504,6 +510,16 @@ void destroy_type(struct ast_node *type) { assert(type->node_type == AST_TYPE); switch (type->_type.kind) { + case AST_TYPE_GENERIC: + destroy_ast_node(type->_type.generic.id); + DESTROY_LIST(type->_type.generic.args); + break; + + case AST_TYPE_MEMBER: + destroy_ast_node(type->_type.member.id); + destroy_ast_node(type->_type.member.expr); + break; + case AST_TYPE_ALIAS: break; @@ -1289,6 +1305,12 @@ static void __dump_ast(int depth, struct ast_node *node) dump_flags(node); switch (node->_type.kind) { + case AST_TYPE_GENERIC: + printf(" GENERIC\n"); + dump_ast(depth + 1, node->_type.generic.id); + dump_ast(depth + 1, node->_type.generic.args); + break; + case AST_TYPE_MEMBER: printf(" MEMBER\n"); dump_ast(depth + 1, node->_type.member.id); @@ -1677,14 +1699,24 @@ struct ast_node *clone_ast_node(struct ast_node *node) /* oh, if a node has a ->type it probably isn't cloned * correctly... */ switch (node->_type.kind) { + case AST_TYPE_GENERIC: + new = gen_type(AST_TYPE_GENERIC, + clone_ast_node(node->_type.generic.id), + clone_ast_node(node->_type.generic.args), + NULL); + break; + case AST_TYPE_MEMBER: - new = gen_type(AST_TYPE_MEMBER, node->_type.member.id, - node->_type.member.expr, + new = gen_type(AST_TYPE_MEMBER, + clone_ast_node(node->_type.member.id), + clone_ast_node(node->_type.member.expr), NULL); break; case AST_TYPE_ALIAS: new = gen_type(AST_TYPE_ALIAS, NULL, + /* should make it more obvious what is a + * reference and what isn't */ node->_type.alias.alias, node->_type.alias.actual); break; @@ -1692,7 +1724,7 @@ struct ast_node *clone_ast_node(struct ast_node *node) case AST_TYPE_TEMPLATE: new = gen_type(AST_TYPE_TEMPLATE, NULL, node->_type.template.template, - /* should actual be cloned? */ + /* ditto, should actual be cloned? */ node->_type.template.actual); break; case AST_TYPE_ID: @@ -1758,6 +1790,8 @@ struct ast_node *clone_ast_node(struct ast_node *node) break; } + + assert(new); new->_type.next = clone_ast_node(node->_type.next); break; @@ -2180,7 +2214,7 @@ static int identical_type_struct(int exact, struct ast_node *a, if (!identical_ast_nodes(exact, a->_type.struc.id, b->_type.struc.id)) return 0; - if (!identical_ast_nodes(exact, a->_type.struc.impls, + if (!identical_ast_nodes(1, a->_type.struc.impls, b->_type.struc.impls)) return 0; @@ -2193,7 +2227,7 @@ static int identical_type_union(int exact, struct ast_node *a, if (!identical_ast_nodes(exact, a->_type.unio.id, b->_type.unio.id)) return 0; - if (!identical_ast_nodes(exact, a->_type.unio.impls, + if (!identical_ast_nodes(1, a->_type.unio.impls, b->_type.unio.impls)) return 0; @@ -2212,6 +2246,34 @@ static int identical_type_enum(int exact, struct ast_node *a, return 1; } +static int identical_type_member(int exact, struct ast_node *a, + struct ast_node *b) +{ + if (!identical_ast_nodes(exact, a->_type.member.id, b->_type.member.id)) + return 0; + + if (!identical_ast_nodes(exact, a->_type.member.expr, + b->_type.member.expr)) + return 0; + + return 1; +} + +static int identical_type_generic(int exact, struct ast_node *a, + struct ast_node *b) +{ + if (!identical_ast_nodes(exact, a->_type.generic.id, + b->_type.generic.id)) + return 0; + + /* array should always be checked, so do an exact match */ + if (!identical_ast_nodes(1, a->_type.generic.args, + b->_type.generic.args)) + return 0; + + return 1; +} + static int identical_type(int exact, struct ast_node *a, struct ast_node *b) { if (a->_type.kind != b->_type.kind) @@ -2219,6 +2281,8 @@ static int identical_type(int exact, struct ast_node *a, struct ast_node *b) int ret = 0; switch (a->_type.kind) { + case AST_TYPE_GENERIC: ret = identical_type_generic(exact, a, b); break; + case AST_TYPE_MEMBER: ret = identical_type_member(exact, a, b); break; case AST_TYPE_ENUM: ret = identical_type_enum(exact, a, b); break; case AST_TYPE_ALIAS: ret = identical_type_alias(exact, a, b); break; case AST_TYPE_TEMPLATE: ret = identical_type_template(exact, a, b); @@ -2767,11 +2831,33 @@ static int call_on_type_enum(int (*call)(struct ast_node *, return ret; } +static int call_on_type_member(int (*call)(struct ast_node *, + void *), struct ast_node *node, void *data) +{ + int ret = 0; + ret |= call(node->_type.member.id, data); + ret |= call(node->_type.member.expr, data); + return ret; +} + +static int call_on_type_generic(int (*call)(struct ast_node *, + void *), struct ast_node *node, void *data) +{ + int ret = 0; + ret |= call(node->_type.generic.id, data); + ret |= call(node->_type.generic.args, data); + return ret; +} + static int call_on_type(int (*call)(struct ast_node *, void *), struct ast_node *node, void *data) { int ret = 0; switch (node->_type.kind) { + case AST_TYPE_GENERIC: ret = call_on_type_generic(call, node, data); + break; + case AST_TYPE_MEMBER: ret = call_on_type_member(call, node, data); + break; case AST_TYPE_ENUM: ret = call_on_type_enum(call, node, data); break; case AST_TYPE_ALIAS: ret = call_on_type_alias(call, node, data); break; case AST_TYPE_TEMPLATE: ret = call_on_type_template(call, node, data); diff --git a/src/debug.c b/src/debug.c index b929876..f850973 100644 --- a/src/debug.c +++ b/src/debug.c @@ -210,10 +210,32 @@ static void _type_str(FILE *fp, struct ast_node *type) break; } + case AST_TYPE_UNION: { + struct ast_node *unio_id = type->_type.unio.id; + fprintf(fp, "%s", unio_id->_id.id); + + struct ast_node *impls = type->_type.unio.impls; + if (impls) { + fprintf(fp, "("); + while (impls) { + _type_str(fp, impls); + impls = impls->next; + if (impls) + fprintf(fp, ", "); + } + fprintf(fp, ")"); + } + break; + } + case AST_TYPE_TYPEOF: { _type_str(fp, type->_type.typeo.actual); fprintf(fp, " (typeof)"); + break; } + + default: + fprintf(fp, "NOT YET IMPLEMENTED"); } _type_str(fp, type->_type.next); diff --git a/src/parser.y b/src/parser.y index 329e072..64f9ef1 100644 --- a/src/parser.y +++ b/src/parser.y @@ -448,7 +448,7 @@ type: id { $$ = gen_type(AST_TYPE_ID, $1, NULL, NULL); } $$->_type.next = $2; } | id "(" type_list ")" { - $$ = gen_type(AST_TYPE_STRUCT, $1, $3, NULL); + $$ = gen_type(AST_TYPE_GENERIC, $1, $3, NULL); } | "'" type { $$ = gen_type(AST_TYPE_POINTER, NULL, NULL, NULL); @@ -596,6 +596,7 @@ top: ";" { $$ = gen_empty(); } | enum { $$ = $1; } | proc { $$ = $1; } | struct { $$ = $1; } + | union { $$ = $1; } | macro { $$ = $1; } | "const" top_if { $$ = $2; ast_set_flags($$, AST_FLAG_CONST); } | import ";" { $$ = $1; } @@ -603,6 +604,7 @@ top: ";" { $$ = gen_empty(); } | type_template { $$ = $1; } | "pub" enum { $$ = $2; ast_set_flags($2, AST_FLAG_PUBLIC); } | "pub" struct { $$ = $2; ast_set_flags($2, AST_FLAG_PUBLIC); } + | "pub" union { $$ = $2; ast_set_flags($2, AST_FLAG_PUBLIC); } | "pub" proc { $$ = $2; ast_set_flags($2, AST_FLAG_PUBLIC); } | "pub" macro { $$ = $2; ast_set_flags($2, AST_FLAG_PUBLIC); } | "pub" import ";" { $$ = $2; ast_set_flags($2, AST_FLAG_PUBLIC); } diff --git a/src/scope.c b/src/scope.c index c2b8aab..b5f7960 100644 --- a/src/scope.c +++ b/src/scope.c @@ -75,6 +75,9 @@ int fully_qualified(struct ast_node *type) assert(type->_type.kind != AST_TYPE_TEMPLATE); if (type->_type.kind == AST_TYPE_STRUCT) { + if (!ast_flags(type, AST_FLAG_GENERIC)) + return 1; + if (type->_type.struc.impls) return fully_qualified(type->_type.struc.impls); @@ -82,6 +85,9 @@ int fully_qualified(struct ast_node *type) } if (type->_type.kind == AST_TYPE_UNION) { + if (!ast_flags(type, AST_FLAG_GENERIC)) + return 1; + if (type->_type.unio.impls) return fully_qualified(type->_type.unio.impls); @@ -91,8 +97,7 @@ int fully_qualified(struct ast_node *type) return fully_qualified(type->_type.next); } -static struct param_node *find_primitive(struct scope *scope, - struct proc_node *node, +static struct param_node *find_primitive(struct proc_node *node, struct ast_node *type) { struct param_node *param = node->primitives; @@ -123,8 +128,7 @@ static int compare_primitives(struct ast_node *a, struct ast_node *b); * otherwise use find_primitive() to get which primitive matches. * (are these names inverted from their intention? I'm not sure) */ -static struct param_node *match_primitive(struct scope *scope, - struct proc_node *node, +static struct param_node *match_primitive(struct proc_node *node, struct ast_node *type) { struct param_node *param = node->primitives; @@ -265,8 +269,7 @@ static int add_next_resolve(struct scope *scope, struct ast_node *proc, assert(params->node_type == AST_VAR); if (primitive_type(params->type)) { - struct param_node *match = match_primitive(scope, node, - params->type); + struct param_node *match = match_primitive(node, params->type); if (match) return add_next_resolve(scope, proc, match->proc, params->next); @@ -361,7 +364,7 @@ static struct ast_node *proc_resolve(struct scope *scope, } /* first check if we match a primitive type */ - struct param_node *found = find_primitive(scope, node, args->type); + struct param_node *found = find_primitive(node, args->type); if (found) return proc_resolve(scope, found->proc, args->next); @@ -508,6 +511,7 @@ void destroy_scope(struct scope *scope) destroy_visible(scope, scope->builtins); destroy_visible(scope, scope->enums); + destroy_visible(scope, scope->unions); destroy_visible(scope, scope->structs); destroy_visible(scope, scope->aliases); destroy_visible(scope, scope->templates); @@ -568,6 +572,7 @@ CREATE_VISIBLE(create_proc, procs, AST_PROC); CREATE_VISIBLE(create_enum, enums, AST_ENUM); CREATE_VISIBLE(create_alias, aliases, AST_ALIAS); CREATE_VISIBLE(create_struct, structs, AST_STRUCT); +CREATE_VISIBLE(create_union, unions, AST_UNION); CREATE_VISIBLE(create_builtin, builtins, AST_TYPE); CREATE_VISIBLE(create_template, templates, AST_TEMPLATE); @@ -592,6 +597,7 @@ REFERENCE_VISIBLE(reference_proc, procs, AST_PROC); REFERENCE_VISIBLE(reference_enum, enums, AST_ENUM); REFERENCE_VISIBLE(reference_alias, aliases, AST_ALIAS); +REFERENCE_VISIBLE(reference_union, unions, AST_UNION); REFERENCE_VISIBLE(reference_struct, structs, AST_STRUCT); REFERENCE_VISIBLE(reference_builtin, builtins, AST_TYPE); REFERENCE_VISIBLE(reference_template, templates, AST_TEMPLATE); @@ -620,6 +626,7 @@ FIND_VISIBLE(scope_find_enum, enums, AST_ENUM, _enum); FIND_VISIBLE(scope_find_alias, aliases, AST_ALIAS, _alias); FIND_VISIBLE(scope_find_builtin, builtins, AST_TYPE, _type); FIND_VISIBLE(scope_find_struct, structs, AST_STRUCT, _struct); +FIND_VISIBLE(scope_find_union, unions, AST_UNION, _union); FIND_VISIBLE(scope_find_template, templates, AST_TEMPLATE, _template); /* note that these return the first match for the ID, and as such might not be * what should be called. */ @@ -685,6 +692,7 @@ struct visible *create_type(struct scope *scope, struct ast_node *type) case AST_TEMPLATE: return create_template(scope, type); case AST_ENUM: return create_enum(scope, type); case AST_STRUCT: return create_struct(scope, type); + case AST_UNION: return create_union(scope, type); default: semantic_error(scope->fctx, type, "unknown type"); return NULL; @@ -699,6 +707,7 @@ int reference_type(int public, struct scope *scope, struct visible *visible) case AST_TEMPLATE: return reference_template(public, scope, visible); case AST_ENUM: return reference_enum(public, scope, visible); case AST_STRUCT: return reference_struct(public, scope, visible); + case AST_UNION: return reference_union(public, scope, visible); default: semantic_error(scope->fctx, visible->node, "unknown type"); return 1; @@ -743,6 +752,10 @@ struct ast_node *scope_find_type(struct scope *scope, struct ast_node *id) if (found) return found; + found = scope_find_union(scope, id); + if (found) + return found; + found = scope_find_alias(scope, id); if (found) return found; @@ -914,6 +927,10 @@ static int implements_var(enum match_flags flags, struct scope *scope, struct ast_node *arg_type, struct ast_node *param_type, struct ast_node *var) { + (void)(flags); + (void)(scope); + (void)(arg_type); + (void)(param_type); assert(var->node_type == AST_VAR); /* temp */ return 0; @@ -1017,13 +1034,6 @@ static int implements_typeof(enum match_flags flags, struct scope *scope, return implements(flags, scope, arg_type, param_type); } -static int implements_pointer(enum match_flags flags, struct scope *scope, - struct ast_node *arg_type, - struct ast_node *param_type) -{ - return implements(flags, scope, arg_type, param_type); -} - int implements(enum match_flags flags, struct scope *scope, struct ast_node *arg_type, struct ast_node *param_type) { @@ -1169,6 +1179,7 @@ static int match_params(enum match_flags flags, struct scope *scope, static struct ast_node *match_proc(enum match_flags flags, struct scope *scope, struct ast_node *id, struct ast_node *args) { + (void)(flags); struct callable *cb = scope->callable; while (cb) { if (identical_ast_nodes(0, cb->id, id)) @@ -1548,6 +1559,10 @@ struct ast_node *scope_resolve_type(struct scope *scope, struct ast_node *type) id = type->_struct.id; break; + case AST_UNION: + id = type->_union.id; + break; + case AST_ENUM: id = type->_enum.id; break; |
