Simplify VALUE
[pforth] / fth / ansilocs.fth
CommitLineData
8e9db35f
PB
1\ @(#) ansilocs.fth 98/01/26 1.3
2\ local variable support words
3\ These support the ANSI standard (LOCAL) and TO words.
4\
5\ They are built from the following low level primitives written in 'C':
6\ (local@) ( i+1 -- n , fetch from ith local variable )
7\ (local!) ( n i+1 -- , store to ith local variable )
8\ (local.entry) ( num -- , allocate stack frame for num local variables )
9\ (local.exit) ( -- , free local variable stack frame )
10\ local-compiler ( -- addr , variable containing CFA of locals compiler )
11\
12\ Author: Phil Burk
1a088514 13\ Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom
8e9db35f
PB
14\
15\ The pForth software code is dedicated to the public domain,
16\ and any third party may reproduce, distribute and modify
17\ the pForth software code or any derivative works thereof
18\ without any compensation or license. The pForth software
19\ code is provided on an "as is" basis without any warranty
20\ of any kind, including, without limitation, the implied
21\ warranties of merchantability and fitness for a particular
22\ purpose and their equivalents under the laws of any jurisdiction.
23\
24\ 10/27/99 Fixed : foo { -- } 55 ; was entering local frame but not exiting.
25
26anew task-ansilocs.fth
27
28private{
29
30decimal
3116 constant LV_MAX_VARS \ maximum number of local variables
3231 constant LV_MAX_CHARS \ maximum number of letters in name
33
34lv_max_vars lv_max_chars $array LV-NAMES
35variable LV-#NAMES \ number of names currently defined
36
37\ Search name table for match
38: LV.MATCH ( $string -- index true | $string false )
39 0 swap
40 lv-#names @ 0
41 ?DO i lv-names
42 over $=
43 IF 2drop true i LEAVE
44 THEN
45 LOOP swap
46;
47
48: LV.COMPILE.FETCH ( index -- )
49 1+ \ adjust for optimised (local@), LocalsPtr points above vars
50 CASE
51 1 OF compile (1_local@) ENDOF
52 2 OF compile (2_local@) ENDOF
53 3 OF compile (3_local@) ENDOF
54 4 OF compile (4_local@) ENDOF
55 5 OF compile (5_local@) ENDOF
56 6 OF compile (6_local@) ENDOF
57 7 OF compile (7_local@) ENDOF
58 8 OF compile (8_local@) ENDOF
59 dup [compile] literal compile (local@)
60 ENDCASE
61;
62
63: LV.COMPILE.STORE ( index -- )
64 1+ \ adjust for optimised (local!), LocalsPtr points above vars
65 CASE
66 1 OF compile (1_local!) ENDOF
67 2 OF compile (2_local!) ENDOF
68 3 OF compile (3_local!) ENDOF
69 4 OF compile (4_local!) ENDOF
70 5 OF compile (5_local!) ENDOF
71 6 OF compile (6_local!) ENDOF
72 7 OF compile (7_local!) ENDOF
73 8 OF compile (8_local!) ENDOF
74 dup [compile] literal compile (local!)
75 ENDCASE
76;
77
78: LV.COMPILE.LOCAL ( $name -- handled? , check for matching locals name )
79\ ." LV.COMPILER.LOCAL name = " dup count type cr
80 lv.match
81 IF ( index )
82 lv.compile.fetch
83 true
84 ELSE
85 drop false
86 THEN
87;
88
89: LV.CLEANUP ( -- , restore stack frame on exit from colon def )
90 lv-#names @
91 IF
92 compile (local.exit)
93 THEN
94;
95: LV.FINISH ( -- , restore stack frame on exit from colon def )
96 lv.cleanup
97 lv-#names off
98 local-compiler off
99;
100
101: LV.SETUP ( -- )
102 0 lv-#names !
103;
104
105: LV.TERM
106 ." Locals turned off" cr
107 lv-#names off
108 local-compiler off
109;
110
111if.forgotten lv.term
112
113}private
114
115: (LOCAL) ( adr len -- , ANSI local primitive )
116 dup
117 IF
118 lv-#names @ lv_max_vars >= abort" Too many local variables!"
119 lv-#names @ lv-names place
120\ Warn programmer if local variable matches an existing dictionary name.
121 lv-#names @ lv-names find nip
122 IF
123 ." (LOCAL) - Note: "
124 lv-#names @ lv-names count type
125 ." redefined as a local variable in "
126 latest id. cr
127 THEN
128 1 lv-#names +!
129 ELSE
130\ Last local. Finish building local stack frame.
131 2drop
132 lv-#names @ dup 0= \ fixed 10/27/99, Thanks to John Providenza
133 IF
134 drop ." (LOCAL) - Warning: no locals defined!" cr
135 ELSE
136 [compile] literal compile (local.entry)
137 ['] lv.compile.local local-compiler !
138 THEN
139 THEN
140;
141
8e9db35f
PB
142: VALUE
143 CREATE ( n <name> )
144 ,
8e9db35f 145 DOES>
146f755d 146 @
8e9db35f
PB
147;
148
149: TO ( val <name> -- )
150 bl word
151 lv.match
152 IF ( -- index )
153 lv.compile.store
154 ELSE
155 find
146f755d 156 0= abort" not found"
8e9db35f
PB
157 >body \ point to data
158 state @
159 IF \ compiling ( -- pfa )
160 [compile] aliteral
161 compile !
162 ELSE \ executing ( -- val pfa )
163 !
164 THEN
165 THEN
166; immediate
167
168: -> ( -- ) [compile] to ; immediate
169
170: +-> ( val <name> -- )
171 bl word
172 lv.match
173 IF ( -- index )
174 1+ \ adjust for optimised (local!), LocalsPtr points above vars
175 [compile] literal compile (local+!)
176 ELSE
177 find
146f755d 178 0= abort" not found"
8e9db35f
PB
179 >body \ point to data
180 state @
181 IF \ compiling ( -- pfa )
182 [compile] aliteral
183 compile +!
184 ELSE \ executing ( -- val pfa )
185 +!
186 THEN
187 THEN
188; immediate
189
190: : lv.setup : ;
191: ; lv.finish [compile] ; ; immediate
192: exit lv.cleanup compile exit ; immediate
193: does> lv.finish [compile] does> ; immediate
194
195privatize