summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c2
-rw-r--r--decls_cgen.c2
-rw-r--r--parse.c2
-rw-r--r--test.toc2
-rw-r--r--types.c24
5 files changed, 25 insertions, 7 deletions
diff --git a/cgen.c b/cgen.c
index ec4c6ab..57eb93f 100644
--- a/cgen.c
+++ b/cgen.c
@@ -292,8 +292,6 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) {
cgen_write(g, " ");
bool ptr = cgen_uses_ptr(&d->type);
if (ptr) {
- fprint_type(stdout, &d->type);
- puts("");
IdentDecl *idecl = ident_decl(*i);
assert(idecl);
idecl->flags |= IDECL_FLAG_CGEN_PTR;
diff --git a/decls_cgen.c b/decls_cgen.c
index 58d8667..58383f7 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -57,12 +57,14 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) {
case EXPR_FN:
e->fn.c.name = NULL;
e->fn.c.id = g->ident_counter++;
+ fn_enter(&e->fn, 0);
if (!cgen_fn_header(g, &e->fn, e->where))
return false;
cgen_write(g, ";");
cgen_nl(g);
if (!cgen_decls_block(g, &e->fn.body))
return false;
+ fn_exit(&e->fn);
break;
case EXPR_TYPE:
case EXPR_DIRECT:
diff --git a/parse.c b/parse.c
index 9061e12..71936ba 100644
--- a/parse.c
+++ b/parse.c
@@ -723,6 +723,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
default:
unrecognized:
tokr_err(t, "Unrecognized expression.");
+ t->token = end + 1;
return false;
}
t->token = end;
@@ -1282,7 +1283,6 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
return true;
}
tokr_err(t, "Unrecognized expression.");
- t->token = end + 1;
return false;
}
}
diff --git a/test.toc b/test.toc
index 7aaeb3a..148b50a 100644
--- a/test.toc
+++ b/test.toc
@@ -16,5 +16,7 @@ putf @= fn(x: float) {
Foo @= int;
main @= fn() {
+ f := fn(x: int) { p := &x; *p = 5; };
+ // f(3);
// x : Foo;
};
diff --git a/types.c b/types.c
index f2f4baf..2d4e702 100644
--- a/types.c
+++ b/types.c
@@ -99,6 +99,10 @@ 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:
@@ -887,10 +891,12 @@ static bool types_expr(Typer *tr, Expression *e) {
}
} break;
case EXPR_BINARY_OP: {
- Type *lhs_type = &e->binary.lhs->type;
- Type *rhs_type = &e->binary.rhs->type;
- if (!types_expr(tr, e->binary.lhs)
- || !types_expr(tr, e->binary.rhs))
+ Expression *lhs = e->binary.lhs;
+ Expression *rhs = e->binary.rhs;
+ Type *lhs_type = &lhs->type;
+ Type *rhs_type = &rhs->type;
+ if (!types_expr(tr, lhs)
+ || !types_expr(tr, rhs))
return false;
if (lhs_type->kind == TYPE_UNKNOWN || rhs_type->kind == TYPE_UNKNOWN) {
return true;
@@ -900,6 +906,16 @@ 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:
case BINARY_SUB: