summaryrefslogtreecommitdiff
path: root/chapter29/src/main/smp/sys/aryu8.smp
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-11-01 10:33:55 -0800
committerCliff Click <cliffc@acm.org>2026-11-01 10:33:55 -0800
commitf4bd723d929e53475f7990374dca7b7dfcbbdc42 (patch)
tree7bb080119e7b88ad4ac9b30af019fe6a5e4ba9dd /chapter29/src/main/smp/sys/aryu8.smp
parent0ac0c9e10287972ac3af5a4ee43d26f0d5b318fe (diff)
downloadSimple-main.tar.gz
Simple-main.zip
Add Chapter 29 for tech debt cleanup with the parser splitmain
Keep Chapter 28b intact and carry the grammar-oriented parser package, Var move, IterPeeps move, and parser regression tests into Chapter 29. Defer privacy and exclude its experimental tests and fixture changes. Register the chapter in the indexes, IntelliJ modules and run configurations, Maven reactor, roadmap, and linear-history publisher. Windows and Linux each pass 573 tests, release builds, 199 allocation replays, and 29 native checks.
Diffstat (limited to 'chapter29/src/main/smp/sys/aryu8.smp')
-rw-r--r--chapter29/src/main/smp/sys/aryu8.smp87
1 files changed, 87 insertions, 0 deletions
diff --git a/chapter29/src/main/smp/sys/aryu8.smp b/chapter29/src/main/smp/sys/aryu8.smp
new file mode 100644
index 00000000..21cf920b
--- /dev/null
+++ b/chapter29/src/main/smp/sys/aryu8.smp
@@ -0,0 +1,87 @@
+
+// Ary/Vector of u8s - a resizable array of bytes.
+struct aryu8 {
+ u32 !len = 0;
+ u8[] !buf;
+
+ new aryu8 = { -> buf = new u8[1]; };
+
+ // Grow as needed
+ val _grow = { int len2 ->
+ if( len+len2 < buf# ) return self;
+ int newlen = buf# * 2;
+ while( len+len2 >= newlen ) newlen *= 2;
+ u8[] !buf2 = new u8[newlen];
+ ary.copy(buf2,0,buf,0,buf#);
+ buf = buf2;
+ self;
+ };
+
+ val clear = { -> len = 0; self; };
+
+ // Add a character to aryu8
+ val add = { u8 c ->
+ _grow(1).buf[len++] = c;
+ self;
+ };
+
+ // Add all of a plain array to the aryu8
+ val addAry = { u8[~] xs ->
+ _grow(xs#);
+ ary.copy(buf,len,xs,0,xs#);
+ len += xs#;
+ self;
+ };
+
+ // Remove x bytes from the tail.
+ val undo = { int x ->
+ len = len >= x ? len-x : 0;
+ self;
+ };
+
+ // Print ASCII number into aryu8
+ val num = { i64 x ->
+ if( !x ) { add('0'); return self; }
+ if( x < 0 ) { add('-'); x = -x; }
+ i64 ten = 1, log = 0;
+ while( ten <= x ) { ten *= 10; log++; }
+ for( int i=0; i<log; i++ ) {
+ ten /= 10;
+ i64 q = x/ten;
+ u8 digit = q+'0';
+ add(digit);
+ x -= q*ten;
+ }
+ self;
+ };
+
+ // Write to fd, returns the number of bytes written (len).
+ val write = { i32 fd ->
+ i64 ptr = buf; // Cast buffer pointer to i64 for native C call
+ libc.write(fd,ptr,len);
+ };
+};
+
+
+// Parse one integer, ignore trailing data; returns 0 with an empty string.
+// If you want a more robust parsing, use the `scan` class
+val atoi = { u8[~] str ->
+ int x = 0;
+ while( x < str# && str[x] <= ' ' ) x++;
+ if( x == str# ) return 0;
+ bool neg = false;
+ if( str[x]=='-' ) { neg=true; x++; }
+ i64 n = 0;
+ while( x < str# && '0' <= str[x] <= '9' )
+ n = n*10 + str[x++]-'0';
+ return neg ? -n : n;
+};
+
+// Zero-terminate string for libc strings. No error checking, just copies and
+// appends a zero.
+{ u8[~] -> u8[] } str0 = { u8[~] str ->
+ u8[] !strz = new u8[str#+1];
+ ary.copy(strz,0,str,0,str#);
+ strz[str#] = '\0';
+ strz;
+};