-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathchains.mu4
199 lines (162 loc) · 7.47 KB
/
chains.mu4
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
| This file is part of muforth: https://muforth.dev/
|
| Copyright 2002-2025 David Frech. (Read the LICENSE for details.)
loading PIC18 meta-compiler (chains and token consumers)
( NOTE: This was cribbed from the MSP430 target.)
forth decimal
( Metacompiler vocabs)
| .meta. is where meta-compiler specific words go - esp if they would
| otherwise shadow a host word of the same name. @ is a good example - the
| meta version writes into the target image, using a local, image-relative
| address. .meta. contains special versions of : to compile macros (though
| I'm thinking of deprecating or removing this) and to define new defining
| words during target compilation. It will also, once the kernel starts
| loading, contain a : that compiles target colon words!
|
| .definer. is slightly exotic. It's like .compiler. but it's specifically
| for making new defining words for the meta-compiler. It contains special
| definitions of words like does> and perhaps others - eg, ; [ etc.
|
| .assembler. contains definitions of instructions, registers, addressing
| modes, and words to build control structures. It is searched when
| building code words, and also when compiling macros.
|
| .equates. contains chip equates and any other constants that should be
| visible to the target compiler. When used interactively, or in the
| assembler, these push their value. When used in a target colon word, these
| compile literals.
|
| Labels - like temporary locations defined in assembler that do not
| represent target words - are in .meta., and are invisible to the target
| compiler.
|
| Also in .meta. are a handful of variables that refer to key pieces of
| target infrastructure that won't get defined until the kernel is loaded.
| Having these as forward-reference variables allows us to write the
| metacompiler using variable references; compilation of the kernel will
| patch these with actual addresses of target code.
|
| .target-compiler. is like .compiler. but for the -target- colon compiler.
| This will contain target versions of [ ; if then begin while etc. It is
| sealed since we don't want to get any host words by accident.
sealed .meta. ( the `meta' version of .forth.)
sealed .definer. ( like .compiler. but only for meta defining words)
sealed .assembler. ( the host-resident target assembler)
sealed .equates. ( chip equates and other constants for target)
sealed .lex. ( comments and conditional interpretation)
sealed .target. ( the target words - like `forth' on the host)
sealed .target-compiler. ( the `meta' version of .compiler.)
: meta .meta. definitions ;
: definer .definer. definitions ;
: assembler .assembler. definitions ;
: equates .equates. definitions ;
: lex .lex. definitions ;
: target .target. definitions ;
: target-compiler .target-compiler. definitions ;
compiler
: \m ( compile from meta) .meta. \chain ;
: \d ( compile from definer) .definer. \chain ;
: \a ( compile from assembler) .assembler. \chain ;
: \eq ( compile from equates) .equates. \chain ;
: \t ( compile from target) .target. \chain ;
: \tc ( compile from target-compiler) .target-compiler. \chain ;
forth
meta
: \f ' execute ; ( execute a forth word from meta)
forth
: \m .meta. chain' execute ; ( execute a meta word from forth)
: \eq .equates. chain' execute ; ( execute an equates word from forth)
lex
( Comments are nice to have!)
: ( \ ( ;
: | \ | ;
( And conditional intepretation is nice to have too.)
: .if \ .if ;
: .else \ .else ;
: .then \ .then ;
: .def \ .def ;
: .ndef \ .ndef ;
: .ifdef \ .ifdef ;
: .ifndef \ .ifndef ;
: .contains \ .contains ;
( For combining conditional tests.)
: .or .or ;
: .and .and ;
: .not .not ;
forth
| Metacompiler token consumers. Let's put them all in one place so we can
| understand how they work in relation to each other.
( XXX use .definer. here instead of .compiler. ?)
-: ." (compiling inlne assembler)" ;
-:
.assembler. find if compile, ^ then ( find assembler's if/then etc)
.compiler. find if execute ^ then ( need } and ; to exit this mode)
.equates. find if compile, ^ then
.meta. find if compile, ^ then ( labels are in .meta.)
.forth. find if compile, ^ then ( utility words in .forth.)
number literal ;
mode __inline-asm
-: ." (assembling)" ;
-:
.assembler. find if execute ^ then
.equates. find if execute ^ then
.meta. find if execute ^ then ( labels are in .meta.)
.forth. find if execute ^ then ( utility words in .forth.)
number ;
mode __asm
| There are two slightly different "meta" modes we can be in. When
| _building_ the target image, we are in __building. When interacting -
| after connecting via chat - we are in __chatting. Since all the compilation
| words want to return to __meta when they are done - eg, this is what the
| meta ; and ;c do - let's just defer what __meta means.
defer __meta
| The build meta-interpreter. We're in this mode when we're building the
| target image, and when in between [ and ] when running the target colon
| compiler.
-: ." (building)" ;
-:
.meta. find if execute ^ then ( labels are in .meta.)
.equates. find if execute ^ then
.forth. find if execute ^ then
number ;
mode __building
now __building is __meta
| __definer-colon is for compiling new defining words that are part of the
| meta-compiler. __definer-colon is to __meta as __inline-asm is to __asm.
-: ." (compiling a meta defining word)" ;
-:
.definer. find if execute ^ then ( does>, ;code, special ;)
.compiler. find if execute ^ then ( also need all that's here!)
.meta. find if compile, ^ then
.equates. find if compile, ^ then
.forth. find if compile, ^ then ( utility words in .forth.)
number literal ;
mode __definer-colon
| Interacting with a chatty, connected target. This differs from __meta in
| three ways:
|
| * we do not search .forth.
| * we actually try to execute target words remotely
| * we potentially convert numbers in a target-specific way
defer target-number ( convert token to a number, specific to target)
defer remote
-: error" tried to remotely execute a target word while not chatting" ;
is remote
-: ." (chatting)" ;
-:
.meta. find if execute ^ then ( labels are in .meta.)
.equates. find if execute ^ then
.target. find if execute remote ^ then ( execute on target)
.forth. find if execute ^ then
target-number ;
mode __chatting
defer target-literal ( compile a target literal)
defer target-compile, ( compile a target word into a colon definition)
-: ." (compiling a target colon word)" ;
-:
.target-compiler. find if execute ^ then
.target. find if execute target-compile, ^ then
.equates. find if execute target-literal ^ then
.lex. find if execute ^ then
target-number target-literal ;
mode __target-colon