From 62dfeef42d6c2e279165b6dbe73ee3abf98db146 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Tue, 27 Aug 2019 16:02:07 -0400 Subject: basic type inference --- cgen.c | 2 +- infer.c | 32 ++++++++++++++++++++++++++++++++ out.c | 2 ++ parse.c | 4 +++- test.toc | 3 +++ 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 -- cgit v1.2.3