From 7911df829428477c49b3a9c3c7efeb74a2608c84 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 22 Jul 2024 13:54:03 -0400 Subject: Make sure array slicing doesn't require a pointer and disallow automatic stackifying of values --- builtins/array.c | 50 +++++++++++++++++++++++++------------------------- builtins/array.h | 6 +++--- compile.c | 13 +++++++------ 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/builtins/array.c b/builtins/array.c index 2d45591c..4e8bf20c 100644 --- a/builtins/array.c +++ b/builtins/array.c @@ -261,54 +261,54 @@ public array_t Array$sample(array_t arr, int64_t n, array_t weights, const TypeI return selected; } -public array_t Array$from(array_t *array, int64_t first) +public array_t Array$from(array_t array, int64_t first) { if (first < 0) - first = array->length + first + 1; + first = array.length + first + 1; - if (first < 1 || first > array->length) - return (array_t){.atomic=array->atomic}; + if (first < 1 || first > array.length) + return (array_t){.atomic=array.atomic}; return (array_t){ - .atomic=array->atomic, - .data=array->data + array->stride*(first-1), - .length=array->length - first + 1, - .stride=array->stride, - .data_refcount=array->data_refcount, + .atomic=array.atomic, + .data=array.data + array.stride*(first-1), + .length=array.length - first + 1, + .stride=array.stride, + .data_refcount=array.data_refcount, }; } -public array_t Array$to(array_t *array, int64_t last) +public array_t Array$to(array_t array, int64_t last) { if (last < 0) - last = array->length + last + 1; + last = array.length + last + 1; - if (last > array->length) - last = array->length; + if (last > array.length) + last = array.length; if (last == 0) - return (array_t){.atomic=array->atomic}; + return (array_t){.atomic=array.atomic}; return (array_t){ - .atomic=array->atomic, - .data=array->data, + .atomic=array.atomic, + .data=array.data, .length=last, - .stride=array->stride, - .data_refcount=array->data_refcount, + .stride=array.stride, + .data_refcount=array.data_refcount, }; } -public array_t Array$by(array_t *array, int64_t stride) +public array_t Array$by(array_t array, int64_t stride) { if (stride == 0) - return (array_t){.atomic=array->atomic}; + return (array_t){.atomic=array.atomic}; return (array_t){ - .atomic=array->atomic, - .data=(stride < 0 ? array->data + (array->stride * (array->length - 1)) : array->data), - .length=(stride < 0 ? array->length / -stride : array->length / stride) + ((array->length % stride) != 0), - .stride=array->stride * stride, - .data_refcount=array->data_refcount, + .atomic=array.atomic, + .data=(stride < 0 ? array.data + (array.stride * (array.length - 1)) : array.data), + .length=(stride < 0 ? array.length / -stride : array.length / stride) + ((array.length % stride) != 0), + .stride=array.stride * stride, + .data_refcount=array.data_refcount, }; } diff --git a/builtins/array.h b/builtins/array.h index 56794a22..d60483db 100644 --- a/builtins/array.h +++ b/builtins/array.h @@ -64,9 +64,9 @@ array_t Array$sample(array_t arr, int64_t n, array_t weights, const TypeInfo *ty void Array$clear(array_t *array); void Array$compact(array_t *arr, const TypeInfo *type); bool Array$contains(array_t array, void *item, const TypeInfo *type); -array_t Array$from(array_t *array, int64_t first); -array_t Array$to(array_t *array, int64_t last); -array_t Array$by(array_t *array, int64_t stride); +array_t Array$from(array_t array, int64_t first); +array_t Array$to(array_t array, int64_t last); +array_t Array$by(array_t array, int64_t stride); array_t Array$reversed(array_t array); array_t Array$concat(array_t x, array_t y, const TypeInfo *type); uint32_t Array$hash(const array_t *arr, const TypeInfo *type); diff --git a/compile.c b/compile.c index dc6e3d78..0acbceb6 100644 --- a/compile.c +++ b/compile.c @@ -1083,7 +1083,7 @@ CORD compile_to_pointer_depth(env_t *env, ast_t *ast, int64_t target_depth, bool if (ast->tag == Var && target_depth == 1) val = CORD_all("(&", val, ")"); else - val = CORD_all("stack(", val, ")"); + code_err(ast, "This should be a pointer, not %T", get_type(env, ast)); t = Type(PointerType, .pointed=t, .is_stack=true); ++depth; } else { @@ -1323,8 +1323,9 @@ CORD compile(env_t *env, ast_t *ast) case StackReference: { ast_t *subject = Match(ast, StackReference)->value; if (can_be_mutated(env, subject)) - return CORD_all("(&", compile(env, subject), ")"); - return CORD_all("stack(", compile(env, subject), ")"); + return CORD_all("(&", compile_lvalue(env, subject), ")"); + else + code_err(subject, "This subject can't be mutated!"); } case Optional: { return compile(env, Match(ast, Optional)->value); @@ -1910,15 +1911,15 @@ CORD compile(env_t *env, ast_t *ast) (void)compile_arguments(env, ast, NULL, call->args); return CORD_all("Array$clear(", self, ")"); } else if (streq(call->name, "from")) { - CORD self = compile_to_pointer_depth(env, call->self, 1, false); + CORD self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="first", .type=Type(IntType, .bits=64)); return CORD_all("Array$from(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); } else if (streq(call->name, "to")) { - CORD self = compile_to_pointer_depth(env, call->self, 1, false); + CORD self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="last", .type=Type(IntType, .bits=64)); return CORD_all("Array$to(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); } else if (streq(call->name, "by")) { - CORD self = compile_to_pointer_depth(env, call->self, 1, false); + CORD self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="stride", .type=Type(IntType, .bits=64)); return CORD_all("Array$by(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); } else if (streq(call->name, "reversed")) { -- cgit v1.2.3