Skip to content

Commit e739503

Browse files
committed
data model
1 parent 7d2f81a commit e739503

File tree

2 files changed

+149
-1
lines changed

2 files changed

+149
-1
lines changed

README.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ cloned into the `_hkdeps` directory, by recursively scanning the
104104
repositories.
105105

106106
Directory structure within a repository is free-form; the compilation
107-
order is determined after scanning the prologue of each module (a file).
107+
order and conditional compilation is determined after scanning the
108+
prologue of each module (a file).
108109

109110
## Compile-time allocations survive into runtime.
110111
Since a lot of code will be executed at compile-time it is likely that
@@ -125,6 +126,45 @@ So allocations during compilation must survive into the executable.
125126
* The read-write `.alloc` section is part of the normal allocation,
126127
allowing deallocation and reusing.
127128

129+
## Enum with associated values
130+
Enums members have zero or more associated values, like the following
131+
optional type, which is a template. Template arguments use the bracketed
132+
argument syntax.
133+
134+
```
135+
enum optional[T : type] {
136+
none
137+
some(T)
138+
}
139+
```
140+
141+
Niche values and niche-mask allow optimization to compress the enum's index-tag to
142+
occupy the same space as the associated value. For example the address of a reference
143+
can never be zero, so this niche-value can be used for `none` with an
144+
optional reference.
145+
146+
## Capturing string literals
147+
String literals with the `t` prefix like the following `t"Hello {foo()}"`
148+
are converted to a tuple of the following form: `("Hello {1:}", foo())`.
149+
150+
## Types are values
151+
All types are constructed from templates. Returned types are interned; two types
152+
returned from the same template with same arguments are identical.
153+
154+
Templates are normal functions that return a type, and like normal functions may have
155+
an overload-set. Templates may be modified, at compile time, before the template is
156+
used to instantiate a type. Since all functions are templates, any type-template in
157+
a type decoration on arguments and return types are not instantiated until that
158+
function is called.
159+
160+
161+
A partially instantiated template returns a wrapper template that calls the original
162+
template with the remaining arguments. This means that a type returned from the
163+
wrapper template still is identified as comming from the original template.
164+
165+
For ease of use when a zero argument template is used where a type is needed it is
166+
automatically instantiated there.
167+
128168
## Elaboration Phase
129169
Certain languages have a separate elaboration phase during compilation.
130170

doc/language/data_model.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# data model
2+
3+
This chapter describes how functions, types, templates and values work in this
4+
language.
5+
6+
Here are a couple of rules in this language:
7+
- Types are first class values, and can be passed to functions or type templates.
8+
- All function and type definitions are always templates.
9+
- A type definition is an alternate representation of a function that returns a type.
10+
- Multiple type and function definition with the same name form a overload set.
11+
- Type and function definitions may be modified until the whole overload set is frozen.
12+
- An overload set is frozen when a type or function is instantiated.
13+
- Functions and types are lazilly evaluated to delay freezing; functions and
14+
global variables are recursively evaluated when they are exported, after
15+
processing the last statement of a file.
16+
17+
## Templates
18+
19+
Function and type definitions are always templates in this language.
20+
21+
22+
## Overload sets
23+
24+
25+
26+
27+
## Compilation Order
28+
29+
The compilation order is important when we are describing how the compiler
30+
knows which types are visible and complete.
31+
32+
Compilation starts after the prologue-scan which will read every source file
33+
in the repository and each imported repository.
34+
35+
Each file is then compiled in random order while satisfying that all imported
36+
modules of a file are compiled first. In incremental/language server mode,
37+
files may trigger recompilation of files and their dependent files.
38+
39+
Each file is compiled statement-by-statement, as-if they executed in a
40+
interpreter, for example:
41+
- type-template definition.
42+
- function-template definition.
43+
- global variable definition.
44+
- executable statements
45+
46+
> [!NOTE]
47+
> All types and function declarations are templates in this language.
48+
49+
At this time function and type declarations remain in their "modifiable" state,
50+
this means:
51+
- Other versions of type and functions can be added to the overload set.
52+
- It is possible to modify types by removing and adding members to types,
53+
as-if types are mutable values.
54+
55+
During the statement-by-statement compilation there may also be normal code
56+
statments at file scope that will be executed that for example can make these
57+
modifications of types. These code statements can cause types and functions
58+
to transition to "frozen" and "instantiated" state.
59+
60+
61+
62+
## Functions
63+
64+
A function is a piece of code to execute, its identity is the memory address to
65+
the start of a function, together with a function's signature.
66+
67+
It is possible for code to be shared by multiple functions, by de-duplication of
68+
identical code being generated.
69+
70+
> [!NOTE]
71+
> A function address is not unique between functions,
72+
73+
74+
### Function Definition
75+
76+
A function definition consists of:
77+
- A fully qualified name
78+
- A function signature
79+
- Attributes
80+
- A block of code
81+
82+
A function definition creates a function-template which is part of an overload set
83+
which shares the fully qualified name with other function definitions.
84+
85+
### Compilation Order
86+
87+
A function definition during compilation has the following states:
88+
1. Modifiable: each function definition is modifiable during compilation.
89+
2. Frozen: all function definitions of a overload set is frozen when the
90+
first reference to a function by that name is being compiled. This will
91+
in turn freeze each type-template mentioned in the signature of each
92+
function definition of that overload set.
93+
3. Instantiation: when a function call is compiled the proper template in
94+
the overload set is matched, and then the function is uniquely instantiated
95+
for this call, with potential constant values. Only when a function is
96+
instantiated will calls in the code block be compiled and trigger freeze
97+
and instantiation of other functions.
98+
99+
The compiler is guaranteed to lazy freeze or instantiate functions only when
100+
those functions are:
101+
- Called directly in the file-scope, in-order from top to bottom.
102+
- When functions are explicitly exported to be part of the executable linkage.
103+
This happens after the last line of the file-scope is processed.
104+
- When a global variable is explicitly exported to be part of the executable linkage.
105+
This happens after the last line of the file-scope is processed.
106+
- A function called `main()` is implicitly exported, this happens as-if
107+
This happens after the last line of the file-scope is processed.
108+

0 commit comments

Comments
 (0)