summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-12-11 19:15:43 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2019-12-11 19:15:43 -0500
commit4792c78ad79404c64decc5af780f1c979a4e7f14 (patch)
tree90b78304534dc92c5816341f0c7eb7b96a11deb6
parent91573bf993dc595dcbc1f83c28c4f7ee66ac334b (diff)
more infer
-rw-r--r--infer.c39
-rw-r--r--test.toc9
-rw-r--r--types.c42
3 files changed, 32 insertions, 58 deletions
diff --git a/infer.c b/infer.c
index ac32f81..d4d4513 100644
--- a/infer.c
+++ b/infer.c
@@ -1,16 +1,29 @@
-/* infers */
-static bool infer_expr(Typer *tr, Expression *e, Declaration *decls,
- Expression *exprs) {
- e->kind = EXPR_VAL;
- Value *val = &e->val;
- val->type = malloc(sizeof *val->type);
- memset(val->type, 0, sizeof *val->type);
- val->type->kind = TYPE_BUILTIN;
- val->type->builtin = BUILTIN_I64;
- val->type->flags = TYPE_IS_RESOLVED;
- memset(&e->type, 0, sizeof e->type);
- e->type.kind = TYPE_TYPE;
- e->type.flags = TYPE_IS_RESOLVED;
+/* infers the expression of decls[idx], according to the types of the other decls */
+static bool infer_expr(Typer *tr, size_t idx, Declaration *decls) {
+ Declaration *decl = decls + idx;
+ if (decl->flags & DECL_HAS_EXPR) return true; /* already did it */
+
+ decl->expr.kind = EXPR_VAL;
+ decl->expr.type.flags = TYPE_IS_RESOLVED;
+ decl->expr.type.kind = TYPE_TYPE;
+ decl->expr.val.type = calloc(1,sizeof (Type));
+ decl->expr.val.type->kind = TYPE_BUILTIN;
+ decl->expr.val.type->builtin = BUILTIN_I64;
+ decl->expr.val.type->flags = TYPE_IS_RESOLVED;
+
+ decl->type = decl->expr.type;
+ decl->flags |= DECL_FOUND_TYPE;
+ decl->flags |= DECL_HAS_EXPR;
+ return true;
+}
+
+/* infers ALL of the expressions in the declarations */
+static bool infer_exprs_in_decls(Typer *tr, Declaration *decls) {
+ for (size_t idx = 0; idx < arr_len(decls); ++idx) {
+ if (decls[idx].flags & DECL_INFER)
+ if (!infer_expr(tr, idx, decls))
+ return false;
+ }
return true;
}
diff --git a/test.toc b/test.toc
index 8cb0741..74980c0 100644
--- a/test.toc
+++ b/test.toc
@@ -1,8 +1,7 @@
-P ::= struct {
- x, y:int;
+f ::= fn(t::=, x :t) t {
+ x + 1
};
+
main ::= fn() {
- p:P;
- x::="y";
- p[x];
+ f(13);
}; \ No newline at end of file
diff --git a/types.c b/types.c
index 1b3d8b2..405d9b1 100644
--- a/types.c
+++ b/types.c
@@ -1203,7 +1203,8 @@ static bool types_expr(Typer *tr, Expression *e) {
U64 *which_are_const = &which_are_const_val->u64;
*which_are_const = 0;
int semi_const_index = 0;
-
+ if (!infer_exprs_in_decls(tr, fn->params))
+ return false;
/* eval compile time arguments */
for (i = 0; i < nparams; ++i) {
bool should_be_evald = arg_is_const(&arg_exprs[i], fn_type->constness[i]);
@@ -1230,45 +1231,6 @@ static bool types_expr(Typer *tr, Expression *e) {
if (!(param_decl->flags & DECL_ANNOTATES_TYPE)) {
param_decl->type = *type;
}
- } else if (param_decl->flags & DECL_INFER) {
- arg_exprs[i].kind = EXPR_VAL;
- arg_exprs[i].flags = EXPR_FOUND_TYPE;
- {
- for (Declaration *p = fn->params; p < param_decl; ++p) {
- if (p->flags & DECL_FOUND_VAL)
- if (!add_ident_decls(&fn->body, p, SCOPE_CHECK_REDECL)) {
- for (Declaration *q = fn->params; q < p; ++q)
- if (q->flags & DECL_FOUND_VAL)
- remove_ident_decls(&fn->body, q);
- return false;
- }
- }
- }
- bool success = infer_expr(tr, &arg_exprs[i], fn->params, arg_exprs);
- for (Declaration *p = fn->params; p < param_decl; ++p) {
- if (p->flags & DECL_FOUND_VAL)
- remove_ident_decls(&fn->body, p);
- }
- if (!success) return false;
- copy_val(tr->allocr, &param_decl->val, &arg_exprs[i].val, &arg_exprs[i].type);
-
-
- if (param_decl->flags & DECL_ANNOTATES_TYPE) {
- if (!type_resolve(tr, &param_decl->type, param_decl->where))
- return false;
- Type *expected = &arg_exprs[i].type;
- Type *got = &param_decl->type;
- if (!type_eq(expected, got)) {
- char *estr = type_to_str(expected);
- char *gstr = type_to_str(got);
- err_print(param_decl->where, "Expected annotated type %s for this argument, but it was annotated as %s.", estr, gstr);
- free(estr); free(gstr);
- return false;
- }
- }
- param_decl->type = arg_exprs[i].type;
- param_decl->flags |= DECL_FOUND_VAL|DECL_FOUND_TYPE;
- params_set[i] = true;
} else {
/* leave gap for this (default argument) */
typer_arr_add(tr, &table_index.tuple);