summaryrefslogtreecommitdiff
path: root/chapter22/README.md
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-04-22 16:59:31 -0700
committerCliff Click <cliffc@acm.org>2025-04-22 16:59:31 -0700
commit3042981431447805adfab326c0f9692305ecab7a (patch)
treeba2909a1b8b0ed341839bc16a90e081a3c92c6a6 /chapter22/README.md
parent4aed9f400a3c51619dafc6b61b4495264a65d6e6 (diff)
downloadSimple-3042981431447805adfab326c0f9692305ecab7a.tar.gz
Simple-3042981431447805adfab326c0f9692305ecab7a.zip
Update README.md
Diffstat (limited to 'chapter22/README.md')
-rw-r--r--chapter22/README.md130
1 files changed, 128 insertions, 2 deletions
diff --git a/chapter22/README.md b/chapter22/README.md
index 570490f8..18a0be81 100644
--- a/chapter22/README.md
+++ b/chapter22/README.md
@@ -70,8 +70,45 @@ The syntax rules are:
- the last field is named `[]` and can be of any type.
- the second-to-last field is named `#` and must be some unsigned integer type
representing the maximum array length.
-- The allocation includes the array length, and can include a constructor:
- `new NTree{val=17;}[2];`
+
+
+
+### Constructors and Arrays
+
+The allocation includes the array length, and can include a constructor:
+`new NTree{val=17;}[2];`
+
+The constructor is optional, the array length is not.
+
+Optional function for initializing arrays, allows for write-once final arrays:
+`new u8[buffer#,{ u32 idx -> buffer[idx].toUpperCase() }`
+
+
+
+### Changing array max length
+
+An issue for range-checked small arrays, is reserving a full 4 bytes for array
+length can substantially increase the array overhead. Simple allows for arrays
+to have smaller max lengths, although these are treated as a different type
+than arrays with different max lengths.
+
+struct x0 { u8 #; u8[]; }; // Array limited to 0-255 length
+struct x1 { u16 #; u8[]; }; // Array limited to 0-65535 length
+struct x2 { u32 #; u8[]; }; //
+struct x3 { u64 #; u8[]; }; //
+
+
+x0 x = "abc"; // 4 bytes total: [3, "a", "b", "c"]
+x1 y = "def"; // 6 bytes total: [3,0, "d", "e", "f", 0,]; 1 pad byte to acheieve 2-byte alignment
+x = y; // ERROR, "x1 is not x0", no auto-widening
+x += y; // OK, 7 bytes total: [6, "a", "b", "c", "d", "e", "f"]
+y += x; // OK, 8 bytes total: [6, 0, "a", "b", "c", "d", "e", "f"]
+
+x += "VeryLongString.... ....255_chars"; // Runtime RangeCheck
+
+// Explicit conversion to widen string
+y = "" + x;
+
## Methods and Final Fields and Classes
@@ -133,8 +170,29 @@ Lifetime management to avoid using an older version of `vecInt` awaits a later
chapter.
+### Two flavors of extendable arrays/strings: an extra indirection or not
+
+With an extra indirection you get e.g. Java `ArrayList` or C++ `Vector`.
+
+Without, then any call which extends the extendable array return a potentially
+new object, only growing as needed.
+
+val vec1 = new vecInt[0].add(2); // len=1, capacity=1
+val vec2 = vec1.add(3); // NEW vecInt returned, only is deleted; len=2; capacity=2;
+vec1[0]; // ERROR, vec1 has been freed by call to `vec1.add(3)`
+vec2[0]; // OK
+vec2[1]; // OK
+vec2[2]; // Runtime error, AIOOBE
+
+
+
## A String Implementation
+Default strings have names like "str", "cstr", "ustr" or such.
+
+Always unicode8 with explicit u8 manipulations. Unicode "characters" will come
+as function calls over the base implementation.
+
### A Final String
### A Extendable String (aka StringBuilder or StringBuffer)
@@ -147,12 +205,80 @@ struct xstr {
```
+
+
+### A "C" string
+
+A zero-terminated string, but the length has to be available directly
+```java
+struct cstr {
+ u8 #; // length with zero
+ u8[]; // always ends in a zero byte; suitable for direct passing to C string fnuctions
+};
+```
+
+### A "german string": a very short string that can exist in a register
+
+Length in memory is 1 byte (3 bits?) of length, then 0-7 chars; max 8 chars.
+Fits in a 64 bit register.
+
+```java
+struct germanString { // aka gstr, or blend string and register "streg"
+ u3 #; // Size is 0-7 bytes???
+ u8 []; // Up to 7 bytes
+}
+```
+
+
## FFI and I/O Calls
Calling external / FFI functions.
+No linker support for getting the correct signature; name `write` has to be singular and unique.
`{ i32 fd, u8[] buf, i32 len -> i32 } write = "C";`
## Importing name spaces
+## Main becomes `main(str[])`
+
+### Allow structs to inline
+
+This is a name-space change only, you cannot take the address of the internal
+struct without entirely consuming its lifetime. No "escaping".
+
+```java
+// 2 64-bit words, no other overheads
+struct Complex { f64 x,y; var len = { ->Math.sqrt(x*x+y*y); }; };
+
+// Current Simple rules: always by-reference
+struct ByRef {
+ Complex c; // 4-byte pointer to a Complex
+};
+print(new ByRef.c.y); // Lookup requires 1 extra memory load from ref to c
+
+// New behavior: by value (inlining a struct)
+// The '*' syntax indicator can be something else.
+// I am pronouncing '*' as "contents of"
+struct ByValue {
+ *Complex c; // c is inlined, full 16 bytes
+};
+print(new ByValue.c.y); // x,y inlined into ByValue, no extra memory load
+
+// Mixing Refs and Struct Values
+ref.c = val.c; // Error, mixing refs and values
+ref.c = *val.c; // Allowed, whole structure copy. Does not allocate, requires ref.c not-null
+val.c = ref.c; // Error, mixing refs and values
+val.c = *ref.c; // Allowed, whole structure copy
+ref.c = ref.c; // Allowed, pointer copy
+val.c = *val.c; // Allowed, whole structure copy.
+val.c = val.c; // Allowed, whole structure copy, same as above, convenience
+
+// Alternative syntax, to avoid the "contents of" being on LHS and field applying to being on RHS:
+ref.c = val.*c; // Assign into ref.c the "contents of" val.c
+
+// Arrays of inlined structures
+var ary = new *Complex[99]; // Array of 99 Complex objects, inlined
+
+```
+