aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-04-01 14:51:20 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2023-04-01 14:51:20 +0300
commit4642bedb436981e92e3312f06bfcb2eb34074596 (patch)
treecc5bf868a391c9880b9917eed44b20e4df535d1d /src
parent0132be5b71f3fe161b2fcda201c945d30bd8d1a5 (diff)
downloadek-4642bedb436981e92e3312f06bfcb2eb34074596.tar.gz
ek-4642bedb436981e92e3312f06bfcb2eb34074596.zip
disallow certain kinds of types in templates
Diffstat (limited to 'src')
-rw-r--r--src/actualize.c44
-rw-r--r--src/scope.c30
2 files changed, 53 insertions, 21 deletions
diff --git a/src/actualize.c b/src/actualize.c
index 0c7a378..4d1d449 100644
--- a/src/actualize.c
+++ b/src/actualize.c
@@ -21,6 +21,7 @@ enum act_flags {
ACT_IN_SWITCH = (1 << 1),
ACT_ONLY_TYPES = (1 << 2),
ACT_HAS_RETURN = (1 << 3),
+ ACT_REQUIRE_FULLY_QUALIFIED = (1 << 4),
};
struct act_state {
@@ -998,6 +999,7 @@ static int actualize_proc(struct act_state *state,
* think */
struct act_state new_state = {0};
new_state.cur_proc = actual;
+ act_set_flags(&new_state, ACT_REQUIRE_FULLY_QUALIFIED);
/* actualize body */
ret |= actualize(&new_state, sign->scope, actual->_proc.body);
if (!act_flags(&new_state, ACT_HAS_RETURN)) {
@@ -1358,7 +1360,23 @@ static int actualize_type(struct act_state *state,
if (actualize(state, scope, types))
EXIT_ACT(-1);
- /* TODO: check that all params are fully qualified */
+ while (types) {
+ if (!primitive_type(types)) {
+ semantic_error(scope->fctx, types,
+ "only primitive types allowed in template initialization");
+ EXIT_ACT(-1);
+ }
+
+ if (act_flags(state, ACT_REQUIRE_FULLY_QUALIFIED)) {
+ if (!fully_qualified(types)) {
+ semantic_error(scope->fctx, types,
+ "context requires fully qualified types");
+ EXIT_ACT(-1);
+ }
+ }
+ types = types->next;
+ }
+
break;
}
@@ -1611,14 +1629,26 @@ static int init_struct(struct act_state *state, struct scope *scope,
struct ast_node *actual_type(struct ast_node *type)
{
assert(type->node_type == AST_TYPE);
- if (type->_type.kind == AST_TYPE_ALIAS)
- return actual_type(type->_type.alias.actual);
+ if (type->_type.kind == AST_TYPE_ALIAS) {
+ if (type->_type.alias.actual)
+ return actual_type(type->_type.alias.actual);
- if (type->_type.kind == AST_TYPE_TEMPLATE)
- return actual_type(type->_type.template.actual);
+ return type;
+ }
- if (type->_type.kind == AST_TYPE_TYPEOF)
- return actual_type(type->_type.typeo.actual);
+ if (type->_type.kind == AST_TYPE_TEMPLATE) {
+ if (type->_type.template.actual)
+ return actual_type(type->_type.template.actual);
+
+ return type;
+ }
+
+ if (type->_type.kind == AST_TYPE_TYPEOF) {
+ if (type->_type.typeo.actual)
+ return actual_type(type->_type.typeo.actual);
+
+ return type;
+ }
return type;
}
diff --git a/src/scope.c b/src/scope.c
index b560e5f..c2b8aab 100644
--- a/src/scope.c
+++ b/src/scope.c
@@ -22,7 +22,7 @@ static int generics_trait_type(struct ast_node *generics)
return generics_trait_type(generics->_type.next);
}
-static int generic_type(struct scope *scope, struct ast_node *type)
+static int generic_type(struct ast_node *type)
{
if (!type)
return 0;
@@ -37,10 +37,10 @@ static int generic_type(struct scope *scope, struct ast_node *type)
if (type->_type.kind == AST_TYPE_TEMPLATE)
return type->_type.template.actual == NULL;
- return generic_type(scope, type->_type.next);
+ return generic_type(type->_type.next);
}
-static int referential_type(struct scope *scope, struct ast_node *type)
+static int referential_type(struct ast_node *type)
{
if (!type)
return 0;
@@ -51,24 +51,24 @@ static int referential_type(struct scope *scope, struct ast_node *type)
if (type->_type.kind == AST_TYPE_MEMBER)
return 1;
- return referential_type(scope, type->_type.next);
+ return referential_type(type->_type.next);
}
-static int primitive_type(struct scope *scope, struct ast_node *type)
+int primitive_type(struct ast_node *type)
{
if (!type)
return 1;
- if (referential_type(scope, type))
+ if (referential_type(type))
return 0;
- if (generic_type(scope, type))
+ if (generic_type(type))
return 0;
return 1;
}
-static int fully_qualified(struct ast_node *type)
+int fully_qualified(struct ast_node *type)
{
if (!type)
return 1;
@@ -123,8 +123,9 @@ 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,
- struct ast_node *type)
+static struct param_node *match_primitive(struct scope *scope,
+ struct proc_node *node,
+ struct ast_node *type)
{
struct param_node *param = node->primitives;
while (param) {
@@ -194,7 +195,8 @@ static int compare_primitives(struct ast_node *a, struct ast_node *b)
return 1;
if (a->_type.kind == AST_TYPE_STRUCT)
- return compare_impls(a->_type.struc.impls, b->_type.struc.impls);
+ return compare_impls(a->_type.struc.impls,
+ b->_type.struc.impls);
if (a->_type.kind == AST_TYPE_UNION)
return compare_impls(a->_type.unio.impls, b->_type.unio.impls);
@@ -262,9 +264,9 @@ static int add_next_resolve(struct scope *scope, struct ast_node *proc,
}
assert(params->node_type == AST_VAR);
- if (primitive_type(scope, params->type)) {
+ if (primitive_type(params->type)) {
struct param_node *match = match_primitive(scope, node,
- params->type);
+ params->type);
if (match)
return add_next_resolve(scope, proc, match->proc,
params->next);
@@ -276,7 +278,7 @@ static int add_next_resolve(struct scope *scope, struct ast_node *proc,
return add_next_resolve(scope, proc, next, params->next);
}
- if (referential_type(scope, params->type)) {
+ if (referential_type(params->type)) {
/* TODO: I don't think there's a good way to check if the
* referential types are identical, but could be worth a shot */
if (!node->referential) {