aboutsummaryrefslogtreecommitdiff
path: root/src/actualize.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-08-14 20:44:26 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-08-14 20:44:26 +0300
commit2023a7b2d9656f80b00de81453348c0a66f200f7 (patch)
tree06e4ea293318955cc4cf620428d04f1708c17364 /src/actualize.c
parent1a56a881bc2c37614cfd074e7b986211c6d04809 (diff)
downloadek-2023a7b2d9656f80b00de81453348c0a66f200f7.tar.gz
ek-2023a7b2d9656f80b00de81453348c0a66f200f7.zip
test cleanup
+ Somewhat poor Git hygiene but I also fixed some bugs while I was at it.
Diffstat (limited to 'src/actualize.c')
-rw-r--r--src/actualize.c87
1 files changed, 58 insertions, 29 deletions
diff --git a/src/actualize.c b/src/actualize.c
index 2cf4c13..ba5475e 100644
--- a/src/actualize.c
+++ b/src/actualize.c
@@ -815,6 +815,14 @@ static int actualize_macro_def(struct act_state *state,
/* macro bodies, arguments, etc aren't expanded upon until the macro is
* called, so just try to add it to the local scope */
assert(n && n->k == AST_MACRO_DEF);
+
+ n->t = void_type();
+
+ /* analysis should've added us to the file scope already */
+ if (scope_flags(scope, SCOPE_FILE))
+ return 0;
+
+ /* otherwise, add us to whatever scope we're in */
return scope_add_macro(scope, n);
}
@@ -1443,7 +1451,8 @@ static int actualize_tconstruct(struct act_state *state,
struct type *t)
{
assert(t->k == TYPE_CONSTRUCT);
- struct ast *d = actualized_file_scope_find_type(state, scope, construct_id(t));
+ struct ast *d = actualized_file_scope_find_type(state, scope,
+ construct_id(t));
if (!d) {
type_error(scope->fctx, t, "no such type");
return -1;
@@ -1602,8 +1611,7 @@ static int actualize_cast(struct act_state *state,
char *left_type = type_str(expr->t);
char *right_type = type_str(type);
- semantic_error(scope->fctx, cast, "illegal cast: %s vs %s",
- left_type, right_type);
+ type_mismatch(scope, "illegal cast", cast, expr->t, type);
free(left_type);
free(right_type);
return -1;
@@ -1690,7 +1698,7 @@ static int actualize_return(struct act_state *state, struct scope *scope,
struct type *rtype = callable_rtype(cur_proc->t);
if (!types_match(node->t, rtype)) {
type_mismatch(scope, "return type mismatch", node,
- rtype, node->t);
+ rtype, node->t);
return -1;
}
@@ -2099,7 +2107,8 @@ static int actualize_struct(struct act_state *state,
else if (same_id(id, "i9"))
node->t = tgen_primitive(TYPE_I9, strdup(id), node, node->loc);
else if (same_id(id, "bool"))
- node->t = tgen_primitive(TYPE_BOOL, strdup(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 */
@@ -2145,7 +2154,7 @@ static int actualize_struct(struct act_state *state,
* table */
if (n->k == AST_VAR_DEF && node->t->k != TYPE_STRUCT) {
semantic_error(scope->fctx, n,
- "variables not allowed in primitive struct");
+ "variables not allowed in primitive struct");
return -1;
}
@@ -2275,8 +2284,17 @@ static int actualize_dot(struct act_state *state,
}
}
+ if (def->k == AST_ENUM_DEF)
+ def = (enum_type(def))->d;
+
+ if (!def) {
+ semantic_error(scope->fctx, node,
+ "no such type");
+ return -1;
+ }
+
struct ast *exists = actualized_scope_find_symbol(state,
- def->scope,
+ def->scope,
id);
if (exists) {
assert(exists->t);
@@ -2284,8 +2302,11 @@ static int actualize_dot(struct act_state *state,
return 0;
}
+ char *tstr = type_str(type);
semantic_error(scope->fctx, node,
- "does not have member");
+ "%s does not have have member",
+ tstr);
+ free(tstr);
return -1;
}
@@ -2430,6 +2451,8 @@ static int actualize_enum_fetch(struct act_state *state, struct scope *scope,
return -1;
}
+ /* this should be safe since we currently don't allow enums to be part
+ * of any generic structures. */
replace_slice_ast(fetch, val_val(member));
set_type(fetch, def->t);
return 0;
@@ -2443,7 +2466,8 @@ static int actualize_fetch(struct act_state *state, struct scope *scope,
if (actualize_type(state, scope, type))
return -1;
- if (type->k == TYPE_ENUM)
+ assert(type->d);
+ if (type->d->k == AST_ENUM_DEF)
return actualize_enum_fetch(state, scope, fetch);
if (type->k != TYPE_STRUCT && type->k != TYPE_TRAIT &&
@@ -2473,41 +2497,45 @@ static int actualize_enum(struct act_state *state, struct scope *scope,
struct ast *node)
{
assert(node->k == AST_ENUM_DEF);
- struct type *type = enum_type(node);
struct scope *enum_scope = node->scope;
/* TODO: here we could save space by choosing the smallest type that
* fits */
- if (!type) {
- type = i27_type(scope);
- node->t = type;
- } else if (actualize_type(state, enum_scope, type))
+ if (!enum_type(node))
+ enum_type(node) = i27_type(scope);
+
+ /* enum are at least currently limited to top scope, so we don't have to
+ * worry about them being part of some generic structure. Might be a
+ * future improvement, though. */
+ struct type *type = enum_type(node);
+ if (actualize_type(state, enum_scope, type))
return -1;
+ /* overwrite type definition to point to us.
+ * This is maybe something of a hack, but effectively 'pretend' to be a
+ * regular i27 or whatever to make casts etc. work like in C. */
+ node->t = clone_type(type);
+ node->t->d = node;
+
long long counter = 0;
- node->t = type;
struct ast *members = enum_body(node);
while (members) {
set_type(members, type);
- if (val_val(members)) {
- struct ast *val = val_val(members);
- if (actualize(state, enum_scope, val))
- return -1;
+ if (!val_val(members))
+ val_val(members) = gen_const_int(counter, NULL_LOC());
- if (val->k != AST_CONST_INT) {
- semantic_error(scope->fctx, members,
- "unable to process nonconstant expression");
- return -1;
- }
+ struct ast *val = val_val(members);
+ if (actualize(state, enum_scope, val))
+ return -1;
- counter = int_val(val);
- }
- else {
- val_val(members) = gen_const_int(counter, NULL_LOC());
+ if (val->k != AST_CONST_INT) {
+ semantic_error(scope->fctx, members,
+ "unable to process nonconstant expression");
+ return -1;
}
+ counter = int_val(val) + 1;
members = members->n;
- counter++;
}
/* TODO: check that we don't go outside the limits of the type */
@@ -2681,6 +2709,7 @@ static int actualize(struct act_state *state, struct scope *scope,
}
switch (node->k) {
+ case AST_IMPORT: ret = 0; node->t = void_type(); break;
case AST_PROC_DEF: ret = actualize_proc(state, scope, node); break;
case AST_TRAIT_DEF: ret = actualize_trait(state, scope, node); break;
case AST_ALIAS_DEF: ret = actualize_alias(state, scope, node); break;