summaryrefslogtreecommitdiff
path: root/std
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-23 00:50:18 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-23 00:50:18 +0000
commit8cb7089b2eb09d40d9497cea40d088d94676a8c6 (patch)
treed4a2a33fe35807abc0cdeeb0be93edcbe75a4996 /std
parent3a4a72a38675893c3a1854d05c72b957a6bd9364 (diff)
More docs, check 'docs/std'.
Diffstat (limited to 'std')
-rw-r--r--std/map.zc67
-rw-r--r--std/string.zc106
2 files changed, 173 insertions, 0 deletions
diff --git a/std/map.zc b/std/map.zc
index a7bae69..ca4766f 100644
--- a/std/map.zc
+++ b/std/map.zc
@@ -23,6 +23,62 @@ struct Map<V> {
cap: usize;
}
+struct MapEntry<V> {
+ key: char*;
+ val: V;
+}
+
+struct MapIter<V> {
+ keys: char**;
+ vals: V*;
+ occupied: bool*;
+ deleted: bool*;
+ cap: usize;
+ idx: usize;
+}
+
+struct MapIterResult<V> {
+ entry: MapEntry<V>;
+ has_val: bool;
+}
+
+impl MapIterResult<V> {
+ fn is_none(self) -> bool {
+ return !self.has_val;
+ }
+
+ fn unwrap(self) -> MapEntry<V> {
+ if (!self.has_val) {
+ !"Panic: Map iterator unwrap on None";
+ exit(1);
+ }
+ return self.entry;
+ }
+}
+
+impl MapIter<V> {
+ fn next(self) -> MapIterResult<V> {
+ while self.idx < self.cap {
+ var i = self.idx;
+ self.idx = self.idx + 1;
+
+ if (self.occupied[i] && !self.deleted[i]) {
+ var entry = MapEntry<V> {
+ key: self.keys[i],
+ val: self.vals[i]
+ };
+ return MapIterResult<V> {
+ entry: entry,
+ has_val: true
+ };
+ }
+ }
+ // Empty entry for None
+ var empty = MapEntry<V> { key: 0, val: self.vals[0] }; // Should be 0-init if possible
+ return MapIterResult<V> { entry: empty, has_val: false };
+ }
+}
+
impl Map<V> {
fn new() -> Map<V> {
return Map<V> { keys: 0, vals: 0, occupied: 0, deleted: 0, len: 0, cap: 0 };
@@ -180,4 +236,15 @@ impl Map<V> {
fn val_at(self, idx: usize) -> V {
return self.vals[idx];
}
+
+ fn iterator(self) -> MapIter<V> {
+ return MapIter<V> {
+ keys: self.keys,
+ vals: self.vals,
+ occupied: self.occupied,
+ deleted: self.deleted,
+ cap: self.cap,
+ idx: 0
+ };
+ }
}
diff --git a/std/string.zc b/std/string.zc
index 02ae6b9..3f96053 100644
--- a/std/string.zc
+++ b/std/string.zc
@@ -139,4 +139,110 @@ impl String {
fn free(self) {
self.vec.free();
}
+
+ fn _utf8_seq_len(first_byte: char) -> usize {
+ var b = (int)first_byte;
+ if ((b & 0x80) == 0) { return 1; }
+ if ((b & 0xE0) == 0xC0) { return 2; }
+ if ((b & 0xF0) == 0xE0) { return 3; }
+ if ((b & 0xF8) == 0xF0) { return 4; }
+ return 1; // Fallback
+ }
+
+ fn utf8_len(self) -> usize {
+ var count: usize = 0;
+ var i: usize = 0;
+ var len = self.length();
+ while i < len {
+ var c = self.vec.get(i);
+ i = i + String::_utf8_seq_len(c);
+ count = count + 1;
+ }
+ return count;
+ }
+
+ fn utf8_at(self, idx: usize) -> String {
+ var count: usize = 0;
+ var i: usize = 0;
+ var len = self.length();
+ while i < len {
+ var c = self.vec.get(i);
+ var seq = String::_utf8_seq_len(c);
+
+ if (count == idx) {
+ return self.substring(i, seq);
+ }
+
+ i = i + seq;
+ count = count + 1;
+ }
+ return String::new("");
+ }
+
+ fn utf8_substr(self, start_idx: usize, num_chars: usize) -> String {
+ if (num_chars == 0) { return String::new(""); }
+
+ var byte_start: usize = 0;
+ var byte_len: usize = 0;
+
+ var count: usize = 0;
+ var i: usize = 0;
+ var len = self.length();
+ var found_start = false;
+
+ while i < len {
+ // Check if we reached the start char
+ if (!found_start && count == start_idx) {
+ byte_start = i;
+ found_start = true;
+ // Reset count to track chars collected
+ count = 0;
+ } else if (!found_start) {
+ // Still seeking start
+ var c = self.vec.get(i);
+ i = i + String::_utf8_seq_len(c);
+ count = count + 1;
+ continue;
+ }
+
+ // If we are here, we are collecting chars
+ if (count < num_chars) {
+ var c = self.vec.get(i);
+ var seq = String::_utf8_seq_len(c);
+ byte_len = byte_len + seq;
+ i = i + seq;
+ count = count + 1;
+ } else {
+ break;
+ }
+ }
+
+ if (!found_start) { return String::new(""); }
+
+ return self.substring(byte_start, byte_len);
+ }
+ fn split(self, delim: char) -> Vec<String> {
+ var parts = Vec<String>::new();
+ var len = self.length();
+ if (len == 0) { return parts; }
+
+ var start: usize = 0;
+ var i: usize = 0;
+
+ while i < len {
+ if (self.vec.get(i) == delim) {
+ // Found delimiter
+ parts.push(self.substring(start, i - start));
+ start = i + 1;
+ }
+ i = i + 1;
+ }
+
+ // Push last segment
+ if (start <= len) {
+ parts.push(self.substring(start, len - start));
+ }
+
+ return parts;
+ }
} \ No newline at end of file