diff options
-rw-r--r-- | allocator.c | 29 | ||||
-rw-r--r-- | err.c | 6 | ||||
-rw-r--r-- | infer.c | 7 | ||||
-rw-r--r-- | parse.c | 4 | ||||
-rw-r--r-- | types.c | 35 |
5 files changed, 57 insertions, 24 deletions
diff --git a/allocator.c b/allocator.c index 9f58ee4..4cde1a9 100644 --- a/allocator.c +++ b/allocator.c @@ -22,6 +22,8 @@ static void *allocr_malloc(Allocator *a, size_t bytes) { (void)a; return err_malloc(bytes); #else + if (bytes == 0) + return NULL; if (a == NULL) return err_malloc(bytes); /* position in this page to return */ @@ -52,6 +54,7 @@ static void *allocr_calloc(Allocator *a, size_t n, size_t sz) { #if NO_ALLOCATOR a = NULL; #endif + if (n == 0 || sz == 0) return NULL; if (a == NULL) return err_calloc(n, sz); /* OPTIM: use calloc */ size_t bytes = n * sz; @@ -60,27 +63,33 @@ static void *allocr_calloc(Allocator *a, size_t n, size_t sz) { return data; } +static void allocr_free(Allocator *a, void *data, size_t size) { +#if NO_ALLOCATOR + a = NULL; +#endif + if (a == NULL) { + free(data); + } + /* OPTIM */ + (void)size; +} + /* OPTIM */ static void *allocr_realloc(Allocator *a, void *data, size_t old_size, size_t new_size) { #if NO_ALLOCATOR a = NULL; #endif + if (new_size == 0) { + allocr_free(a, data, old_size); + return NULL; + } if (a == NULL) return err_realloc(data, new_size); void *ret = allocr_malloc(a, new_size); memcpy(ret, data, old_size); return ret; } -static void allocr_free(Allocator *a, void *data, size_t size) { -#if NO_ALLOCATOR - a = NULL; -#endif - if (a == NULL) { - free(data); - } - /* OPTIM */ - (void)size; -} + static void allocr_free_all(Allocator *a) { for (Page *page = a->first; page;) { @@ -158,6 +158,7 @@ static void warn_print(Location where, const char *fmt, ...) { } static void *err_malloc(size_t size) { + if (size == 0) return NULL; void *ret = malloc(size); if (!ret) { fprintf(stderr, "Error: Out of memory.\n"); @@ -167,6 +168,7 @@ static void *err_malloc(size_t size) { } static void *err_calloc(size_t n, size_t size) { + if (n == 0 || size == 0) return NULL; void *ret = calloc(n, size); if (!ret) { fprintf(stderr, "Error: Out of memory.\n"); @@ -176,6 +178,10 @@ static void *err_calloc(size_t n, size_t size) { } static void *err_realloc(void *data, size_t new_size) { + if (new_size == 0) { + free(data); + return NULL; + } void *ret = realloc(data, new_size); if (!ret) { fprintf(stderr, "Error: Out of memory.\n"); @@ -1,9 +1,12 @@ /* 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 +idents is a dyn array +find the value of each 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) { +static bool infer(Type **match, Type **to, Identifier *idents, Value *vals, Type *types) { + Value *val = vals; + Type *type = types; val->type = calloc(1,sizeof(Type)); val->type->flags = TYPE_IS_RESOLVED; val->type->kind = TYPE_BUILTIN; @@ -1798,6 +1798,10 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla if ((flags & PARSE_DECL_ALLOW_INFER) && ends_decl(t->token, ends_with)) { /* inferred expression */ d->flags |= DECL_INFER; + if (arr_len(d->idents) > 1) { + err_print(d->where, "Inferred declarations can only have one identifier. Please separate this declaration."); + goto ret_false; + } if (!(d->flags & DECL_IS_CONST)) { tokr_err(t, "Inferred parameters must be constant."); goto ret_false; @@ -1257,20 +1257,12 @@ static bool types_expr(Typer *tr, Expression *e) { i = 0; Type **arg_types = NULL; Type **decl_types = NULL; + Identifier *infer_idents = 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; + *(Identifier *)arr_add(&infer_idents) = *ident; } else if ((param->flags & DECL_ANNOTATES_TYPE) && !(param->flags & DECL_HAS_EXPR)) { @@ -1285,8 +1277,27 @@ static bool types_expr(Typer *tr, Expression *e) { ++i; } } - + Value *inferred_vals = typer_malloc(tr, arr_len(infer_idents) * sizeof *inferred_vals); + Type *inferred_types = typer_malloc(tr, arr_len(infer_idents) * sizeof *inferred_types); + if (!infer(arg_types, decl_types, infer_idents, inferred_vals, inferred_types)) + return false; + + i = 0; + arr_foreach(fn->params, Declaration, param) { + arr_foreach(param->idents, Identifier, ident) { + if (param->flags & DECL_INFER) { + param->expr.kind = EXPR_VAL; + param->expr.flags = 0; + param->expr.val = inferred_vals[i]; + param->expr.type = inferred_types[i]; + param->expr.flags |= EXPR_FOUND_TYPE; + param->type = param->expr.type; + param->flags |= DECL_HAS_EXPR|DECL_FOUND_TYPE; + ++i; + } + } + } /* type return declarations, etc */ if (!type_of_fn(tr, &fn_copy, e->where, &f->type, TYPE_OF_FN_IS_INSTANCE)) return false; |