summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eval.c3
-rw-r--r--main.c3
-rw-r--r--test.toc7
-rw-r--r--types.c60
4 files changed, 40 insertions, 33 deletions
diff --git a/eval.c b/eval.c
index d6a3487..8542eb4 100644
--- a/eval.c
+++ b/eval.c
@@ -484,9 +484,6 @@ static void val_cast(Value vin, Type *from, Value *vout, Type *to) {
case TYPE_PTR:
vout->ptr = vin.arr;
break;
- case TYPE_ARR:
- vout->arr = vin.arr;
- break;
default:
assert(0); break;
}
diff --git a/main.c b/main.c
index 3e06c41..4515bc9 100644
--- a/main.c
+++ b/main.c
@@ -8,9 +8,10 @@
/*
@TODO:
-figure out how printf is gonna work
+error when a template is used after it's defined
if we do #include "foo.toc", bar; and foo.toc fails, bar should be declared as TYPE_UNKNOWN (right now it's undeclared)
fix #foreign not at global scope - right now the cgen'd definition doesn't use the proper type
+figure out how printf is gonna work
find out why loop with file output is really slow at compile time; try to improve it
improve type_to_str:
Foo ::= struct(t::Type) {}
diff --git a/test.toc b/test.toc
index 6acebc5..dfcbe51 100644
--- a/test.toc
+++ b/test.toc
@@ -1,4 +1,5 @@
-n ::= nms {
- putchar ::= #foreign("putchar") fn(#C int) #C int;
+#include "std/mem.toc";
+main ::= fn(){
+ a : []int = news(int, 5);
}
-main ::= fn(){}
+main();
diff --git a/types.c b/types.c
index 81ebfeb..fc877af 100644
--- a/types.c
+++ b/types.c
@@ -402,6 +402,9 @@ static bool type_eq_exact(Type *a, Type *b) {
/* are a and b equal, allowing implicit conversions? */
static bool type_eq_implicit(Type *a, Type *b) {
+ assert(a->flags & TYPE_IS_RESOLVED);
+ assert(b->flags & TYPE_IS_RESOLVED);
+
if (a->kind == TYPE_UNKNOWN || b->kind == TYPE_UNKNOWN)
return true;
if (a->kind != b->kind) return false;
@@ -965,8 +968,7 @@ static Status type_resolve(Typer *tr, Type *t, Location where) {
return false;
}
}
- if (!eval_expr(tr->evalr, expr, &typeval))
- return false;
+ if (!eval_expr(tr->evalr, expr, &typeval)) return false;
*t = *typeval.type;
if (t->kind == TYPE_STRUCT) {
if (struct_is_template(t->struc)) {
@@ -1139,7 +1141,6 @@ static CastStatus type_cast_status(Type *from, Type *to) {
return CAST_STATUS_NONE;
if (to->kind == TYPE_FN)
return CAST_STATUS_WARN;
- /* @TODO: Cast from ptr to arr */
return CAST_STATUS_ERR;
case TYPE_ARR:
return CAST_STATUS_ERR;
@@ -2259,10 +2260,11 @@ static Status types_expr(Typer *tr, Expression *e) {
if (!eval_expr(tr->evalr, expr, &arg_val))
return false;
Type *type = &expr->type;
- arg_exprs[i].kind = EXPR_VAL;
- arg_exprs[i].flags = EXPR_FOUND_TYPE;
- arg_exprs[i].val = arg_val;
- param_decl->flags |= DECL_FOUND_VAL;
+ expr->kind = EXPR_VAL;
+ expr->flags = EXPR_FOUND_TYPE;
+ expr->val = arg_val;
+ param_decl->expr = *expr;
+ param_decl->flags |= DECL_FOUND_VAL|DECL_HAS_EXPR;
copy_val(tr->allocr, &param_decl->val, arg_val, type);
if (!(param_decl->flags & DECL_ANNOTATES_TYPE)) {
param_decl->type = *type;
@@ -3057,15 +3059,16 @@ static Status types_decl(Typer *tr, Declaration *d) {
Type *dtype = &d->type;
if (d->flags & DECL_FOUND_TYPE) return true;
bool success = true;
- Expression *e = (d->flags & DECL_HAS_EXPR) ? &d->expr : NULL;
+ DeclFlags flags = d->flags;
+ Expression *e = (flags & DECL_HAS_EXPR) ? &d->expr : NULL;
- if (d->flags & DECL_INFER) {
+ if (flags & DECL_INFER) {
dtype->kind = TYPE_UNKNOWN;
dtype->flags = 0;
return true;
}
typer_arr_add(tr, tr->in_decls, d);
- if (d->flags & DECL_ANNOTATES_TYPE) {
+ if (flags & DECL_ANNOTATES_TYPE) {
/* type supplied */
if (!type_resolve(tr, dtype, d->where)) {
success = false;
@@ -3097,11 +3100,15 @@ static Status types_decl(Typer *tr, Declaration *d) {
goto ret;
}
assert(d->expr.type.flags & TYPE_IS_RESOLVED);
- if (d->flags & DECL_ANNOTATES_TYPE) {
+ if (flags & DECL_ANNOTATES_TYPE) {
if (!type_eq_implicit(&e->type, dtype)) {
char *decl_type = type_to_str(dtype),
*expr_type = type_to_str(&e->type);
- err_print(e->where, "Declaration type %s does not match expression type %s.", decl_type, expr_type);
+ bool is_parameter = (flags & DECL_IS_PARAM) && (flags & DECL_FOUND_VAL); /* this can happen if the wrong type is passed to a template function */
+ if (is_parameter)
+ err_print(e->where, "Parameter type %s does not match argument type %s.", decl_type, expr_type);
+ else
+ err_print(e->where, "Declaration type %s does not match expression type %s.", decl_type, expr_type);
free(decl_type); free(expr_type);
success = false;
goto ret;
@@ -3116,17 +3123,17 @@ static Status types_decl(Typer *tr, Declaration *d) {
*dtype = e->type;
dtype->flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; /* x := 5; => x is not flexible */
}
- bool need_value = (d->flags & DECL_IS_CONST) || !tr->block || tr->block->kind == BLOCK_NMS;
+ bool need_value = (flags & DECL_IS_CONST) || !tr->block || tr->block->kind == BLOCK_NMS;
if (need_value) {
- if (!(d->flags & DECL_FOUND_VAL)) {
+ if (!(flags & DECL_FOUND_VAL)) {
Value val;
if (!eval_expr(tr->evalr, e, &val)) {
success = false;
goto ret;
}
copy_val(tr->allocr, &d->val, val, dtype);
- d->flags |= DECL_FOUND_VAL;
- if (!(d->flags & DECL_IS_CONST)) {
+ flags |= DECL_FOUND_VAL;
+ if (!(flags & DECL_IS_CONST)) {
/*
create a value stack for this declaration so that it can be modified by compile time execution,
but not permanently (i.e. output will still have old value)
@@ -3161,7 +3168,7 @@ static Status types_decl(Typer *tr, Declaration *d) {
if (type_is_compileonly(dtype)) {
- if (!(d->flags & DECL_IS_CONST) && !type_is_builtin(dtype, BUILTIN_VARARGS)) {
+ if (!(flags & DECL_IS_CONST) && !type_is_builtin(dtype, BUILTIN_VARARGS)) {
char *s = type_to_str(dtype);
err_print(d->where, "Declarations with type %s must be constant.", s);
free(s);
@@ -3184,7 +3191,7 @@ static Status types_decl(Typer *tr, Declaration *d) {
goto ret;
}
if (dtype->kind == TYPE_BUILTIN) {
- if (dtype->builtin == BUILTIN_VARARGS && !(d->flags & DECL_IS_PARAM)) {
+ if (dtype->builtin == BUILTIN_VARARGS && !(flags & DECL_IS_PARAM)) {
err_print(d->where, "Only parameters can be varargs.");
success = false;
goto ret;
@@ -3194,7 +3201,7 @@ static Status types_decl(Typer *tr, Declaration *d) {
goto ret;
}
}
- if (d->flags & DECL_IS_CONST) {
+ if (flags & DECL_IS_CONST) {
if (dtype->kind == TYPE_PTR) {
err_print(d->where, "You can't have a constant pointer.");
success = false;
@@ -3206,7 +3213,7 @@ static Status types_decl(Typer *tr, Declaration *d) {
for (int i = 0, len = (int)n_idents; i < len; ++i) {
Type *t = decl_type_at_index(d, i);
if (type_is_builtin(t, BUILTIN_TYPE)) {
- if (d->flags & DECL_HAS_EXPR) {
+ if (flags & DECL_HAS_EXPR) {
Value *val = decl_val_at_index(d, i);
if (val->type->kind == TYPE_STRUCT && val->type->struc->params) {
/* don't resolve it because it's not really complete */
@@ -3214,7 +3221,7 @@ static Status types_decl(Typer *tr, Declaration *d) {
if (!type_resolve(tr, val->type, d->where)) return false;
}
}
- } else if (!(d->flags & DECL_IS_CONST) && t->kind == TYPE_FN && t->fn->constness) {
+ } else if (!(flags & DECL_IS_CONST) && t->kind == TYPE_FN && t->fn->constness) {
for (size_t p = 0; p < arr_len(t->fn->types)-1; ++p) {
if (t->fn->constness[p] == CONSTNESS_YES) {
err_print(d->where, "You can't have a pointer to a function with constant parameters.");
@@ -3227,7 +3234,7 @@ static Status types_decl(Typer *tr, Declaration *d) {
}
}
- if (d->flags & DECL_USE) {
+ if (flags & DECL_USE) {
int idx = 0;
if (arr_len(d->idents) > 1) {
err_print(d->where, "Used declarations cannot have more than one identifier (you're trying to use two things at once).");
@@ -3244,9 +3251,9 @@ static Status types_decl(Typer *tr, Declaration *d) {
}
}
- if (d->flags & DECL_EXPORT) {
- if (d->expr.kind == EXPR_FN)
- d->expr.fn->flags |= FN_EXPR_EXPORT;
+ if (flags & DECL_EXPORT) {
+ if (e->kind == EXPR_FN)
+ e->fn->flags |= FN_EXPR_EXPORT;
}
if (tr->block == NULL || tr->block->kind == BLOCK_NMS) {
@@ -3256,7 +3263,8 @@ static Status types_decl(Typer *tr, Declaration *d) {
ret:
/* pretend we found the type even if we didn't to prevent too many errors */
- d->flags |= DECL_FOUND_TYPE;
+ flags |= DECL_FOUND_TYPE;
+ d->flags = flags;
if (!success) {
/* use unknown type if we didn't get the type */
dtype->flags = TYPE_IS_RESOLVED;