3 \ Optional wordset words for 8086 hForth
\r
8 \ Fix D.R . Thank Benjamin Hoyt.
\r
10 \ Facelift to be used with other CPUs.
\r
12 \ Fix 'compiles>' for colon-sys.
\r
14 \ Remove PICK which was added in assembly source.
\r
15 \ Revise CASE, ENDCASE, OF, ENDOF, RETRY for control-flow stack.
\r
16 \ Revise '.xt' due to the removal of 'do."' and change of 'doS"'.
\r
20 \ Add RETRY described by Dr. Astle
\r
21 \ in Forth Dimensions 17(4), 19-21 (1995).
\r
25 \ Check validity of xt in 'xt>name'. '-1 @' generates exception.
\r
27 \ Replace < with U< in the definition of MARKER for RAM and EXE
\r
28 \ models. U< should be used to compare addresses.
\r
29 \ Fix < to U< in the definition of xtSEE
\r
31 \ Rename WORDLIST-NAME which more consistant along VARIABLE, CONSTANT
\r
32 \ than NAME-WORDLIST
\r
34 \ Make HERE VALUE type and remove 'hereP'. Revise 'xhere'
\r
35 \ and remove 'TOxhere'.
\r
36 \ Make SOURCE-ID VALUE type, replace TOsource-id with
\r
37 \ "TO SOURCE-ID" and remove TOsource-id .
\r
41 \ Fix 'xtSEE' for RAM and EXE model.
\r
43 \ Dictionary structures of hForth ROM, RAM and EXE models are all
\r
45 \ o WORDLIST allocate empty wordlist dynamically in RAM and EXE model. Thus,
\r
46 \ there is no limit on maximum number of wordlist for RAM and EXE model.
\r
47 \ Maximum number os wordlists are limited to 10 in ROM model.
\r
48 \ o -1 SET-ORDER is hard coded to put NONSTANDARD-WORDLIST and
\r
49 \ FORTH-WORDLIST into the search order stack for RAM model.
\r
50 \ o MARKER is revised for combined code and name space for RAM model.
\r
51 \ o 'xt>name' are different
\r
52 \ o PAD, xtSEE, xDUMP are different.
\r
57 \ **********************
\r
58 \ Optional String wordset
\r
59 \ **********************
\r
61 \ COMPARE ( c-addr1 u1 c-addr2 u2 -- -1|0|1 ) \ STRING
\r
62 \ Compare the two strings. Return 0 if two strings are identical;
\r
63 \ -1 if ca1 u1 is smaller than ca2 u2; 1 otherwise.
\r
65 ROT 2DUP SWAP - >R \ ca1 ca2 u2 u1 R: u1-u2
\r
67 IF R> DROP EXIT THEN
\r
68 R> DUP IF 0< 2* 1+ THEN ;
\r
70 \ **********************
\r
71 \ Optional Prgramming-Tools wordset
\r
72 \ **********************
\r
74 \ [ELSE] ( *<spaces>name...* - ) \ TOOLS EXT
\r
75 \ Skipping leading spaces, parse and discard words from the
\r
76 \ parse area, including nested [IF] ... [THEN] and [IF] ...
\r
77 \ [ELSE] ... [THEN], until the word [THEN] has been parsed
\r
81 BEGIN PARSE-WORD DUP WHILE \ level c-addr len
\r
82 2DUP S" [IF]" COMPARE 0= IF \ level c-addr len
\r
84 ELSE \ level c-addr len
\r
85 2DUP S" [ELSE]" COMPARE 0= IF \ level c-addr len
\r
86 2DROP 1- DUP IF 1+ THEN \ level'
\r
87 ELSE \ level c-addr len
\r
88 S" [THEN]" COMPARE 0= IF \ level
\r
92 THEN ?DUP 0= IF EXIT THEN \ level'
\r
93 REPEAT 2DROP \ level
\r
94 REFILL 0= UNTIL \ level
\r
97 \ [IF] ( flag | flag *<spaces>name...* -- ) \ TOOLS EXT
\r
98 \ If flag is true, do nothing. Otherwise, Skipping leading
\r
99 \ spaces, parse and discard words from the parse area,
\r
100 \ including nested [IF] ... [THEN] and [IF] ... [ELSE] ...
\r
101 \ [THEN], until either the word [ELSE] or [THEN] has been
\r
102 \ parsed and discared.
\r
103 : [IF] ( flag -- ) \ TOOLS EXT
\r
104 0= IF POSTPONE [ELSE] THEN ; IMMEDIATE
\r
108 : [THEN] ( -- ) ; IMMEDIATE
\r
110 \ **********************
\r
111 \ Optional Search-Order wordset -- complete
\r
112 \ **********************
\r
114 \ SET-CURRENT ( wid -- ) \ SEARCH
\r
115 \ Set the compilation wordlist to the wordlist identified by wid.
\r
116 : SET-CURRENT current ! ;
\r
118 \ DEFINITIONS ( -- ) \ SEARCH
\r
119 \ Make the compilation wordlist the same as the first wordlist
\r
120 \ in the search order.
\r
121 : DEFINITIONS #order CELL+ @ SET-CURRENT ;
\r
123 \ GET-ORDER ( -- widn .. wid1 n ) \ SEARCH
\r
124 \ Return the number of wordlist in the search order and the
\r
125 \ wordlist identifiers widn ... wid1 .
\r
128 IF 1- 0 SWAP DO I CELLS #order CELL+ + @ -1 +LOOP
\r
132 \ SET-ORDER ( widn .. wid1 n -- ) \ SEARCH
\r
133 \ Set the search order to the wordlist identified by widn ...
\r
134 \ wid1. Later wordlist wid1 will be searched first, with wordlist
\r
135 \ widn searched last. If n is 0, empty the search order. If n
\r
136 \ is -1, set the search order to the implementation-defined
\r
137 \ minimum search order.
\r
139 CHAR " PARSE model" ENVIRONMENT? DROP
\r
140 CHAR " PARSE ROM Model" COMPARE 0=
\r
144 IF DROP [ #order var0 - sysVar0 + ] LITERAL #order
\r
145 [ BL PARSE WORDLISTS ENVIRONMENT? DROP 1+ ] LITERAL CELLS
\r
147 DUP [ BL PARSE WORDLISTS ENVIRONMENT? DROP ] LITERAL >
\r
150 ?DUP IF 0 DO I CELLS #order CELL+ + ! LOOP THEN ;
\r
152 CHAR " PARSE model" ENVIRONMENT? DROP
\r
153 CHAR " PARSE RAM Model" COMPARE 0=
\r
154 CHAR " PARSE model" ENVIRONMENT? DROP
\r
155 CHAR " PARSE EXE Model" COMPARE 0= OR
\r
159 IF DROP \ restore default # of search order
\r
160 #order0 DUP @ #order SWAP 1+ CELLS MOVE EXIT THEN
\r
161 DUP [ BL PARSE WORDLISTS ENVIRONMENT? DROP ] LITERAL >
\r
164 ?DUP IF 0 DO #order I CELLS + CELL+ ! LOOP THEN ;
\r
167 \ WORDLIST ( -- wid ) \ SEARCH
\r
168 \ Create a new empty wordlist and return its identifier wid.
\r
169 \ The new wordlist is returned from a preallocated pool for
\r
170 \ RAM/ROM system in this implementation since they need to be
\r
171 \ initialized after SAVE-SYSTEM. It may be dynamically allocated
\r
172 \ in RAM only system.
\r
174 \ structure of a wordlist
\r
175 \ //lastWord/next_wordlist/wordlist_name//
\r
177 CHAR " PARSE model" ENVIRONMENT? DROP
\r
178 CHAR " PARSE ROM Model" COMPARE 0=
\r
181 FORTH-WORDLIST \ the first wordlist
\r
182 BEGIN CELL+ DUP @ WHILE @ REPEAT
\r
183 DUP CELL+ CELL+ DUP @ IF \ pre-allocated wordlist is available?
\r
184 -49 THROW THEN \ search-order overflow
\r
185 DUP ROT ! ; \ attach a wordlist to wordlist link
\r
187 CHAR " PARSE model" ENVIRONMENT? DROP
\r
188 CHAR " PARSE RAM Model" COMPARE 0=
\r
189 CHAR " PARSE model" ENVIRONMENT? DROP
\r
190 CHAR " PARSE EXE Model" COMPARE 0= OR
\r
193 FORTH-WORDLIST \ the first wordlist
\r
194 BEGIN CELL+ DUP @ WHILE @ REPEAT \ find end of wordlist link
\r
195 HERE SWAP ! \ attach a wordlist to wordlist link
\r
196 HERE 0 , \ no word in this wordlist yet
\r
197 0 , \ this is end of wordlist link
\r
198 0 , ; \ no name is assigned to this wordlist yet.
\r
201 \ ALSO ( -- ) \ SEARCH EXT
\r
202 \ Transform the search order widn ... wid2, wid1 into widn ...
\r
203 \ wid2, wid1, wid1.
\r
204 : ALSO GET-ORDER OVER SWAP 1+ SET-ORDER ;
\r
207 \ Transform the search order widn ... wid2, wid1 into widn ...
\r
208 \ wid2, wid_FORTH-WORDLIST.
\r
209 : FORTH GET-ORDER NIP FORTH-WORDLIST SWAP SET-ORDER ;
\r
212 \ Set the search order to the implementation-defined minimum
\r
214 : ONLY -1 SET-ORDER ;
\r
217 \ Transform the search order widn ... wid2, wid1 into widn ...
\r
219 : PREVIOUS GET-ORDER NIP 1- SET-ORDER ;
\r
221 NONSTANDARD-WORDLIST SET-CURRENT
\r
223 \ .name ( c-addr -- )
\r
224 \ Display name of a word.
\r
225 : .name COUNT 31 AND TYPE SPACE ;
\r
227 \ WORDLIST-NAME ( wid -- )
\r
228 \ Name a wordlist. Used to attach a name to a new wordlist
\r
229 \ returned by WORDLIST to be displayed by ORDER.
\r
230 : WORDLIST-NAME DUP CONSTANT lastName SWAP CELL+ CELL+ ! ;
\r
232 \ .wordlist ( c-addr -- )
\r
233 \ Display name of a wordlist.
\r
235 8 SPACES DUP CELL+ CELL+ @ ?DUP
\r
236 IF .name DROP CR EXIT THEN . CR ;
\r
238 FORTH-WORDLIST SET-CURRENT
\r
240 \ ORDER ( -- ) \ SEARCH EXT
\r
241 \ Display the wordlists in the search order from the first
\r
242 \ to the last. Also display the wordlist into which new
\r
243 \ definitions will be placed.
\r
245 CR ." Search-Order:" CR
\r
246 GET-ORDER 0 DO .wordlist LOOP
\r
248 GET-CURRENT .wordlist ;
\r
250 envQList SET-CURRENT
\r
251 -1 CONSTANT SEARCH-ORDER
\r
252 -1 CONSTANT SEARCH-ORDER-EXT
\r
253 FORTH-WORDLIST SET-CURRENT
\r
255 \ **********************
\r
256 \ Optional Core Extention wordset
\r
257 \ **********************
\r
259 NONSTANDARD-WORDLIST SET-CURRENT
\r
260 CHAR " PARSE model" ENVIRONMENT? DROP
\r
261 CHAR " PARSE RAM Model" COMPARE 0=
\r
267 FORTH-WORDLIST SET-CURRENT
\r
269 \ .( ( "ccc<)>" -- ) \ CORE EXT
\r
270 \ Output following string up to next ) .
\r
271 : .( [CHAR] ) PARSE TYPE ; IMMEDIATE
\r
273 \ D.R ( d n -- ) \ DOUBLE
\r
274 \ Display d right-justified in field of width n.
\r
275 : D.R >R (d.) R> OVER - SPACES TYPE ;
\r
277 \ .R ( n1 n2 -- ) \ CORE EXT
\r
278 \ Display n right-justified in field of width n2.
\r
279 : .R >R S>D R> D.R ;
\r
281 \ FALSE ( -- false ) \ CORE EXT
\r
282 \ Return a false flag.
\r
285 \ HEX ( -- ) \ CORE EXT
\r
286 \ Set contents of BASE to sixteen.
\r
289 \ U> ( u1 u2 -- flag ) \ CORE EXT
\r
290 \ flag is true if and only if u1 is greater than u2.
\r
293 \ MARKER ( "<spaces>name" -- ) \ CORE EXT
\r
294 \ Create a definition with name. The new definition will
\r
295 \ restore on execution all dictionary allocations and search
\r
296 \ order pointers to the state they had just prior to the
\r
297 \ definition of name.
\r
298 CHAR " PARSE model" ENVIRONMENT? DROP
\r
299 CHAR " PARSE ROM Model" COMPARE 0=
\r
302 ROMB @ ROMT @ RAMB @ RAMT @
\r
303 CREATE , , , , GET-CURRENT ,
\r
304 FORTH-WORDLIST \ start of wordlist link
\r
305 BEGIN CELL+ DUP @ WHILE @ REPEAT \ find end of wordlist link
\r
306 , GET-ORDER DUP , 0 DO , LOOP
\r
307 DOES> DUP @ RAMT ! CELL+ DUP @ RAMB !
\r
308 CELL+ DUP @ ROMT ! CELL+ DUP @ ROMB !
\r
309 CELL+ DUP @ SET-CURRENT
\r
310 CELL+ DUP @ 0 SWAP ! \ restore end of wordlist link
\r
311 CELL+ DUP @ DUP >R CELLS + R@ 0 DO DUP @ SWAP cell- LOOP
\r
312 DROP R> SET-ORDER \ restore search order
\r
313 FORTH-WORDLIST \ start of wordlist link
\r
314 BEGIN DUP @ \ last word name field of wordlist
\r
315 BEGIN DUP npVar @ @ U<
\r
317 REPEAT OVER ! \ restore search order pointer
\r
318 CELL+ @ ?DUP 0= \ repeat to next wordlist
\r
321 CHAR " PARSE model" ENVIRONMENT? DROP
\r
322 CHAR " PARSE RAM Model" COMPARE 0=
\r
326 CREATE , GET-CURRENT ,
\r
327 FORTH-WORDLIST \ start of wordlist link
\r
328 BEGIN CELL+ DUP @ WHILE @ REPEAT \ find end of wordlist link
\r
329 , GET-ORDER DUP , 0 DO , LOOP
\r
330 DOES> DUP @ TO HERE
\r
331 CELL+ DUP @ SET-CURRENT
\r
332 CELL+ DUP @ 0 SWAP ! \ restore end of wordlist link
\r
333 CELL+ DUP @ DUP >R CELLS + R@ 0 DO DUP @ SWAP cell- LOOP
\r
334 DROP R> SET-ORDER \ restore search order
\r
335 FORTH-WORDLIST \ start of wordlist link
\r
336 BEGIN DUP @ \ last word name field of wordlist
\r
339 REPEAT OVER ! \ restore search order pointer
\r
340 CELL+ @ ?DUP 0= \ repeat to next wordlist
\r
343 CHAR " PARSE model" ENVIRONMENT? DROP
\r
344 CHAR " PARSE EXE Model" COMPARE 0=
\r
348 CREATE , , GET-CURRENT ,
\r
349 FORTH-WORDLIST \ start of wordlist link
\r
350 BEGIN CELL+ DUP @ WHILE @ REPEAT \ find end of wordlist link
\r
351 , GET-ORDER DUP , 0 DO , LOOP
\r
352 DOES> DUP @ TO xhere CELL+ DUP @ TO HERE
\r
353 CELL+ DUP @ SET-CURRENT
\r
354 CELL+ DUP @ 0 SWAP ! \ restore end of wordlist link
\r
355 CELL+ DUP @ DUP >R CELLS + R@ 0 DO DUP @ SWAP cell- LOOP
\r
356 DROP R> SET-ORDER \ restore search order
\r
357 FORTH-WORDLIST \ start of wordlist link
\r
358 BEGIN DUP @ \ last word name field of wordlist
\r
361 REPEAT OVER ! \ restore search order pointer
\r
362 CELL+ @ ?DUP 0= \ repeat to next wordlist
\r
366 \ PAD ( -- a-addr ) \ CORE EXT
\r
367 \ Return the address of a temporary buffer. See REFILL
\r
369 CHAR " PARSE model" ENVIRONMENT? DROP
\r
370 CHAR " PARSE ROM Model" COMPARE 0=
\r
372 : PAD npVar @ [ BL PARSE /PAD ENVIRONMENT? DROP CHARS 3 * NEGATE ] LITERAL + ;
\r
374 CHAR " PARSE model" ENVIRONMENT? DROP
\r
375 CHAR " PARSE RAM Model" COMPARE 0=
\r
377 : PAD memTop [ BL PARSE /PAD ENVIRONMENT? DROP CHARS 2* NEGATE ] LITERAL + ;
\r
379 CHAR " PARSE model" ENVIRONMENT? DROP
\r
380 CHAR " PARSE EXE Model" COMPARE 0=
\r
382 : PAD memTop [ BL PARSE /PAD ENVIRONMENT? DROP CHARS 2* NEGATE ] LITERAL + ;
\r
385 \ TRUE ( -- true ) \ CORE EXT
\r
386 \ Return a true flag.
\r
389 \ U.R ( u n -- ) \ CORE EXT
\r
390 \ Display u right-justified in field of width n.
\r
395 \ CASE ( C: -- case-sys ) \ CORE EXT
\r
397 \ Mark the start of CASE ... OF ... ENDOF ... ENDCASE structure.
\r
398 \ On run-time, continue execution.
\r
399 : CASE ( C: -- case-mark )
\r
400 0 3 \ case type is 3
\r
401 bal+ ; COMPILE-ONLY IMMEDIATE
\r
403 \ ENDCASE ( C: case-sys -- ) \ CORE EXT
\r
404 \ Run-time: ( x -- )
\r
405 \ Mark the end of CASE ... OF ... ENDOF ... ENDCASE structure.
\r
406 \ On run-time, discard the case selector x and continue execution.
\r
407 : ENDCASE ( C: case-mark of-orig ... of-orig -- )
\r
409 BEGIN DUP 2 = \ of-orig type is 2
\r
410 WHILE 1- POSTPONE THEN
\r
412 3 - IF -22 THROW THEN \ control structure mismatch
\r
413 DROP bal- ; COMPILE-ONLY IMMEDIATE
\r
415 \ OF ( C: -- of-sys ) \ CORE EXT
\r
416 \ Run-time: ( x1 x2 -- |x1 )
\r
417 \ Mark the start of OF ... ENDOF part of CASE structure.
\r
418 \ On run-time if two values on the stack are not equal, discard
\r
419 \ the top value and continue execution following the next ENDOF.
\r
420 \ Otherwise discard both values and continue execution in line.
\r
421 : OF ( C: -- of-orig )
\r
422 POSTPONE OVER POSTPONE = POSTPONE IF POSTPONE DROP
\r
423 1+ \ change orig type 1 to of-sys type 2
\r
424 ; COMPILE-ONLY IMMEDIATE
\r
426 \ ENDOF ( C: case-sys1 of-sys -- case-sys2 ) \ CORE EXT
\r
428 \ Mark the end of OF ... ENDOF part of CASE structre.
\r
429 \ On run-time, continue execution following ENDCASE .
\r
430 : ENDOF ( C: of-orig1 -- of-orig2 )
\r
431 1- POSTPONE ELSE 1+ \ of-orig type is 2; orig type is 1
\r
432 ; COMPILE-ONLY IMMEDIATE
\r
434 \ UNUSED ( -- u ) \ CORE EXT
\r
435 \ Return available data space in address units.
\r
436 : UNUSED PAD HERE - ; \ Available data space is HERE to PAD
\r
438 \ **********************
\r
439 \ Optional Prgramming-Tools wordset -- complete
\r
440 \ **********************
\r
444 \ .S ( -- ) \ TOOLS
\r
445 \ Display the values on the data stack.
\r
447 IF 1- 0 SWAP \ 0 depth-1
\r
449 BASE @ 10 = IF . ELSE U. THEN
\r
453 \ ? ( a-addr -- ) \ TOOLS
\r
454 \ Display the contents at a-addr.
\r
456 : ? @ BASE @ 10 = IF . EXIT THEN U. ;
\r
458 NONSTANDARD-WORDLIST SET-CURRENT
\r
460 \ enough? ( -- flag )
\r
461 \ Return false if no input, else pause and if CR return true.
\r
462 : enough? EKEY? DUP IF EKEY 2DROP EKEY 13 ( CR) = THEN ;
\r
464 FORTH-WORDLIST SET-CURRENT
\r
466 \ DUMP ( addr u -- ) \ TOOLS
\r
467 \ Display the contents of u consecutive address units starting
\r
473 0 DO CR DUP DUP 0 <# # # # # #> TYPE SPACE SPACE
\r
474 16 0 DO DUP C@ 0 <# # # #> TYPE SPACE CHAR+ LOOP
\r
476 16 0 DO DUP C@ 127 AND DUP 0 BL WITHIN
\r
478 IF DROP [CHAR] . THEN
\r
481 enough? IF LEAVE THEN
\r
486 NONSTANDARD-WORDLIST SET-CURRENT
\r
488 CHAR " PARSE model" ENVIRONMENT? DROP
\r
489 CHAR " PARSE EXE Model" COMPARE 0=
\r
491 \ xDUMP ( code-addr u -- )
\r
492 \ Display the contents of u consecutive address units
\r
493 \ starting at the code addr.
\r
498 0 DO CR DUP 0 <# # # # # #> TYPE SPACE SPACE
\r
499 8 0 DO DUP code@ 0 <# # # # # #> TYPE SPACE CELL+ LOOP
\r
500 enough? IF LEAVE THEN
\r
506 \ xt>name ( xt -- c-addr | 0 )
\r
507 \ Remove xt from the stack and return the name address if xt
\r
508 \ is execution token of valid word; otherwise return 0.
\r
509 CHAR " PARSE model" ENVIRONMENT? DROP
\r
510 CHAR " PARSE ROM Model" COMPARE 0=
\r
513 DUP ALIGNED OVER XOR IF DROP 0 EXIT THEN \ xt should be aligned
\r
515 FORTH-WORDLIST \ Start of wordlist link
\r
516 BEGIN DUP @ \ last word name field of wordlist
\r
517 BEGIN DUP name>xt R@ XOR
\r
518 WHILE cell- @ ?DUP 0=
\r
519 UNTIL \ continue until the end of wordlist
\r
520 ELSE SWAP R> 2DROP EXIT \ found
\r
521 THEN CELL+ @ ?DUP 0=
\r
522 UNTIL \ continue to next wordlist
\r
523 R> DROP 0 ; \ not found
\r
525 CHAR " PARSE model" ENVIRONMENT? DROP
\r
526 CHAR " PARSE RAM Model" COMPARE 0=
\r
529 DUP ALIGNED OVER XOR IF DROP 0 EXIT THEN \ xt should be aligned
\r
530 DUP cell- @ \ xt c-addr
\r
531 DUP ALIGNED OVER XOR IF 2DROP 0 EXIT THEN
\r
532 SWAP OVER name>xt = AND ;
\r
534 CHAR " PARSE model" ENVIRONMENT? DROP
\r
535 CHAR " PARSE EXE Model" COMPARE 0=
\r
538 DUP ALIGNED OVER XOR IF DROP 0 EXIT THEN \ xt should be aligned
\r
539 DUP cell- code@ \ xt c-addr
\r
540 DUP ALIGNED OVER XOR IF 2DROP 0 EXIT THEN
\r
541 SWAP OVER name>xt = AND ;
\r
544 \ .xt ( a-addr1 xt -- a-addr2 )
\r
545 \ Display name of a xt if xt is valid and display string
\r
546 \ constant and adjust a-addr1 to the end of string if xt is
\r
547 \ not POSTPONEd 'doS"' ; otherwise display the xt as a number.
\r
548 CHAR " PARSE model" ENVIRONMENT? DROP
\r
549 CHAR " PARSE ROM Model" COMPARE 0=
\r
550 CHAR " PARSE model" ENVIRONMENT? DROP
\r
551 CHAR " PARSE RAM Model" COMPARE 0= OR
\r
555 IF DUP xt>name ?DUP
\r
556 IF .name DUP >R ['] doS" =
\r
557 IF DUP cell- @ ['] doLIT XOR
\r
558 IF DUP CELL+ SWAP cell- @ 2DUP TYPE + ALIGNED
\r
559 cell- [CHAR] " EMIT SPACE THEN THEN
\r
560 R> DUP ['] branch = OVER ['] 0branch = OR
\r
561 OVER ['] doLOOP = OR SWAP ['] do+LOOP = OR
\r
562 IF DUP cell- @ ['] doLIT XOR
\r
563 IF CELL+ DUP @ OVER CELL+ - . THEN THEN
\r
568 CHAR " PARSE model" ENVIRONMENT? DROP
\r
569 CHAR " PARSE EXE Model" COMPARE 0=
\r
573 IF DUP xt>name ?DUP
\r
575 DUP ['] branch = OVER ['] 0branch = OR
\r
576 OVER ['] doLOOP = OR SWAP ['] do+LOOP = OR
\r
577 IF DUP cell- code@ ['] doLIT XOR
\r
578 IF CELL+ DUP code@ OVER CELL+ - . THEN THEN
\r
585 \ Display human-readable representation of xt.
\r
586 CHAR " PARSE model" ENVIRONMENT? DROP
\r
587 CHAR " PARSE ROM Model" COMPARE 0=
\r
589 : xtSEE >R lastName
\r
590 BEGIN DUP COUNT 31 AND + ALIGNED CELL+ CELL+ \ na na'
\r
593 REPEAT DROP name>xt R>
\r
594 2DUP U> 0= IF NIP xhere SWAP THEN \ end-of-code xt
\r
597 IF ." call-" .xt THEN
\r
598 DUP @ .xt enough? 0=
\r
599 WHILE CELL+ 2DUP U> 0=
\r
600 UNTIL THEN 2DROP R> BASE ! ;
\r
602 CHAR " PARSE model" ENVIRONMENT? DROP
\r
603 CHAR " PARSE RAM Model" COMPARE 0=
\r
605 \ Following definition is less dependent on dictionary structure although
\r
606 \ slower. It only assumes xt of a word is larger than xt of previously
\r
607 \ defined words. This works for ROM model also.
\r
608 : xtSEE >R xhere >R \ Search all wordlist to find end of xt.
\r
609 FORTH-WORDLIST \ Find smallest link pointer larger than xt.
\r
612 WHILE DUP name>xt R@ U<
\r
613 IF R> OVER name>xt R@ U>
\r
614 IF DROP DUP name>xt THEN
\r
619 CELL+ @ ?DUP 0= \ continue to next wordlist
\r
620 UNTIL R> R> \ end-of-code xt
\r
623 IF ." call-" .xt THEN
\r
624 DUP @ .xt enough? 0=
\r
625 WHILE CELL+ 2DUP U> 0=
\r
626 UNTIL THEN 2DROP R> BASE ! ;
\r
628 CHAR " PARSE model" ENVIRONMENT? DROP
\r
629 CHAR " PARSE EXE Model" COMPARE 0=
\r
631 \ Following definition is less dependent on dictionary structure although
\r
632 \ slower. It only assumes xt of a word is larger than xt of previously
\r
633 \ defined words. This works for ROM model also.
\r
634 : xtSEE >R xhere >R \ Search all wordlist to find end of xt.
\r
635 FORTH-WORDLIST \ Find smallest link pointer larger than xt.
\r
638 WHILE DUP name>xt R@ U<
\r
639 IF R> OVER name>xt R@ U>
\r
640 IF DROP DUP name>xt THEN
\r
645 CELL+ @ ?DUP 0= \ continue to next wordlist
\r
646 UNTIL R> R> \ end-of-code xt
\r
649 IF ." call-" .xt THEN
\r
650 DUP code@ .xt enough? 0=
\r
651 WHILE CELL+ 2DUP U> 0=
\r
652 UNTIL THEN 2DROP R> BASE ! ;
\r
655 FORTH-WORDLIST SET-CURRENT
\r
657 \ SEE ( "<spaces>name" -- ) \ TOOLS
\r
658 \ Display human-readable representation of the name's definition.
\r
659 : SEE (') 1+ IF ." IMMEDIATE-word" THEN xtSEE ;
\r
661 NONSTANDARD-WORDLIST SET-CURRENT
\r
663 \ WORDLIST-WORDS ( wid -- )
\r
664 \ List the definition names in wordlist identified by wid.
\r
668 WHILE DUP .name R> 1+ >R
\r
669 cell- \ pointer to next word
\r
671 THEN SPACE R> . ." words " ;
\r
673 \ NONSTANDARD-WORDS ( -- )
\r
674 \ List the definition names in NONSTANDARD-WORDLIST.
\r
675 : NONSTANDARD-WORDS NONSTANDARD-WORDLIST WORDLIST-WORDS ;
\r
677 FORTH-WORDLIST SET-CURRENT
\r
679 \ WORDS ( -- ) \ TOOLS
\r
680 \ List the definition names in the first wordlist of the
\r
682 : WORDS #order CELL+ @ WORDLIST-WORDS ;
\r
684 envQList SET-CURRENT
\r
686 FORTH-WORDLIST SET-CURRENT
\r
688 \ **********************
\r
689 \ Nonstandard system utility word
\r
690 \ **********************
\r
692 NONSTANDARD-WORDLIST SET-CURRENT
\r
694 \ SAVE-SYSTEM ( -- )
\r
695 \ Save current state of the system. There must be a way
\r
696 \ to preserve the memory image. Use non-volatile RAM or
\r
697 \ DEBUG.EXE to store the image in MS-DOS.
\r
699 CHAR " PARSE model" ENVIRONMENT? DROP
\r
700 CHAR " PARSE ROM Model" COMPARE 0=
\r
703 var0 sysVar0 [ sysVar0End sysVar0 - ] LITERAL MOVE ;
\r
705 CHAR " PARSE model" ENVIRONMENT? DROP
\r
706 CHAR " PARSE RAM Model" COMPARE 0=
\r
709 #order DUP @ #order0 SWAP 1+ CELLS MOVE ;
\r
712 CHAR " PARSE model" ENVIRONMENT? DROP
\r
713 CHAR " PARSE ROM Model" COMPARE 0=
\r
716 \ **********************
\r
717 \ RAM/ROM System Only
\r
718 \ **********************
\r
721 \ Set data space in RAM area.
\r
722 : RAM RAMB TO hereVar ;
\r
725 \ Set data space in ROM area.
\r
726 : ROM ROMB TO hereVar ;
\r
728 \ RAM/ROM@ ( -- ram/rom-id )
\r
729 \ Return RAM/ROM identifier which will be consumed by RAM/ROM!
\r
730 : RAM/ROM@ hereVar ;
\r
732 \ RAM/ROM! ( ram/rom-id -- )
\r
733 \ Set HERE according to RAM/ROM identifier on the stack.
\r
734 : RAM/ROM! TO hereVar ;
\r
738 \ Compile unconditional jump to the start of the current
\r
739 \ definition. Described by Dr. Astle in Forth Dimensions
\r
740 \ 17(4), 19-21 (1995).
\r
741 : RETRY bal 1- 2* PICK 1+ IF -22 THROW THEN
\r
742 \ control structure mismatch; colon-sys type is -1
\r
743 bal 1- 2* 1+ PICK \ xt of current definition
\r
744 ?call DROP POSTPONE branch COMPILE, ; IMMEDIATE COMPILE-ONLY
\r
746 CHAR " PARSE model" ENVIRONMENT? DROP
\r
747 CHAR " PARSE EXE Model" COMPARE 0=
\r
750 \ Structure of CREATEd word:
\r
751 \ |compile_xt|name_ptr| call-doCREATE | 0 or DOES>_xt | a-addr |
\r
753 lastName DUP C@ 128 ( =seman) <
\r
754 IF -12 THROW THEN \ argument type mismatch
\r
755 name>xt cell- cell- code! ;
\r
756 \ compiles> ( xt colon-sys -- colon-sys )
\r
757 \ Assign xt as special compilation action of the last CREATEd
\r
758 \ word. It is the user's responsibility to match the special
\r
759 \ compilation action and the execution action.
\r
760 \ Example: '2CONSTANT' can be defined as following:
\r
761 \ :NONAME EXECUTE POSTPONE 2LITERAL ;
\r
762 \ : 2CONSTANT CREATE SWAP , , compiles> DOES> DUP @ SWAP CELL+ @ ;
\r
763 : compiles> ROT POSTPONE LITERAL POSTPONE doCompiles> ; IMMEDIATE
\r
766 FORTH-WORDLIST SET-CURRENT
\r
770 CHAR " PARSE FILE" ENVIRONMENT?
\r
772 0= [IF] << CON [THEN]
\r