aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-08-14 18:08:54 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-08-14 18:08:54 +0300
commit085817c69d145400eac84e09704f48ede2bece68 (patch)
tree593f8a8bf8254cb78586d0355d7a0e1dbbe71c59
parent6385450ddba34bc28bd7492d126fd38cb3f86f36 (diff)
downloadek-085817c69d145400eac84e09704f48ede2bece68.tar.gz
ek-085817c69d145400eac84e09704f48ede2bece68.zip
compiling example of a res struct
-rw-r--r--examples/res.ek25
-rw-r--r--src/actualize.c39
-rw-r--r--src/lower.c2
3 files changed, 49 insertions, 17 deletions
diff --git a/examples/res.ek b/examples/res.ek
new file mode 100644
index 0000000..f7c96df
--- /dev/null
+++ b/examples/res.ek
@@ -0,0 +1,25 @@
+/* simple example with C-like strings. A real implementation would likely want
+ * to use a string wrapper or something. */
+
+typedef i27 {}
+typedef i9 {}
+
+typedef res[any T] {
+ *i9 e;
+ T v;
+
+ ok(T v => res![T]) {
+ return res![T]{.e = 0 as *i9, .v = v};
+ }
+
+ error(*i9 e, T v => res![T]) {
+ return res![T]{.e = e, .v = v};
+ }
+}
+
+define any[] {}
+
+main()
+{
+ const a = ok::res![i27](20);
+}
diff --git a/src/actualize.c b/src/actualize.c
index 66fcff9..5a642a7 100644
--- a/src/actualize.c
+++ b/src/actualize.c
@@ -618,9 +618,6 @@ static int replace_id(struct ast *body, struct ast *id,
static int implements(struct type *trait, struct type *type)
{
- assert(type->d);
- struct ast *def = type->d;
-
assert(trait->d);
struct ast *trait_def = trait->d;
assert(trait_def->k == AST_TRAIT_DEF);
@@ -629,6 +626,9 @@ static int implements(struct type *trait, struct type *type)
if (!trait_body(trait_def))
return 1;
+ assert(type->d);
+ struct ast *def = type->d;
+
foreach_node(n, def) {
if (n->k != AST_TYPE_EXPAND)
continue;
@@ -765,7 +765,6 @@ static struct ast *maybe_expand_struct(struct scope *scope, struct ast *def,
if (expand_type(expd, struct_params(def), args))
return NULL;
- scope_add_expd_struct(scope, def, args, expd);
return expd;
}
@@ -1033,15 +1032,15 @@ static int actualize_proc_sign(struct scope *scope, struct ast *proc)
if (!proc_rtype(proc))
proc_rtype(proc) = void_type();
- if (actualize_type_list(&new_state, proc->scope, proc_rtype(proc))) {
+ struct type *rtype = clone_type(proc_rtype(proc));
+ if (actualize_type_list(&new_state, proc->scope, rtype)) {
destroy_act_state(&new_state);
return -1;
}
- struct type *callable = tgen_callable(NULL, proc_rtype(proc),
- proc->loc);
+ struct type *callable = tgen_callable(NULL, rtype, proc->loc);
foreach_node(p, proc_params(proc)) {
- /* we must manually 'start' the chain **/
+ /* we must manually 'start' the chain */
if (!callable_ptypes(callable)) {
callable_ptypes(callable) = clone_type(p->t);
continue;
@@ -1424,7 +1423,7 @@ static int actualize_tconstruct(struct act_state *state,
struct type *t)
{
assert(t->k == TYPE_CONSTRUCT);
- struct ast *d = file_scope_find_type(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;
@@ -1668,8 +1667,8 @@ 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 = proc_rtype(cur_proc);
- if (!types_match(node->t, rtype)) {
+ struct type *rtype = cur_proc->t;
+ if (!types_match(node->t, callable_rtype(rtype))) {
type_mismatch(scope, "return type mismatch", node, rtype,
node->t);
return -1;
@@ -2082,6 +2081,7 @@ static int actualize_struct(struct act_state *state,
node->t = tgen_struct(id, node, node->loc);
/* iterate over types and make aliases to them */
+ struct type *types = NULL;
foreach_node(n, struct_params(node)) {
char *id = var_id(n);
struct type *type = var_type(n);
@@ -2089,10 +2089,9 @@ static int actualize_struct(struct act_state *state,
if (actualize_type(&type_state, scope, type))
return -1;
- type_append(&tstruct_params(node->t), type);
+ type_append(&types, type);
- struct ast *alias = gen_alias(strdup(id), clone_type(type),
- n->loc);
+ struct ast *alias = gen_alias(strdup(id), type, n->loc);
if (analyze_visibility(struct_scope, alias))
return -1;
@@ -2101,6 +2100,13 @@ static int actualize_struct(struct act_state *state,
return -1;
}
+ if (node->t->k == TYPE_STRUCT)
+ tstruct_params(node->t) = types;
+
+ struct ast *def = file_scope_find_type(scope, id);
+ int ret = scope_add_expd_struct(scope, def, types, node);
+ assert(ret == 0);
+
foreach_node(n, struct_body(node)) {
if (n->k != AST_TYPE_EXPAND)
continue;
@@ -2265,10 +2271,11 @@ static int actualize_init(struct act_state *state,
return -1;
}
- if (actualize_type_list(state, scope, init_args(node)))
+ struct type *types = clone_type_list(init_args(node));
+ if (actualize_type_list(state, scope, types))
return -1;
- def = maybe_expand_type(scope, def, node->loc, init_args(node));
+ def = maybe_expand_type(scope, def, node->loc, types);
if (!def)
return -1;
diff --git a/src/lower.c b/src/lower.c
index d0dd161..02d28e4 100644
--- a/src/lower.c
+++ b/src/lower.c
@@ -206,7 +206,7 @@ static ssize_t visit_struct(struct lower_state *s, struct ast *def, size_t base,
if (r < 0)
return -1;
- offset += (size_t)r;
+ offset = (size_t)r;
continue;
}