summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arr.c15
-rw-r--r--infer.c39
-rw-r--r--types.c41
3 files changed, 62 insertions, 33 deletions
diff --git a/arr.c b/arr.c
index fc6149e..1be5a26 100644
--- a/arr.c
+++ b/arr.c
@@ -57,6 +57,14 @@ static void arr_clear_(void **arr) {
}
}
+static void arr_cleara_(void **arr, size_t size, Allocator *allocr) {
+ if (*arr) {
+ ArrHeader *header = arr_hdr(*arr);
+ allocr_free(allocr, header, header->cap * size);
+ *arr = NULL;
+ }
+}
+
static void arr_set_len_(void **arr, size_t n, size_t item_sz) {
if (n == 0) {
arr_clear_(arr);
@@ -149,12 +157,13 @@ You shouldn't rely on this, though, e.g. by doing
#endif
#define arr_add(arr) (arr_ptr_type(arr))arr_add_((void **)(arr), sizeof **(arr))
-#define arr_adda(arr, allocr) (arr_ptr_type(arr))arr_adda_((void **)(arr), sizeof **(arr), allocr)
+#define arr_adda(arr, allocr) (arr_ptr_type(arr))arr_adda_((void **)(arr), sizeof **(arr), (allocr))
#define arr_resv(arr, n) arr_resv_((void **)(arr), n, sizeof **(arr))
-#define arr_resva(arr, n, allocr) arr_resva_((void **)(arr), n, sizeof **(arr), allocr)
+#define arr_resva(arr, n, allocr) arr_resva_((void **)(arr), n, sizeof **(arr), (allocr))
#define arr_set_len(arr, n) arr_set_len_((void **)(arr), n, sizeof **(arr))
-#define arr_set_lena(arr, n, a) arr_set_lena_((void **)(arr), n, sizeof **(arr), a)
+#define arr_set_lena(arr, n, a) arr_set_lena_((void **)(arr), n, sizeof **(arr), (a))
#define arr_clear(arr) arr_clear_((void **)(arr)), (void)sizeof **arr /* second part makes sure most of the time that you don't accidentally call it without taking the address */
+#define arr_cleara(arr, allocr) arr_cleara_((void **)(arr), sizeof **(arr), (allocr))
#define arr_last(arr) arr_last_((void *)(arr), sizeof *(arr))
/* OPTIM: maybe replace with less standard-compliant version */
#define arr_foreach(arr, type, var) for (type *var = arr_len(arr) ? arr : NULL, *var##_foreach_end = arr_last(arr); var; var == var##_foreach_end ? var = NULL : ++var)
diff --git a/infer.c b/infer.c
index d4d4513..08eb5ab 100644
--- a/infer.c
+++ b/infer.c
@@ -1,29 +1,16 @@
-/* infers the expression of decls[idx], according to the types of the other decls */
-static bool infer_expr(Typer *tr, size_t idx, Declaration *decls) {
- Declaration *decl = decls + idx;
- if (decl->flags & DECL_HAS_EXPR) return true; /* already did it */
-
- decl->expr.kind = EXPR_VAL;
- decl->expr.type.flags = TYPE_IS_RESOLVED;
- decl->expr.type.kind = TYPE_TYPE;
-
- decl->expr.val.type = calloc(1,sizeof (Type));
- decl->expr.val.type->kind = TYPE_BUILTIN;
- decl->expr.val.type->builtin = BUILTIN_I64;
- decl->expr.val.type->flags = TYPE_IS_RESOLVED;
-
- decl->type = decl->expr.type;
- decl->flags |= DECL_FOUND_TYPE;
- decl->flags |= DECL_HAS_EXPR;
+/*
+match and to are dynamic arrays of equal size
+find the value (and put it into val) of ident by matching match[i] to to[i], i = 0..arr_len(match)-1
+all the types in match must be resolved, and all the types in to must be unresolved
+*/
+static bool infer(Type **match, Type **to, Identifier ident, Value *val, Type *type) {
+ val->type = calloc(1,sizeof(Type));
+ val->type->flags = TYPE_IS_RESOLVED;
+ val->type->kind = TYPE_BUILTIN;
+ val->type->builtin = BUILTIN_I64;
+ type->flags = TYPE_IS_RESOLVED;
+ type->kind = TYPE_TYPE;
+ type->was_expr = NULL;
return true;
}
-/* infers ALL of the expressions in the declarations */
-static bool infer_exprs_in_decls(Typer *tr, Declaration *decls) {
- for (size_t idx = 0; idx < arr_len(decls); ++idx) {
- if (decls[idx].flags & DECL_INFER)
- if (!infer_expr(tr, idx, decls))
- return false;
- }
- return true;
-}
diff --git a/types.c b/types.c
index 405d9b1..224c957 100644
--- a/types.c
+++ b/types.c
@@ -233,6 +233,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags)
success = false;
goto ret;
}
+
if (param->type.kind == TYPE_TUPLE) {
err_print(param->where, "Functions can't have tuple parameters.");
success = false;
@@ -1203,8 +1204,6 @@ static bool types_expr(Typer *tr, Expression *e) {
U64 *which_are_const = &which_are_const_val->u64;
*which_are_const = 0;
int semi_const_index = 0;
- if (!infer_exprs_in_decls(tr, fn->params))
- return false;
/* eval compile time arguments */
for (i = 0; i < nparams; ++i) {
bool should_be_evald = arg_is_const(&arg_exprs[i], fn_type->constness[i]);
@@ -1254,10 +1253,44 @@ static bool types_expr(Typer *tr, Expression *e) {
++param_decl;
}
}
- /* type param declarations, etc */
+
+ i = 0;
+ Type **arg_types = NULL;
+ Type **decl_types = NULL;
+ arr_foreach(fn->params, Declaration, param) {
+ arr_foreach(param->idents, Identifier, ident) {
+ if (param->flags & DECL_INFER) {
+ Value val;
+ Type type;
+ if (!infer(arg_types, decl_types, *ident, &val, &type))
+ return false;
+ param->expr.kind = EXPR_VAL;
+ param->expr.flags = 0;
+ param->expr.val = val;
+ param->expr.type = type;
+ param->expr.flags |= EXPR_FOUND_TYPE;
+ param->type = param->expr.type;
+ param->flags |= DECL_HAS_EXPR|DECL_FOUND_TYPE;
+ } else if ((param->flags & DECL_ANNOTATES_TYPE)
+ && !(param->flags & DECL_HAS_EXPR)) {
+
+ if (param->type.kind == TYPE_TUPLE)
+ err_print(param->where, "Parameters cannot have tuple types.");
+
+ Type **p = typer_arr_add(tr, &decl_types);
+ *p = &param->type;
+ Type **q = typer_arr_add(tr, &arg_types);
+ *q = &arg_exprs[i].type;
+ }
+ ++i;
+ }
+ }
+
+
+ /* type return declarations, etc */
if (!type_of_fn(tr, &fn_copy, e->where, &f->type, TYPE_OF_FN_IS_INSTANCE))
return false;
-
+
/* deal with default arguments */
i = 0;