summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-04-21 15:23:48 -0700
committerCliff Click <cliffc@acm.org>2025-04-21 15:23:48 -0700
commit33feb607bb4458a4258a985e77666f9a904fe6e4 (patch)
treee069feaea473dbcae1cee5ddf496544aada274a1
parent988656f475230e845fa3b553e97799b0829e9830 (diff)
downloadSimple-33feb607bb4458a4258a985e77666f9a904fe6e4.tar.gz
Simple-33feb607bb4458a4258a985e77666f9a904fe6e4.zip
README
-rw-r--r--chapter22/.#README.md1
-rw-r--r--chapter22/README.md117
2 files changed, 116 insertions, 2 deletions
diff --git a/chapter22/.#README.md b/chapter22/.#README.md
deleted file mode 100644
index 3db1c7b4..00000000
--- a/chapter22/.#README.md
+++ /dev/null
@@ -1 +0,0 @@
-cliffc@DESKTOP-DAD.3440:1744424503 \ No newline at end of file
diff --git a/chapter22/README.md b/chapter22/README.md
index 8d38d707..b2bd8d3f 100644
--- a/chapter22/README.md
+++ b/chapter22/README.md
@@ -12,7 +12,122 @@ You can also read [this chapter](https://github.com/SeaOfNodes/Simple/tree/linea
## Unifying Structs and Arrays
-## Methods
+The idea is that structs have fields indexed by names, and arrays have fields
+indexed by numbers, and these ideas are compatible with each other. This idea
+has been used by the C language for a long time - following a normal struct we
+allow an array, and index it with the usual array syntax.
+
+```java
+struct str {
+ int hash; // A cache of the strings hash code
+ uint #; // The array length
+ u8 []; // Array of bytes
+}
+```
+
+Here, the field named `#` holds the array length and the field named `[]` is
+the actual array, which follows the other fields directly in memory.
+Here is another example for variable length array:
+
+```java
+struct vecInt {
+ uint size; // Actual number of elements
+ uint #; // The array length or capacity
+ int []; // Array of integers.
+};
+```
+
+The obvious limit here is that the array cannot be directly resized; it is
+literally in the same memory block as the leading structures. Such a `vecInt`
+can be *re-allocated* to a new larger `vecInt`, but the original `vecInt` may
+be reclaimed.
+
+Any number of named fields are allowed:
+
+```java
+struct Class {
+ str className;
+ str professor;
+ int time;
+ int credits;
+ Class prerequist;
+ u16 #; // Limit of 65535 students per class
+ Student [];
+};
+```
+
+Or self-reference:
+
+```java
+struct NTree {
+ Some val;
+ u8 #; // Length is 0-255
+ NTree []; // More NTrees
+};
+```
+
+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.
+
+
+
+
+
+## Methods and Final Fields and Classes
+
+Methods are simply function values (final fields) declared inside a struct that
+take an implicit `this` argument.
+
+Final field declared in the original struct definition are *values* and cannot
+change; they are the same for all structs. They get moved out of the struct's
+memory footprint and into a *class*. Classes are just plain namespaces and
+have no concrete implementation; they are not reified.
+
+```java
+struct vecInt {
+ // Add an element to a vector, possibly returning a new larger vector
+ val add = { int e ->
+ if( size >= # ) return copy(# ? #*2 : 1).add(e);
+ [size++] = e;
+ return this;
+ };
+ // Copy 'this' to a new larger size
+ val copy = { int sz2 ->
+ val v2 = new vecInt[sz2];
+ for( int i=0; i<size; i++ )
+ v2[i] = [i];
+ v2.size = size;
+ return v2;
+ }
+
+ u32 size; // Actual number of elements
+ u32 #; // The array length or capacity
+ int []; // Array of integers.
+};
+
+val primes = new vecInt[0].add(2).add(3).add(5).add(7);
+
+```
+
+Here the `val add = ` field is a *value* field, a constant function value. It
+is moved out of the basic `vecInt` object into `vecInt`'s *class*, and takes no
+storage space in `vecInt` objects. The same happens for `copy`. The size of a
+`vecInt` is thus 2 `u32` words, plus `#*sizeof(int)`, plus any padding
+(probably none here).
+
+The actual usage of this `vecInt` class differs from other similar classes in
+other languages:
+
+- The data and header object are *inlined*, one level of indirection (and
+ possible cache miss cost) is avoided.
+- The array cannot be resized without resizing the entire object. Once the
+ array is full, further adds will return a **new** larger `vecInt`.
+
+Lifetime management to avoid using an older version of `vecInt` awaits a later
+chapter.
+
## A String Implementation