summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-12-16 09:49:50 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2019-12-16 09:49:50 -0500
commitaa3ce16dc115f7b6f04e46fc1e311263aa2bc21b (patch)
treecb0ae72b5c90839db76223f285fe0e2653ee8404
parentdd4a12e33e2e04e90e6ceb92aae71c3f3b3bdd85 (diff)
better inference
-rw-r--r--infer.c16
-rw-r--r--test.toc11
-rw-r--r--typedefs_cgen.c24
3 files changed, 37 insertions, 14 deletions
diff --git a/infer.c b/infer.c
index 02fd34c..1e99fec 100644
--- a/infer.c
+++ b/infer.c
@@ -23,6 +23,22 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Expres
}
break;
case EXPR_CALL: {
+ while (to->kind == EXPR_IDENT) {
+ IdentDecl *idecl = ident_decl(to->ident);
+ if (idecl->kind == IDECL_DECL) {
+ Declaration *decl = idecl->decl;
+ int index = ident_index_in_decl(to->ident, decl);
+ Expression *expr = NULL;
+ if (decl->type.kind == TYPE_TUPLE) {
+ if (decl->expr.kind == EXPR_TUPLE) {
+ expr = &decl->expr.tuple[index];
+ }
+ } else {
+ expr = &decl->expr;
+ }
+ if (expr) to = expr;
+ } else break;
+ }
if (to->kind != EXPR_CALL) return true; /* give up */
Argument *m_args = match->call.args;
Expression *t_args = to->call.arg_exprs;
diff --git a/test.toc b/test.toc
index c53a160..9b414ad 100644
--- a/test.toc
+++ b/test.toc
@@ -6,7 +6,12 @@ putf ::= fn(x: float) {
#C("printf(\"%f\\n\", (double)x);
");
};
+
main ::= fn() {
- x : : = 3;
- puti(x);
-}; \ No newline at end of file
+ Integer ::= id(int);
+ x : Integer;
+ puti(foo(x));
+};
+id ::= fn(t ::=, x :: t) t { x };
+
+foo ::= fn(t ::=, x : id(t)) int { 3 as t };
diff --git a/typedefs_cgen.c b/typedefs_cgen.c
index cfba024..3760eec 100644
--- a/typedefs_cgen.c
+++ b/typedefs_cgen.c
@@ -72,18 +72,20 @@ static bool typedefs_decl(CGenerator *g, Declaration *d) {
cgen_write(g, ";");
}
} else {
- cgen_write(g, "typedef ");
- if (!cgen_type_pre(g, val->type, d->where)) return false;
- cgen_write(g, " ");
- if (id) {
- cgen_ident_id(g, id);
- } else {
- cgen_ident(g, i);
- }
- if (val->type->kind != TYPE_STRUCT) {
- if (!cgen_type_post(g, val->type, d->where)) return false;
+ if (val->type->kind != TYPE_TYPE) {
+ cgen_write(g, "typedef ");
+ if (!cgen_type_pre(g, val->type, d->where)) return false;
+ cgen_write(g, " ");
+ if (id) {
+ cgen_ident_id(g, id);
+ } else {
+ cgen_ident(g, i);
+ }
+ if (val->type->kind != TYPE_STRUCT) {
+ if (!cgen_type_post(g, val->type, d->where)) return false;
+ }
+ cgen_write(g, ";");
}
- cgen_write(g, ";");
}
cgen_nl(g);
}