diff options
| author | Cliff Click <cliffc@acm.org> | 2025-04-25 14:46:29 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2025-04-25 14:46:29 -0700 |
| commit | 024335df60fb769a87bd4e75aba853ce74276f43 (patch) | |
| tree | 26047767bac4783597547f8a03ed3ecbdb555934 /chapter22/README.md | |
| parent | 9bc0831d5db4ad3ef0ef45870e0892fa11fefe82 (diff) | |
| download | Simple-024335df60fb769a87bd4e75aba853ce74276f43.tar.gz Simple-024335df60fb769a87bd4e75aba853ce74276f43.zip | |
Update README.md
Diffstat (limited to 'chapter22/README.md')
| -rw-r--r-- | chapter22/README.md | 117 |
1 files changed, 59 insertions, 58 deletions
diff --git a/chapter22/README.md b/chapter22/README.md index 7bf420b7..ef2304d0 100644 --- a/chapter22/README.md +++ b/chapter22/README.md @@ -19,6 +19,7 @@ No linker support for getting the correct signature; name `write` has to be sing `{ i32 fd, u8[] buf, i32 len -> i32 } write = "C";` + ## Importing name spaces Ponder a `struct sys{}` default import struct. @@ -28,63 +29,6 @@ Includes `sys.io{}` struct with I/O calls. Includes `sys.libc{}` with default libc calls. -## Structs can be inlined - -Structs are normally by-reference, but can be converted to by-value by using -the `*` operator, pronounced "contents of" (this name might be changed to -e.g. `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, e.g. a keyword "inline" -// I am pronouncing '*' as "contents of" -struct ByValue { - *Complex c; // c is inlined, full 16 bytes into ByValue -}; -print(new ByValue.c.y); // x,y inlined into ByValue, no extra memory load - -// Mixing Refs and Struct Values. Basically, a ref can be converted -// to a value by taking the "contents of" the ref, and values cannot -// be *converted* to a ref, although they can be copied over a ref. -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; // Error, cannot take "contents of" a value - -// 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 - -// Calling methods has the same syntax -ref.c.len(); -val.c.len(); - -// Function arguments use the same typing, so can pass-by-value -val math.sin = { Complex *c -> ... }; // Passes a complex by value -math.sin(ref.*c); // Requires de-reference to pass by value -math.sin(val. c); // Pass by value - -``` - - - ## Unifying Structs and Arrays The idea is that structs have fields indexed by names, and arrays have fields @@ -151,6 +95,7 @@ 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. +- may require a leading space in front of ` []` @@ -405,8 +350,64 @@ gstr *prize3 = "bronze"; ### Main becomes `val main = { str[] args -> ...}` +## Structs can be inlined + +Structs are normally by-reference, but can be converted to by-value by using +the `*` operator, pronounced "contents of" (this name might be changed to +e.g. `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; val 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, e.g. a keyword "inline" +// I am pronouncing '*' as "contents of" +struct ByValue { + *Complex c; // c is inlined, full 16 bytes into ByValue +}; +print(new ByValue.c.y); // x,y inlined into ByValue, no extra memory load + +// Mixing Refs and Struct Values. Basically, a ref can be converted +// to a value by taking the "contents of" the ref, and values cannot +// be *converted* to a ref, although they can be copied over a ref. +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; // Error, cannot take "contents of" a value + +// 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 + +// Calling methods has the same syntax +ref.c.len(); +val.c.len(); + +// Function arguments use the same typing, so can pass-by-value +val math.sin = { Complex *c -> ... }; // Passes a complex by value +math.sin(ref.*c); // Requires de-reference to pass by value +math.sin(val. c); // Pass by value + +``` + + -### RoadMap for other chapters +## RoadMap for other chapters `&&` and `||` Drop `int` to `i32`. |
