summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh2
-rw-r--r--cgen.c18
-rw-r--r--copy.c61
-rw-r--r--decls_cgen.c2
-rw-r--r--eval.c6
-rw-r--r--infer.c9
-rw-r--r--main.c1
-rw-r--r--parse.c67
-rw-r--r--sdecls_cgen.c7
-rw-r--r--test.toc72
-rw-r--r--types.c30
-rw-r--r--types.h3
12 files changed, 179 insertions, 99 deletions
diff --git a/build.sh b/build.sh
index 6a415a6..6f9b1d3 100755
--- a/build.sh
+++ b/build.sh
@@ -29,6 +29,8 @@ fi
DEBUG_FLAGS="-O0 $WARNINGS -std=c11 -DTOC_DEBUG"
if [ "$CC" = "gcc" ]; then
DEBUG_FLAGS="$DEBUG_FLAGS -no-pie -gdwarf-2 -pipe"
+elif [ "$CC" = "clang" ]; then
+ DEBUG_FLAGS="$DEBUG_FLAGS -no-pie -gdwarf-2 -pipe"
fi
RELEASE_FLAGS="-O3 -s -DNDEBUG $WARNINGS -std=c11"
diff --git a/cgen.c b/cgen.c
index 79c2745..a3903a8 100644
--- a/cgen.c
+++ b/cgen.c
@@ -35,14 +35,16 @@ static void cgen_defs_block(CGenerator *g, Block *b);
static void cgen_defs_decl(CGenerator *g, Declaration *d);
#define cgen_recurse_subexprs_fn_simple(fn, decl_f, block_f) \
- FnExpr *prev_fn = g->f##n; \
- g->f##n = fn; \
- arr_foreach(fn->params, Declaration, param) \
- decl_f(g, param); \
- arr_foreach(fn->ret_decls, Declaration, r) \
- decl_f(g, r); \
- block_f(g, &fn->body); \
- g->f##n = prev_fn;
+ if (!(fn->flags & FN_EXPR_FOREIGN)) { \
+ FnExpr *prev_fn = g->f##n; \
+ g->f##n = fn; \
+ arr_foreach(fn->params, Declaration, param) \
+ decl_f(g, param); \
+ arr_foreach(fn->ret_decls, Declaration, r) \
+ decl_f(g, r); \
+ block_f(g, &fn->body); \
+ g->f##n = prev_fn; \
+ }
/* calls f on every sub-expression of e, block_f on every sub-block, and decl_f on every sub-declaration. */
#define cgen_recurse_subexprs(g, e, f, block_f, decl_f) \
diff --git a/copy.c b/copy.c
index 28115d2..b821750 100644
--- a/copy.c
+++ b/copy.c
@@ -172,31 +172,44 @@ static Type *copy_type_(Copier *c, Type *in) {
return out;
}
+static inline void *copier_malloc(Copier *c, size_t n) {
+ return allocr_malloc(c->allocr, n);
+}
+
static void copy_fn_expr(Copier *c, FnExpr *fout, FnExpr *fin, bool copy_body) {
*fout = *fin;
- Block *prev;
- if (copy_body) {
- prev = c->block;
- c->block = &fout->body;
- idents_create(&fout->body.idents, c->allocr, &fout->body);
- }
- size_t i;
- size_t nparam_decls = arr_len(fin->params);
- fout->params = NULL;
- arr_set_lena(&fout->params, nparam_decls, c->allocr);
- for (i = 0; i < nparam_decls; ++i)
- copy_decl(c, fout->params + i, fin->params + i);
- size_t nret_decls = arr_len(fin->ret_decls);
- if (fin->ret_decls) {
- fout->ret_decls = NULL;
- arr_set_lena(&fout->ret_decls, nret_decls, c->allocr);
- for (i = 0; i < nret_decls; ++i)
- copy_decl(c, fout->ret_decls + i, fin->ret_decls + i);
- }
- copy_type(c, &fout->ret_type, &fin->ret_type);
- if (copy_body) {
- copy_block(c, &fout->body, &fin->body, COPY_BLOCK_DONT_CREATE_IDENTS);
- c->block = prev;
+ if (fin->flags & FN_EXPR_FOREIGN) {
+ copy_expr(c, fout->foreign.name_expr = copier_malloc(c, sizeof *fin->foreign.name_expr), fin->foreign.name_expr);
+ copy_expr(c, fout->foreign.lib_expr = copier_malloc(c, sizeof *fin->foreign.lib_expr), fin->foreign.lib_expr);
+ copy_type(c, &fout->foreign.type, &fin->foreign.type);
+ size_t nctypes = arr_len(fin->foreign.type.fn.types);
+ fout->foreign.ctypes = copier_malloc(c, nctypes * sizeof(CType));
+ memcpy(fout->foreign.ctypes, fin->foreign.ctypes, nctypes * sizeof(CType));
+ } else {
+ Block *prev;
+ if (copy_body) {
+ prev = c->block;
+ c->block = &fout->body;
+ idents_create(&fout->body.idents, c->allocr, &fout->body);
+ }
+ size_t i;
+ size_t nparam_decls = arr_len(fin->params);
+ fout->params = NULL;
+ arr_set_lena(&fout->params, nparam_decls, c->allocr);
+ for (i = 0; i < nparam_decls; ++i)
+ copy_decl(c, fout->params + i, fin->params + i);
+ size_t nret_decls = arr_len(fin->ret_decls);
+ if (fin->ret_decls) {
+ fout->ret_decls = NULL;
+ arr_set_lena(&fout->ret_decls, nret_decls, c->allocr);
+ for (i = 0; i < nret_decls; ++i)
+ copy_decl(c, fout->ret_decls + i, fin->ret_decls + i);
+ }
+ copy_type(c, &fout->ret_type, &fin->ret_type);
+ if (copy_body) {
+ copy_block(c, &fout->body, &fin->body, COPY_BLOCK_DONT_CREATE_IDENTS);
+ c->block = prev;
+ }
}
}
@@ -335,7 +348,7 @@ static void copy_expr(Copier *c, Expression *out, Expression *in) {
sout->to = copy_expr_(c, sin->to);
} break;
case EXPR_TYPE:
- copy_type(c, &out->typeval, &in->typeval);
+ copy_type(c, out->typeval = copier_malloc(c, sizeof *out->typeval), in->typeval);
break;
case EXPR_VAL:
copy_val(a, &out->val, &in->val, &in->type);
diff --git a/decls_cgen.c b/decls_cgen.c
index 7dcd311..70e405c 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -184,7 +184,7 @@ static void cgen_decls_expr(CGenerator *g, Expression *e) {
cgen_fn_decl(g, e->fn, &e->type);
} break;
case EXPR_TYPE: {
- Type *type = &e->typeval;
+ Type *type = e->typeval;
cgen_decls_type(g, type);
} break;
case EXPR_CAST:
diff --git a/eval.c b/eval.c
index 08db84b..df2c3c6 100644
--- a/eval.c
+++ b/eval.c
@@ -986,11 +986,11 @@ static Status eval_ident(Evaluator *ev, Identifier ident, Value *v, Location whe
Declaration *d = NULL;
if (is_decl) {
d = ident->decl;
- if ((d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_TYPE && d->expr.typeval.kind == TYPE_STRUCT) {
+ if ((d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_TYPE && d->expr.typeval->kind == TYPE_STRUCT) {
v->type = allocr_malloc(ev->allocr, sizeof *v->type);
v->type->flags = TYPE_IS_RESOLVED;
v->type->kind = TYPE_STRUCT;
- v->type->struc = d->expr.typeval.struc;
+ v->type->struc = d->expr.typeval->struc;
return true;
} else {
if (!types_decl(ev->typer, d)) return false;
@@ -1526,7 +1526,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
}
} break;
case EXPR_TYPE:
- v->type = &e->typeval;
+ v->type = e->typeval;
break;
case EXPR_NMS:
v->nms = e->nms;
diff --git a/infer.c b/infer.c
index f96c35e..49fa364 100644
--- a/infer.c
+++ b/infer.c
@@ -32,7 +32,7 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Identi
break;
case EXPR_CALL: {
- if (to->kind == EXPR_TYPE && to->typeval.kind == TYPE_STRUCT) {
+ if (to->kind == EXPR_TYPE && to->typeval->kind == TYPE_STRUCT) {
/* maybe it's a parameterized struct? */
/* it might not be possible that it's not, but might as well keep that possibility around. */
Value fn_val = {0};
@@ -52,7 +52,7 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Identi
free(order);
return false;
}
- Declaration *params = to->typeval.struc->params;
+ Declaration *params = to->typeval->struc->params;
int arg_idx = 0;
arr_foreach(params, Declaration, param) {
int ident_idx = 0;
@@ -96,7 +96,7 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Identi
}
if (to->kind != EXPR_CALL) {
if (to->kind == EXPR_TYPE) {
- to = to->typeval.was_expr;
+ to = to->typeval->was_expr;
}
if (!to || to->kind != EXPR_CALL)
return true; /* give up */
@@ -208,7 +208,8 @@ static bool infer_from_type(Typer *tr, Type *match, Type *to, Identifier *idents
Expression *to_expr = to->was_expr;
Expression e = {0};
e.kind = EXPR_TYPE;
- e.typeval = *to;
+ e.typeval = allocr_malloc(tr->allocr, sizeof *e.typeval);
+ *e.typeval = *to;
e.flags = EXPR_FOUND_TYPE;
Type *type = &e.type;
type->flags = TYPE_IS_RESOLVED;
diff --git a/main.c b/main.c
index f954e8c..36c6b6d 100644
--- a/main.c
+++ b/main.c
@@ -8,7 +8,6 @@
/*
TODO:
-remove Location from Type.
fix x ::= fn_that_returns_array(); fn_that_takes_array(x);
#if
variadic fns
diff --git a/parse.c b/parse.c
index 745b965..07af202 100644
--- a/parse.c
+++ b/parse.c
@@ -461,10 +461,13 @@ static Status parse_args(Parser *p, Argument **args) {
return true;
}
-static Status parse_type(Parser *p, Type *type) {
+/* where will be filled out with the location, if not NULL */
+static Status parse_type(Parser *p, Type *type, Location *where) {
Tokenizer *t = p->tokr;
- type->where = parser_mk_loc(p);
- type->where.start = t->token;
+ if (where) {
+ *where = parser_mk_loc(p);
+ where->start = t->token;
+ }
type->flags = 0;
switch (t->token->kind) {
case TOKEN_KW:
@@ -494,9 +497,10 @@ static Status parse_type(Parser *p, Type *type) {
if (!token_is_kw(t->token, KW_RPAREN)) {
while (1) {
Type *param_type = parser_arr_add(p, &type->fn.types);
- if (!parse_type(p, param_type)) return false;
+ Location type_where;
+ if (!parse_type(p, param_type, &type_where)) return false;
if (param_type->kind == TYPE_TUPLE) {
- err_print(param_type->where, "Functions cannot have tuples as parameters.");
+ err_print(type_where, "Functions cannot have tuples as parameters.");
return false;
}
if (token_is_kw(t->token, KW_RPAREN))
@@ -520,7 +524,7 @@ static Status parse_type(Parser *p, Type *type) {
ret_type->kind = TYPE_VOID;
ret_type->flags = 0;
} else {
- if (!parse_type(p, ret_type))
+ if (!parse_type(p, ret_type, NULL))
return false;
}
break;
@@ -534,9 +538,10 @@ static Status parse_type(Parser *p, Type *type) {
type->kind = TYPE_SLICE;
type->slice = parser_malloc(p, sizeof *type->slice);
++t->token; /* move past ] */
- if (!parse_type(p, type->slice)) return false;
+ Location slice_where;
+ if (!parse_type(p, type->slice, &slice_where)) return false;
if (type->slice->kind == TYPE_TUPLE) {
- err_print(type->where, "You cannot have a slice of tuples.");
+ err_print(slice_where, "You cannot have a slice of tuples.");
return false;
}
break;
@@ -546,9 +551,10 @@ static Status parse_type(Parser *p, Type *type) {
if (!parse_expr(p, type->arr.n_expr, end)) return false;
t->token = end + 1; /* go past ] */
type->arr.of = parser_malloc(p, sizeof *type->arr.of);
- if (!parse_type(p, type->arr.of)) return false;
+ Location of_where;
+ if (!parse_type(p, type->arr.of, &of_where)) return false;
if (type->arr.of->kind == TYPE_TUPLE) {
- err_print(type->where, "You cannot have an array of tuples.");
+ err_print(of_where, "You cannot have an array of tuples.");
return false;
}
} break;
@@ -559,9 +565,10 @@ static Status parse_type(Parser *p, Type *type) {
++t->token; /* move past < */
while (1) {
Type *child = parser_arr_add(p, &type->tuple);
- if (!parse_type(p, child)) return false;
+ Location child_where;
+ if (!parse_type(p, child, &child_where)) return false;
if (child->kind == TYPE_TUPLE) {
- err_print(child->where, "Tuples cannot contain tuples.");
+ err_print(child_where, "Tuples cannot contain tuples.");
return false;
}
if (token_is_kw(t->token, KW_GT)) { /* we're done with the tuple */
@@ -577,17 +584,18 @@ static Status parse_type(Parser *p, Type *type) {
}
}
break;
- case KW_AMPERSAND:
+ case KW_AMPERSAND: {
/* pointer */
type->kind = TYPE_PTR;
type->ptr = parser_malloc(p, sizeof *type->ptr);
++t->token; /* move past & */
- if (!parse_type(p, type->ptr)) return false;
+ Location ptr_where;
+ if (!parse_type(p, type->ptr, &ptr_where)) return false;
if (type->ptr->kind == TYPE_TUPLE) {
- err_print(type->ptr->where, "You cannot have a pointer to a tuple.");
+ err_print(ptr_where, "You cannot have a pointer to a tuple.");
return false;
}
- break;
+ } break;
case KW_STRUCT: {
/* struct */
type->kind = TYPE_STRUCT;
@@ -694,7 +702,8 @@ static Status parse_type(Parser *p, Type *type) {
}
} break;
}
- type->where.end = t->token;
+ if (where)
+ where->end = t->token;
return true;
}
@@ -791,9 +800,8 @@ static bool parser_is_definitely_type(Parser *p, Token **end) {
goto end;
}
Type return_type;
- if (!parse_type(p, &return_type)) {
- /* couldn't parse a return type. this shouldn't happen in theory. */
- assert(0);
+ if (!parse_type(p, &return_type, NULL)) {
+ return false;
}
if (token_is_kw(t->token, KW_LBRACE)) {
/* non-void fn expr */
@@ -983,7 +991,7 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) {
f->ret_type.kind = TYPE_VOID;
f->ret_type.flags = 0;
} else {
- if (!parse_type(p, &f->ret_type)) {
+ if (!parse_type(p, &f->ret_type, NULL)) {
success = false;
goto ret;
}
@@ -1203,7 +1211,7 @@ static Status parse_c_type(Parser *p, CType *ctype, Type *type) {
return false;
} else {
ctype->kind = CTYPE_NONE;
- if (!parse_type(p, type))
+ if (!parse_type(p, type, NULL))
return false;
}
return true;
@@ -1237,7 +1245,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
if (parser_is_definitely_type(p, NULL)) {
/* it's a type! */
e->kind = EXPR_TYPE;
- if (!parse_type(p, &e->typeval))
+ if (!parse_type(p, e->typeval = parser_malloc(p, sizeof *e->typeval), NULL))
return false;
if (t->token == end) goto success;
/* there's more stuff after */
@@ -1455,7 +1463,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
}
if (!token_is_kw(t->token, KW_EQ)) {
fo->flags |= FOR_ANNOTATED_TYPE;
- if (!parse_type(p, &fo->type))
+ if (!parse_type(p, &fo->type, NULL))
goto for_fail;
if (!token_is_kw(t->token, KW_EQ)) {
tokr_err(t, "Expected = in for statement.");
@@ -1666,7 +1674,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
return false;
}
++t->token;
- if (!parse_type(p, &e->new.type)) return false;
+ if (!parse_type(p, &e->new.type, NULL)) return false;
if (token_is_kw(t->token, KW_COMMA)) {
/* new(int, 5) */
++t->token;
@@ -1729,7 +1737,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
if (!parse_c_type(p, &unused, &e->cast.type))
return false;
} else {
- if (!parse_type(p, &e->cast.type))
+ if (!parse_type(p, &e->cast.type, NULL))
return false;
}
if (t->token != end) {
@@ -2233,12 +2241,13 @@ static Status parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 f
if (annotates_type) {
d->flags |= DECL_ANNOTATES_TYPE;
Type type;
- if (!parse_type(p, &type)) {
+ Location type_where;
+ if (!parse_type(p, &type, &type_where)) {
goto ret_false;
}
d->type = type;
if (type.kind == TYPE_TUPLE && arr_len(d->type.tuple) != arr_len(d->idents)) {
- err_print(type.where, "Expected to have %lu things declared in declaration, but got %lu.", (unsigned long)arr_len(d->type.tuple), (unsigned long)arr_len(d->idents));
+ err_print(type_where, "Expected to have %lu things declared in declaration, but got %lu.", (unsigned long)arr_len(d->type.tuple), (unsigned long)arr_len(d->idents));
goto ret_false;
}
}
@@ -2738,7 +2747,7 @@ static void fprint_expr(FILE *out, Expression *e) {
fprintf(out, "]");
} break;
case EXPR_TYPE:
- fprint_type(out, &e->typeval);
+ fprint_type(out, e->typeval);
break;
case EXPR_VAL:
fprint_val(out, e->val, &e->type);
diff --git a/sdecls_cgen.c b/sdecls_cgen.c
index 4ad038f..ce89ad6 100644
--- a/sdecls_cgen.c
+++ b/sdecls_cgen.c
@@ -75,7 +75,7 @@ static void cgen_sdecls_expr(CGenerator *g, Expression *e) {
e->fn->c.id = ++g->ident_counter;
break;
case EXPR_TYPE:
- cgen_sdecls_type(g, &e->typeval);
+ cgen_sdecls_type(g, e->typeval);
break;
case EXPR_NMS: {
char *prefix_part = cgen_nms_prefix_part(g, e->nms);
@@ -107,8 +107,9 @@ static void cgen_sdecls_decl(CGenerator *g, Declaration *d) {
}
for (int idx = 0; idx < (int)arr_len(d->idents); ++idx) {
Type *type = decl_type_at_index(d, idx);
- Value *val = decl_val_at_index(d, idx);
- if (type_is_builtin(type, BUILTIN_TYPE)) {
+
+ if (type_is_builtin(type, BUILTIN_TYPE) && !(d->flags & DECL_IS_PARAM)) {
+ Value *val = decl_val_at_index(d, idx);
cgen_sdecls_type(g, val->type);
}
}
diff --git a/test.toc b/test.toc
index f4a1cd6..eee514a 100644
--- a/test.toc
+++ b/test.toc
@@ -1,16 +1,70 @@
-#include "std/io.toc", io;
+puti ::= fn(x: int) {
+//tcc's giving me "incompatible types for redefinition of 'printf'" for some reason (even though the declarations have the exact same type)
+ #C("#ifndef __TINYC__
+extern int printf(const char *fmt, ...);
+#endif
+");
+ #C("printf(\"%ld\\n\", (long)x);");
+};
+putf ::= fn(x: float) {
+ #C("#ifndef __TINYC__
+extern int printf(const char *fmt, ...);
+#endif
+");
+ #C("printf(\"%f\\n\", (double)x);");
+};
-Foo ::= struct (n ::= 12) {
- x ::= n;
+// it would be nice if Arr.data.len == Arr.len (: but this will require some C code...
+Arr ::= fn (t :: Type) Type {
+ struct {
+ data : []t;
+ len, cap : int;
+ }
};
-Bar ::= struct {
- a ::= -1243.3;
+arr_add ::= fn(t :: Type, a : &Arr(t), x : t) {
+ if a.len >= a.cap {
+ a.cap = a.cap * 2 + 2;
+ new_data := new(t, a.cap);
+ for i := 0..a.len-1 {
+ new_data[i] = a.data[i];
+ }
+ a.data = new_data;
+ }
+ a.data[a.len] = x;
+ a.len += 1;
+};
+
+square ::= fn(t :: Type, x : t) t {
+ a : Arr(t);
+ for i := 1,2..2*x-1 {
+ arr_add(t, &a, i);
+ };
+ sum := 0 as t;
+ for i := 0..a.len-1 {
+ sum += a.data[i];
+ };
+ sum
};
-main ::= fn() {
- io.puti(Foo(3).x);
- io.puti(Foo().n);
- io.puti(Bar.a as int);
+ArrInt ::= Arr(int);
+
+inc ::= fn(t :: Type, x : t) t {
+ x + 1
+};
+
+main ::= fn() {
+ arr : ArrInt;
+ farr : Arr(float);
+ for i := 1..100 {
+ arr_add(int, &arr, inc(int, square(int, i)));
+ arr_add(float, &farr, inc(float, square(float, i as float)));
+ }
+ for i := 0..arr.len - 1 {
+ puti(arr.data[i]);
+ }
+ for i := 0..farr.len - 1 {
+ putf(farr.data[i]);
+ }
};
diff --git a/types.c b/types.c
index f10834c..55fca89 100644
--- a/types.c
+++ b/types.c
@@ -508,7 +508,6 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
f->ret_type.flags = TYPE_IS_RESOLVED;
f->ret_type.was_expr = NULL;
f->ret_type.tuple = NULL;
- f->ret_type.where = f->ret_decls[0].where;
arr_foreach(f->ret_decls, Declaration, d) {
arr_foreach(d->idents, Identifier, i) {
*(Type *)arr_add(&f->ret_type.tuple) = d->type;
@@ -517,7 +516,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
}
}
if (!generic) {
- if (!type_resolve(tr, &f->ret_type, f->ret_type.where)) {
+ if (!type_resolve(tr, &f->ret_type, f->where)) {
success = false;
goto ret;
}
@@ -1725,7 +1724,6 @@ static Status types_expr(Typer *tr, Expression *e) {
if (expr_is_definitely_const(f) || type_is_builtin(&f->type, BUILTIN_TYPE)) {
Value val;
-
if (!eval_expr(tr->evalr, f, &val))
return false;
if (type_is_builtin(&f->type, BUILTIN_TYPE)) {
@@ -1841,10 +1839,10 @@ static Status types_expr(Typer *tr, Expression *e) {
/* expression is actually a type */
e->kind = EXPR_TYPE;
- memset(&e->typeval, 0, sizeof e->typeval);
- e->typeval.kind = TYPE_STRUCT;
- e->typeval.flags = TYPE_IS_RESOLVED;
- e->typeval.struc = &inst->struc;
+ e->typeval = typer_calloc(tr, 1, sizeof *e->typeval);
+ e->typeval->kind = TYPE_STRUCT;
+ e->typeval->flags = TYPE_IS_RESOLVED;
+ e->typeval->struc = &inst->struc;
t->kind = TYPE_BUILTIN;
t->builtin = BUILTIN_TYPE;
arr_clear(&arg_types);
@@ -2025,16 +2023,17 @@ static Status types_expr(Typer *tr, Expression *e) {
}
return false;
}
-
+ Value val_copy;
Type *type = &expr->type;
+ copy_val(tr->allocr, &val_copy, arg_val, type);
+
*(Type *)typer_arr_add(tr, &table_index_type.tuple) = *type;
-
+
arg_exprs[i].kind = EXPR_VAL;
arg_exprs[i].flags = EXPR_FOUND_TYPE;
- copy_val(tr->allocr, &arg_exprs[i].val, arg_val, type);
- arg_exprs[i].val = *arg_val;
- copy_val(tr->allocr, &param_decl->val, arg_val, type);
+ arg_exprs[i].val = val_copy;
param_decl->flags |= DECL_FOUND_VAL;
+ copy_val(tr->allocr, &param_decl->val, &val_copy, type);
if (!(param_decl->flags & DECL_ANNOTATES_TYPE)) {
param_decl->type = *type;
}
@@ -2510,6 +2509,7 @@ static Status types_expr(Typer *tr, Expression *e) {
Value lval = {0};
if (!eval_expr(tr->evalr, lhs, &lval))
return false;
+
lhs->kind = EXPR_VAL;
lhs->flags = EXPR_FOUND_TYPE;
lhs->val = lval;
@@ -2613,7 +2613,7 @@ static Status types_expr(Typer *tr, Expression *e) {
break;
}
case EXPR_TYPE: {
- Type *tval = &e->typeval;
+ Type *tval = e->typeval;
if (tval->kind == TYPE_STRUCT && tval->struc->params) {
/* don't try to resolve this */
t->kind = TYPE_BUILTIN;
@@ -2706,8 +2706,8 @@ static Status types_decl(Typer *tr, Declaration *d) {
if ((d->flags & DECL_HAS_EXPR)
&& d->expr.kind == EXPR_TYPE
- && d->expr.typeval.kind == TYPE_STRUCT) {
- d->expr.typeval.struc->name = d->idents[0];
+ && d->expr.typeval->kind == TYPE_STRUCT) {
+ d->expr.typeval->struc->name = d->idents[0];
}
if (d->flags & DECL_INFER) {
diff --git a/types.h b/types.h
index d5a2b69..d8e780d 100644
--- a/types.h
+++ b/types.h
@@ -445,7 +445,6 @@ enum {
};
typedef U8 TypeFlags;
typedef struct Type {
- Location where;
struct Expression *was_expr; /* if non-NULL, indicates that this type used to be an expression (TYPE_EXPR) */
TypeKind kind;
TypeFlags flags;
@@ -827,7 +826,7 @@ typedef struct Expression {
SliceExpr slice;
Block *block;
struct Expression *tuple; /* dynamic array, even after typing */
- Type typeval;
+ Type *typeval;
Value val;
};
} Expression;