aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actualize.c62
-rw-r--r--src/debug.c25
2 files changed, 76 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);
diff --git a/src/debug.c b/src/debug.c
index 47e53f2..92d85d2 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -218,6 +218,22 @@ void internal_warn(const char *fmt, ...)
va_end(args);
}
+static void _type_str(FILE *fp, struct type *type);
+
+static void _type_list_str(FILE *fp, struct type *types)
+{
+ if (!types)
+ return;
+
+ _type_str(fp, types);
+
+ types = types->n;
+ foreach_type(t, types) {
+ fprintf(fp, ", ");
+ _type_str(fp, t);
+ }
+}
+
/**
* Workhorse for type_str().
*
@@ -263,6 +279,15 @@ static void _type_str(FILE *fp, struct type *type)
break;
}
+ case TYPE_CALLABLE: {
+ fputc('(', fp);
+ _type_list_str(fp, callable_ptypes(type));
+ fprintf(fp, " => ");
+ _type_str(fp, callable_rtype(type));
+ fputc(')', fp);
+ break;
+ }
+
default:
if (is_primitive(type))
fprintf(fp, "%s", primitive_str(type));