summaryrefslogtreecommitdiff
path: root/chapter25/README.md
blob: 10cfe7e1cf6fe604adea76c6bb0abb482dc3259f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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,