Work on the spec a bit.
Chris Pressey
6 years ago
0 | Sixtypical | |
0 | SixtyPical | |
1 | 1 | ========== |
2 | 2 | |
3 | Sixtypical is a simplified version of [Sixtypical][]. | |
4 | ||
5 | This is a complete reboot of the previous design and implementation, which | |
6 | was semantically a mess due to the way it was built. | |
7 | This aims to be a simpler design which gets the static semantics right first, | |
8 | and only then is extended to be more practical. | |
3 | This document describes the SixtyPical programming language version 0.2, | |
4 | both its execution aspect and its static analysis aspect (even though | |
5 | these are, technically speaking, separate concepts.) | |
6 | ||
7 | This document is nominally normative, but the tests in the `tests` directory | |
8 | are even more normative. | |
9 | 9 | |
10 | 10 | Types |
11 | 11 | ----- |
12 | 12 | |
13 | There are two TYPES in Sixtypical: | |
13 | There are two TYPES in SixtyPical: | |
14 | 14 | |
15 | 15 | * bit (2 possible values) |
16 | 16 | * byte (256 possible values) |
18 | 18 | Memory locations |
19 | 19 | ---------------- |
20 | 20 | |
21 | The primary concept in Sixtypical is the MEMORY LOCATION. At any given point | |
21 | A primary concept in SixtyPical is the MEMORY LOCATION. At any given point | |
22 | 22 | in time during execution, each memory location is either UNINITIALIZED or |
23 | 23 | INITIALIZED. At any given point in the program text, too, each memory |
24 | 24 | location is either uninitialized or initialized. Where-ever it is one or |
25 | 25 | the other during execution, it is the same in the corresponding place in |
26 | 26 | the program text; thus, it is a static property. |
27 | 27 | |
28 | (There is actually a third state, WRITTEN, which indicates that the memory | |
29 | location is not only initialized, but also that it has been written to in | |
30 | the current routine.) | |
31 | ||
32 | 28 | There are four general kinds of memory location. The first three are |
33 | 29 | pre-defined and built-in. |
34 | 30 | |
52 | 48 | ### Constants ### |
53 | 49 | |
54 | 50 | It may be strange to think of constants as memory locations, but keep in mind |
55 | that a memory location in Sixtypical need not map to a memory location in the | |
56 | underlying hardware. All constants are read-only. Each is | |
57 | initially initialized with the value that corresponds with its name. | |
51 | that a memory location in SixtyPical need not map to a memory location in the | |
52 | underlying hardware. All constants are read-only. Each is initially | |
53 | initialized with the value that corresponds with its name. | |
58 | 54 | |
59 | 55 | They come in bit and byte types. There are two bit constants, |
60 | 56 | |
80 | 76 | |
81 | 77 | Every routine must list all the memory locations it READS from, i.e. its |
82 | 78 | INPUTS, and all the memory locations it WRITES to, whether they are OUTPUTS |
83 | or merely TRASHED. Every memory location that is not written to is PRESERVED. | |
79 | or merely TRASHED. Every memory location that is not written to by the | |
80 | routine (or any routines that the routine calls) is PRESERVED by the routine. | |
84 | 81 | |
85 | 82 | routine foo |
86 | 83 | inputs a, score |
92 | 89 | Routines may call only routines previously defined in the program source. |
93 | 90 | Thus, recursive routines are not allowed. |
94 | 91 | |
95 | There must be one routine called `main`. This routine is executed when | |
96 | the program is run. | |
92 | For a SixtyPical program to be run, there must be one routine called `main`. | |
93 | This routine is executed when the program is run. | |
94 | ||
95 | The memory locations given given as inputs are considered to be initialized | |
96 | at the beginning of the routine. Various instructions cause memory locations | |
97 | to be initialized after they are executed. Calling a routine which trashes | |
98 | some memory locations causes those memory locations to be uninitialized after | |
99 | that routine is called. At the end of a routine, all memory locations listed | |
100 | as outputs must be initialised. | |
97 | 101 | |
98 | 102 | Instructions |
99 | 103 | ------------ |
105 | 109 | Reads from src and writes to dest. |
106 | 110 | |
107 | 111 | * It is illegal if dest is not a register. |
108 | * It is illegal if dest does not occur in the WRITES list of the current | |
112 | * It is illegal if dest does not occur in the WRITES lists of the current | |
109 | 113 | routine. |
110 | 114 | * It is illegal if src is not of same type as dest (i.e., is not a byte.) |
111 | 115 | * It is illegal if src is uninitialized. |
112 | * It is illegal if src does not either: | |
113 | * be a constant, or | |
114 | * occur in the READS list of the current routine, or | |
115 | * occur in the WRITES list of the current routine AND | |
116 | that location has previously been written inside this routine. | |
117 | 116 | |
118 | 117 | After execution, dest is considered initialized. The flags `z` and `n` may be |
119 | changed by this instruction, and they are considered initialized after it has | |
120 | executed. | |
118 | changed by this instruction; they must be named in the WRITES lists, and they | |
119 | are considered initialized after it has executed. | |
121 | 120 | |
122 | 121 | Some combinations, such as `ld x, y`, are illegal because they do not map to |
123 | 122 | underlying opcodes. |
142 | 141 | Reads from src and writes to dest. |
143 | 142 | |
144 | 143 | * It is illegal if dest is a register or if dest is read-only. |
145 | * It is illegal if dest does not occur in the WRITES list of the current | |
144 | * It is illegal if dest does not occur in the WRITES lists of the current | |
146 | 145 | routine. |
147 | 146 | * It is illegal if src is not of same type as dest. |
148 | 147 | * It is illegal if src is uninitialized. |
149 | * It is illegal if src does not either: | |
150 | * be a constant, or | |
151 | * occur in the READS list of the current routine, or | |
152 | * occur in the WRITES list of the current routine AND | |
153 | that location has previously been written inside this routine. | |
154 | 148 | |
155 | 149 | After execution, dest is considered initialized. No flags are |
156 | 150 | changed by this instruction (unless of course dest is a flag.) |
171 | 165 | |
172 | 166 | * It is illegal if src OR dest OR c is uninitialized. |
173 | 167 | * It is illegal if dest is read-only. |
174 | * It is illegal if dest does not occur in the WRITES AND READS lists | |
168 | * It is illegal if dest does not occur in the WRITES lists | |
175 | 169 | of the current routine. |
176 | * It is illegal if src does not either: | |
177 | * be a constant, or | |
178 | * occur in the READS list of the current routine, or | |
179 | * occur in the WRITES list of the current routine AND | |
180 | that location has previously been written inside this routine. | |
181 | ||
182 | Affects n, z, c, and v flags. | |
183 | ||
184 | dest continues to be initialized afterwards. | |
170 | ||
171 | Affects n, z, c, and v flags, requiring that they be in the WRITES lists, | |
172 | and initializing them afterwards. | |
173 | ||
174 | dest and src continue to be initialized afterwards. | |
185 | 175 | |
186 | 176 | Notes: |
187 | 177 | |
190 | 180 | |
191 | 181 | ### inc ### |
192 | 182 | |
193 | TODO: these do not honour carry! | |
183 | inc <dest-memory-location> | |
184 | ||
185 | Increments the value in dest. Does not honour carry. | |
186 | ||
187 | * It is illegal if dest is uninitialized. | |
188 | * It is illegal if dest is read-only. | |
189 | * It is illegal if dest does not occur in the WRITES lists | |
190 | of the current routine. | |
191 | ||
192 | Affects n and z flags, requiring that they be in the WRITES lists, | |
193 | and initializing them afterwards. | |
194 | ||
195 | Notes: | |
194 | 196 | |
195 | 197 | inc x → INX |
196 | 198 | inc y → INY |
202 | 204 | |
203 | 205 | Subtracts the contents of src from dest and stores the result in dest. |
204 | 206 | |
205 | The constraints and effects are exactly the same as for `add`. | |
207 | * It is illegal if src OR dest OR c is uninitialized. | |
208 | * It is illegal if dest is read-only. | |
209 | * It is illegal if dest does not occur in the WRITES lists | |
210 | of the current routine. | |
211 | ||
212 | Affects n, z, c, and v flags, requiring that they be in the WRITES lists, | |
213 | and initializing them afterwards. | |
214 | ||
215 | dest and src continue to be initialized afterwards. | |
206 | 216 | |
207 | 217 | Notes: |
208 | 218 | |
211 | 221 | |
212 | 222 | ### dec ### |
213 | 223 | |
214 | TODO: these do not honour carry! | |
224 | inc <dest-memory-location> | |
225 | ||
226 | Decrements the value in dest. Does not honour carry. | |
227 | ||
228 | * It is illegal if dest is uninitialized. | |
229 | * It is illegal if dest is read-only. | |
230 | * It is illegal if dest does not occur in the WRITES lists | |
231 | of the current routine. | |
232 | ||
233 | Affects n and z flags, requiring that they be in the WRITES lists, | |
234 | and initializing them afterwards. | |
235 | ||
236 | Notes: | |
215 | 237 | |
216 | 238 | dec x → DEX |
217 | 239 | dec y → DEY |
223 | 245 | |
224 | 246 | Subtracts the contents of src from dest, but does not store the result. |
225 | 247 | |
226 | The constraints and effects are the same as for `sub`, except that `c` | |
227 | need not be initialized before executing `cmp`, and the `v` flag is | |
228 | unaffected. | |
248 | * It is illegal if src OR dest is uninitialized. | |
249 | ||
250 | Affects n, z, and c flags, requiring that they be in the WRITES lists, | |
251 | and initializing them afterwards. | |
229 | 252 | |
230 | 253 | Notes: |
231 | 254 | |
233 | 256 | cmp a, 1 → CMP #1 |
234 | 257 | cmp x, 1 → CPX #1 |
235 | 258 | cmp y, 1 → CPY #1 |
259 | ||
260 | - - - - | |
236 | 261 | |
237 | 262 | ### and ### |
238 | 263 |