[gforth] / gforth / kernel / basics.fs  

gforth: gforth/kernel/basics.fs


1 : anton 1.1 \ kernel.fs GForth kernel 17dec92py
2 :    
3 : anton 1.48 \ Copyright (C) 1995,1998,2000,2003,2004,2005 Free Software Foundation, Inc.
4 : anton 1.1
5 :     \ This file is part of Gforth.
6 :    
7 :     \ Gforth is free software; you can redistribute it and/or
8 :     \ modify it under the terms of the GNU General Public License
9 :     \ as published by the Free Software Foundation; either version 2
10 :     \ of the License, or (at your option) any later version.
11 :    
12 :     \ This program is distributed in the hope that it will be useful,
13 :     \ but WITHOUT ANY WARRANTY; without even the implied warranty of
14 :     \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 :     \ GNU General Public License for more details.
16 :    
17 :     \ You should have received a copy of the GNU General Public License
18 :     \ along with this program; if not, write to the Free Software
19 : anton 1.29 \ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
20 : anton 1.1
21 :     \ Idea and implementation: Bernd Paysan (py)
22 :    
23 : jwilke 1.16 \ Needs:
24 :    
25 :     require ./vars.fs
26 : anton 1.32 require ../compat/strcomp.fs
27 : jwilke 1.16
28 :     hex
29 : anton 1.1
30 :     \ labels for some code addresses
31 :    
32 :     \- NIL NIL AConstant NIL \ gforth
33 :    
34 :     \ Aliases
35 :    
36 : jwilke 1.4 [IFUNDEF] r@
37 : anton 1.1 ' i Alias r@ ( -- w ; R: w -- w ) \ core r-fetch
38 : jwilke 1.4 [THEN]
39 : anton 1.1
40 :     \ !! this is machine-dependent, but works on all but the strangest machines
41 :    
42 : anton 1.23 : maxaligned ( addr1 -- addr2 ) \ gforth
43 :     \G @i{addr2} is the first address after @i{addr1} that satisfies
44 :     \G all alignment restrictions.
45 : anton 1.1 [ /maxalign 1 - ] Literal + [ 0 /maxalign - ] Literal and ;
46 : anton 1.23 \ !! machine-dependent and won't work if "0 >body" <> "0 >body
47 :     \G maxaligned"
48 : anton 1.1 ' maxaligned Alias cfaligned ( addr1 -- addr2 ) \ gforth
49 : anton 1.23 \G @i{addr2} is the first address after @i{addr1} that is aligned for
50 :     \G a code field (i.e., such that the corresponding body is maxaligned).
51 : anton 1.1
52 :     : chars ( n1 -- n2 ) \ core
53 : anton 1.23 \G @i{n2} is the number of address units of @i{n1} chars.""
54 : anton 1.1 ; immediate
55 :    
56 :    
57 :     \ : A! ( addr1 addr2 -- ) \ gforth
58 :     \ dup relon ! ;
59 :     \ : A, ( addr -- ) \ gforth
60 :     \ here cell allot A! ;
61 :     ' ! alias A! ( addr1 addr2 -- ) \ gforth
62 :    
63 : anton 1.2 \ UNUSED 17may93jaw
64 :    
65 : pazsan 1.41 has? ec [IF]
66 : jwilke 1.30 unlock ram-dictionary borders nip lock
67 :     AConstant dictionary-end
68 : jwilke 1.4 [ELSE]
69 : pazsan 1.35 has? header [IF]
70 :     : dictionary-end ( -- addr )
71 :     forthstart [ 3 cells image-header + ] Aliteral @ + ;
72 :     [ELSE]
73 :     : forthstart 0 ;
74 :     : dictionary-end ( -- addr )
75 :     forthstart [ has? kernel-size ] Literal + ;
76 :     [THEN]
77 : jwilke 1.4 [THEN]
78 : anton 1.2
79 : anton 1.14 : usable-dictionary-end ( -- addr )
80 :     dictionary-end [ word-pno-size pad-minsize + ] Literal - ;
81 :    
82 : anton 1.2 : unused ( -- u ) \ core-ext
83 : crook 1.13 \G Return the amount of free space remaining (in address units) in
84 :     \G the region addressed by @code{here}.
85 : anton 1.14 usable-dictionary-end here - ;
86 : anton 1.2
87 : pazsan 1.40 has? ec [IF]
88 :     : in-dictionary? ( x -- f )
89 : pazsan 1.41 dictionary-end u< ;
90 : pazsan 1.40 [ELSE]
91 : anton 1.34 : in-dictionary? ( x -- f )
92 :     forthstart dictionary-end within ;
93 : pazsan 1.40 [THEN]
94 : anton 1.34
95 : anton 1.1 \ here is used for pad calculation!
96 :    
97 :     : dp ( -- addr ) \ gforth
98 :     dpp @ ;
99 : crook 1.13 : here ( -- addr ) \ core
100 :     \G Return the address of the next free location in data space.
101 : anton 1.1 dp @ ;
102 :    
103 :     \ on off 23feb93py
104 :    
105 : jwilke 1.4 \ on is used by docol:
106 : crook 1.15 : on ( a-addr -- ) \ gforth
107 :     \G Set the (value of the) variable at @i{a-addr} to @code{true}.
108 : anton 1.1 true swap ! ;
109 : crook 1.15 : off ( a-addr -- ) \ gforth
110 :     \G Set the (value of the) variable at @i{a-addr} to @code{false}.
111 : anton 1.1 false swap ! ;
112 :    
113 :     \ dabs roll 17may93jaw
114 :    
115 : anton 1.24 : dabs ( d -- ud ) \ double d-abs
116 : anton 1.1 dup 0< IF dnegate THEN ;
117 :    
118 :     : roll ( x0 x1 .. xn n -- x1 .. xn x0 ) \ core-ext
119 : anton 1.47 \ dup 1+ pick >r
120 :     \ cells sp@ cell+ dup cell+ rot move drop r> ;
121 :     recursive
122 :     dup 0<= if
123 :     drop
124 :     else
125 :     swap >r 1- roll r> swap
126 :     then ;
127 : anton 1.1
128 :     \ place bounds 13feb93py
129 :    
130 :     : place ( addr len to -- ) \ gforth
131 :     over >r rot over 1+ r> move c! ;
132 : anton 1.27 : bounds ( addr u -- addr+u addr ) \ gforth
133 :     \G Given a memory block represented by starting address @i{addr}
134 :     \G and length @i{u} in aus, produce the end address @i{addr+u} and
135 :     \G the start address in the right order for @code{u+do} or
136 :     \G @code{?do}.
137 : anton 1.1 over + swap ;
138 :    
139 :     \ (word) 22feb93py
140 :    
141 :     : scan ( addr1 n1 char -- addr2 n2 ) \ gforth
142 : anton 1.43 \G skip all characters not equal to char
143 : anton 1.1 >r
144 :     BEGIN
145 :     dup
146 :     WHILE
147 :     over c@ r@ <>
148 :     WHILE
149 :     1 /string
150 :     REPEAT THEN
151 :     rdrop ;
152 :     : skip ( addr1 n1 char -- addr2 n2 ) \ gforth
153 : anton 1.43 \G skip all characters equal to char
154 : anton 1.1 >r
155 :     BEGIN
156 :     dup
157 :     WHILE
158 :     over c@ r@ =
159 :     WHILE
160 :     1 /string
161 :     REPEAT THEN
162 :     rdrop ;
163 :    
164 :     \ digit? 17dec92py
165 :    
166 :     : digit? ( char -- digit true/ false ) \ gforth
167 :     toupper [char] 0 - dup 9 u> IF
168 : jwilke 1.16 [ char A char 9 1 + - ] literal -
169 : anton 1.1 dup 9 u<= IF
170 :     drop false EXIT
171 :     THEN
172 :     THEN
173 :     dup base @ u>= IF
174 :     drop false EXIT
175 :     THEN
176 :     true ;
177 :    
178 :     : accumulate ( +d0 addr digit - +d1 addr )
179 : pazsan 1.40 swap >r swap base @ um* drop rot base @ um* d+ r> ;
180 : anton 1.1
181 : crook 1.18 : >number ( ud1 c-addr1 u1 -- ud2 c-addr2 u2 ) \ core to-number
182 : anton 1.22 \G Attempt to convert the character string @var{c-addr1 u1} to an
183 : crook 1.13 \G unsigned number in the current number base. The double
184 :     \G @var{ud1} accumulates the result of the conversion to form
185 :     \G @var{ud2}. Conversion continues, left-to-right, until the whole
186 :     \G string is converted or a character that is not convertable in
187 :     \G the current number base is encountered (including + or -). For
188 :     \G each convertable character, @var{ud1} is first multiplied by
189 :     \G the value in @code{BASE} and then incremented by the value
190 :     \G represented by the character. @var{c-addr2} is the location of
191 :     \G the first unconverted character (past the end of the string if
192 :     \G the whole string was converted). @var{u2} is the number of
193 :     \G unconverted characters in the string. Overflow is not detected.
194 : anton 1.1 0
195 :     ?DO
196 :     count digit?
197 :     WHILE
198 :     accumulate
199 :     LOOP
200 :     0
201 :     ELSE
202 :     1- I' I -
203 :     UNLOOP
204 :     THEN ;
205 :    
206 :     \ s>d um/mod 21mar93py
207 :    
208 :     : s>d ( n -- d ) \ core s-to-d
209 :     dup 0< ;
210 :    
211 :     : ud/mod ( ud1 u2 -- urem udquot ) \ gforth
212 :     >r 0 r@ um/mod r> swap >r
213 :     um/mod r> ;
214 :    
215 :     \ catch throw 23feb93py
216 :    
217 : jwilke 1.5 has? glocals [IF]
218 : crook 1.12 : lp@ ( -- addr ) \ gforth lp-fetch
219 : anton 1.1 laddr# [ 0 , ] ;
220 :     [THEN]
221 :    
222 : anton 1.17 defer catch ( x1 .. xn xt -- y1 .. ym 0 / z1 .. zn error ) \ exception
223 : anton 1.24 \G @code{Executes} @i{xt}. If execution returns normally,
224 :     \G @code{catch} pushes 0 on the stack. If execution returns through
225 :     \G @code{throw}, all the stacks are reset to the depth on entry to
226 :     \G @code{catch}, and the TOS (the @i{xt} position) is replaced with
227 :     \G the throw code.
228 :    
229 : anton 1.17 :noname ( ... xt -- ... 0 )
230 :     execute 0 ;
231 :     is catch
232 : anton 1.1
233 : anton 1.24 defer throw ( y1 .. ym nerror -- y1 .. ym / z1 .. zn error ) \ exception
234 :     \G If @i{nerror} is 0, drop it and continue. Otherwise, transfer
235 :     \G control to the next dynamically enclosing exception handler, reset
236 :     \G the stacks accordingly, and push @i{nerror}.
237 :    
238 :     :noname ( y1 .. ym error -- y1 .. ym / z1 .. zn error )
239 : anton 1.19 ?dup if
240 : pazsan 1.35 [ has? header [IF] here image-header 9 cells + ! [THEN] ]
241 : pazsan 1.21 cr .error cr
242 :     [ has? file [IF] ] script? IF 1 (bye) ELSE quit THEN
243 :     [ [ELSE] ] quit [ [THEN] ]
244 : anton 1.19 then ;
245 :     is throw
246 :    
247 : anton 1.1 \ (abort")
248 :    
249 : anton 1.33 : c(abort") ( c-addr -- )
250 :     "error ! -2 throw ;
251 :    
252 : anton 1.1 : (abort")
253 :     "lit >r
254 :     IF
255 :     r> "error ! -2 throw
256 :     THEN
257 :     rdrop ;
258 : pazsan 1.6
259 :     : abort ( ?? -- ?? ) \ core,exception-ext
260 : crook 1.12 \G @code{-1 throw}.
261 : pazsan 1.6 -1 throw ;
262 : anton 1.1
263 :     \ ?stack 23feb93py
264 :    
265 :     : ?stack ( ?? -- ?? ) \ gforth
266 : jwilke 1.3 sp@ sp0 @ u> IF -4 throw THEN
267 : jwilke 1.5 [ has? floating [IF] ]
268 : jwilke 1.3 fp@ fp0 @ u> IF -&45 throw THEN
269 : anton 1.1 [ [THEN] ]
270 :     ;
271 :     \ ?stack should be code -- it touches an empty stack!
272 :    
273 :     \ DEPTH 9may93jaw
274 :    
275 : crook 1.9 : depth ( -- +n ) \ core depth
276 : crook 1.12 \G @var{+n} is the number of values that were on the data stack before
277 :     \G @var{+n} itself was placed on the stack.
278 : jwilke 1.3 sp@ sp0 @ swap - cell / ;
279 : crook 1.9
280 :     : clearstack ( ... -- ) \ gforth clear-stack
281 : anton 1.42 \G remove and discard all/any items from the data stack.
282 : jwilke 1.3 sp0 @ sp! ;
283 : anton 1.42
284 :     : clearstacks ( ... -- ) \ gforth clear-stacks
285 :     \G empty data and FP stack
286 :     clearstack fp0 @ fp! ;
287 : anton 1.1
288 :     \ Strings 22feb93py
289 :    
290 :     : "lit ( -- addr )
291 :     r> r> dup count + aligned >r swap >r ;
292 :    
293 :     \ HEX DECIMAL 2may93jaw
294 :    
295 :     : decimal ( -- ) \ core
296 : anton 1.26 \G Set @code{base} to &10 (decimal).
297 : anton 1.1 a base ! ;
298 :     : hex ( -- ) \ core-ext
299 : anton 1.26 \G Set @code{base} to &16 (hexadecimal).
300 : anton 1.1 10 base ! ;
301 :    

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help