aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-07-10 13:42:58 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-07-10 13:42:58 -0400
commit068d0e8563dab7708711e0171ba1190d6037f0c9 (patch)
tree97797b983af875147e05ad5a0e233b1d8928c5c2
parent10e86153a2c619d7f853ab149e451a9cc05fdb27 (diff)
Add array:to() to split out functionality of array:from()
-rw-r--r--builtins/array.c26
-rw-r--r--builtins/array.h3
-rw-r--r--compile.c7
-rw-r--r--test/arrays.tm4
-rw-r--r--typecheck.c1
5 files changed, 30 insertions, 11 deletions
diff --git a/builtins/array.c b/builtins/array.c
index 1c31be80..2d45591c 100644
--- a/builtins/array.c
+++ b/builtins/array.c
@@ -261,24 +261,38 @@ 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, int64_t last)
+public array_t Array$from(array_t *array, int64_t first)
{
if (first < 0)
first = array->length + first + 1;
+ 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,
+ };
+}
+
+public array_t Array$to(array_t *array, int64_t last)
+{
if (last < 0)
last = array->length + last + 1;
- if (first < 1 || first > array->length || last < first)
- return (array_t){.atomic=array->atomic};
-
if (last > array->length)
last = array->length;
+ if (last == 0)
+ return (array_t){.atomic=array->atomic};
+
return (array_t){
.atomic=array->atomic,
- .data=array->data + array->stride*(first-1),
- .length=last - first + 1,
+ .data=array->data,
+ .length=last,
.stride=array->stride,
.data_refcount=array->data_refcount,
};
diff --git a/builtins/array.h b/builtins/array.h
index b2884d99..56794a22 100644
--- a/builtins/array.h
+++ b/builtins/array.h
@@ -64,7 +64,8 @@ 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, int64_t last);
+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);
diff --git a/compile.c b/compile.c
index 9d6b1665..fe6d8454 100644
--- a/compile.c
+++ b/compile.c
@@ -1815,9 +1815,12 @@ CORD compile(env_t *env, ast_t *ast)
return CORD_all("Array$clear(", self, ")");
} else if (streq(call->name, "from")) {
CORD self = compile_to_pointer_depth(env, call->self, 1, false);
- arg_t *arg_spec = new(arg_t, .name="first", .type=Type(IntType, .bits=64), .default_val=FakeAST(Int, .i=1, .bits=64),
- .next=new(arg_t, .name="last", .type=Type(IntType, .bits=64), .default_val=FakeAST(Int, .i=-1, .bits=64)));
+ 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);
+ 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);
arg_t *arg_spec = new(arg_t, .name="stride", .type=Type(IntType, .bits=64));
diff --git a/test/arrays.tm b/test/arrays.tm
index 9eea9dd9..fb6d16ca 100644
--- a/test/arrays.tm
+++ b/test/arrays.tm
@@ -121,9 +121,9 @@ func main():
do:
>> [i*10 for i in 5]:from(3)
= [30, 40, 50]
- >> [i*10 for i in 5]:from(last=3)
+ >> [i*10 for i in 5]:to(3)
= [10, 20, 30]
- >> [i*10 for i in 5]:from(last=-2)
+ >> [i*10 for i in 5]:to(-2)
= [10, 20, 30, 40]
>> [i*10 for i in 5]:from(-2)
= [40, 50]
diff --git a/typecheck.c b/typecheck.c
index 5cc9d664..43e384f4 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -670,6 +670,7 @@ type_t *get_type(env_t *env, ast_t *ast)
else if (streq(call->name, "sample")) return self_value_t;
else if (streq(call->name, "clear")) return Type(VoidType);
else if (streq(call->name, "from")) return self_value_t;
+ else if (streq(call->name, "to")) return self_value_t;
else if (streq(call->name, "by")) return self_value_t;
else if (streq(call->name, "reversed")) return self_value_t;
else if (streq(call->name, "heapify")) return Type(VoidType);