1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; UrForth level
1: self
-hosting
32-bit Forth compiler
3 ;; Copyright
(C
) 2020 Ketmar Dark
// Invisible Vector
5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 ;; do not use comma directly
, so high
-level words will survive any threaded code changes
10 ;; also
, do not use this ONLY
to compile calls
to other words
!
11 ;; this is because of possible future optimiser
13 forth
:(opt
-forth?
) if optimiser
:optimise
-forth
-call ifnot reladdr
, endif else reladdr
, endif
16 ;; compile CFA it is is not zero
17 : ?COMPILE
, ( cfa
//0 -- ) ?dup
if compile
, endif ;
20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32 voc
-set
-active COMPILER
37 : !CSP
( -- ) sp@
(csp
) ! ;
38 : ?CSP
( -- ) sp@
(csp
) @
- err
-unfinished
-definition ?error
;
39 : ?COMP
( -- ) state @
0= err
-compilation
-only ?error
;
40 : ?NON
-MACRO
( -- ) (latest
-macro?
) err
-nonmacro
-only ?error
;
41 : ?EXEC
( -- ) state @ err
-execution
-only ?error
;
44 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
45 : forth
-word
-prologue
( -- )
48 true
to (dbginfo
-active?
)
53 (URFORTH
-DOFORTH
-ADDR
) compiler
:(cfa
-call,)
59 : forth
-word
-epilogue
( -- )
62 ;; save debug info
(this also resets and deactivates it
)
63 (dbginfo
-finalize
-and
-copy
)
67 : start
-compile
-forth
-word
( -- )
68 forth
-word
-prologue
[compile
] ]
71 : end-compile
-forth
-word
( -- )
77 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
78 ;; write 4-byte displacement
for CALL/JMP jmpdest instruction
to addr
79 ;; addr should point after the instruction
, at the first displacement byte
80 : (DISP32
!) ( jmpdest addr
-- )
81 dup cell
+ rot swap
- swap
!
84 : (DISP32@
) ( addr
-- jumpdest
)
88 ;; write 5-byte
CALL calldest machine instruction
to addr
89 : (CALL!) ( calldest addr
-- )
90 0xe8 over c
! 1+ ;; write CALL, advance address
94 ;; write 5-byte JMP jmpdest machine instruction
to addr
95 : (JMP
!) ( jmpdest addr
-- )
96 0xe9 over c
! 1+ ;; write JMP
, advance address
100 ;; compile
5-byte
CALL calldest machine instruction
to HERE
101 : (CFA
-CALL,) ( calldest
-- )
102 $
if URFORTH_ALIGN_CFA
106 $
if URFORTH_ALIGN_PFA
111 ;; compile
5-byte JMP jmpdest machine instruction
to HERE
112 : (JMP
,) ( jmpdest
-- )
117 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
118 : c4str
-unaligned
, ( addr count
-- )
119 dup forth
:unused
2u/ u
>= ERR
-STRING
-TOO
-LONG ?error
120 ;; check
if the string is at
"here" (just in case
)
121 over here here cell
+ 1- bounds?
if ;; move forward
to make room
for counter
122 dup
>r here cell
+ swap move
125 dup cell
+ n
-allot
( addr count destaddr
)
126 2dup
! cell
+ ;; length
127 swap move
;; string itself
130 : c4str
, ( addr count
-- ) c4str
-unaligned
, align
-here
;
132 : c4strz
-unaligned
, ( addr count
-- ) c4str
-unaligned
, 0 c
, ;
133 : c4strz
, ( addr count
-- ) c4strz
-unaligned
, align
-here
;
135 : c1str
-unaligned
, ( addr count
-- )
136 dup forth
:unused
2u/ u
>= ERR
-STRING
-TOO
-LONG ?error
137 dup
255 u
> ERR
-STRING
-TOO
-LONG ?error
138 ;; check
if the string is at
"here" (just in case
)
139 over here
= if ;; move forward
to make room
for counter
140 dup
>r here
1+ swap move
143 dup
1+ n
-allot
( addr count destaddr
)
145 swap move
;; string itself
148 : c1str
, ( addr count
-- ) c1str
-unaligned
, align
-here
;
150 : c1strz
-unaligned
, ( addr count
-- ) c1str
-unaligned
, 0 c
, ;
151 : c1strz
, ( addr count
-- ) c1strz
-unaligned
, align
-here
;
155 : custom
-c1sliteral
, ( addr count cfa
-- )
157 over
255 u
> ERR
-STRING
-TOO
-LONG ?error
159 ;; check
if the string is at
"here" (just in case
)
160 over here here cell
+ bounds?
if ;; move forward
to make room
for "litstr" and other things
161 dup
>r here cell
+ swap move
164 r
> compile
, ;; literal word
169 : custom
-c4sliteral
, ( addr count cfa
-- )
171 over forth
:unused
2u/ u
>= ERR
-STRING
-TOO
-LONG ?error
173 ;; check
if the string is at
"here" (just in case
)
174 over here here
2 +cells
1- bounds?
if ;; move forward
to make room
for "litstr" and other things
175 dup
>r here
2 +cells swap move
178 r
> compile
, ;; literal word
184 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
187 0 of drop compile lit0 endof
188 1 of drop compile lit1 endof
189 -1 of drop compile lit
-1 endof
190 $
if URFORTH_ALIGN_PFA
191 ;; no
8/16 bit literals
193 0 256 within
-of compile litu8 c
, endof
194 -128 128 within
-of compile lits8 c
, endof
195 0 65536 within
-of compile litu16 w
, endof
196 -32768 32768 within
-of compile lits16 w
, endof
202 : 2literal
, ( dlo dhi
-- ) swap compiler
:literal
, compiler
:literal
, ;
203 : addrliteral
, ( addr
-- ) compile lit reladdr
, ;
204 : cfaliteral
, ( cfa
-- ) compile litcfa reladdr
, ;
205 : c4sliteral
, ( addr count
-- ) ['] litc4str custom-c4sliteral, ;
206 : c1sliteral, ( addr count -- ) ['] litc1str custom
-c1sliteral
, ;
207 ;; puts byte
-counted string literal
if possible
208 : sliteral
, ( addr count
-- )
209 dup
0 255 bounds?
if ['] litc1str custom-c1sliteral,
210 else ['] litc4str custom
-c4sliteral
, endif
216 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
217 ;; this is better done with custom creation word
, but metacompiler cannot
do that
...
218 : LITERAL
( n
-- ) state @
if compiler
:literal
, endif ; immediate
219 : 2LITERAL
( dlo dhi
-- ) state @
if compiler
:2literal
, endif ; immediate
220 : ADDRLITERAL
( n
-- ) state @
if compiler
:addrliteral
, endif ; immediate
221 : CFALITERAL
( cfa
-- ) state @
if compiler
:cfaliteral
, endif ; immediate
222 : C4SLITERAL
( addr count
-- ) state @
if compiler
:c4sliteral
, endif ; immediate
223 : C1SLITERAL
( addr count
-- ) state @
if compiler
:c1sliteral
, endif ; immediate
224 ;; puts byte
-counted string literal
if possible
225 : SLITERAL
( addr count
-- ) state @
if compiler
:sliteral
, endif ; immediate