PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/fth/system.fth

https://github.com/cataska/pforth
Forth | 827 lines | 673 code | 148 blank | 6 comment | 14 complexity | a5700c70da331fee669dfa424aa48391 MD5 | raw file
  1. : FIRST_COLON ;
  2. : LATEST context @ ;
  3. : FLAG_IMMEDIATE 64 ;
  4. : IMMEDIATE
  5. latest dup c@ flag_immediate OR
  6. swap c!
  7. ;
  8. : ( 41 word drop ; immediate
  9. ( That was the definition for the comment word. )
  10. ( Now we can add comments to what we are doing! )
  11. ( Note that we are in decimal numeric input mode. )
  12. : \ ( <line> -- , comment out rest of line )
  13. EOL word drop
  14. ; immediate
  15. \ *********************************************************************
  16. \ This is another style of comment that is common in Forth.
  17. \ pFORTH - Portable Forth System
  18. \ Based on HMSL Forth
  19. \
  20. \ Author: Phil Burk
  21. \ Copyright 1994 3DO, Phil Burk, Larry Polansky, Devid Rosenboom
  22. \
  23. \ The pForth software code is dedicated to the public domain,
  24. \ and any third party may reproduce, distribute and modify
  25. \ the pForth software code or any derivative works thereof
  26. \ without any compensation or license. The pForth software
  27. \ code is provided on an "as is" basis without any warranty
  28. \ of any kind, including, without limitation, the implied
  29. \ warranties of merchantability and fitness for a particular
  30. \ purpose and their equivalents under the laws of any jurisdiction.
  31. \ *********************************************************************
  32. : COUNT dup 1+ swap c@ ;
  33. \ Miscellaneous support words
  34. : ON ( addr -- , set true )
  35. -1 swap !
  36. ;
  37. : OFF ( addr -- , set false )
  38. 0 swap !
  39. ;
  40. \ size of data items
  41. \ FIXME - move these into 'C' code for portability ????
  42. : CELL ( -- size_of_stack_item ) 4 ;
  43. : CELL+ ( n -- n+cell ) cell + ;
  44. : CELL- ( n -- n+cell ) cell - ;
  45. : CELLS ( n -- n*cell ) 2 lshift ;
  46. : CHAR+ ( n -- n+size_of_char ) 1+ ;
  47. : CHARS ( n -- n*size_of_char , don't do anything) ; immediate
  48. \ useful stack manipulation words
  49. : -ROT ( a b c -- c a b )
  50. rot rot
  51. ;
  52. : 3DUP ( a b c -- a b c a b c )
  53. 2 pick 2 pick 2 pick
  54. ;
  55. : 2DROP ( a b -- )
  56. drop drop
  57. ;
  58. : NIP ( a b -- b )
  59. swap drop
  60. ;
  61. : TUCK ( a b -- b a b )
  62. swap over
  63. ;
  64. : <= ( a b -- f , true if A <= b )
  65. > 0=
  66. ;
  67. : >= ( a b -- f , true if A >= b )
  68. < 0=
  69. ;
  70. : INVERT ( n -- 1'comp )
  71. -1 xor
  72. ;
  73. : NOT ( n -- !n , logical negation )
  74. 0=
  75. ;
  76. : NEGATE ( n -- -n )
  77. 0 swap -
  78. ;
  79. : DNEGATE ( d -- -d , negate by doing 0-d )
  80. 0 0 2swap d-
  81. ;
  82. \ --------------------------------------------------------------------
  83. : ID. ( nfa -- )
  84. count 31 and type
  85. ;
  86. : DECIMAL 10 base ! ;
  87. : OCTAL 8 base ! ;
  88. : HEX 16 base ! ;
  89. : BINARY 2 base ! ;
  90. : PAD ( -- addr )
  91. here 128 +
  92. ;
  93. : $MOVE ( $src $dst -- )
  94. over c@ 1+ cmove
  95. ;
  96. : BETWEEN ( n lo hi -- flag , true if between lo & hi )
  97. >r over r> > >r
  98. < r> or 0=
  99. ;
  100. : [ ( -- , enter interpreter mode )
  101. 0 state !
  102. ; immediate
  103. : ] ( -- enter compile mode )
  104. 1 state !
  105. ;
  106. : EVEN-UP ( n -- n | n+1 , make even ) dup 1 and + ;
  107. : ALIGNED ( addr -- a-addr )
  108. [ cell 1- ] literal +
  109. [ cell 1- invert ] literal and
  110. ;
  111. : ALIGN ( -- , align DP ) dp @ aligned dp ! ;
  112. : ALLOT ( nbytes -- , allot space in dictionary ) dp +! ( align ) ;
  113. : C, ( c -- ) here c! 1 chars dp +! ;
  114. : W, ( w -- ) dp @ even-up dup dp ! w! 2 chars dp +! ;
  115. : , ( n -- , lay into dictionary ) align here ! cell allot ;
  116. \ Dictionary conversions ------------------------------------------
  117. : N>NEXTLINK ( nfa -- nextlink , traverses name field )
  118. dup c@ 31 and 1+ + aligned
  119. ;
  120. : NAMEBASE ( -- base-of-names )
  121. Headers-Base @
  122. ;
  123. : CODEBASE ( -- base-of-code dictionary )
  124. Code-Base @
  125. ;
  126. : NAMELIMIT ( -- limit-of-names )
  127. Headers-limit @
  128. ;
  129. : CODELIMIT ( -- limit-of-code, last address in dictionary )
  130. Code-limit @
  131. ;
  132. : NAMEBASE+ ( rnfa -- nfa , convert relocatable nfa to actual )
  133. namebase +
  134. ;
  135. : >CODE ( xt -- secondary_code_address, not valid for primitives )
  136. codebase +
  137. ;
  138. : CODE> ( secondary_code_address -- xt , not valid for primitives )
  139. codebase -
  140. ;
  141. : N>LINK ( nfa -- lfa )
  142. 8 -
  143. ;
  144. : >BODY ( xt -- pfa )
  145. >code body_offset +
  146. ;
  147. : BODY> ( pfa -- xt )
  148. body_offset - code>
  149. ;
  150. \ convert between addresses useable by @, and relocatable addresses.
  151. : USE->REL ( useable_addr -- rel_addr )
  152. codebase -
  153. ;
  154. : REL->USE ( rel_addr -- useable_addr )
  155. codebase +
  156. ;
  157. \ for JForth code
  158. \ : >REL ( adr -- adr ) ; immediate
  159. \ : >ABS ( adr -- adr ) ; immediate
  160. : X@ ( addr -- xt , fetch execution token from relocatable ) @ ;
  161. : X! ( addr -- xt , store execution token as relocatable ) ! ;
  162. \ Compiler support ------------------------------------------------
  163. : COMPILE, ( xt -- , compile call to xt )
  164. ,
  165. ;
  166. ( Compiler support , based on FIG )
  167. : [COMPILE] ( <name> -- , compile now even if immediate )
  168. ' compile,
  169. ; IMMEDIATE
  170. : (COMPILE) ( xt -- , postpone compilation of token )
  171. [compile] literal ( compile a call to literal )
  172. ( store xt of word to be compiled )
  173. [ ' compile, ] literal \ compile call to compile,
  174. compile,
  175. ;
  176. : COMPILE ( <name> -- , save xt and compile later )
  177. ' (compile)
  178. ; IMMEDIATE
  179. : :NONAME ( -- xt , begin compilation of headerless secondary )
  180. align
  181. here code> \ convert here to execution token
  182. ]
  183. ;
  184. \ Error codes defined in ANSI Exception word set.
  185. : ERR_ABORT -1 ; \ general abort
  186. : ERR_EXECUTING -14 ; \ compile time word while not compiling
  187. : ERR_PAIRS -22 ; \ mismatch in conditional
  188. : ERR_DEFER -258 ; \ not a deferred word
  189. : ABORT ( i*x -- )
  190. ERR_ABORT throw
  191. ;
  192. \ Conditionals in '83 form -----------------------------------------
  193. : CONDITIONAL_KEY ( -- , lazy constant ) 29521 ;
  194. : ?CONDITION ( f -- ) conditional_key - err_pairs ?error ;
  195. : >MARK ( -- addr ) here 0 , ;
  196. : >RESOLVE ( addr -- ) here over - swap ! ;
  197. : <MARK ( -- addr ) here ;
  198. : <RESOLVE ( addr -- ) here - , ;
  199. : ?COMP ( -- , error if not compiling )
  200. state @ 0= err_executing ?error
  201. ;
  202. : ?PAIRS ( n m -- )
  203. - err_pairs ?error
  204. ;
  205. \ conditional primitives
  206. : IF ( -- f orig ) ?comp compile 0branch conditional_key >mark ; immediate
  207. : THEN ( f orig -- ) swap ?condition >resolve ; immediate
  208. : BEGIN ( -- f dest ) ?comp conditional_key <mark ; immediate
  209. : AGAIN ( f dest -- ) compile branch swap ?condition <resolve ; immediate
  210. : UNTIL ( f dest -- ) compile 0branch swap ?condition <resolve ; immediate
  211. : AHEAD ( -- f orig ) compile branch conditional_key >mark ; immediate
  212. \ conditionals built from primitives
  213. : ELSE ( f orig1 -- f orig2 )
  214. [compile] AHEAD 2swap [compile] THEN ; immediate
  215. : WHILE ( f dest -- f orig f dest ) [compile] if 2swap ; immediate
  216. : REPEAT ( -- f orig f dest ) [compile] again [compile] then ; immediate
  217. : ['] ( <name> -- xt , define compile time tick )
  218. ?comp ' [compile] literal
  219. ; immediate
  220. \ for example:
  221. \ compile time: compile create , (does>) then ;
  222. \ execution time: create <name>, ',' data, then patch pi to point to @
  223. \ : con create , does> @ ;
  224. \ 345 con pi
  225. \ pi
  226. \
  227. : (DOES>) ( xt -- , modify previous definition to execute code at xt )
  228. latest name> >code \ get address of code for new word
  229. cell + \ offset to second cell in create word
  230. ! \ store execution token of DOES> code in new word
  231. ;
  232. : DOES> ( -- , define execution code for CREATE word )
  233. 0 [compile] literal \ dummy literal to hold xt
  234. here cell- \ address of zero in literal
  235. compile (does>) \ call (DOES>) from new creation word
  236. >r \ move addrz to return stack so ; doesn't see stack garbage
  237. [compile] ; \ terminate part of code before does>
  238. r>
  239. :noname ( addrz xt )
  240. swap ! \ save execution token in literal
  241. ; immediate
  242. : VARIABLE ( <name> -- )
  243. CREATE 0 , \ IMMEDIATE
  244. \ DOES> [compile] aliteral \ %Q This could be optimised
  245. ;
  246. : 2VARIABLE ( <name> -c- ) ( -x- addr )
  247. create 0 , 0 ,
  248. ;
  249. : CONSTANT ( n <name> -c- ) ( -x- n )
  250. CREATE , ( n -- )
  251. DOES> @ ( -- n )
  252. ;
  253. 0 1- constant -1
  254. 0 2- constant -2
  255. : 2! ( x1 x2 addr -- , store x2 followed by x1 )
  256. swap over ! cell+ !
  257. ;
  258. : 2@ ( addr -- x1 x2 )
  259. dup cell+ @ swap @
  260. ;
  261. : ABS ( n -- |n| )
  262. dup 0<
  263. IF negate
  264. THEN
  265. ;
  266. : DABS ( d -- |d| )
  267. dup 0<
  268. IF dnegate
  269. THEN
  270. ;
  271. : S>D ( s -- d , extend signed single precision to double )
  272. dup 0<
  273. IF -1
  274. ELSE 0
  275. THEN
  276. ;
  277. : D>S ( d -- s ) drop ;
  278. : /MOD ( a b -- rem quo , unsigned version, FIXME )
  279. >r s>d r> um/mod
  280. ;
  281. : MOD ( a b -- rem )
  282. /mod drop
  283. ;
  284. : 2* ( n -- n*2 )
  285. 1 lshift
  286. ;
  287. : 2/ ( n -- n/2 )
  288. 1 arshift
  289. ;
  290. : D2* ( d -- d*2 )
  291. 2* over 31 rshift or swap
  292. 2* swap
  293. ;
  294. \ define some useful constants ------------------------------
  295. 1 0= constant FALSE
  296. 0 0= constant TRUE
  297. 32 constant BL
  298. \ Store and Fetch relocatable data addresses. ---------------
  299. : IF.USE->REL ( use -- rel , preserve zero )
  300. dup IF use->rel THEN
  301. ;
  302. : IF.REL->USE ( rel -- use , preserve zero )
  303. dup IF rel->use THEN
  304. ;
  305. : A! ( dictionary_address addr -- )
  306. >r if.use->rel r> !
  307. ;
  308. : A@ ( addr -- dictionary_address )
  309. @ if.rel->use
  310. ;
  311. : A, ( dictionary_address -- )
  312. if.use->rel ,
  313. ;
  314. \ Stack data structure ----------------------------------------
  315. \ This is a general purpose stack utility used to implement necessary
  316. \ stacks for the compiler or the user. Not real fast.
  317. \ These stacks grow up which is different then normal.
  318. \ cell 0 - stack pointer, offset from pfa of word
  319. \ cell 1 - limit for range checking
  320. \ cell 2 - first data location
  321. : :STACK ( #cells -- )
  322. CREATE 2 cells , ( offset of first data location )
  323. dup , ( limit for range checking, not currently used )
  324. cells cell+ allot ( allot an extra cell for safety )
  325. ;
  326. : >STACK ( n stack -- , push onto stack, postincrement )
  327. dup @ 2dup cell+ swap ! ( -- n stack offset )
  328. + !
  329. ;
  330. : STACK> ( stack -- n , pop , predecrement )
  331. dup @ cell- 2dup swap !
  332. + @
  333. ;
  334. : STACK@ ( stack -- n , copy )
  335. dup @ cell- + @
  336. ;
  337. : STACK.PICK ( index stack -- n , grab Nth from top of stack )
  338. dup @ cell- +
  339. swap cells - \ offset for index
  340. @
  341. ;
  342. : STACKP ( stack -- ptr , to next empty location on stack )
  343. dup @ +
  344. ;
  345. : 0STACKP ( stack -- , clear stack)
  346. 8 swap !
  347. ;
  348. 32 :stack ustack
  349. ustack 0stackp
  350. \ Define JForth like words.
  351. : >US ustack >stack ;
  352. : US> ustack stack> ;
  353. : US@ ustack stack@ ;
  354. : 0USP ustack 0stackp ;
  355. \ DO LOOP ------------------------------------------------
  356. 3 constant do_flag
  357. 4 constant leave_flag
  358. 5 constant ?do_flag
  359. : DO ( -- , loop-back do_flag jump-from ?do_flag )
  360. ?comp
  361. compile (do)
  362. here >us do_flag >us ( for backward branch )
  363. ; immediate
  364. : ?DO ( -- , loop-back do_flag jump-from ?do_flag , on user stack )
  365. ?comp
  366. ( leave address to set for forward branch )
  367. compile (?do)
  368. here 0 ,
  369. here >us do_flag >us ( for backward branch )
  370. >us ( for forward branch ) ?do_flag >us
  371. ; immediate
  372. : LEAVE ( -- addr leave_flag )
  373. compile (leave)
  374. here 0 , >us
  375. leave_flag >us
  376. ; immediate
  377. : LOOP-FORWARD ( -us- jump-from ?do_flag -- )
  378. BEGIN
  379. us@ leave_flag =
  380. us@ ?do_flag =
  381. OR
  382. WHILE
  383. us> leave_flag =
  384. IF
  385. us> here over - cell+ swap !
  386. ELSE
  387. us> dup
  388. here swap -
  389. cell+ swap !
  390. THEN
  391. REPEAT
  392. ;
  393. : LOOP-BACK ( loop-addr do_flag -us- )
  394. us> do_flag ?pairs
  395. us> here - here
  396. !
  397. cell allot
  398. ;
  399. : LOOP ( -- , loop-back do_flag jump-from ?do_flag )
  400. compile (loop)
  401. loop-forward loop-back
  402. ; immediate
  403. \ : DOTEST 5 0 do 333 . loop 888 . ;
  404. \ : ?DOTEST0 0 0 ?do 333 . loop 888 . ;
  405. \ : ?DOTEST1 5 0 ?do 333 . loop 888 . ;
  406. : +LOOP ( -- , loop-back do_flag jump-from ?do_flag )
  407. compile (+loop)
  408. loop-forward loop-back
  409. ; immediate
  410. : UNLOOP ( loop-sys -r- )
  411. r> \ save return pointer
  412. rdrop rdrop
  413. >r
  414. ;
  415. : RECURSE ( ? -- ? , call the word currently being defined )
  416. latest name> compile,
  417. ; immediate
  418. : SPACE bl emit ;
  419. : SPACES 512 min 0 max 0 ?DO space LOOP ;
  420. : 0SP depth 0 ?do drop loop ;
  421. : >NEWLINE ( -- , CR if needed )
  422. out @ 0>
  423. IF cr
  424. THEN
  425. ;
  426. \ Support for DEFER --------------------
  427. : CHECK.DEFER ( xt -- , error if not a deferred word by comparing to type )
  428. >code @
  429. ['] emit >code @
  430. - err_defer ?error
  431. ;
  432. : >is ( xt -- address_of_vector )
  433. >code
  434. cell +
  435. ;
  436. : (IS) ( xt_do xt_deferred -- )
  437. >is !
  438. ;
  439. : IS ( xt <name> -- , act like normal IS )
  440. ' \ xt
  441. dup check.defer
  442. state @
  443. IF [compile] literal compile (is)
  444. ELSE (is)
  445. THEN
  446. ; immediate
  447. : (WHAT'S) ( xt -- xt_do )
  448. >is @
  449. ;
  450. : WHAT'S ( <name> -- xt , what will deferred word call? )
  451. ' \ xt
  452. dup check.defer
  453. state @
  454. IF [compile] literal compile (what's)
  455. ELSE (what's)
  456. THEN
  457. ; immediate
  458. : /STRING ( addr len n -- addr' len' )
  459. over min rot over + -rot -
  460. ;
  461. : PLACE ( addr len to -- , move string )
  462. 3dup 1+ swap cmove c! drop
  463. ;
  464. : PARSE-WORD ( char -- addr len )
  465. >r source tuck >in @ /string r@ skip over swap r> scan
  466. >r over - rot r> dup 0<> + - >in !
  467. ;
  468. : PARSE ( char -- addr len )
  469. >r source >in @ /string over swap r> scan
  470. >r over - dup r> 0<> - >in +!
  471. ;
  472. : LWORD ( char -- addr )
  473. parse-word here place here \ 00002 , use PARSE-WORD
  474. ;
  475. : ASCII ( <char> -- char , state smart )
  476. bl parse drop c@
  477. state @
  478. IF [compile] literal
  479. THEN
  480. ; immediate
  481. : CHAR ( <char> -- char , interpret mode )
  482. bl parse drop c@
  483. ;
  484. : [CHAR] ( <char> -- char , for compile mode )
  485. char [compile] literal
  486. ; immediate
  487. : $TYPE ( $string -- )
  488. count type
  489. ;
  490. : 'word ( -- addr ) here ;
  491. : EVEN ( addr -- addr' ) dup 1 and + ;
  492. : (C") ( -- $addr , some Forths return addr AND count, OBSOLETE?)
  493. r> dup count + aligned >r
  494. ;
  495. : (S") ( -- c-addr cnt )
  496. r> count 2dup + aligned >r
  497. ;
  498. : (.") ( -- , type following string )
  499. r> count 2dup + aligned >r type
  500. ;
  501. : ", ( adr len -- , place string into dictionary )
  502. tuck 'word place 1+ allot align
  503. ;
  504. : ," ( -- )
  505. [char] " parse ",
  506. ;
  507. : .( ( <string> -- , type string delimited by parentheses )
  508. [CHAR] ) PARSE TYPE
  509. ; IMMEDIATE
  510. : ." ( <string> -- , type string )
  511. state @
  512. IF compile (.") ,"
  513. ELSE [char] " parse type
  514. THEN
  515. ; immediate
  516. : .' ( <string> -- , type string delimited by single quote )
  517. state @
  518. IF compile (.") [char] ' parse ",
  519. ELSE [char] ' parse type
  520. THEN
  521. ; immediate
  522. : C" ( <string> -- addr , return string address, ANSI )
  523. state @
  524. IF compile (c") ,"
  525. ELSE [char] " parse pad place pad
  526. THEN
  527. ; immediate
  528. : S" ( <string> -- , -- addr , return string address, ANSI )
  529. state @
  530. IF compile (s") ,"
  531. ELSE [char] " parse pad place pad count
  532. THEN
  533. ; immediate
  534. : " ( <string> -- , -- addr , return string address )
  535. [compile] C"
  536. ; immediate
  537. : P" ( <string> -- , -- addr , return string address )
  538. [compile] C"
  539. ; immediate
  540. : "" ( <string> -- addr )
  541. state @
  542. IF
  543. compile (C")
  544. bl parse-word ",
  545. ELSE
  546. bl parse-word pad place pad
  547. THEN
  548. ; immediate
  549. : SLITERAL ( addr cnt -- , compile string )
  550. compile (S")
  551. ",
  552. ; IMMEDIATE
  553. : $APPEND ( addr count $1 -- , append text to $1 )
  554. over >r
  555. dup >r
  556. count + ( -- a2 c2 end1 )
  557. swap cmove
  558. r> dup c@ ( a1 c1 )
  559. r> + ( -- a1 totalcount )
  560. swap c!
  561. ;
  562. \ ANSI word to replace [COMPILE] and COMPILE ----------------
  563. : POSTPONE ( <name> -- )
  564. bl word find
  565. dup 0=
  566. IF
  567. ." Postpone could not find " count type cr abort
  568. ELSE
  569. 0>
  570. IF compile, \ immediate
  571. ELSE (compile) \ normal
  572. THEN
  573. THEN
  574. ; immediate
  575. \ -----------------------------------------------------------------
  576. \ Auto Initialization
  577. : AUTO.INIT ( -- )
  578. \ Kernel finds AUTO.INIT and executes it after loading dictionary.
  579. \ ." Begin AUTO.INIT ------" cr
  580. ;
  581. : AUTO.TERM ( -- )
  582. \ Kernel finds AUTO.TERM and executes it on bye.
  583. \ ." End AUTO.TERM ------" cr
  584. ;
  585. \ -------------- INCLUDE ------------------------------------------
  586. variable TRACE-INCLUDE
  587. : INCLUDE.MARK.START ( $filename -- , mark start of include for FILE?)
  588. " ::::" pad $MOVE
  589. count pad $APPEND
  590. pad ['] noop (:)
  591. ;
  592. : INCLUDE.MARK.END ( -- , mark end of include )
  593. " ;;;;" ['] noop (:)
  594. ;
  595. : $INCLUDE ( $filename -- )
  596. \ Print messages.
  597. trace-include @
  598. IF
  599. >newline ." Include " dup count type cr
  600. THEN
  601. here >r
  602. dup
  603. count r/o open-file
  604. IF ( -- $filename bad-fid )
  605. drop ." Could not find file " $type cr abort
  606. ELSE ( -- $filename good-fid )
  607. swap include.mark.start
  608. dup >r \ save fid for close-file
  609. depth >r
  610. include-file
  611. depth 1+ r> -
  612. IF
  613. ." Warning: stack depth changed during include!" cr
  614. .s cr
  615. 0sp
  616. THEN
  617. r> close-file drop
  618. include.mark.end
  619. THEN
  620. trace-include @
  621. IF
  622. ." include added " here r@ - . ." bytes,"
  623. codelimit here - . ." left." cr
  624. THEN
  625. rdrop
  626. ;
  627. create INCLUDE-SAVE-NAME 128 allot
  628. : INCLUDE ( <fname> -- )
  629. BL lword
  630. dup include-save-name $move \ save for RI
  631. $include
  632. ;
  633. : RI ( -- , ReInclude previous file as a convenience )
  634. include-save-name $include
  635. ;
  636. : INCLUDE? ( <word> <file> -- , load file if word not defined )
  637. bl word find
  638. IF drop bl word drop ( eat word from source )
  639. ELSE drop include
  640. THEN
  641. ;
  642. \ desired sizes for dictionary loaded after SAVE-FORTH
  643. variable HEADERS-SIZE
  644. variable CODE-SIZE
  645. : AUTO.INIT
  646. auto.init
  647. codelimit codebase - code-size !
  648. namelimit namebase - headers-size !
  649. ;
  650. auto.init
  651. : SAVE-FORTH ( $name -- )
  652. 0 \ Entry point
  653. headers-ptr @ namebase - 65536 + \ NameSize
  654. headers-size @ MAX
  655. here codebase - 131072 + \ CodeSize
  656. code-size @ MAX
  657. (save-forth)
  658. IF
  659. ." SAVE-FORTH failed!" cr abort
  660. THEN
  661. ;
  662. : TURNKEY ( $name entry-token-- )
  663. 0 \ NameSize = 0, names not saved in turnkey dictionary
  664. here codebase - 131072 + \ CodeSize, remember that base is HEX
  665. (save-forth)
  666. IF
  667. ." TURNKEY failed!" cr abort
  668. THEN
  669. ;
  670. \ load remainder of dictionary
  671. trace-include on
  672. trace-stack on
  673. include loadp4th.fth
  674. decimal
  675. : ;;;; ; \ Mark end of this file so FILE? can find things in here.
  676. FREEZE \ prevent forgetting below this point
  677. .( Dictionary compiled, save in "pforth.dic".) cr
  678. c" pforth.dic" save-forth
  679. SDAD