[gforth] / gforth / kernel / Attic / interp.fs  

gforth: gforth/kernel/Attic/interp.fs


1 : anton 1.1 \ definitions needed for interpreter / compiler only
2 :    
3 :     doer? :docon [IF]
4 :     : docon: ( -- addr ) \ gforth
5 :     \G the code address of a @code{CONSTANT}
6 :     ['] bl >code-address ;
7 :     [THEN]
8 :    
9 :     : docol: ( -- addr ) \ gforth
10 :     \G the code address of a colon definition
11 :     ['] docol: >code-address ;
12 :    
13 :     doer? :dovar [IF]
14 :     : dovar: ( -- addr ) \ gforth
15 :     \G the code address of a @code{CREATE}d word
16 : jwilke 1.3 \ in rom-applications variable might be implemented with constant
17 :     \ use really a created word!
18 :     ['] ??? >code-address ;
19 : anton 1.1 [THEN]
20 :    
21 :     doer? :douser [IF]
22 :     : douser: ( -- addr ) \ gforth
23 :     \G the code address of a @code{USER} variable
24 : jwilke 1.3 ['] sp0 >code-address ;
25 : anton 1.1 [THEN]
26 :    
27 :     doer? :dodefer [IF]
28 :     : dodefer: ( -- addr ) \ gforth
29 :     \G the code address of a @code{defer}ed word
30 :     ['] source >code-address ;
31 :     [THEN]
32 :    
33 :     doer? :dofield [IF]
34 :     : dofield: ( -- addr ) \ gforth
35 :     \G the code address of a @code{field}
36 :     ['] reveal-method >code-address ;
37 :     [THEN]
38 :    
39 :     .( test1 )
40 :     has-prims 0= [IF]
41 :     : dodoes: ( -- addr ) \ gforth
42 :     \G the code address of a @code{field}
43 :     ['] spaces >code-address ;
44 :     .( test2 )
45 :     [THEN]
46 :    
47 :     \ here allot , c, A, 17dec92py
48 :    
49 :     : allot ( n -- ) \ core
50 : anton 1.2 dup unused > -8 and throw
51 : anton 1.1 dp +! ;
52 :     : c, ( c -- ) \ core
53 :     here 1 chars allot c! ;
54 :     : , ( x -- ) \ core
55 :     here cell allot ! ;
56 :     : 2, ( w1 w2 -- ) \ gforth
57 :     here 2 cells allot 2! ;
58 :    
59 :     \ : aligned ( addr -- addr' ) \ core
60 :     \ [ cell 1- ] Literal + [ -1 cells ] Literal and ;
61 :     : align ( -- ) \ core
62 :     here dup aligned swap ?DO bl c, LOOP ;
63 :    
64 :     \ : faligned ( addr -- f-addr ) \ float
65 :     \ [ 1 floats 1- ] Literal + [ -1 floats ] Literal and ;
66 :    
67 :     : falign ( -- ) \ float
68 :     here dup faligned swap
69 :     ?DO
70 :     bl c,
71 :     LOOP ;
72 :    
73 :     : maxalign ( -- ) \ float
74 :     here dup maxaligned swap
75 :     ?DO
76 :     bl c,
77 :     LOOP ;
78 :    
79 :     \ the code field is aligned if its body is maxaligned
80 :     ' maxalign Alias cfalign ( -- ) \ gforth
81 :    
82 :     ' , alias A, ( addr -- ) \ gforth
83 :    
84 : jwilke 1.3 ' NOOP ALIAS const
85 :    
86 : anton 1.1 \ name> found 17dec92py
87 :    
88 :     $80 constant alias-mask \ set when the word is not an alias!
89 :     $40 constant immediate-mask
90 :     $20 constant restrict-mask
91 :    
92 :     : ((name>)) ( nfa -- cfa )
93 :     name>string + cfaligned ;
94 :    
95 :     : (name>x) ( nfa -- cfa b )
96 :     \ cfa is an intermediate cfa and b is the flags byte of nfa
97 :     dup ((name>))
98 :     swap cell+ c@ dup alias-mask and 0=
99 :     IF
100 :     swap @ swap
101 :     THEN ;
102 :    
103 :     \ input stream primitives 23feb93py
104 :    
105 :     : tib ( -- c-addr ) \ core-ext
106 :     \ obsolescent
107 :     >tib @ ;
108 :     Defer source ( -- addr count ) \ core
109 :     \ used by dodefer:, must be defer
110 :     : (source) ( -- addr count )
111 :     tib #tib @ ;
112 :     ' (source) IS source
113 :    
114 :     : (word) ( addr1 n1 char -- addr2 n2 )
115 :     dup >r skip 2dup r> scan nip - ;
116 :    
117 :     \ (word) should fold white spaces
118 :     \ this is what (parse-white) does
119 :    
120 :     \ word parse 23feb93py
121 :    
122 :     : parse-word ( char -- addr len ) \ gforth
123 :     source 2dup >r >r >in @ over min /string
124 :     rot dup bl = IF drop (parse-white) ELSE (word) THEN
125 :     2dup + r> - 1+ r> min >in ! ;
126 :     : word ( char -- addr ) \ core
127 :     parse-word here place bl here count + c! here ;
128 :    
129 :     : parse ( char -- addr len ) \ core-ext
130 :     >r source >in @ over min /string over swap r> scan >r
131 :     over - dup r> IF 1+ THEN >in +! ;
132 :    
133 :     \ name 13feb93py
134 :    
135 :     : capitalize ( addr len -- addr len ) \ gforth
136 :     2dup chars chars bounds
137 :     ?DO I c@ toupper I c! 1 chars +LOOP ;
138 : jwilke 1.3
139 :     [IFUNDEF] (name) \ name might be a primitive
140 : anton 1.1 : (name) ( -- c-addr count )
141 :     source 2dup >r >r >in @ /string (parse-white)
142 :     2dup + r> - 1+ r> min >in ! ;
143 :     \ name count ;
144 : jwilke 1.3 [THEN]
145 : anton 1.1
146 :     : name-too-short? ( c-addr u -- c-addr u )
147 :     dup 0= -&16 and throw ;
148 :    
149 :     : name-too-long? ( c-addr u -- c-addr u )
150 :     dup $1F u> -&19 and throw ;
151 :    
152 :     \ Literal 17dec92py
153 :    
154 :     : Literal ( compilation n -- ; run-time -- n ) \ core
155 :     postpone lit , ; immediate restrict
156 :     : ALiteral ( compilation addr -- ; run-time -- addr ) \ gforth
157 :     postpone lit A, ; immediate restrict
158 :    
159 :     : char ( 'char' -- n ) \ core
160 :     bl word char+ c@ ;
161 :     : [char] ( compilation 'char' -- ; run-time -- n )
162 :     char postpone Literal ; immediate restrict
163 :    
164 :     : (compile) ( -- ) \ gforth
165 :     r> dup cell+ >r @ compile, ;
166 :    
167 :     : postpone, ( w xt -- )
168 :     \g Compiles the compilation semantics represented by @var{w xt}.
169 :     dup ['] execute =
170 :     if
171 :     drop compile,
172 :     else
173 :     dup ['] compile, =
174 :     if
175 :     drop POSTPONE (compile) compile,
176 :     else
177 :     swap POSTPONE aliteral compile,
178 :     then
179 :     then ;
180 :    
181 :     : POSTPONE ( "name" -- ) \ core
182 :     \g Compiles the compilation semantics of @var{name}.
183 :     COMP' postpone, ; immediate restrict
184 :    
185 :     : interpret/compile: ( interp-xt comp-xt "name" -- ) \ gforth
186 :     Create immediate swap A, A,
187 :     DOES>
188 :     abort" executed primary cfa of an interpret/compile: word" ;
189 :     \ state @ IF cell+ THEN perform ;
190 :    
191 :     \ number? number 23feb93py
192 :    
193 :     hex
194 : jwilke 1.3 const Create bases 10 , 2 , A , 100 ,
195 :     \ 16 2 10 character
196 : anton 1.1 \ !! this saving and restoring base is an abomination! - anton
197 :     : getbase ( addr u -- addr' u' )
198 :     over c@ [char] $ - dup 4 u<
199 :     IF
200 :     cells bases + @ base ! 1 /string
201 :     ELSE
202 :     drop
203 :     THEN ;
204 :     : s>number ( addr len -- d )
205 :     base @ >r dpl on
206 :     over c@ '- = dup >r
207 :     IF
208 :     1 /string
209 :     THEN
210 :     getbase dpl on 0 0 2swap
211 :     BEGIN
212 :     dup >r >number dup
213 :     WHILE
214 :     dup r> -
215 :     WHILE
216 :     dup dpl ! over c@ [char] . =
217 :     WHILE
218 :     1 /string
219 :     REPEAT THEN
220 :     2drop rdrop dpl off
221 :     ELSE
222 :     2drop rdrop r>
223 :     IF
224 :     dnegate
225 :     THEN
226 :     THEN
227 :     r> base ! ;
228 :    
229 :     : snumber? ( c-addr u -- 0 / n -1 / d 0> )
230 :     s>number dpl @ 0=
231 :     IF
232 :     2drop false EXIT
233 :     THEN
234 :     dpl @ dup 0> 0= IF
235 :     nip
236 :     THEN ;
237 :    
238 :     : number? ( string -- string 0 / n -1 / d 0> )
239 :     dup >r count snumber? dup if
240 :     rdrop
241 :     else
242 :     r> swap
243 :     then ;
244 :    
245 :     : number ( string -- d )
246 :     number? ?dup 0= abort" ?" 0<
247 :     IF
248 :     s>d
249 :     THEN ;
250 :    
251 :     \ interpret 10mar92py
252 :    
253 :     Defer parser
254 :     Defer name ( -- c-addr count ) \ gforth
255 :     \ get the next word from the input buffer
256 :     ' (name) IS name
257 :     Defer compiler-notfound ( c-addr count -- )
258 :     Defer interpreter-notfound ( c-addr count -- )
259 :    
260 :     : no.extensions ( addr u -- )
261 :     2drop -&13 bounce ;
262 :     ' no.extensions IS compiler-notfound
263 :     ' no.extensions IS interpreter-notfound
264 :    
265 :     : compile-only-error ( ... -- )
266 :     -&14 throw ;
267 :    
268 :     : interpret ( ?? -- ?? ) \ gforth
269 :     \ interpret/compile the (rest of the) input buffer
270 :     BEGIN
271 :     ?stack name dup
272 :     WHILE
273 :     parser
274 :     REPEAT
275 :     2drop ;
276 :    
277 :     \ interpreter compiler 30apr92py
278 :    
279 :     \ not the most efficient implementations of interpreter and compiler
280 :     : interpreter ( c-addr u -- )
281 :     2dup find-name dup
282 :     if
283 :     nip nip name>int execute
284 :     else
285 :     drop
286 :     2dup 2>r snumber?
287 :     IF
288 :     2rdrop
289 :     ELSE
290 :     2r> interpreter-notfound
291 :     THEN
292 :     then ;
293 :    
294 :     : compiler ( c-addr u -- )
295 :     2dup find-name dup
296 :     if ( c-addr u nt )
297 :     nip nip name>comp execute
298 :     else
299 :     drop
300 :     2dup snumber? dup
301 :     IF
302 :     0>
303 :     IF
304 :     swap postpone Literal
305 :     THEN
306 :     postpone Literal
307 :     2drop
308 :     ELSE
309 :     drop compiler-notfound
310 :     THEN
311 :     then ;
312 :    
313 :     ' interpreter IS parser
314 :    
315 :     : [ ( -- ) \ core left-bracket
316 :     ['] interpreter IS parser state off ; immediate
317 :     : ] ( -- ) \ core right-bracket
318 :     ['] compiler IS parser state on ;
319 :    
320 :     \ Strings 22feb93py
321 :    
322 :     : ," ( "string"<"> -- ) [char] " parse
323 :     here over char+ allot place align ;
324 :     : SLiteral ( Compilation c-addr1 u ; run-time -- c-addr2 u ) \ string
325 :     postpone (S") here over char+ allot place align ;
326 :     immediate restrict
327 :     : ( ( compilation 'ccc<close-paren>' -- ; run-time -- ) \ core,file paren
328 :     [char] ) parse 2drop ; immediate
329 :    
330 :     : \ ( -- ) \ core-ext backslash
331 :     blk @
332 :     IF
333 :     >in @ c/l / 1+ c/l * >in !
334 :     EXIT
335 :     THEN
336 :     source >in ! drop ; immediate
337 :    
338 :     : \G ( -- ) \ gforth backslash
339 :     POSTPONE \ ; immediate
340 :    
341 :     \ error handling 22feb93py
342 :     \ 'abort thrown out! 11may93jaw
343 :    
344 :     : abort" ( compilation 'ccc"' -- ; run-time f -- ) \ core,exception-ext abort-quote
345 :     postpone (abort") ," ; immediate restrict
346 :    
347 :     \ Header states 23feb93py
348 :    
349 :     : cset ( bmask c-addr -- )
350 :     tuck c@ or swap c! ;
351 :     : creset ( bmask c-addr -- )
352 :     tuck c@ swap invert and swap c! ;
353 :     : ctoggle ( bmask c-addr -- )
354 :     tuck c@ xor swap c! ;
355 :    
356 :     : lastflags ( -- c-addr )
357 :     \ the address of the flags byte in the last header
358 :     \ aborts if the last defined word was headerless
359 :     last @ dup 0= abort" last word was headerless" cell+ ;
360 :    
361 :     : immediate ( -- ) \ core
362 :     immediate-mask lastflags cset ;
363 :     : restrict ( -- ) \ gforth
364 :     restrict-mask lastflags cset ;
365 :     ' restrict alias compile-only ( -- ) \ gforth
366 :    
367 :     \ Header 23feb93py
368 :    
369 :     \ input-stream, nextname and noname are quite ugly (passing
370 :     \ information through global variables), but they are useful for dealing
371 :     \ with existing/independent defining words
372 :    
373 :     defer (header)
374 :     defer header ( -- ) \ gforth
375 :     ' (header) IS header
376 :    
377 :     : string, ( c-addr u -- ) \ gforth
378 :     \G puts down string as cstring
379 :     dup c, here swap chars dup allot move ;
380 :    
381 :     : header, ( c-addr u -- ) \ gforth
382 :     name-too-long?
383 :     align here last !
384 :     current @ 1 or A, \ link field; before revealing, it contains the
385 :     \ tagged reveal-into wordlist
386 :     string, cfalign
387 :     alias-mask lastflags cset ;
388 :    
389 :     : input-stream-header ( "name" -- )
390 :     name name-too-short? header, ;
391 :     : input-stream ( -- ) \ general
392 :     \G switches back to getting the name from the input stream ;
393 :     ['] input-stream-header IS (header) ;
394 :    
395 :     ' input-stream-header IS (header)
396 :    
397 :     \ !! make that a 2variable
398 :     create nextname-buffer 32 chars allot
399 :    
400 :     : nextname-header ( -- )
401 :     nextname-buffer count header,
402 :     input-stream ;
403 :    
404 :     \ the next name is given in the string
405 :     : nextname ( c-addr u -- ) \ gforth
406 :     name-too-long?
407 :     nextname-buffer c! ( c-addr )
408 :     nextname-buffer count move
409 :     ['] nextname-header IS (header) ;
410 :    
411 :     : noname-header ( -- )
412 :     0 last ! cfalign
413 :     input-stream ;
414 :    
415 :     : noname ( -- ) \ gforth
416 :     \ the next defined word remains anonymous. The xt of that word is given by lastxt
417 :     ['] noname-header IS (header) ;
418 :    
419 :     : lastxt ( -- xt ) \ gforth
420 :     \ xt is the execution token of the last word defined. The main purpose of this word is to get the xt of words defined using noname
421 :     lastcfa @ ;
422 :    
423 :     : Alias ( cfa "name" -- ) \ gforth
424 :     Header reveal
425 :     alias-mask lastflags creset
426 :     dup A, lastcfa ! ;
427 :    
428 :     : name>string ( nt -- addr count ) \ gforth name-to-string
429 :     \g @var{addr count} is the name of the word represented by @var{nt}.
430 :     cell+ count $1F and ;
431 :    
432 : jwilke 1.3 : head>string
433 :     cell+ count $1F and ;
434 :    
435 :    
436 :     const Create ??? 0 , 3 c, char ? c, char ? c, char ? c,
437 :     \ ??? is used by dovar:, must be created/:dovar
438 :    
439 :     : >head ( cfa -- nt ) \ gforth to-name
440 : anton 1.1 $21 cell do
441 :     dup i - count $9F and + cfaligned over alias-mask + = if
442 :     i - cell - unloop exit
443 :     then
444 :     cell +loop
445 :     drop ??? ( wouldn't 0 be better? ) ;
446 :    
447 : jwilke 1.3 ' >head ALIAS >name
448 :    
449 :     : body> 0 >body - ;
450 :    
451 : anton 1.1 \ threading 17mar93py
452 :    
453 :     : cfa, ( code-address -- ) \ gforth cfa-comma
454 :     here
455 :     dup lastcfa !
456 :     0 A, 0 , code-address! ;
457 :     : compile, ( xt -- ) \ core-ext compile-comma
458 :     A, ;
459 :     : !does ( addr -- ) \ gforth store-does
460 :     lastxt does-code! ;
461 :     : (does>) ( R: addr -- )
462 :     r> cfaligned /does-handler + !does ;
463 :     : dodoes, ( -- )
464 :     cfalign here /does-handler allot does-handler! ;
465 :    
466 :     doer? :dovar [IF]
467 :     : Create ( "name" -- ) \ core
468 :     Header reveal dovar: cfa, ;
469 :     [ELSE]
470 :     : Create ( "name" -- ) \ core
471 :     Header reveal here lastcfa ! 0 A, 0 , DOES> ;
472 :     [THEN]
473 :    
474 :     \ Create Variable User Constant 17mar93py
475 :    
476 :     : Variable ( "name" -- ) \ core
477 :     Create 0 , ;
478 :     : AVariable ( "name" -- ) \ gforth
479 :     Create 0 A, ;
480 :     : 2Variable ( "name" -- ) \ double
481 :     create 0 , 0 , ;
482 :    
483 :     : uallot ( n -- ) udp @ swap udp +! ;
484 :    
485 :     doer? :douser [IF]
486 :     : User ( "name" -- ) \ gforth
487 :     Header reveal douser: cfa, cell uallot , ;
488 :     : AUser ( "name" -- ) \ gforth
489 :     User ;
490 :     [ELSE]
491 : jwilke 1.3 : User Create cell uallot , DOES> @ up @ + ;
492 : anton 1.1 : AUser User ;
493 :     [THEN]
494 :    
495 :     doer? :docon [IF]
496 :     : (Constant) Header reveal docon: cfa, ;
497 :     [ELSE]
498 :     : (Constant) Create DOES> @ ;
499 :     [THEN]
500 :     : Constant ( w "name" -- ) \ core
501 :     \G Defines constant @var{name}
502 :     \G
503 :     \G @var{name} execution: @var{-- w}
504 :     (Constant) , ;
505 :     : AConstant ( addr "name" -- ) \ gforth
506 :     (Constant) A, ;
507 :     : Value ( w "name" -- ) \ core-ext
508 :     (Constant) , ;
509 :    
510 :     : 2Constant ( w1 w2 "name" -- ) \ double
511 :     Create ( w1 w2 "name" -- )
512 :     2,
513 :     DOES> ( -- w1 w2 )
514 :     2@ ;
515 :    
516 :     doer? :dofield [IF]
517 :     : (Field) Header reveal dofield: cfa, ;
518 :     [ELSE]
519 :     : (Field) Create DOES> @ + ;
520 :     [THEN]
521 :     \ IS Defer What's Defers TO 24feb93py
522 :    
523 :     doer? :dodefer [IF]
524 :     : Defer ( "name" -- ) \ gforth
525 :     \ !! shouldn't it be initialized with abort or something similar?
526 :     Header Reveal dodefer: cfa,
527 :     ['] noop A, ;
528 :     [ELSE]
529 :     : Defer ( "name" -- ) \ gforth
530 :     Create ['] noop A,
531 :     DOES> @ execute ;
532 :     [THEN]
533 :    
534 :     : Defers ( "name" -- ) \ gforth
535 :     ' >body @ compile, ; immediate
536 :    
537 :     \ : ; 24feb93py
538 :    
539 :     defer :-hook ( sys1 -- sys2 )
540 :     defer ;-hook ( sys2 -- sys1 )
541 :    
542 :     : : ( "name" -- colon-sys ) \ core colon
543 :     Header docol: cfa, defstart ] :-hook ;
544 :     : ; ( compilation colon-sys -- ; run-time nest-sys ) \ core semicolon
545 :     ;-hook ?struc postpone exit reveal postpone [ ; immediate restrict
546 :    
547 :     : :noname ( -- xt colon-sys ) \ core-ext colon-no-name
548 :     0 last !
549 :     cfalign here docol: cfa, 0 ] :-hook ;
550 :    
551 :     \ Search list handling 23feb93py
552 :    
553 :     : last? ( -- false / nfa nfa )
554 :     last @ ?dup ;
555 :     : (reveal) ( nt wid -- )
556 :     ( wid>wordlist-id ) dup >r
557 :     @ over ( name>link ) !
558 :     r> ! ;
559 :    
560 :     \ object oriented search list 17mar93py
561 :    
562 :     \ word list structure:
563 :    
564 :     struct
565 :     1 cells: field find-method \ xt: ( c_addr u wid -- nt )
566 :     1 cells: field reveal-method \ xt: ( nt wid -- ) \ used by dofield:, must be field
567 : jwilke 1.3 1 cells: field rehash-method \ xt: ( wid -- ) \ re-initializes a "search-data" (hashtables)
568 :     1 cells: field hash-method \ xt: ( wid -- ) \ initializes ""
569 : anton 1.1 \ \ !! what else
570 :     end-struct wordlist-map-struct
571 :    
572 :     struct
573 :     1 cells: field wordlist-id \ not the same as wid; representation depends on implementation
574 :     1 cells: field wordlist-map \ pointer to a wordlist-map-struct
575 :     1 cells: field wordlist-link \ link field to other wordlists
576 : jwilke 1.3 1 cells: field wordlist-extend \ points to wordlist extensions (eg hashtables)
577 : anton 1.1 end-struct wordlist-struct
578 :    
579 :     : f83find ( addr len wordlist -- nt / false )
580 :     ( wid>wordlist-id ) @ (f83find) ;
581 :    
582 : jwilke 1.3 : initvoc ( wid -- )
583 :     dup wordlist-map @ hash-method perform ;
584 :    
585 : anton 1.1 \ Search list table: find reveal
586 :     Create f83search ( -- wordlist-map )
587 : jwilke 1.3 ' f83find A, ' (reveal) A, ' drop A, ' drop A,
588 :    
589 :     here NIL A, G f83search T A, NIL A, NIL A,
590 :     AValue forth-wordlist \ variable, will be redefined by search.fs
591 :    
592 :     AVariable lookup forth-wordlist lookup !
593 :     \ !! last is user and lookup?! jaw
594 :     AVariable current ( -- addr ) \ gforth
595 :     AVariable voclink forth-wordlist wordlist-link voclink !
596 :     lookup AValue context
597 : anton 1.1
598 : jwilke 1.3 forth-wordlist current !
599 : anton 1.1
600 :     \ higher level parts of find
601 :    
602 :     ( struct )
603 :     0 >body cell
604 :     1 cells: field interpret/compile-int
605 :     1 cells: field interpret/compile-comp
606 :     end-struct interpret/compile-struct
607 :    
608 :     : interpret/compile? ( xt -- flag )
609 :     >does-code ['] S" >does-code = ;
610 :    
611 :     : (cfa>int) ( cfa -- xt )
612 :     dup interpret/compile?
613 :     if
614 :     interpret/compile-int @
615 :     then ;
616 :    
617 :     : (x>int) ( cfa b -- xt )
618 :     \ get interpretation semantics of name
619 :     restrict-mask and
620 :     if
621 :     drop ['] compile-only-error
622 :     else
623 :     (cfa>int)
624 :     then ;
625 :    
626 :     : name>int ( nt -- xt ) \ gforth
627 :     \G @var{xt} represents the interpretation semantics of the word
628 :     \G @var{nt}. Produces @code{' compile-only-error} if
629 :     \G @var{nt} is compile-only.
630 :     (name>x) (x>int) ;
631 :    
632 :     : name?int ( nt -- xt ) \ gforth
633 :     \G Like name>int, but throws an error if compile-only.
634 :     (name>x) restrict-mask and
635 :     if
636 :     compile-only-error \ does not return
637 :     then
638 :     (cfa>int) ;
639 :    
640 :     : name>comp ( nt -- w xt ) \ gforth
641 :     \G @var{w xt} is the compilation token for the word @var{nt}.
642 :     (name>x) >r dup interpret/compile?
643 :     if
644 :     interpret/compile-comp @
645 :     then
646 :     r> immediate-mask and if
647 :     ['] execute
648 :     else
649 :     ['] compile,
650 :     then ;
651 :    
652 :     : (search-wordlist) ( addr count wid -- nt / false )
653 :     dup wordlist-map @ find-method perform ;
654 :    
655 :     : flag-sign ( f -- 1|-1 )
656 :     \ true becomes 1, false -1
657 :     0= 2* 1+ ;
658 :    
659 :     : (name>intn) ( nfa -- xt +-1 )
660 :     (name>x) tuck (x>int) ( b xt )
661 :     swap immediate-mask and flag-sign ;
662 :    
663 :     : search-wordlist ( addr count wid -- 0 / xt +-1 ) \ search
664 :     \ xt is the interpretation semantics
665 :     (search-wordlist) dup if
666 :     (name>intn)
667 :     then ;
668 :    
669 :     : find-name ( c-addr u -- nt/0 ) \ gforth
670 :     \g Find the name @var{c-addr u} in the current search
671 :     \g order. Return its nt, if found, otherwise 0.
672 :     lookup @ (search-wordlist) ;
673 :    
674 :     : sfind ( c-addr u -- 0 / xt +-1 ) \ gforth-obsolete
675 :     find-name dup
676 :     if ( nt )
677 :     state @
678 :     if
679 :     name>comp ['] execute = flag-sign
680 :     else
681 :     (name>intn)
682 :     then
683 :     then ;
684 :    
685 :     : find ( c-addr -- xt +-1 / c-addr 0 ) \ core,search
686 :     dup count sfind dup
687 :     if
688 :     rot drop
689 :     then ;
690 :    
691 :     : (') ( "name" -- nt ) \ gforth
692 :     name find-name dup 0=
693 :     IF
694 :     drop -&13 bounce
695 :     THEN ;
696 :    
697 :     : [(')] ( compilation "name" -- ; run-time -- nt ) \ gforth bracket-paren-tick
698 :     (') postpone ALiteral ; immediate restrict
699 :    
700 :     : ' ( "name" -- xt ) \ core tick
701 :     \g @var{xt} represents @var{name}'s interpretation
702 :     \g semantics. Performs @code{-14 throw} if the word has no
703 :     \g interpretation semantics.
704 :     (') name?int ;
705 :     : ['] ( compilation. "name" -- ; run-time. -- xt ) \ core bracket-tick
706 :     \g @var{xt} represents @var{name}'s interpretation
707 :     \g semantics. Performs @code{-14 throw} if the word has no
708 :     \g interpretation semantics.
709 :     ' postpone ALiteral ; immediate restrict
710 :    
711 :     : COMP' ( "name" -- w xt ) \ gforth c-tick
712 :     \g @var{w xt} represents @var{name}'s compilation semantics.
713 :     (') name>comp ;
714 :     : [COMP'] ( compilation "name" -- ; run-time -- w xt ) \ gforth bracket-comp-tick
715 :     \g @var{w xt} represents @var{name}'s compilation semantics.
716 :     COMP' swap POSTPONE Aliteral POSTPONE ALiteral ; immediate restrict
717 :    
718 :     \ reveal words
719 :    
720 :     Variable warnings ( -- addr ) \ gforth
721 :     G -1 warnings T !
722 :    
723 :     : check-shadow ( addr count wid -- )
724 :     \G prints a warning if the string is already present in the wordlist
725 :     >r 2dup 2dup r> (search-wordlist) warnings @ and ?dup if
726 :     ." redefined " name>string 2dup type
727 :     compare 0<> if
728 :     ." with " type
729 :     else
730 :     2drop
731 :     then
732 :     space space EXIT
733 :     then
734 :     2drop 2drop ;
735 :    
736 :     : reveal ( -- ) \ gforth
737 :     last?
738 :     if \ the last word has a header
739 :     dup ( name>link ) @ 1 and
740 :     if \ it is still hidden
741 :     dup ( name>link ) @ 1 xor ( nt wid )
742 :     2dup >r name>string r> check-shadow ( nt wid )
743 :     dup wordlist-map @ reveal-method perform
744 :     then
745 :     then ;
746 :    
747 :     : rehash ( wid -- )
748 :     dup wordlist-map @ rehash-method perform ;
749 :    
750 :     \ Query 07apr93py
751 :    
752 :     has-files 0= [IF]
753 :     : sourceline# ( -- n ) loadline @ ;
754 :     [THEN]
755 :    
756 :     : refill ( -- flag ) \ core-ext,block-ext,file-ext
757 :     blk @ IF 1 blk +! true 0 >in ! EXIT THEN
758 :     tib /line
759 :     [ has-files [IF] ]
760 :     loadfile @ ?dup
761 :     IF read-line throw
762 :     ELSE
763 :     [ [THEN] ]
764 :     sourceline# 0< IF 2drop false EXIT THEN
765 :     accept true
766 :     [ has-files [IF] ]
767 :     THEN
768 :     [ [THEN] ]
769 :     1 loadline +!
770 :     swap #tib ! 0 >in ! ;
771 :    
772 :     : query ( -- ) \ core-ext
773 :     \G obsolescent
774 :     blk off loadfile off
775 :     tib /line accept #tib ! 0 >in ! ;
776 :    
777 :     \ save-mem extend-mem
778 :    
779 :     has-os [IF]
780 :     : save-mem ( addr1 u -- addr2 u ) \ gforth
781 :     \g copy a memory block into a newly allocated region in the heap
782 :     swap >r
783 :     dup allocate throw
784 :     swap 2dup r> -rot move ;
785 :    
786 :     : extend-mem ( addr1 u1 u -- addr addr2 u2 )
787 :     \ extend memory block allocated from the heap by u aus
788 :     \ the (possibly reallocated piece is addr2 u2, the extension is at addr
789 :     over >r + dup >r resize throw
790 :     r> over r> + -rot ;
791 :     [THEN]
792 :    
793 :     \ RECURSE 17may93jaw
794 :    
795 :     : recurse ( compilation -- ; run-time ?? -- ?? ) \ core
796 : anton 1.2 \g calls the current definition.
797 : anton 1.1 lastxt compile, ; immediate restrict
798 : anton 1.2 ' reveal alias recursive ( compilation -- ; run-time -- ) \ gforth
799 :     \g makes the current definition visible, enabling it to call itself
800 :     \g recursively.
801 :     immediate restrict
802 : anton 1.1
803 :     \ EVALUATE 17may93jaw
804 :    
805 :     has-files 0= [IF]
806 :     : push-file ( -- ) r>
807 :     sourceline# >r tibstack @ >r >tib @ >r #tib @ >r
808 :     >tib @ tibstack @ = IF r@ tibstack +! THEN
809 :     tibstack @ >tib ! >in @ >r >r ;
810 :    
811 :     : pop-file ( throw-code -- throw-code )
812 :     r>
813 :     r> >in ! r> #tib ! r> >tib ! r> tibstack ! r> loadline ! >r ;
814 :     [THEN]
815 :    
816 :     : evaluate ( c-addr len -- ) \ core,block
817 :     push-file #tib ! >tib !
818 :     >in off blk off loadfile off -1 loadline !
819 :     ['] interpret catch
820 :     pop-file throw ;
821 :    
822 :     : abort ( ?? -- ?? ) \ core,exception-ext
823 :     -1 throw ;
824 :    
825 :     \+ environment? true ENV" CORE"
826 :     \ core wordset is now complete!
827 :    
828 :     \ Quit 13feb93py
829 :    
830 :     Defer 'quit
831 :     Defer .status
832 :     : prompt state @ IF ." compiled" EXIT THEN ." ok" ;
833 :     : (Query) ( -- )
834 :     loadfile off blk off refill drop ;
835 :     : (quit) BEGIN .status cr (query) interpret prompt AGAIN ;
836 :     ' (quit) IS 'quit
837 :    
838 :     \ DOERROR (DOERROR) 13jun93jaw
839 :    
840 :     8 Constant max-errors
841 :     Variable error-stack 0 error-stack !
842 :     max-errors 6 * cells allot
843 :     \ format of one cell:
844 :     \ source ( addr u )
845 :     \ >in
846 :     \ line-number
847 :     \ Loadfilename ( addr u )
848 :    
849 :     : dec. ( n -- ) \ gforth
850 :     \ print value in decimal representation
851 :     base @ decimal swap . base ! ;
852 :    
853 :     : hex. ( u -- ) \ gforth
854 :     \ print value as unsigned hex number
855 :     '$ emit base @ swap hex u. base ! ;
856 :    
857 :     : typewhite ( addr u -- ) \ gforth
858 :     \ like type, but white space is printed instead of the characters
859 :     bounds ?do
860 :     i c@ #tab = if \ check for tab
861 :     #tab
862 :     else
863 :     bl
864 :     then
865 :     emit
866 :     loop ;
867 :    
868 :     DEFER DOERROR
869 :    
870 :     : .error-frame ( addr1 u1 n1 n2 addr2 u2 -- )
871 :     cr error-stack @
872 :     IF
873 :     ." in file included from "
874 :     type ." :" dec. drop 2drop
875 :     ELSE
876 :     type ." :" dec.
877 :     cr dup 2over type cr drop
878 :     nip -trailing 1- ( line-start index2 )
879 :     0 >r BEGIN
880 :     2dup + c@ bl > WHILE
881 :     r> 1+ >r 1- dup 0< UNTIL THEN 1+
882 :     ( line-start index1 )
883 :     typewhite
884 :     r> 1 max 0 ?do \ we want at least one "^", even if the length is 0
885 :     [char] ^ emit
886 :     loop
887 :     THEN
888 :     ;
889 :    
890 :     : (DoError) ( throw-code -- )
891 :     [ has-os [IF] ]
892 :     outfile-id dup flush-file drop >r
893 :     stderr to outfile-id
894 :     [ [THEN] ]
895 :     sourceline# IF
896 :     source >in @ sourceline# 0 0 .error-frame
897 :     THEN
898 :     error-stack @ 0 ?DO
899 :     -1 error-stack +!
900 :     error-stack dup @ 6 * cells + cell+
901 :     6 cells bounds DO
902 :     I @
903 :     cell +LOOP
904 :     .error-frame
905 :     LOOP
906 :     dup -2 =
907 :     IF
908 :     "error @ ?dup
909 :     IF
910 :     cr count type
911 :     THEN
912 :     drop
913 :     ELSE
914 :     .error
915 :     THEN
916 :     normal-dp dpp !
917 :     [ has-os [IF] ] r> to outfile-id [ [THEN] ]
918 :     ;
919 :    
920 :     ' (DoError) IS DoError
921 :    
922 :     : quit ( ?? -- ?? ) \ core
923 : jwilke 1.3 rp0 @ rp! handler off >tib @ >r
924 : anton 1.1 BEGIN
925 :     postpone [
926 :     ['] 'quit CATCH dup
927 :     WHILE
928 :     DoError r@ >tib ! r@ tibstack !
929 :     REPEAT
930 :     drop r> >tib ! ;
931 :    
932 :     \ Cold 13feb93py
933 :    
934 :     \ : .name ( name -- ) name>string type space ;
935 :     \ : words listwords @
936 :     \ BEGIN @ dup WHILE dup .name REPEAT drop ;
937 :    
938 :     : (bootmessage)
939 :     ." GForth " version-string type
940 :     ." , Copyright (C) 1994-1997 Free Software Foundation, Inc." cr
941 :     ." GForth comes with ABSOLUTELY NO WARRANTY; for details type `license'"
942 :     [ has-os [IF] ]
943 :     cr ." Type `bye' to exit"
944 :     [ [THEN] ] ;
945 :    
946 :     defer bootmessage
947 :    
948 :     ' (bootmessage) IS bootmessage
949 :    
950 : jwilke 1.3 Defer 'cold
951 :     \ hook (deferred word) for things to do right before interpreting the
952 :     \ command-line arguments
953 :     ' noop IS 'cold
954 :    
955 :     include chains.fs
956 :    
957 :     Variable init8
958 :    
959 : anton 1.1 : cold ( -- ) \ gforth
960 :     [ has-files [IF] ]
961 :     pathstring 2@ fpath only-path
962 :     init-included-files
963 :     [ [THEN] ]
964 :     'cold
965 : jwilke 1.3 init8 chainperform
966 : anton 1.1 [ has-files [IF] ]
967 :     ['] process-args catch ?dup
968 :     IF
969 :     dup >r DoError cr r> negate (bye)
970 :     THEN
971 :     argc @ 1 >
972 :     IF \ there may be some unfinished line, so let's finish it
973 :     cr
974 :     THEN
975 :     [ [THEN] ]
976 :     bootmessage
977 :     loadline off quit ;
978 :    
979 :     : boot ( path **argv argc -- )
980 :     main-task up!
981 :     [ has-os [IF] ]
982 :     stdout TO outfile-id
983 :     [ [THEN] ]
984 :     [ has-files [IF] ]
985 :     argc ! argv ! pathstring 2!
986 :     [ [THEN] ]
987 : jwilke 1.3 sp@ sp0 !
988 : anton 1.1 [ has-locals [IF] ]
989 :     lp@ forthstart 7 cells + @ -
990 :     [ [ELSE] ]
991 :     [ has-os [IF] ]
992 :     sp@ $1040 +
993 :     [ [ELSE] ]
994 :     sp@ $40 +
995 :     [ [THEN] ]
996 :     [ [THEN] ]
997 :     dup >tib ! tibstack ! #tib off >in off
998 : jwilke 1.3 rp@ rp0 !
999 : anton 1.1 [ has-floats [IF] ]
1000 : jwilke 1.3 fp@ fp0 !
1001 : anton 1.1 [ [THEN] ]
1002 :     ['] cold catch DoError
1003 :     [ has-os [IF] ]
1004 :     bye
1005 :     [ [THEN] ]
1006 :     ;
1007 :    
1008 :     has-os [IF]
1009 :     : bye ( -- ) \ tools-ext
1010 :     [ has-files [IF] ]
1011 :     script? 0= IF cr THEN
1012 :     [ [ELSE] ]
1013 :     cr
1014 :     [ [THEN] ]
1015 :     0 (bye) ;
1016 :     [THEN]
1017 :    
1018 :     \ **argv may be scanned by the C starter to get some important
1019 :     \ information, as -display and -geometry for an X client FORTH
1020 :     \ or space and stackspace overrides
1021 :    
1022 :     \ 0 arg contains, however, the name of the program.

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help