aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtins/array.c8
-rw-r--r--builtins/array.h1
-rw-r--r--compile.c3
-rw-r--r--test/arrays.tm5
-rw-r--r--typecheck.c1
5 files changed, 18 insertions, 0 deletions
diff --git a/builtins/array.c b/builtins/array.c
index 3380d4d3..6ebc6429 100644
--- a/builtins/array.c
+++ b/builtins/array.c
@@ -223,6 +223,14 @@ public array_t Array__slice(array_t *array, int64_t first, int64_t length, int64
};
}
+public array_t Array__reversed(array_t array)
+{
+ array_t reversed = array;
+ reversed.stride = -array.stride;
+ reversed.data = array.data + (array.length-1)*array.stride;
+ return reversed;
+}
+
public array_t Array__concat(array_t x, array_t y, const TypeInfo *type)
{
int64_t item_size = get_item_size(type);
diff --git a/builtins/array.h b/builtins/array.h
index b538be30..dad72b7e 100644
--- a/builtins/array.h
+++ b/builtins/array.h
@@ -63,6 +63,7 @@ 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__slice(array_t *array, int64_t first, int64_t length, int64_t stride, const TypeInfo *type);
+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);
int32_t Array__compare(const array_t *x, const array_t *y, const TypeInfo *type);
diff --git a/compile.c b/compile.c
index 3bb8151b..6af4bf1d 100644
--- a/compile.c
+++ b/compile.c
@@ -1493,6 +1493,9 @@ CORD compile(env_t *env, ast_t *ast)
.next=new(arg_t, .name="stride", .type=Type(IntType, .bits=64), .default_val=FakeAST(Int, .i=1, .bits=64))));
return CORD_all("Array__slice(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
compile_type_info(env, self_value_t), ")");
+ } else if (streq(call->name, "reversed")) {
+ CORD self = compile_to_pointer_depth(env, call->self, 0, false);
+ return CORD_all("Array__reversed(", self, ")");
} else code_err(ast, "There is no '%s' method for arrays", call->name);
}
case TableType: {
diff --git a/test/arrays.tm b/test/arrays.tm
index 07a89e19..e8856b3b 100644
--- a/test/arrays.tm
+++ b/test/arrays.tm
@@ -68,3 +68,8 @@ if yes
= @[10, 20, 30]
>> copy
= [10, 20]
+
+if yes
+ >> arr := [10, 20, 30]
+ >> arr:reversed()
+ = [30, 20, 10]
diff --git a/typecheck.c b/typecheck.c
index 70bfd70b..05a1fb59 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -510,6 +510,7 @@ type_t *get_type(env_t *env, ast_t *ast)
return Type(PointerType, .pointed=Match(self_value_t, ArrayType)->item_type, .is_optional=true, .is_readonly=true);
else if (streq(call->name, "clear")) return Type(VoidType);
else if (streq(call->name, "slice")) return self_value_t;
+ else if (streq(call->name, "reversed")) return self_value_t;
else code_err(ast, "There is no '%s' method for arrays", call->name);
}
case TableType: {