summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-08-27 16:02:07 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-08-27 16:02:07 -0400
commit62dfeef42d6c2e279165b6dbe73ee3abf98db146 (patch)
tree1fed7f782a1ead7308a0ee7a4439d74f50fa272e
parentdf10470f1f10f1f1f2f5cad792976de8d734bf27 (diff)
basic type inference
-rw-r--r--cgen.c2
-rw-r--r--infer.c32
-rw-r--r--out.c2
-rw-r--r--parse.c4
-rw-r--r--test.toc3
5 files changed, 41 insertions, 2 deletions
diff --git a/cgen.c b/cgen.c
index 222d624..2cb7dcb 100644
--- a/cgen.c
+++ b/cgen.c
@@ -5,7 +5,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
break;
case EXPR_FLOAT_LITERAL:
/* TODO: more precision */
- cgen_write(g, "%f", e->floatl);
+ cgen_write(g, "%f", (double)e->floatl);
break;
case EXPR_STR_LITERAL:
cgen_write(g, "\"");
diff --git a/infer.c b/infer.c
index f4faf07..dad5241 100644
--- a/infer.c
+++ b/infer.c
@@ -1,3 +1,35 @@
+/* if check_curr, this will check against the current value of t */
+static bool infer_expr(Expression *e) {
+ Type *t = &e->type;
+ switch (e->kind) {
+ case EXPR_INT_LITERAL:
+ t->kind = TYPE_BUILTIN;
+ t->builtin = BUILTIN_I64;
+ break;
+ case EXPR_FLOAT_LITERAL:
+ t->kind = TYPE_BUILTIN;
+ t->builtin = BUILTIN_FLOAT;
+ break;
+ }
+ return true;
+}
+
+static bool type_eq(Type *a, Type *b) {
+ return true; /* TODO */
+}
+
static bool infer_decl(Declaration *d) {
+ if (d->flags & DECL_FLAG_FOUND_TYPE) return true;
+ if (!infer_expr(&d->expr)) return false;
+ if (d->flags & DECL_FLAG_INFER_TYPE) {
+ d->type = d->expr.type;
+ } else {
+ if (!type_eq(&d->type, &d->expr.type)) {
+ /* TODO more helpful error */
+ err_print(d->where, "Type mismatch");
+ return false;
+ }
+ }
+ d->flags |= DECL_FLAG_FOUND_TYPE;
return true;
}
diff --git a/out.c b/out.c
index ca6858c..33076c5 100644
--- a/out.c
+++ b/out.c
@@ -7,6 +7,8 @@ void main__(void) {
void (*bar)(void) = a___;
foo();
a___();
+ int64_t r = 12;
+ float p = 13.800000;
}
static void foo(void) {
void (*x)(void) = a___;
diff --git a/parse.c b/parse.c
index c4d8588..5b1326b 100644
--- a/parse.c
+++ b/parse.c
@@ -69,7 +69,7 @@ typedef enum {
BINARY_MINUS
} BinaryOp;
-#define EXPR_FLAG_FLEXIBLE 0x01
+#define EXPR_FLAG_FLEXIBLE 0x01 /* e.g. 4 => float/i32/etc. */
typedef struct Expression {
Location where;
@@ -101,6 +101,7 @@ typedef struct Expression {
#define DECL_FLAG_INFER_TYPE 0x01
#define DECL_FLAG_CONST 0x02
#define DECL_FLAG_HAS_EXPR 0x04
+#define DECL_FLAG_FOUND_TYPE 0x08
/* OPTIM: Instead of using dynamic arrays, do two passes. */
typedef struct Declaration {
@@ -446,6 +447,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
e->type.kind = TYPE_BUILTIN;
e->type.builtin = BUILTIN_FLOAT;
e->floatl = num->floatval;
+ printf("%g\n",(double)e->floatl);
break;
case NUM_LITERAL_INT:
e->kind = EXPR_INT_LITERAL;
diff --git a/test.toc b/test.toc
index 0adc8f2..94c5a84 100644
--- a/test.toc
+++ b/test.toc
@@ -5,4 +5,7 @@ main @= fn() {
foo();
bar();
+
+ r := 12;
+ p @= 13.8;
}; \ No newline at end of file