forked from danmey/FourK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bootstrap.4k
306 lines (283 loc) · 7.51 KB
/
bootstrap.4k
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
token ; make
postpone lit 1 c,
postpone state
postpone !
postpone last
postpone @
postpone lit 1 c,
postpone +
postpone last
postpone !
postpone lit
0 c,
postpone here
postpone @
postpone lit
0 c,
postpone +
postpone c!
postpone lit
2 c,
postpone here
postpone @
postpone lit
1 c,
postpone +
postpone c!
immediate
last @ 1 + last !
token (:) make
postpone make
postpone lit
0 c,
postpone state
postpone !
;
token : (:) token (:) ;
: here@ here @ ;
: begin here@ ; immediate
: until postpone branch0 here@ - c, ; immediate
: | begin key 10 = until ; immediate
| ANS compability
: \ postpone | ; immediate
| State manipulation
: [ 1 state ! ; immediate
: ] 0 state ! ;
| Compilaton of literals
: literal 3 c, c, ;
: rliteral 4 c, , ;
: sliteral swap rliteral literal ;
| Allocation and sizes
: allot there @ + there ! ;
| 4 byte cells
: cell 4 ;
: cells cell * ;
: cells+ cells + ;
| Byte cells
: byte 1 ;
: bytes byte * ;
: bytes+ bytes + ;
| Creation of data words
: (create) make there @ rliteral postpone ; ;
: create token (create) ;
| Variables
: variable : there @ rliteral postpone ; cell allot ;
: constant : rliteral postpone ; ;
: const constant ;
: bconst : literal postpone ; ;
| Sections
create table 16 32 * allot
variable #section
| Must be 7, as we've defined 7 sections already
7 #section !
| Control flow
: if postpone branch0 here@ 0 c, ; immediate
: then dup here@ swap - swap c! ; immediate
: else >r postpone branch here@ 0 c, r> postpone then ; immediate
: again postpone branch here@ - c, immediate ;
| Generic loop
: while postpone branch0 here@ 0 c, ; immediate
: repeat postpone branch swap here@ - c, dup here@ swap - swap c! ; immediate
| Compile read character
: c: key state @ 0 = if literal then ; immediate
| Increments, decrements, tests
: 1+ 1 + ;
: 1- 1 - ;
: 0= 0 = ;
| New line space (does not honor windows)
: cr 10 emit ;
: space 32 emit ;
| Operation on pair of cells
: 2drop drop drop ;
: over swap dup >r swap r> ;
: 2dup over over ;
| Line comments
: ( 1
begin
c: ) key dup rot = if swap 1- dup 0 = if drop drop ;; then swap then
c: ( = if 1+ then
again ; immediate
| Case statement
: ?dup dup if dup then ;
: case 0 ; immediate
: of postpone over postpone = postpone if postpone drop ; immediate
: endof postpone else ; immediate
: endcase' begin ?dup while postpone then repeat ; immediate
: endcase postpone drop postpone endcase' ; immediate
| to verbose but will make optimisations later
| by default we will use byte bytes, as it is meant to be 4kb tool
: r ( -- r ) postpone r> postpone dup postpone >r ; immediate
: rdrop ( -- r: v -- ) postpone r> postpone drop ; immediate
| Counted loops
: do
postpone swap postpone >r postpone >r postpone begin
; immediate
: leave postpone r> postpone r> postpone drop postpone drop ; immediate
: loop postpone r>
postpone dup
postpone 1+
postpone r
postpone swap
postpone >r
postpone =
postpone until
postpone r>
postpone r>
postpone drop
postpone drop
; immediate
: i postpone r ; immediate
| Very ineficent! Maybe we should move it to core
: j postpone r>
postpone r>
postpone r>
postpone dup
postpone >r
postpone swap
postpone >r
postpone swap
postpone >r
; immediate
| Increment variable
: inc ( adr -- ) dup @ 1+ swap ! ;
: dec ( adr -- ) dup @ 1- swap ! ;
| exit current word if TOS is zero
: 0; ( n -- ) postpone = postpone if
postpone ;; postpone then
; immediate
| Multiline comments
: (* begin key c: * = if key c: ) = if ;; then then again ; immediate
(*
a multi
line
comment
*)
| comparison words
: <> = invert ;
: 0<> 0= invert ;
: <= > invert ;
: >= < invert ;
: +! swap >r dup @ r> + swap ! ;
: -! swap >r dup @ r> - swap ! ;
: 1+! 1 swap +! ;
: 1-! 1 swap -! ;
: data: here there @ here@ there ! swap ! ;
: data; data: ;
| STRINGS
create #str 1000 allot
: parse ( delimiter -- str c ) [ there @ rliteral ] c! here @ >r #str here !
begin key dup [ there @ rliteral ]
c@ = if drop #str here @ #str - 0 c, r> here ! ;; then
c, again
;
create parse-buffer 1000 allot
: >with-here postpone here@ postpone >r postpone here postpone ! ; immediate
: with-here> postpone r> postpone here postpone ! ; immediate
: parse2 ( delimiter -- str c )
parse-buffer >with-here
>r 0 begin key dup r = 0= while c, 1+ repeat rdrop drop
with-here> parse-buffer swap
;
: \" c: " parse ;
| inlines a counted list of bytes to there
: inline ( str c -- str c )
here @ >r there @ here ! here @ + >r
begin r here @ = if drop there @ r> there @ - here @ there ! r> here ! ;; then
dup c@ c, 1+ again
;
: type ( str c -- ) 1- dup 0 >= if 0 do dup i + c@ emit loop then drop ;
: next-set ( char-adr char-adr -- ) 1+ swap 1+ swap ;
: ch@ ( char-adr char-adr -- t/f ) c@ swap c@ ;
variable flag
| compare two zero terminated strings, the strings are assumed to be
| of the same size (no size checking )
: compare ( str str -- t/f ) -1 flag !
begin
2dup ch@ 2dup = invert if 0 flag ! then
and 0 = if 2drop flag @ ;; then next-set
again
;
| compare two counted strings ( so with size checking )
: str= ( str c str c -- t/f ) >r swap r> = if compare ;; then 2drop 0 ;
| pimped ", it now compiles the string to there @compile time
: " \" state @ 0 = if inline there @ dup 0 swap c! 1+ there !
sliteral then
; immediate
(*
: " \" inline there @ dup 0 swap c! 1+ there !
state @ 0 = if sliteral then ; immediate
*)
: ." ( -- ) postpone "
state @ 0 = if postpone type ;; then type
; immediate
variable #ccall 0 #ccall !
| Shared libraries and dynamic loading of symbols
| create word and slot for address of a symbol
: ccall: : postpone ccall c, postpone ; ;
: symbol: #ccall @ #ccall 1+! : postpone ccall c, postpone ; ;
| Initially filled with dlopen and dlsym
symbol: dlopen
symbol: dlsym
| Convert string to zero terminated string
: >cstr drop ;
| Load library
: lib >cstr $1 $100 or swap dlopen ;
| Load symbol
: sym >cstr swap dlsym ;
variable #ithere
| dlopen and dlsym again
| 2 * 2 cells, 1st cell stack fixup second address (or either way)
4 #ithere !
| Should be renamed
: add-handle ( handle stackfix -- )
ithere @ 1 #ithere @ + cells+ !
ithere @ #ithere @ cells+ !
#ithere @ 2 + #ithere !
;
| Inclusion of files
: include" \" include ;
| Inlude just once
: require" \" over over find -1 = if over over make postpone ; include ;; then ;
| count the given zero-terminated string
: count ( str -- c ) 0 >r
begin dup c@ 0 = if drop r> ;; then 1+ r> 1+ >r again
;
| Print all the words
: words ( -- )
last @ 1-
begin
dup 32 * ntab @ + dup count type space
dup 0 = if cr drop ;; then
1-
again
;
: inc ( ptr1 ptr2 c -- ptr1 ptr2 ) dup rot + swap rot + swap ;
| Not 100% correct (but works with overlapping blocks )
| @spec, what does this thing do???
| @phon, copy blocks of memory even if they overlap.
: cmove> ( src dst c -- )
>r 2dup <
if
2dup swap r + <
if
r 1- inc
begin r> dup 0 = if drop r> drop drop drop ;; then 1- >r 2dup swap c@ swap c! -1 inc again
then
then
begin r> dup 0 = if drop r> drop drop drop ;; then 1- >r 2dup swap c@ swap c! 1 inc again
;
: copy ( src c dst -- )
there @ >r there ! inline 2drop r> there !
;
: there: ( -- ) here there @ here @ there ! swap ! ;
: ;there ( -- ) there here @ there @ here ! swap ! ;
: mark ( -- ) here @ there @
" *marker*" make rliteral rliteral postpone ;
; immediate
: forget ( -- )
" *marker*" find
dup -1 <> if dup last ! execute there ! here !
-1 here @ c! -1 -2 here @ 1+ c! ;; then drop
;
: f>d ( float -- double ) >f d> ;
: printc dup count type ;