diff options
| author | Cliff Click <cliffc@acm.org> | 2025-01-20 09:30:37 -0800 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2025-01-20 09:30:37 -0800 |
| commit | cfecd341531f29ba7d67decdd907071a9e49cf60 (patch) | |
| tree | 845bbec5f1b37a60e2b220e1794933969c5c0c8f | |
| parent | 8d9cd9a0aa846b44dde6dc97138398f6d7ce00d9 (diff) | |
| download | Simple-cfecd341531f29ba7d67decdd907071a9e49cf60.tar.gz Simple-cfecd341531f29ba7d67decdd907071a9e49cf60.zip | |
Minor readme updates
Add linear history links
| -rw-r--r-- | chapter17/README.md | 39 | ||||
| -rw-r--r-- | chapter18/README.md | 24 |
2 files changed, 33 insertions, 30 deletions
diff --git a/chapter17/README.md b/chapter17/README.md index 8a7cc8b1..6c19b642 100644 --- a/chapter17/README.md +++ b/chapter17/README.md @@ -1,5 +1,8 @@ # Chapter 17: Syntax Sugar +In this chapter we introduce a number of convenient syntax sugars and mutability concepts. + +You can also read [this chapter](https://github.com/SeaOfNodes/Simple/tree/linear-chapter17) in a linear Git revision history on the [linear](https://github.com/SeaOfNodes/Simple/tree/linear) branch and [compare](https://github.com/SeaOfNodes/Simple/compare/linear-chapter16...linear-chapter17) it to the previous chapter. ## Pre/Post-increment @@ -27,9 +30,10 @@ value), whose type will be inferred from the required initalizing expression. `val` is the same as `var`, except it is a "value" (not mutable). -The inferred value is the `glb` of the peephole type, which means `var` and -`val` will not infer types like `u8` or `f32`, instead inferring `int` and -`flt` respectively. Reference types will always infer as nullable, so e.g. +The inferred value is the Greatest Lower Bound `glb` type of the peephole type, +which means `var` and `val` will not infer types like `u8` or `f32`, instead +inferring `int` and `flt` respectively. Reference types will always infer as +nullable, so e.g. `var s = new S;` @@ -42,8 +46,8 @@ infers as Typed primitive fields are always mutable. Typed reference fields without an initializer must be mutable to get a value. Initialized reference variables -are immutable by default and can be made mutable with a leading `!`. `var` and -`val` keep their current sense and can be used to make any field mutable or +are *immutable* by default and can be made mutable with a leading `!`. `var` +and `val` keep their current sense and can be used to make any field mutable or immutable. Fields are always mutable during construction, but will become immutable at the end of either constructor. @@ -68,17 +72,16 @@ Leading `!` makes mutable: `S !s = new S; s.x++; // Ok, has '!' so mutable` -'var' is variable: +`var` is variable, i.e. mutable: `var s = new S; s.x++; // Ok, has var so mutable` -'val' is a "value": not mutable through this reference, but may be mutable +`val` is a "value": not mutable through this reference, but may be mutable through other references. `val s = new S; s.x++; // Error, val so s.x is immutable` - ### Reference variables with an initializer are deeply immutable Initialized reference variables are deeply immutable, but a mutable version of the same @@ -87,20 +90,20 @@ reference can exist. This works for `val` and normal type declarations: `val s ```cpp struct Bar { int x; } -Bar !bar = new Bar; -bar.x = 3; // Ok, bar is mutable +Bar !bar = new Bar; // '!' so bar is mutable +bar.x = 3; // Ok, bar is mutable struct Foo { Bar !bar; int y; } -Foo !foo = new Foo; -foo.bar = bar; // Ok bar is mutable -foo.bar.x++; // Ok foo and foo.bar and foo.bar.x are all mutable +Foo !foo = new Foo; // '!' so foo is mutable +foo.bar = bar; // Ok foo is mutable +foo.bar.x++; // Ok foo and foo.bar and foo.bar.x are all mutable -val xfoo = foo; // Throw away mutability -xfoo.bar.x++; // Error, cannot mutate through xfoo +val xfoo = foo; // Throw away mutability deeply on foo +xfoo.bar.x++; // Error, cannot mutate through xfoo -print(xfoo.bar.x); // Ok to read through xfoo, prints 4 -foo.bar.x++; // Bumps to 5 -print(xfoo.bar.x); // Ok to read through xfoo, prints 5 +print(xfoo.bar.x); // Ok to read through xfoo, prints 4 +foo.bar.x++; // Bumps to 5 +print(xfoo.bar.x); // Ok to read through xfoo, prints 5 ``` ## Trinary diff --git a/chapter18/README.md b/chapter18/README.md index 031ce589..e471f49e 100644 --- a/chapter18/README.md +++ b/chapter18/README.md @@ -23,6 +23,7 @@ changes and subtle complexities than sensible for such a large chapter. Functions can only refer to out of scope variables if they are some final constant. This generally includes e.g. recursive function pointers. +You can also read [this chapter](https://github.com/SeaOfNodes/Simple/tree/linear-chapter18) in a linear Git revision history on the [linear](https://github.com/SeaOfNodes/Simple/tree/linear) branch and [compare](https://github.com/SeaOfNodes/Simple/compare/linear-chapter17...linear-chapter18) it to the previous chapter. ## Function and RPC Types @@ -54,14 +55,15 @@ and return. Function types can be `null` just like references. Functions cannot return `void`, but they can return `null` and have their -return value ignored. A syntactic sugar for void returns may be added in the future. +return value ignored. A syntactic sugar for void returns may be added in the +future. ### Return Program Counters -Just like functions have a unique `function index` mapped one to one with -function start addresses, call sites generate a unique `return program -counter`, one per unique call site. These are required for the evaluator to return +Just like functions have a unique "function index" mapped one to one with +function start addresses, call sites generate a unique "return program +counter", one per unique call site. These are required for the evaluator to return from functions without itself relying on the implementing language's (e.g. Java) stack. This is the type for such values and `TypeRPC` is very similar to a `TypeFunPtr` except that the signature doesn't matter. @@ -71,14 +73,13 @@ analysis of a hypothetical `call/cc` operation. That is outside our current scope, so for now these are only used in the evaluator. - ## Functions Functions themselves using the same syntax with as function types, but filled in: ``` -{ int x, int y -> - sqrt(x*x+y*y); +{ flt x, flt y -> // Signature + sqrt(x*x+y*y); // Body } ``` @@ -186,7 +187,7 @@ from GVN) then the function inlines in the IR. There is now a top-level compile driver that enforces a phase ordering, and allows multiple compilations; the Fuzzer uses this to compare various generated -programs. The phases are: +programs. The phases (for now) are: - *Parse* - Convert program text to Simple IR - *Opto* - General optimizations; for now iterate peepholes. @@ -198,17 +199,16 @@ programs. The phases are: some required rules: Phis appear at block heads, branchs at block exits. There's room in the algorithm for a much more sophisticated list scheduler. The `Eval2` evaluator requires this information. -- *RegAlloc* - Not implemented (yet). +- *RegAlloc* - Not implemented (yet). Several globals moved from the Parser to CodeGen, and probably several others -ought to move here. +ought to move here. There is a very nice `toString()` here; hovering over the `code` variable in the debug winow will pretty-print the IR "as if" globally scheduled, and the code becomes very readable. - ## Eval2 - A new Evaluator There is now a second evaluator that uses the scheduling information to @@ -222,7 +222,7 @@ recursive calls). Run as `make view` or `java JSViewer`, type your program in the text box, click outside the box and then use the arrow keys to view IR generator both forwards -and backwards. +and backwards. Nodes are color coded according to type, same as the lattice diagrams. Nodes are shaped according to node function as well. At the bottom are `ScopeNode`s, |
