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
|
\ tag: local variables
\
\ Copyright (C) 2012 Mark Cave-Ayland
\
\ See the file "COPYING" for further information about
\ the copyright and warranty status of this work.
\
[IFDEF] CONFIG_LOCALS
\ Init local variable stack
variable locals-var-stack
here 200 cells allot locals-var-stack !
\ Set initial stack pointer
\
\ Stack looks like this:
\ ... (sp n-2) local1 ... localm-1 localm (sp n-1) <-- sp
locals-var-stack @ value locals-var-sp
locals-var-sp locals-var-stack @ !
0 value locals-var-count
0 value locals-flags
here 200 cells allot locals-dict-buf !
8 constant #locals
: (local1) locals-var-sp @ /n + ;
: (local2) locals-var-sp @ 2 cells + ;
: (local3) locals-var-sp @ 3 cells + ;
: (local4) locals-var-sp @ 4 cells + ;
: (local5) locals-var-sp @ 5 cells + ;
: (local6) locals-var-sp @ 6 cells + ;
: (local7) locals-var-sp @ 7 cells + ;
: (local8) locals-var-sp @ 8 cells + ;
: local1@ (local1) @ ;
: local2@ (local2) @ ;
: local3@ (local3) @ ;
: local4@ (local4) @ ;
: local5@ (local5) @ ;
: local6@ (local6) @ ;
: local7@ (local7) @ ;
: local8@ (local8) @ ;
: local1! (local1) ! ;
: local2! (local2) ! ;
: local3! (local3) ! ;
: local4! (local4) ! ;
: local5! (local5) ! ;
: local6! (local6) ! ;
: local7! (local7) ! ;
: local8! (local8) ! ;
create locals-read-table
['] local1@ ,
['] local2@ ,
['] local3@ ,
['] local4@ ,
['] local5@ ,
['] local6@ ,
['] local7@ ,
['] local8@ ,
create locals-write-table
['] local1! ,
['] local2! ,
['] local3! ,
['] local4! ,
['] local5! ,
['] local6! ,
['] local7! ,
['] local8! ,
: locals-push ( n -- )
locals-var-sp /n + to locals-var-sp
locals-var-sp !
;
: locals-0-push ( -- )
0 locals-push
;
: (apply-local-flags) ( lfa -- )
1 - dup c@ locals-flags or swap c!
;
: locals-no-pop? ( lfa -- ? )
1 - c@ 8 and 0<>
;
: locals-drop \ Destroy current stack frame
locals-var-sp @ to locals-var-sp
;
['] locals-drop to locals-end
: (local-init) ( str len -- )
header 1 , \ DOCOL
['] (lit) , ['] noop , \ read-xt
['] (lit) , ['] noop , \ write-xt
['] 2drop , \ do nothing
['] (lit) ,
here 5 cells - ,
['] @ , ['] , , \ store read-xt
['] (semis) ,
reveal
immediate
last @ (apply-local-flags)
;
: (local-noop) ( str len -- )
2drop
;
\ Word called when consuming a local variable
defer (local)
: } ( C: current latest here -- )
here! latest ! current ! \ Switch back to normal dict
locals-dict-buf @ to locals-dict \ Make locals-dict visible to $find
0 to locals-var-count
['] locals-var-sp , \ save previous sp on rstack
['] >r ,
locals-dict @ \ ( last -- )
begin
?dup 0<>
while
>r
locals-var-count /n *
locals-read-table + @ r@ 3 cells + ! \ set read-xt
locals-var-count /n *
locals-write-table + @ r@ 5 cells + ! \ set write-xt
locals-var-count 1+ to locals-var-count
r@ locals-no-pop? if
['] locals-0-push , \ initialise with 0
else
['] locals-push , \ initialise from stack
then
r> @ \ next lfa
repeat
['] r> ,
['] locals-push , \ write previous sp
; immediate
: { ( C: -- current latest here )
current @ latest @ here
['] (local-init) to (local)
0 to locals-flags
0 to locals-var-count
locals-dict-buf @ 200 cells 0 fill \ Zero out temporary dictionary
locals-dict-buf @ current ! \ Switch to locals dictionary
locals-dict-buf @ /n + here!
begin
parse-word
2dup s" }" strcmp 0= if
2drop
['] } execute -1
else
2dup s" ;" strcmp 0= if
2drop
8 to locals-flags 0 \ Don't init from stack
else
2dup s" |" strcmp 0= if
2drop
8 to locals-flags 0 \ Don't init from stack
else
2dup s" --" strcmp 0= if
2drop
['] (local-noop) to (local) 0
else
locals-var-count #locals < if
(local) 0 \ accept local
else
s" maximum locals used ignoring " type type cr 0
then
locals-var-count 1+ to locals-var-count
then
then
then
then
until
; immediate
: -> ( n -- )
parse-word $find if
4 cells + @ ,
else
s" unable to find word " type type
then
; immediate
[THEN]
|