summaryrefslogtreecommitdiff
path: root/chapter25/README.md
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-08-10 11:11:18 -0700
committerCliff Click <cliffc@acm.org>2026-08-10 11:11:18 -0700
commit51f1f8f4b871e3b52eb0c5d18b03f362a2b37791 (patch)
tree0d734f9d53fa58acfd0ad2875f6c753c78d523a1 /chapter25/README.md
parentac3cfbfd58a2e7fdc61995c83a587778cb4e2919 (diff)
downloadSimple-51f1f8f4b871e3b52eb0c5d18b03f362a2b37791.tar.gz
Simple-51f1f8f4b871e3b52eb0c5d18b03f362a2b37791.zip
Chapter 25: add separate compilation and simplify SSA construction
Introduce Chapter 25 with separately compiled Simple modules, serialized IR, cross-compilation-unit linking, and native system-library integration. This also completes a broad parser and type-system cleanup needed to make graph construction independent of incomplete parse-time type information. Separate compilation and linking - Add compilation-unit Start/Stop nodes and track functions, classes, aliases, and global indices across compilation-unit boundaries. - Serialize canonical types and ideal graph nodes into ELF objects, including dependency metadata, relocations, global/local bitset remapping, and dense memory-alias information. - Load dependent objects on demand, recursively resolve source and object paths, relink calls and function pointers, and preserve external C symbols. - Distinguish the post-optimization ownership hook from unknown callers so private call graphs can remain precise while public functions remain externally callable. - Add command-line and build support for compiling modules and the reusable `sys` object library. Parser, constructors, and SSA - Replace inline constructor expansion with a hidden default `<init>` followed by an explicit user constructor declared as `new Type = { ... }`. - Keep the default constructor private, pass private object memory through constructor calls, and require user constructors to initialize non-default fields before the object escapes. - Track possibly-uninitialized fields in parser `Var` state and diagnose early reads without encoding parser-only constraints in Load and Store nodes. - Make ordinary parser memory bulk and recover precise alias slices in the optimizer using `MemMerge`, `MemPhi`, and `BulkMemPhi` nodes. - Remove parser-supplied type constraints from Loads and ordinary Phis, defer integer/float arithmetic selection, and keep call shape driven by syntax instead of provisional inferred types. - Preserve chained field declarations as static parser information when flow types are not yet available, including postfix field updates through calls. Types, functions, and escape analysis - Add `TypeScalar` as the common lattice family for integer, float, memory pointer, and function-pointer values, with scalar TOP/BOT values for generic Loads, Stores, parameters, and invalid intermediate expressions. - Represent unresolved struct definitions directly with the `TypeStruct` forward-reference flag while retaining the separate open-structure concept; close and canonicalize recursive structures without side maps. - Add explicit `FunPtrNode` references so constant function pointers retain a graph edge to their Return, and keep referenced functions alive until Opto proves the pointer dead. - Refine public-function and class-initializer escape handling, including public-only fallback escape sets and monotone compilation-unit summaries. - Add guards, proof casts, read-only propagation, pointer-to-integer conversion for non-null FFI arguments, and consistent deep mutability checks at calls. Optimization and code generation - Make weak and unresolved graph inputs compute conservatively and monotonically throughout iterative peepholes and SCCP. - Preserve independent memory slices when sharpening Stores, retain control on conditional Stores, and freeze Store widths from their target field types. - Extend serialization for new node kinds, scalar types, Store modes, function pointers, and memory partitions, preserving serialize/deserialize bijection. - Complete native selection and encoding support across x86-64, RISC-V, and ARM, including FFI pointer conversion and missing integer operations. - Fix x86 immediate multiply REX encoding and assorted scheduling, register allocation, spilling, relocation, and constant-pool issues exposed by the larger linked graphs. System library, tests, and documentation - Compile and link the Simple `sys` library, including libc bindings, I/O, scanners, strings, vectors, array helpers, and executable entry points. - Add Chapter 25 module, serialization, constructor, forward-reference, postfix-update, system, Hello World, and Bubble Sort coverage; update golden graphs and spill expectations for the new IR shape. - Add module and type-system documentation, parser-simplification design notes, grammar updates, examples, diagrams, and graph visualization assets. The resulting compiler passes the raw Chapter 1-24 suite and the Chapter 25 system and separate-compilation tests, including a freshly rebuilt `sys.o` and the native Bubble Sort example.
Diffstat (limited to 'chapter25/README.md')
-rw-r--r--chapter25/README.md86
1 files changed, 86 insertions, 0 deletions
diff --git a/chapter25/README.md b/chapter25/README.md
new file mode 100644
index 00000000..10cfe7e1
--- /dev/null
+++ b/chapter25/README.md
@@ -0,0 +1,86 @@
+# Chapter 25: Modules
+
+
+You can also read [this chapter](https://github.com/SeaOfNodes/Simple/tree/linear-chapter25) 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-chapter22...linear-chapter24) it to the previous chapter.
+
+
+## Modules
+
+Goal: A Module plan (not yet a "system")
+Goal: No syntax for the starter 1-file-1-line helloWorld.smp "module"
+Goal: External symbols are in ".o" files, like Java ".class" - not an source file #include like C/C++
+
+Needs a search strategy for ".o" files, so they mirror the source code directory structure.
+Means there is a "build" root for .o files.
+Means the CLI has a --flag for the build root, or some sensible default ($cwd/build)
+
+Projects with subdirectories pick up all symbols qualified names from the path-to-project-root
+
+Goal: under no circumstances can you load from an uninitialized variable (although you can see default inits for fields that have defaults).
+Goal: nested tree-structured name spaces, to control complexity.
+Goal: field decl order within a file is fairly flexible.
+
+
+## more
+
+Has a defined project root (default: CWD).
+
+Has a path to root: %PATH, e.g. $ROOT/a/b/c/
+
+Has a file name: $ROOT/ a/b/c/ foo.smp
+
+Everything in a dir is implicitly in name-space above it.
+
+Suppose `foo.smp` contains `PI=3.14;`
+
+Then the fully qualified name is: a.b.c.foo.PI
+
+Code is implicitly in the `struct a.b.c.foo {}` namespace.
+
+Final constant values can be accessed by direct names.
+
+Non-finals or non-constant need a constructed object.
+
+
+
+Top-level code in `foo.smp` is implicitly in the foo class init,
+which runs the first time foo is touched,
+which requires a "has been init" touch on every possible-first-access,
+which is every non-local ("sideways") reference.
+
+Always the init for parents are done before children,
+so `a` completes before `a.b`, and so on.
+
+Means `a` init can NOT reference e.g. `b,c,foo`, although
+you can define top-level fcns that refer to `b`.
+
+Legal in `a.smp`: `val make_b = { -> new b{} };` // fcn is final constant
+
+Legal in `a.smp`: `val b = new b{} ;` // not constant, so requires instance & <clinit> is done
+
+Means making an `a` instance in a's <clinit>, will also run a's <init>
+which can refer to instance fcns, which can refer to not-init finals?
+Limit: all fcns can only refer to instance vars *before* them.
+
+
+
+Would like to make golden instances, static singletons:
+val special = new a{/*anything already in-scope and <clinit>ed*/};
+
+
+
+The default 1-file main then:
+$ROOT==$CWD
+Code is implicitly in the *empty* name space, is in the <clinit> for the empty
+name space and gets run on project start.
+
+------
+
+Implications for e.g. sys:
+
+ .../simple/sys.smp - top level, has sys.parseAryI64
+ ../simple/sys/sys.io.smp - has `struct io { ... }`
+
+
+For now just gather the exported TYPE symbols, and a count of them, and export/input ELF.
+NO: for now split into `sys` class from instance, \ No newline at end of file