aboutsummaryrefslogtreecommitdiff
path: root/src/actualize.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/actualize.c')
-rw-r--r--src/actualize.c62
1 files changed, 51 insertions, 11 deletions
diff --git a/src/actualize.c b/src/actualize.c
index 5a642a7..2cf4c13 100644
--- a/src/actualize.c
+++ b/src/actualize.c
@@ -462,6 +462,8 @@ static struct ast *analyze_type_expand(struct scope *scope,
return NULL;
}
+ n->t = trait->t;
+
struct ast *body = trait_body(trait);
body = clone_ast(body);
@@ -553,6 +555,13 @@ int types_match(struct type *a, struct type *b)
if (a->k == TYPE_STRUCT)
return structs_match(a, b);
+ if (a->k == TYPE_PTR && b->k == TYPE_PTR) {
+ if (is_void(ptr_base(a)))
+ return 1;
+ else if (is_void(ptr_base(b)))
+ return 1;
+ }
+
if (a->k == TYPE_PTR)
return types_match(ptr_base(a), ptr_base(b));
@@ -628,8 +637,10 @@ static int implements(struct type *trait, struct type *type)
assert(type->d);
struct ast *def = type->d;
+ assert(def->k == AST_STRUCT_DEF);
+ struct ast *body = struct_body(def);
- foreach_node(n, def) {
+ foreach_node(n, body) {
if (n->k != AST_TYPE_EXPAND)
continue;
@@ -915,6 +926,9 @@ static int maybe_ufcs(struct act_state *state, struct scope *scope,
/* is ufcs expects reference to member, try to take address */
ref = gen_unop(AST_REF, expr, dot->loc);
ref->t = tgen_ptr(clone_type(expr->t), dot->loc);
+ if (actualize_type(state, scope, ref->t))
+ return -1;
+
ref->scope = scope;
}
else {
@@ -1302,6 +1316,12 @@ static int actualize_ptr(struct act_state *state, struct scope *scope,
struct type *t)
{
assert(ptr_base(t));
+ t->d = actualized_file_scope_find_type(state, scope, "ptr");
+ if (!t->d) {
+ type_error(scope->fctx, t, "no pointer type");
+ return -1;
+ }
+
if (actualize_type(state, scope, ptr_base(t)))
return -1;
@@ -1667,10 +1687,10 @@ static int actualize_return(struct act_state *state, struct scope *scope,
assert(state->cur_proc);
struct ast *cur_proc = state->cur_proc;
- struct type *rtype = cur_proc->t;
- if (!types_match(node->t, callable_rtype(rtype))) {
- type_mismatch(scope, "return type mismatch", node, rtype,
- node->t);
+ struct type *rtype = callable_rtype(cur_proc->t);
+ if (!types_match(node->t, rtype)) {
+ type_mismatch(scope, "return type mismatch", node,
+ rtype, node->t);
return -1;
}
@@ -1827,6 +1847,9 @@ static int actualize_unop(struct act_state *state,
case AST_REF: {
/** @todo array pointer decay? */
node->t = tgen_ptr(clone_type(expr->t), node->loc);
+ if (actualize_type(state, scope, node->t))
+ return -1;
+
if (simplify_refderef(state, scope, node))
return -1;
@@ -2070,15 +2093,20 @@ static int actualize_struct(struct act_state *state,
ast_set_flags(node, AST_FLAG_GENERIC);
/* do type setting first to make sure body checking works */
- char *id = strdup(struct_id(node));
+ char *id = struct_id(node);
if (same_id(id, "i27"))
- node->t = tgen_primitive(TYPE_I27, id, node, node->loc);
+ node->t = tgen_primitive(TYPE_I27, strdup(id), node, node->loc);
else if (same_id(id, "i9"))
- node->t = tgen_primitive(TYPE_I9, id, node, node->loc);
+ node->t = tgen_primitive(TYPE_I9, strdup(id), node, node->loc);
else if (same_id(id, "bool"))
- node->t = tgen_primitive(TYPE_BOOL, id, node, node->loc);
+ node->t = tgen_primitive(TYPE_BOOL, strdup(id), node, node->loc);
+ else if (same_id(id, "ptr")) {
+ node->t = tgen_ptr(void_type(), node->loc);
+ /* we know we're the definition for pointers */
+ node->t->d = node;
+ }
else
- node->t = tgen_struct(id, node, node->loc);
+ node->t = tgen_struct(strdup(id), node, node->loc);
/* iterate over types and make aliases to them */
struct type *types = NULL;
@@ -2111,6 +2139,16 @@ static int actualize_struct(struct act_state *state,
if (n->k != AST_TYPE_EXPAND)
continue;
+ /** @todo when I eventually implement continuing structure
+ * definitions I might add the primitive types by default to
+ * structs, that way we don't need this check or the above type
+ * table */
+ if (n->k == AST_VAR_DEF && node->t->k != TYPE_STRUCT) {
+ semantic_error(scope->fctx, n,
+ "variables not allowed in primitive struct");
+ return -1;
+ }
+
if (has_trait(struct_body(node), type_expand_id(n))) {
n->k = AST_EMPTY;
continue;
@@ -2224,6 +2262,7 @@ static int actualize_dot(struct act_state *state,
case TYPE_I9:
case TYPE_I27:
case TYPE_BOOL:
+ case TYPE_PTR:
case TYPE_TRAIT:
case TYPE_STRUCT: def = type->d; break;
default: {
@@ -2236,7 +2275,8 @@ static int actualize_dot(struct act_state *state,
}
}
- struct ast *exists = actualized_scope_find_symbol(state, def->scope,
+ struct ast *exists = actualized_scope_find_symbol(state,
+ def->scope,
id);
if (exists) {
assert(exists->t);