summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-31 17:54:29 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-31 18:02:32 -0400
commit11c93eafd9b19546a1190a7cf8c9d5bf70a56e58 (patch)
treed9fd3169b8347871f9aab42e187fde5406354846
parent9e55cdb1ea5cd8318a1a0b7a9f64f09e8d8ad692 (diff)
discovered a bug where stuff isn't typed before being eval'd. trying to fix it.
-rw-r--r--.gitignore1
-rw-r--r--cgen.c19
-rw-r--r--eval.c17
-rw-r--r--main.c2
-rw-r--r--test.toc23
-rw-r--r--types.c16
-rw-r--r--types.h2
7 files changed, 37 insertions, 43 deletions
diff --git a/.gitignore b/.gitignore
index 02d75f2..7337ed8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ a.out
out.c
tests/**/*.c
tests/**/*.bin
+vgcore* \ No newline at end of file
diff --git a/cgen.c b/cgen.c
index 22ac57d..78a2b5f 100644
--- a/cgen.c
+++ b/cgen.c
@@ -117,12 +117,7 @@ static void cgen_ident(CGenerator *g, Identifier i) {
cgen_write(g, "main__");
} else {
cgen_indent(g);
- IdentDecl *idecl = ident_decl(i);
- if (idecl && (idecl->flags & IDECL_FLAG_CGEN_PTR))
- cgen_write(g, "(*");
fprint_ident(cgen_writing_to(g), i);
- if (idecl && (idecl->flags & IDECL_FLAG_CGEN_PTR))
- cgen_write(g, ")");
}
}
@@ -307,21 +302,17 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) {
}
cgen_write(g, "(");
arr_foreach(f->params, Declaration, d) {
+ long idx = 0;
arr_foreach(d->idents, Identifier, i) {
if (d != f->params || i != d->idents)
cgen_write(g, ", ");
+ Type *type = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx++] : &d->type;
any_params = true;
- if (!cgen_type_pre(g, &d->type, where))
+ if (!cgen_type_pre(g, type, where))
return false;
cgen_write(g, " ");
- bool ptr = cgen_uses_ptr(&d->type);
- if (ptr) {
- IdentDecl *idecl = ident_decl(*i);
- assert(idecl);
- idecl->flags |= IDECL_FLAG_CGEN_PTR;
- }
cgen_ident(g, *i);
- if (!cgen_type_post(g, &d->type, where))
+ if (!cgen_type_post(g, type, where))
return false;
}
}
@@ -469,8 +460,6 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
arr_foreach(to->call.arg_exprs, Expression, arg) {
if (arg != to->call.arg_exprs)
cgen_write(g, ", ");
- if (cgen_uses_ptr(&arg->type))
- cgen_write(g, "&");
if (!cgen_expr(g, arg))
return false;
}
diff --git a/eval.c b/eval.c
index ed88c2c..86fdc61 100644
--- a/eval.c
+++ b/eval.c
@@ -1,13 +1,15 @@
+static bool types_block(Typer *tr, Block *b);
static size_t compiler_sizeof(Type *t);
static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v);
static bool eval_expr(Evaluator *ev, Expression *e, Value *v);
static bool block_enter(Block *b, Statement *stmts, U32 flags);
static void block_exit(Block *b, Statement *stmts);
-static void evalr_create(Evaluator *ev) {
+static void evalr_create(Evaluator *ev, Typer *tr) {
allocr_create(&ev->allocr);
ev->returning = NULL;
ev->to_free = NULL;
+ ev->typer = tr;
}
static void evalr_free(Evaluator *ev) {
@@ -706,7 +708,11 @@ static bool eval_set(Evaluator *ev, Expression *set, Value *to) {
return true;
}
-static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
+static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
+ if (e->type.kind == TYPE_UNKNOWN) {
+ err_print(e->where, "Cannot determine type of expression.");
+ return false;
+ }
/* WARNING: macros ahead */
#define eval_unary_op_one(low, up, op) \
case BUILTIN_##up: \
@@ -1073,6 +1079,9 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
if (!eval_expr(ev, e->call.fn, &fnv))
return false;
FnExpr *fn = fnv.fn;
+ /* make sure function body is typed before calling it */
+ if (!types_block(ev->typer, &fn->body))
+ return false;
/* set parameter declaration values */
Declaration *params = fn->params;
/* OPTIM (NOTE: currently needed for recursion) */
@@ -1085,9 +1094,11 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
fn_enter(fn, 0);
long arg = 0;
arr_foreach(params, Declaration, p) {
+ long idx = 0;
arr_foreach(p->idents, Identifier, i) {
+ Type *type = p->type.kind == TYPE_TUPLE ? &p->type.tuple[idx++] : &p->type;
IdentDecl *id = ident_decl(*i);
- id->val = args[arg];
+ val_copy(NULL, &id->val, &args[arg], type);
id->flags |= IDECL_FLAG_HAS_VAL;
arg++;
}
diff --git a/main.c b/main.c
index ec7e164..557d389 100644
--- a/main.c
+++ b/main.c
@@ -85,7 +85,7 @@ int main(int argc, char **argv) {
Typer tr;
Evaluator ev;
- evalr_create(&ev);
+ evalr_create(&ev, &tr);
typer_create(&tr, &ev);
if (!block_enter(NULL, f.stmts, SCOPE_FLAG_CHECK_REDECL)) /* enter global scope */
diff --git a/test.toc b/test.toc
index 3fc2dc2..3a17585 100644
--- a/test.toc
+++ b/test.toc
@@ -7,15 +7,22 @@ Point @= struct {
x, y : int;
};
-sum34 @= fn() int {
- p: Point;
- x := &p.x;
- *x = 3;
- p.y = 4;
- p.x + p.y
+sum @= fn(p: &Point) int {
+ p.x + p.y
+};
+
+
+somesum @= fn() int {
+
+ p : Point;
+ p.x = 12389;
+ p.y = 29404;
+ total := sum(&p);
+ total
};
main @= fn() {
-X @= sum34();
-puti(sum34());
+// puti(somesum());
+foo @= somesum();
+// puti(foo);
};
diff --git a/types.c b/types.c
index 0726550..cdc762b 100644
--- a/types.c
+++ b/types.c
@@ -106,10 +106,6 @@ static bool expr_arr_must_mut(Expression *e) {
err_print(e->where, "Cannot modify a constant array.");
return false;
}
- if (d->flags & DECL_FLAG_PARAM) {
- err_print(e->where, "Parameters are immutable.");
- return false;
- }
} return true;
case EXPR_CAST:
case EXPR_CALL:
@@ -742,7 +738,6 @@ static bool types_expr(Typer *tr, Expression *e) {
err_print(e->where, "Calling non-function (type %s).", type);
return false;
}
-
Type *ret_type = f->type.fn.types;
Type *param_types = ret_type + 1;
Argument *args = c->args;
@@ -837,8 +832,8 @@ static bool types_expr(Typer *tr, Expression *e) {
}
}
}
- c->arg_exprs = new_args;
*t = *ret_type;
+ c->arg_exprs = new_args;
break;
}
case EXPR_BLOCK: {
@@ -959,15 +954,6 @@ static bool types_expr(Typer *tr, Expression *e) {
if (!expr_must_lval(e->binary.lhs)) {
return false;
}
- {
- if (lhs->kind == EXPR_IDENT) {
- Declaration *d = ident_decl(lhs->ident)->decl;
- if (d->flags & DECL_FLAG_PARAM) {
- err_print(e->where, "Parameters are immutable.");
- return false;
- }
- }
- }
/* fallthrough */
case BINARY_ADD:
diff --git a/types.h b/types.h
index d89d6a8..523f882 100644
--- a/types.h
+++ b/types.h
@@ -95,7 +95,6 @@ typedef union Value {
} Value;
#define IDECL_FLAG_HAS_VAL 0x01
-#define IDECL_FLAG_CGEN_PTR 0x02 /* is a pointer being used for this identifier? */
typedef struct {
struct Declaration *decl;
struct Block *scope; /* NULL for file scope */
@@ -547,6 +546,7 @@ typedef enum {
typedef struct {
Allocator allocr;
+ struct Typer *typer;
bool returning;
Value ret_val;
void **to_free; /* an array of data to free for this scope. */