diff options
Diffstat (limited to 'std')
| -rw-r--r-- | std/map.zc | 67 | ||||
| -rw-r--r-- | std/string.zc | 106 |
2 files changed, 173 insertions, 0 deletions
@@ -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 |
