diff options
23 files changed, 89 insertions, 32 deletions
diff --git a/src/actualize.c b/src/actualize.c index 11c8db7..991beed 100644 --- a/src/actualize.c +++ b/src/actualize.c @@ -2131,6 +2131,22 @@ static int params_match(struct scope *scope, struct ast *base, struct ast *node) return 1; } +/* slightly hacky but works well enough for now */ +static int trait_exported(struct scope *scope, struct ast *def) +{ + assert(file_scope_find_type(scope, def->s) == def); + + while (!scope_flags(scope, SCOPE_FILE) && scope->parent) + scope = scope->parent; + + assert(scope && scope_flags(scope, SCOPE_FILE)); + struct scope *parent = scope->parent; + if (!parent) + return true; + + return file_scope_find_type(parent, def->s) == def; +} + static int expand_struct_body(struct act_state *state, struct scope *scope, struct ast *node, @@ -2178,6 +2194,17 @@ static int expand_struct_body(struct act_state *state, if (actualize_type(&type_state, scope, type)) return -1; + if (ast_flags(node, AST_FLAG_PUBLIC)) { + struct ast *def = type->d; + /* traits should only show up during the initial + * expansion, but should maybe make sure somehow */ + if (def->k == AST_TRAIT_DEF && !trait_exported(scope, def)) { + semantic_error(struct_scope->fctx, n, + "trait used in pub def must also be exported"); + return -1; + } + } + type_append(&types, type); struct ast *alias = gen_alias(strdup(id), type, n->loc); @@ -2187,6 +2214,7 @@ static int expand_struct_body(struct act_state *state, struct act_state state = {0}; if (actualize(&state, struct_scope, alias)) return -1; + } if (node->k == AST_STRUCT_CONT_DEF diff --git a/src/compiler.c b/src/compiler.c index f7e6a14..2041efd 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -160,6 +160,7 @@ static struct scopes scopes; static void destroy_scopes() { + if (scopes_len(&scopes)) foreach(scopes, n, &scopes) { free(n->key); } diff --git a/src/parser.y b/src/parser.y index 18de0e1..45cac92 100644 --- a/src/parser.y +++ b/src/parser.y @@ -683,7 +683,7 @@ opt_types | { $$ = NULL; } type_expand - : APPLY "[" opt_types "]" { $$ = gen_type_expand($1, $3, src_loc(@$)); } + : APPLY { $$ = gen_type_expand($1, NULL, src_loc(@$)); } var_decl : type ID { $$ = gen_var($2, $1, NULL, src_loc(@$)); } @@ -810,8 +810,8 @@ opt_type_params | { $$ = NULL; } trait - : "define" ID "[" opt_type_params "]" "{" opt_behaviours "}" { - $$ = gen_trait($2, $4, $7, src_loc(@$)); + : "define" ID "{" opt_behaviours "}" { + $$ = gen_trait($2, NULL, $4, src_loc(@$)); } enum_val diff --git a/tests/defer_shadow/defer_shadow.ek b/tests/defer_shadow/defer_shadow.ek index 0e890a2..e12df32 100644 --- a/tests/defer_shadow/defer_shadow.ek +++ b/tests/defer_shadow/defer_shadow.ek @@ -1,7 +1,7 @@ typedef i9 {} typedef i27 {} -define any[] {} +define any {} extern _putchar(i9 c); diff --git a/tests/generic/generic.ek b/tests/generic/generic.ek index 065477e..d8a3e7c 100644 --- a/tests/generic/generic.ek +++ b/tests/generic/generic.ek @@ -1,4 +1,4 @@ -define any[] {} +define any {} typedef i27 {} typedef i9 {} diff --git a/tests/generic_defer/generic_defer.ek b/tests/generic_defer/generic_defer.ek index cb11154..cb2ae33 100644 --- a/tests/generic_defer/generic_defer.ek +++ b/tests/generic_defer/generic_defer.ek @@ -1,4 +1,4 @@ -define any[] {} +define any {} typedef i27 {} typedef i9 {} diff --git a/tests/ptr/ptr.ek b/tests/ptr/ptr.ek index 86f413c..3e74917 100644 --- a/tests/ptr/ptr.ek +++ b/tests/ptr/ptr.ek @@ -1,14 +1,14 @@ typedef bool {} typedef i27 { - cmp![]; + cmp!; eq(i27 a, i27 b => bool) { return a == b; } } typedef ptr { - cmp![]; + cmp!; eq(ptr a, ptr b => bool) { return a == b; } @@ -16,7 +16,7 @@ typedef ptr { typedef test[cmp T] {} -define cmp[] { +define cmp { eq(cmp, cmp => bool); } diff --git a/tests/struct_generic_cont/struct_generic_cont.ek b/tests/struct_generic_cont/struct_generic_cont.ek index 34c604b..661b9e6 100644 --- a/tests/struct_generic_cont/struct_generic_cont.ek +++ b/tests/struct_generic_cont/struct_generic_cont.ek @@ -1,4 +1,4 @@ -define any[] {} +define any {} typedef ptr {} typedef i27 {} diff --git a/tests/struct_priv_trait/source.mk b/tests/struct_priv_trait/source.mk new file mode 100644 index 0000000..45e3623 --- /dev/null +++ b/tests/struct_priv_trait/source.mk @@ -0,0 +1 @@ +SIMPLE_XFAIL += struct_priv_trait,'trait used in pub def must also be exported' diff --git a/tests/struct_priv_trait/struct.ek b/tests/struct_priv_trait/struct.ek new file mode 100644 index 0000000..5efb96f --- /dev/null +++ b/tests/struct_priv_trait/struct.ek @@ -0,0 +1,8 @@ +pub typedef ptr {}; +pub typedef i27 {}; + +define trait { + do_something(=> i27); +} + +pub typedef struct[trait T] {}; diff --git a/tests/struct_priv_trait/struct_priv_trait.ek b/tests/struct_priv_trait/struct_priv_trait.ek new file mode 100644 index 0000000..0e3bd9c --- /dev/null +++ b/tests/struct_priv_trait/struct_priv_trait.ek @@ -0,0 +1,5 @@ +import "struct.ek" + +main() +{ +} diff --git a/tests/struct_priv_trait_cont/struct.ek b/tests/struct_priv_trait_cont/struct.ek index 6c94aaa..b790dd4 100644 --- a/tests/struct_priv_trait_cont/struct.ek +++ b/tests/struct_priv_trait_cont/struct.ek @@ -1,13 +1,13 @@ pub typedef ptr {}; pub typedef i27 {}; -pub define trait[] { +pub define trait { do_something(=> i27); } pub typedef implementer {} continue implementer { - trait![]; + trait!; do_something(=> i27) { return 0; diff --git a/tests/struct_priv_trait_cont/struct_priv_trait_cont.ek b/tests/struct_priv_trait_cont/struct_priv_trait_cont.ek index cd67050..7fb7e12 100644 --- a/tests/struct_priv_trait_cont/struct_priv_trait_cont.ek +++ b/tests/struct_priv_trait_cont/struct_priv_trait_cont.ek @@ -12,7 +12,7 @@ import "struct.ek" * by the codegen. Should maybe try and do something about that as well. */ continue implementer { - trait![]; + trait!; do_something(=> i27) { return 1; diff --git a/tests/struct_pub_generic_cont/struct.ek b/tests/struct_pub_generic_cont/struct.ek index 5abbe38..4689736 100644 --- a/tests/struct_pub_generic_cont/struct.ek +++ b/tests/struct_pub_generic_cont/struct.ek @@ -1,4 +1,4 @@ -pub define any[] {} +pub define any {} pub typedef i27 {} pub typedef struct[any T] {} diff --git a/tests/struct_trait_cont/struct_trait_cont.ek b/tests/struct_trait_cont/struct_trait_cont.ek index f8e05c5..b4f7a2a 100644 --- a/tests/struct_trait_cont/struct_trait_cont.ek +++ b/tests/struct_trait_cont/struct_trait_cont.ek @@ -1,10 +1,10 @@ -define a[] { +define a { a(); } typedef struct {} continue struct { - a![]; + a!; a(){} } diff --git a/tests/struct_unexported_trait/source.mk b/tests/struct_unexported_trait/source.mk new file mode 100644 index 0000000..fb22304 --- /dev/null +++ b/tests/struct_unexported_trait/source.mk @@ -0,0 +1 @@ +SIMPLE_XFAIL += struct_unexported_trait,'trait used in pub def must also be exported' diff --git a/tests/struct_unexported_trait/struct.ek b/tests/struct_unexported_trait/struct.ek new file mode 100644 index 0000000..acf01f5 --- /dev/null +++ b/tests/struct_unexported_trait/struct.ek @@ -0,0 +1,3 @@ +import "trait.ek" + +pub typedef struct[trait T] {}; diff --git a/tests/struct_unexported_trait/struct_unexported_trait.ek b/tests/struct_unexported_trait/struct_unexported_trait.ek new file mode 100644 index 0000000..0e3bd9c --- /dev/null +++ b/tests/struct_unexported_trait/struct_unexported_trait.ek @@ -0,0 +1,5 @@ +import "struct.ek" + +main() +{ +} diff --git a/tests/struct_unexported_trait/trait.ek b/tests/struct_unexported_trait/trait.ek new file mode 100644 index 0000000..8280a53 --- /dev/null +++ b/tests/struct_unexported_trait/trait.ek @@ -0,0 +1,5 @@ +pub typedef i27 {}; + +pub define trait { + do_something(=> i27); +} diff --git a/tests/trait_expand/trait_expand.ek b/tests/trait_expand/trait_expand.ek index c5f0f1c..d7aa288 100644 --- a/tests/trait_expand/trait_expand.ek +++ b/tests/trait_expand/trait_expand.ek @@ -1,15 +1,15 @@ typedef ptr {} -define b[] { - a![]; +define b { + a!; } -define a[] { +define a { a(*a a); } typedef c { - b![]; + b!; a(*c) {} } diff --git a/tests/trait_multiple_expand/source.mk b/tests/trait_multiple_expand/source.mk index 6d1bcbb..e6193c7 100644 --- a/tests/trait_multiple_expand/source.mk +++ b/tests/trait_multiple_expand/source.mk @@ -1 +1 @@ -SIMPLE_XFAIL += trait_multiple_expand +SIMPLE_XFAIL += trait_multiple_expand,"reimplementation of trait" diff --git a/tests/trait_multiple_expand/trait_multiple_expand.ek b/tests/trait_multiple_expand/trait_multiple_expand.ek index 04e2b82..3444305 100644 --- a/tests/trait_multiple_expand/trait_multiple_expand.ek +++ b/tests/trait_multiple_expand/trait_multiple_expand.ek @@ -1,21 +1,21 @@ typedef ptr {} -define b[] { - c![]; - a![]; +define b { + c!; + a!; } -define a[] { - c![]; +define a { + c!; a(*a a); } -define c[] { +define c { c(*c c); } typedef d { - b![]; + b!; c(*d d) {} } diff --git a/tests/trait_recursive_expand/trait_recursive_expand.ek b/tests/trait_recursive_expand/trait_recursive_expand.ek index 53012bf..6b71b23 100644 --- a/tests/trait_recursive_expand/trait_recursive_expand.ek +++ b/tests/trait_recursive_expand/trait_recursive_expand.ek @@ -1,8 +1,8 @@ -define b[] { - a![]; +define b { + a!; } -define a[] { - b![]; +define a { + b!; a(*a a); } |
