aboutsummaryrefslogtreecommitdiff
path: root/src/stdlib
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-04-07 00:46:26 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-04-07 00:46:26 -0400
commitef23faa3e6e003282e53fc08031ec4eb9a2e2aae (patch)
tree763944687f506e5dded02956ab3b45c456e16146 /src/stdlib
parent3554c56b209a1544c69e189ddab3b19b4bf80ae6 (diff)
Add Byte.to() method and improved micro optimization of iterating over
fixed-width integer ranges
Diffstat (limited to 'src/stdlib')
-rw-r--r--src/stdlib/bytes.c25
-rw-r--r--src/stdlib/bytes.h9
-rw-r--r--src/stdlib/datatypes.h8
3 files changed, 35 insertions, 7 deletions
diff --git a/src/stdlib/bytes.c b/src/stdlib/bytes.c
index 09e19c40..1203aa55 100644
--- a/src/stdlib/bytes.c
+++ b/src/stdlib/bytes.c
@@ -30,6 +30,31 @@ public Text_t Byte$hex(Byte_t byte, bool uppercase, bool prefix) {
return text;
}
+typedef struct {
+ OptionalByte_t current, last;
+ Int8_t step;
+} ByteRange_t;
+
+static OptionalByte_t _next_Byte(ByteRange_t *info) {
+ OptionalByte_t i = info->current;
+ if (!i.is_none) {
+ Byte_t next; bool overflow = __builtin_add_overflow(i.value, info->step, &next);
+ if (overflow || (!info->last.is_none && (info->step >= 0 ? next > info->last.value : next < info->last.value)))
+ info->current = (OptionalByte_t){.is_none=true};
+ else
+ info->current = (OptionalByte_t){.value=next};
+ }
+ return i;
+}
+
+public CONSTFUNC Closure_t Byte$to(Byte_t first, Byte_t last, OptionalInt8_t step) {
+ ByteRange_t *range = GC_MALLOC(sizeof(ByteRange_t));
+ range->current = (OptionalByte_t){.value=first};
+ range->last = (OptionalByte_t){.value=last};
+ range->step = step.is_none ? (last >= first ? 1 : -1) : step.value;
+ return (Closure_t){.fn=_next_Byte, .userdata=range};
+}
+
public PUREFUNC Byte_t Byte$from_int(Int_t i, bool truncate) {
if unlikely (truncate && Int$compare_value(i, I_small(0xFF)) > 0)
fail("This value is too large to convert to a byte without truncation: ", i);
diff --git a/src/stdlib/bytes.h b/src/stdlib/bytes.h
index ac1b61a3..f875e7cb 100644
--- a/src/stdlib/bytes.h
+++ b/src/stdlib/bytes.h
@@ -6,6 +6,7 @@
#include <stdint.h>
#include "datatypes.h"
+#include "integers.h"
#include "stdlib.h"
#include "types.h"
#include "util.h"
@@ -18,6 +19,7 @@ Byte_t Byte$from_int(Int_t i, bool truncate);
Byte_t Byte$from_int64(int64_t i, bool truncate);
Byte_t Byte$from_int32(int32_t i, bool truncate);
Byte_t Byte$from_int16(int16_t i, bool truncate);
+Closure_t Byte$to(Byte_t first, Byte_t last, OptionalInt8_t step);
MACROLIKE Byte_t Byte$from_int8(int8_t i) { return (Byte_t)i; }
MACROLIKE Byte_t Byte$from_bool(bool b) { return (Byte_t)b; }
@@ -28,11 +30,4 @@ extern const TypeInfo_t Byte$info;
Text_t Byte$hex(Byte_t byte, bool uppercase, bool prefix);
-typedef struct {
- Byte_t value;
- bool has_value:1;
-} OptionalByte_t;
-
-#define NONE_BYTE ((OptionalByte_t){.has_value=false})
-
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/src/stdlib/datatypes.h b/src/stdlib/datatypes.h
index 950c9457..77c09ddb 100644
--- a/src/stdlib/datatypes.h
+++ b/src/stdlib/datatypes.h
@@ -111,4 +111,12 @@ typedef struct {
#define OptionalText_t Text_t
#define OptionalClosure_t Closure_t
+typedef struct {
+ Byte_t value;
+ bool is_none:1;
+} OptionalByte_t;
+
+#define NONE_BYTE ((OptionalByte_t){.is_none=true})
+
+
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0