diff options
| author | Cliff Click <cliffc@acm.org> | 2025-04-21 15:23:48 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2025-04-21 15:23:48 -0700 |
| commit | 33feb607bb4458a4258a985e77666f9a904fe6e4 (patch) | |
| tree | e069feaea473dbcae1cee5ddf496544aada274a1 | |
| parent | 988656f475230e845fa3b553e97799b0829e9830 (diff) | |
| download | Simple-33feb607bb4458a4258a985e77666f9a904fe6e4.tar.gz Simple-33feb607bb4458a4258a985e77666f9a904fe6e4.zip | |
README
| -rw-r--r-- | chapter22/.#README.md | 1 | ||||
| -rw-r--r-- | chapter22/README.md | 117 |
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 |
