1 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; and now
for something completely different
...
5 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6 ;; Z80 Assembler
: Forth macros
7 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13 macro
: xte_rstack_put_imm16
( -- )
14 mc
-arg
-count
1 <> " one argument expected" ?error
22 xte_rstack_put_imm16
0x29a
24 it is ok
to use
"EXIT" in macro word
(but not other
return stack tricks
).
28 vocabulary asm
-macro
-helpers
29 also
-defs
: asm
-macro
-helpers
37 0 value
(mac
-argv
) ;; header
, then margs
38 0 value
(mac
-argc
) ;; argument count
39 0 value
(mc
-buffer
) ;; string buffer
41 ;; at exit
, token is comma or eol
43 0 ;; current paren level
44 begin token
-eol? not
-while
49 token
-`
(`?
if-of
1+ endof
50 token
-`
[`?
if-of
1+ endof
51 token
-`
)`?
if-of
1- 0 max endof
52 token
-`
]`?
if-of
1- 0 max endof
53 token
-`
:`?
if-of
" macro cannot be combined with other instructions" error endof
54 otherwise
;; suppress
"DROP"
56 next
-token repeat drop
60 ;; token is at the first arg
62 forth
:(max
-handle
-ofs
) 1+ 0 handle
:new
-alloc
to (mc
-buffer
)
64 forth
:(max
-handle
-ofs
) 1+ 0 handle
:new
-alloc
67 begin token
-eol? not
-while
68 (mac
-argc
) dup
255 >= " too many macro arguments" ?error
70 (tok
->in
) >in
! parse
-skip
-blanks next
-token
71 tib @
(tok
->in
) + !+4>a
;; start
73 tib @
(tok
->in
) + !+4>a
;; end
74 token
-eol? ifnot expect
-`
,`
endif
79 (mac
-argv
) dup
" FREE-ARGS without BUILD-ARGS" ?not
-error
80 handle
:free
0 to (mac
-argv
)
81 (mc
-buffer
) handle
:free
0 to (mc
-buffer
)
84 : mc
-arg
-count
( -- count
)
85 (mac
-argv
) " call BUILD-ARGS first" ?not
-error
88 alias mc
-arg
-count arg#
90 : mc
-arg
-str
( idx
-- addr count
)
91 (mac
-argv
) " call BUILD-ARGS first" ?not
-error
92 dup
0 (mac
-argc
) within
" invalid argument index" ?not
-error
93 marg
-size
* (mac
-argv
) +
94 dup marg
->start@ swap marg
->end@ over
-
100 0 (mc
-buffer
) handle
:used
!
104 (mc
-buffer
) " MACRO-START is not called" ?not
-error
105 (mc
-buffer
) handle
:used@
106 dup
(mc
-buffer
) handle
:size@ cell
- u
>= " macro string too long" ?error
107 swap over
(mc
-buffer
) + c
!
108 1+ (mc
-buffer
) handle
:used
!
111 : mc
+str
( addr count
-- )
112 (mc
-buffer
) " MACRO-START is not called" ?not
-error
113 dup
0< " invalid macro string" ?error
115 (mc
-buffer
) handle
:used@ over
+
116 0 (mc
-buffer
) handle
:size@ cell
- within
" macro string too long" ?not
-error
117 dup
>r
;; save counter
118 (mc
-buffer
) dup handle
:used@
+ swap cmove
119 (mc
-buffer
) handle
:used@ r
> + (mc
-buffer
) handle
:used
!
128 (mc
-buffer
) " MACRO-START is not called" ?not
-error
129 0 (mc
-buffer
) dup handle
:used@
+ c
!
130 (mc
-buffer
) tib
! >in
0!
132 ." <" (tib
-in
) 0 begin dup tib
-peekch
-ofs
while 1+ repeat xtype
." >" cr
134 next
-token
do-assemble
-line
137 : mc
-compile
-str
( addr count
-- )
138 mc
-start mc
+str mc
-compile
141 ;; A is string address
142 : (mc
-parse
-number
) ( count
-- num count
)
143 >r
0 begin r@
while c@a
10 string
:digit
while swap
10 U*
+ +1>a r
> 1- >r repeat
144 dup
0< " numeric overflow" ?error
148 ;; A is string address
, at
'['
149 : (mc
-char
-indexed
) ( idx count
-- count
)
151 c@a
10 string
:digit?
" number expected" ?not
-error
152 (mc
-parse
-number
) ( idx str
-idx count
)
153 dup
0<= " `]` expected" ?error
154 c@a
[char
] ] <> " `]` expected" ?error
157 mc
-arg
-str r@
<= " invalid string index" ?error
162 ;; A is string address
163 : (mc
-indexed
) ( idx count
-- )
164 dup
if c@a
[char
] [ = if (mc
-char
-indexed
) exit
endif endif
165 swap mc
-arg
-str mc
+str
168 : (mc
-") ( addr count -- )
171 begin ( count ) dup +while
172 c@+1>a dup [char] $ <> if mc+char 1-
173 else drop c@a 10 string:digit? if (mc-parse-number) (mc-indexed)
174 else [char] $ mc+char 1-
181 ;; compile asm string
182 ;; use "%idx
" for arg substitution
185 34 parse " string expected
" ?not-error
186 strliteral compile (mc-")
190 : label@
( addr count
-- value
)
191 2dup asm
-labels
:get ifnot
192 endcr space
." label '" xtype
." ' not defined" cr
193 " label not defined" error
194 else nrot
2drop
endif
197 : eval
-const
( addr count
-- value
)
199 0 (mc
-buffer
) dup handle
:used@
+ c
!
200 (mc
-buffer
) tib
! >in
0!
202 ." <" (tib
-in
) 0 begin dup tib
-peekch
-ofs
while 1+ repeat xtype
." >" cr
204 next
-token asm
-expr
:expression
-const
207 : eval
-arg
( idx
-- value
)
208 mc
-arg
-str eval
-const
214 vocabulary
(asm
-in
-macro
)
215 also
-defs
: (asm
-in
-macro
)
217 0 value saved
-current
219 : ; -- end macro definition
220 compiler
:?comp compiler
:(ctlid
-colon
) 2- compiler
:?pairs
221 saved
-current
" wut?!" ?not
-error
222 compiler
:(ctlid
-colon
) [compile
] ;
223 previous previous previous saved
-current current
!
232 : MACRO
: ( -- ) \ name
233 parse
-name dup
" macro name expected" ?not
-error
234 (asm
-in
-macro
):saved
-current
" already defining a macro" ?error
235 current @
to (asm
-in
-macro
):saved
-current
236 vocid
: asm
-instr current
!
237 \ compiler
:(create
-forth
-header
)
240 also asm
-macro
-helpers
242 compiler
:(ctlid
-colon
) 2- [compile
] ]
245 asm
-lexer
:next
-token
;; skip macro name
246 asm
-macro
-helpers
:(mac
-argv
) >r
247 asm
-macro
-helpers
:(mac
-argc
) >r
248 asm
-macro
-helpers
:(mc
-buffer
) >r
249 asm
-macro
-helpers
:(build
-args
)
251 asm
-macro
-helpers
:(free
-args
)
252 r
> to asm
-macro
-helpers
:(mc
-buffer
)
253 r
> to asm
-macro
-helpers
:(mac
-argc
)
254 r
> to asm
-macro
-helpers
:(mac
-argv
)
255 \ r
> >in
! r
> tib
! next
-token
;; restore last token
256 r
> >in
! r
> tib
! parse
-skip
-line next
-token