File:
[gforth] /
gforth /
kernel /
int.fs
Revision
1.31:
download - view:
text,
annotated -
select for diffs
Thu May 6 21:33:36 1999 UTC (24 years, 11 months ago) by
crook
Branches:
MAIN
CVS tags:
HEAD
Major re-write of manual sections concerning text interpreter and
defining words. Much fine-tuning of other sections. The manual is
``nearly finished'' -- at least, all the major pieces of work that
I envisaged for the first mods (which were only going to take a
couple of weeks...). The manual has grown from 127 pages to 192
which is good news in terms of content but bad news in terms of the
time it takes to print out on my HP550C DeskJet.
Other changes are just tweaks to glossary entries.
1: \ definitions needed for interpreter only
2:
3: \ Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
4:
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: \ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20:
21: \ \ Revision-Log
22:
23: \ put in seperate file 14sep97jaw
24:
25: \ \ input stream primitives 23feb93py
26:
27: : tib ( -- c-addr ) \ core-ext
28: \G @var{c-addr} is the address of the Terminal Input Buffer.
29: \G OBSOLESCENT: @code{source} superceeds the function of this word.
30: >tib @ ;
31:
32: Defer source ( -- c-addr u ) \ core
33: \ used by dodefer:, must be defer
34: \G @var{c-addr} is the address of the input buffer and @var{u} is the
35: \G number of characters in it.
36:
37: : (source) ( -- c-addr u )
38: tib #tib @ ;
39: ' (source) IS source
40:
41: : (word) ( addr1 n1 char -- addr2 n2 )
42: dup >r skip 2dup r> scan nip - ;
43:
44: \ (word) should fold white spaces
45: \ this is what (parse-white) does
46:
47: \ word parse 23feb93py
48:
49: : sword ( char -- addr len ) \ gforth s-word
50: \G Parses like @code{word}, but the output is like @code{parse} output
51: \ this word was called PARSE-WORD until 0.3.0, but Open Firmware and
52: \ dpANS6 A.6.2.2008 have a word with that name that behaves
53: \ differently (like NAME).
54: source 2dup >r >r >in @ over min /string
55: rot dup bl = IF drop (parse-white) ELSE (word) THEN
56: 2dup + r> - 1+ r> min >in ! ;
57:
58: : word ( char "<chars>ccc<char>-- c-addr ) \ core
59: \G Skip leading delimiters. Parse @var{ccc}, delimited by
60: \G @var{char}, in the parse area. @var{c-addr} is the addres of a
61: \G transient region containing the parsed string in
62: \G counted-strinng format. If the parse area was empty or
63: \G contained no characters other than delimiters, the resulting
64: \G string has zero length. A program may replace characters within
65: \G the counted string. OBSOLESCENT: the counted string has a
66: \G trailing space that is not included in its length.
67: sword here place bl here count + c! here ;
68:
69: : parse ( char "ccc<char>" -- c-addr u ) \ core-ext
70: \G Parse @var{ccc}, delimited by @var{char}, in the parse
71: \G area. @var{c-addr u} specifies the parsed string within the
72: \G parse area. If the parse area was empty, @var{u} is 0.
73: >r source >in @ over min /string over swap r> scan >r
74: over - dup r> IF 1+ THEN >in +! ;
75:
76: \ name 13feb93py
77:
78: [IFUNDEF] (name) \ name might be a primitive
79:
80: : (name) ( -- c-addr count )
81: source 2dup >r >r >in @ /string (parse-white)
82: 2dup + r> - 1+ r> min >in ! ;
83: \ name count ;
84: [THEN]
85:
86: : name-too-short? ( c-addr u -- c-addr u )
87: dup 0= -&16 and throw ;
88:
89: : name-too-long? ( c-addr u -- c-addr u )
90: dup $1F u> -&19 and throw ;
91:
92: \ \ Number parsing 23feb93py
93:
94: \ number? number 23feb93py
95:
96: hex
97: const Create bases 10 , 2 , A , 100 ,
98: \ 16 2 10 character
99:
100: \ !! protect BASE saving wrapper against exceptions
101: : getbase ( addr u -- addr' u' )
102: over c@ [char] $ - dup 4 u<
103: IF
104: cells bases + @ base ! 1 /string
105: ELSE
106: drop
107: THEN ;
108:
109: : sign? ( addr u -- addr u flag )
110: over c@ '- = dup >r
111: IF
112: 1 /string
113: THEN
114: r> ;
115:
116: : s>unumber? ( addr u -- ud flag )
117: base @ >r dpl on getbase
118: 0. 2swap
119: BEGIN ( d addr len )
120: dup >r >number dup
121: WHILE \ there are characters left
122: dup r> -
123: WHILE \ the last >number parsed something
124: dup 1- dpl ! over c@ [char] . =
125: WHILE \ the current char is '.'
126: 1 /string
127: REPEAT THEN \ there are unparseable characters left
128: 2drop false
129: ELSE
130: rdrop 2drop true
131: THEN
132: r> base ! ;
133:
134: \ ouch, this is complicated; there must be a simpler way - anton
135: : s>number? ( addr len -- d f )
136: \ converts string addr len into d, flag indicates success
137: sign? >r
138: s>unumber?
139: 0= IF
140: rdrop false
141: ELSE \ no characters left, all ok
142: r>
143: IF
144: dnegate
145: THEN
146: true
147: THEN ;
148:
149: : s>number ( addr len -- d )
150: \ don't use this, there is no way to tell success
151: s>number? drop ;
152:
153: : snumber? ( c-addr u -- 0 / n -1 / d 0> )
154: s>number? 0=
155: IF
156: 2drop false EXIT
157: THEN
158: dpl @ dup 0< IF
159: nip
160: ELSE
161: 1+
162: THEN ;
163:
164: : number? ( string -- string 0 / n -1 / d 0> )
165: dup >r count snumber? dup if
166: rdrop
167: else
168: r> swap
169: then ;
170:
171: : number ( string -- d )
172: number? ?dup 0= abort" ?" 0<
173: IF
174: s>d
175: THEN ;
176:
177: \ \ Comments ( \ \G
178:
179: : ( ( compilation 'ccc<close-paren>' -- ; run-time -- ) \ thisone- core,file paren
180: \G ** this will not get annotated. The alias in glocals.fs will instead **
181: \G It does not work to use "wordset-" prefix since this file is glossed
182: \G by cross.fs which doesn't have the same functionalty as makedoc.fs
183: [char] ) parse 2drop ; immediate
184:
185: : \ ( -- ) \ thisone- core-ext,block-ext backslash
186: \G ** this will not get annotated. The alias in glocals.fs will instead **
187: \G It does not work to use "wordset-" prefix since this file is glossed
188: \G by cross.fs which doesn't have the same functionalty as makedoc.fs
189: [ has? file [IF] ]
190: blk @
191: IF
192: >in @ c/l / 1+ c/l * >in !
193: EXIT
194: THEN
195: [ [THEN] ]
196: source >in ! drop ; immediate
197:
198: : \G ( -- ) \ gforth backslash-gee
199: \G Equivalent to @code{\} but used as a tag to annotate definition
200: \G comments into documentation.
201: POSTPONE \ ; immediate
202:
203: \ \ object oriented search list 17mar93py
204:
205: \ word list structure:
206:
207: struct
208: cell% field find-method \ xt: ( c_addr u wid -- nt )
209: cell% field reveal-method \ xt: ( nt wid -- ) \ used by dofield:, must be field
210: cell% field rehash-method \ xt: ( wid -- ) \ re-initializes a "search-data" (hashtables)
211: cell% field hash-method \ xt: ( wid -- ) \ initializes ""
212: \ \ !! what else
213: end-struct wordlist-map-struct
214:
215: struct
216: cell% field wordlist-map \ pointer to a wordlist-map-struct
217: cell% field wordlist-id \ linked list of words (for WORDS etc.)
218: cell% field wordlist-link \ link field to other wordlists
219: cell% field wordlist-extend \ wordlist extensions (eg bucket offset)
220: end-struct wordlist-struct
221:
222: : f83find ( addr len wordlist -- nt / false )
223: wordlist-id @ (f83find) ;
224:
225: : initvoc ( wid -- )
226: dup wordlist-map @ hash-method perform ;
227:
228: \ Search list table: find reveal
229: Create f83search ( -- wordlist-map )
230: ' f83find A, ' drop A, ' drop A, ' drop A,
231:
232: here G f83search T A, NIL A, NIL A, NIL A,
233: AValue forth-wordlist \ variable, will be redefined by search.fs
234:
235: AVariable lookup forth-wordlist lookup !
236: \ !! last is user and lookup?! jaw
237: AVariable current ( -- addr ) \ gforth
238: \G VARIABLE: holds the wid of the current compilation word list.
239: AVariable voclink forth-wordlist wordlist-link voclink !
240: lookup AValue context ( -- addr ) \ gforth
241: \G VALUE: @code{context} @code{@@} is the wid of the word list at the
242: \G top of the search order stack.
243:
244: forth-wordlist current !
245:
246: \ \ header, finding, ticks 17dec92py
247:
248: $80 constant alias-mask \ set when the word is not an alias!
249: $40 constant immediate-mask
250: $20 constant restrict-mask
251:
252: \ higher level parts of find
253:
254: : flag-sign ( f -- 1|-1 )
255: \ true becomes 1, false -1
256: 0= 2* 1+ ;
257:
258: : compile-only-error ( ... -- )
259: -&14 throw ;
260:
261: : (cfa>int) ( cfa -- xt )
262: [ has? compiler [IF] ]
263: dup interpret/compile?
264: if
265: interpret/compile-int @
266: then
267: [ [THEN] ] ;
268:
269: : (x>int) ( cfa b -- xt )
270: \ get interpretation semantics of name
271: restrict-mask and
272: if
273: drop ['] compile-only-error
274: else
275: (cfa>int)
276: then ;
277:
278: : name>string ( nt -- addr count ) \ gforth head-to-string
279: \g @var{addr count} is the name of the word represented by @var{nt}.
280: cell+ count $1F and ;
281:
282: : ((name>)) ( nfa -- cfa )
283: name>string + cfaligned ;
284:
285: : (name>x) ( nfa -- cfa b )
286: \ cfa is an intermediate cfa and b is the flags byte of nfa
287: dup ((name>))
288: swap cell+ c@ dup alias-mask and 0=
289: IF
290: swap @ swap
291: THEN ;
292:
293: : name>int ( nt -- xt ) \ gforth
294: \G @i{xt} represents the interpretation semantics of the word
295: \G @i{nt}. If @i{nt} has no interpretation semantics (i.e. is
296: \G @code{compile-only}), @i{xt} is the execution token for
297: \G @code{compile-only-error}, which performs @code{-14 throw}.
298: (name>x) (x>int) ;
299:
300: : name?int ( nt -- xt ) \ gforth
301: \G Like @code{name>int}, but perform @code{-14 throw} if @i{nt}
302: \G has no interpretation semantics.
303: (name>x) restrict-mask and
304: if
305: compile-only-error \ does not return
306: then
307: (cfa>int) ;
308:
309: : (name>comp) ( nt -- w +-1 ) \ gforth
310: \G @i{w xt} is the compilation token for the word @i{nt}.
311: (name>x) >r
312: [ has? compiler [IF] ]
313: dup interpret/compile?
314: if
315: interpret/compile-comp @
316: then
317: [ [THEN] ]
318: r> immediate-mask and flag-sign
319: ;
320:
321: : (name>intn) ( nfa -- xt +-1 )
322: (name>x) tuck (x>int) ( b xt )
323: swap immediate-mask and flag-sign ;
324:
325: const Create ??? 0 , 3 c, char ? c, char ? c, char ? c,
326: \ ??? is used by dovar:, must be created/:dovar
327:
328: [IFDEF] forthstart
329: \ if we have a forthstart we can define head? with it
330: \ otherwise leave out the head? check
331:
332: : head? ( addr -- f )
333: \G heuristic check whether addr is a name token; may deliver false
334: \G positives; addr must be a valid address
335: \ we follow the link fields and check for plausibility; two
336: \ iterations should catch most false addresses: on the first
337: \ iteration, we may get an xt, on the second a code address (or
338: \ some code), which is typically not in the dictionary.
339: 2 0 do
340: dup @ dup
341: if ( addr addr1 )
342: dup rot forthstart within
343: if \ addr1 is outside forthstart..addr, not a head
344: drop false unloop exit
345: then ( addr1 )
346: else \ 0 in the link field, no further checks
347: 2drop true unloop exit
348: then
349: loop
350: \ in dubio pro:
351: drop true ;
352:
353: : >head ( cfa -- nt ) \ gforth to-head
354: $21 cell do ( cfa )
355: dup i - count $9F and + cfaligned over alias-mask + =
356: if ( cfa )
357: dup i - cell - dup head?
358: if
359: nip unloop exit
360: then
361: drop
362: then
363: cell +loop
364: drop ??? ( wouldn't 0 be better? ) ;
365:
366: [ELSE]
367:
368: : >head ( cfa -- nt ) \ gforth to-head
369: $21 cell do ( cfa )
370: dup i - count $9F and + cfaligned over alias-mask + =
371: if ( cfa ) i - cell - unloop exit
372: then
373: cell +loop
374: drop ??? ( wouldn't 0 be better? ) ;
375:
376: [THEN]
377:
378: ' >head ALIAS >name
379:
380: : body> 0 >body - ;
381:
382: : (search-wordlist) ( addr count wid -- nt | false )
383: dup wordlist-map @ find-method perform ;
384:
385: : search-wordlist ( c-addr count wid -- 0 | xt +-1 ) \ search
386: \G Search the word list identified by @i{wid}
387: \G for the definition named by the string at @i{c-addr count}.
388: \G If the definition is not found, return 0. If the definition
389: \G is found return 1 (if the definition is immediate) or -1
390: \G (if the definition is not immediate) together with the @i{xt}.
391: \G The @i{xt} returned represents the interpretation semantics.
392: (search-wordlist) dup if
393: (name>intn)
394: then ;
395:
396: : find-name ( c-addr u -- nt | 0 ) \ gforth
397: \g Find the name @i{c-addr u} in the current search
398: \g order. Return its @i{nt}, if found, otherwise 0.
399: lookup @ (search-wordlist) ;
400:
401: : sfind ( c-addr u -- 0 / xt +-1 ) \ gforth-obsolete
402: find-name dup
403: if ( nt )
404: state @
405: if
406: (name>comp)
407: else
408: (name>intn)
409: then
410: then ;
411:
412: : find ( c-addr -- xt +-1 | c-addr 0 ) \ core,search
413: \G Search all word lists in the current search order
414: \G for the definition named by the counted string at @i{c-addr}.
415: \G If the definition is not found, return 0. If the definition
416: \G is found return 1 (if the definition is immediate) or -1
417: \G (if the definition is not immediate) together with the @i{xt}.
418: dup count sfind dup
419: if
420: rot drop
421: then ;
422:
423: \ ticks
424:
425: : (') ( "name" -- nt ) \ gforth
426: name dup 0= -&16 and throw \ test for length 0
427: find-name dup 0=
428: IF
429: drop -&13 bounce
430: THEN ;
431:
432: : ' ( "name" -- xt ) \ core tick
433: \g @i{xt} represents @i{name}'s interpretation
434: \g semantics. Perform @code{-14 throw} if the word has no
435: \g interpretation semantics.
436: (') name?int ;
437:
438: \ \ the interpreter loop mar92py
439:
440: \ interpret 10mar92py
441:
442: Defer parser
443: Defer name ( -- c-addr count ) \ gforth
444: \ get the next word from the input buffer
445: ' (name) IS name
446: Defer compiler-notfound ( c-addr count -- )
447: Defer interpreter-notfound ( c-addr count -- )
448:
449: : no.extensions ( addr u -- )
450: 2drop -&13 bounce ;
451: ' no.extensions IS compiler-notfound
452: ' no.extensions IS interpreter-notfound
453:
454: : interpret ( ?? -- ?? ) \ gforth
455: \ interpret/compile the (rest of the) input buffer
456: rp@ backtrace-rp0 !
457: BEGIN
458: ?stack name dup
459: WHILE
460: parser
461: REPEAT
462: 2drop ;
463:
464: \ interpreter 30apr92py
465:
466: \ not the most efficient implementations of interpreter and compiler
467: | : interpreter ( c-addr u -- )
468: 2dup find-name dup
469: if
470: nip nip name>int execute
471: else
472: drop
473: 2dup 2>r snumber?
474: IF
475: 2rdrop
476: ELSE
477: 2r> interpreter-notfound
478: THEN
479: then ;
480:
481: ' interpreter IS parser
482:
483: \ \ Query Evaluate 07apr93py
484:
485: has? file 0= [IF]
486: : sourceline# ( -- n ) 1 ;
487: [THEN]
488:
489: : refill ( -- flag ) \ core-ext,block-ext,file-ext
490: \G Attempt to fill the input buffer from the input source. When
491: \G the input source is the user input device, attempt to receive
492: \G input into the terminal input device. If successful, make the
493: \G result the input buffer, set @code{>IN} to 0 and return true;
494: \G otherwise return false. When the input source is a block, add 1
495: \G to the value of @code{BLK} to make the next block the input
496: \G source and current input buffer, and set @code{>IN} to 0;
497: \G return true if the new value of @code{BLK} is a valid block
498: \G number, false otherwise. When the input source is a text file,
499: \G attempt to read the next line from the file. If successful,
500: \G make the result the current input buffer, set @code{>IN} to 0
501: \G and return true; otherwise, return false. A successful result
502: \G includes receipt of a line containing 0 characters.
503: [ has? file [IF] ]
504: blk @ IF 1 blk +! true 0 >in ! EXIT THEN
505: [ [THEN] ]
506: tib /line
507: [ has? file [IF] ]
508: loadfile @ ?dup
509: IF read-line throw
510: ELSE
511: [ [THEN] ]
512: sourceline# 0< IF 2drop false EXIT THEN
513: accept true
514: [ has? file [IF] ]
515: THEN
516: 1 loadline +!
517: [ [THEN] ]
518: swap #tib ! 0 >in ! ;
519:
520: : query ( -- ) \ core-ext
521: \G Make the user input device the input source. Receive input into
522: \G the Terminal Input Buffer. Set @code{>IN} to zero. OBSOLESCENT:
523: \G superceeded by @code{accept}.
524: [ has? file [IF] ]
525: blk off loadfile off
526: [ [THEN] ]
527: tib /line accept #tib ! 0 >in ! ;
528:
529: \ save-mem extend-mem
530:
531: has? os [IF]
532: : save-mem ( addr1 u -- addr2 u ) \ gforth
533: \g copy a memory block into a newly allocated region in the heap
534: swap >r
535: dup allocate throw
536: swap 2dup r> -rot move ;
537:
538: : extend-mem ( addr1 u1 u -- addr addr2 u2 )
539: \ extend memory block allocated from the heap by u aus
540: \ the (possibly reallocated piece is addr2 u2, the extension is at addr
541: over >r + dup >r resize throw
542: r> over r> + -rot ;
543: [THEN]
544:
545: \ EVALUATE 17may93jaw
546:
547: has? file 0= [IF]
548: : push-file ( -- ) r>
549: tibstack @ >r >tib @ >r #tib @ >r
550: >tib @ tibstack @ = IF r@ tibstack +! THEN
551: tibstack @ >tib ! >in @ >r >r ;
552:
553: : pop-file ( throw-code -- throw-code )
554: r>
555: r> >in ! r> #tib ! r> >tib ! r> tibstack ! >r ;
556: [THEN]
557:
558: : evaluate ( c-addr u -- ) \ core,block
559: \G Save the current input source specification. Store -1 in
560: \G @code{source-id} and 0 in @code{blk}. Set @code{>IN} to 0 and
561: \G make the string @var{c-addr u} the input source and input
562: \G buffer. Interpret. When the parse area is empty, restore the
563: \G input source specification.
564: push-file #tib ! >tib !
565: >in off
566: [ has? file [IF] ]
567: blk off loadfile off -1 loadline !
568: [ [THEN] ]
569: ['] interpret catch
570: pop-file throw ;
571:
572: \ \ Quit 13feb93py
573:
574: Defer 'quit
575:
576: Defer .status
577:
578: : prompt state @ IF ." compiled" EXIT THEN ." ok" ;
579:
580: : (Query) ( -- )
581: [ has? file [IF] ]
582: loadfile off blk off loadline off
583: [ [THEN] ]
584: refill drop ;
585:
586: : (quit) BEGIN .status cr (query) interpret prompt AGAIN ;
587:
588: ' (quit) IS 'quit
589:
590: \ \ DOERROR (DOERROR) 13jun93jaw
591:
592: 8 Constant max-errors
593: Variable error-stack 0 error-stack !
594: max-errors 6 * cells allot
595: \ format of one cell:
596: \ source ( addr u )
597: \ >in
598: \ line-number
599: \ Loadfilename ( addr u )
600:
601: : dec. ( n -- ) \ gforth
602: \G Display @var{n} as a signed decimal number, followed by a space.
603: \G !! not used...
604: base @ decimal swap . base ! ;
605:
606: : dec.r ( u -- ) \ gforth
607: \G Display @var{u} as a unsigned decimal number
608: base @ decimal swap 0 .r base ! ;
609:
610: : hex. ( u -- ) \ gforth
611: \G Display @var{u} as an unsigned hex number, prefixed with a "$" and
612: \G followed by a space.
613: \G !! not used...
614: '$ emit base @ swap hex u. base ! ;
615:
616: : typewhite ( addr u -- ) \ gforth
617: \ like type, but white space is printed instead of the characters
618: bounds ?do
619: i c@ #tab = if \ check for tab
620: #tab
621: else
622: bl
623: then
624: emit
625: loop ;
626:
627: DEFER DOERROR
628: Defer dobacktrace ( -- )
629: ' noop IS dobacktrace
630:
631: : .error-string ( throw-code -- )
632: dup -2 =
633: IF "error @ ?dup IF count type THEN drop
634: ELSE .error
635: THEN ;
636:
637: : .error-frame ( throwcode addr1 u1 n1 n2 addr2 u2 -- throwcode )
638: \ addr2 u2: filename of included file
639: \ n2: line number
640: \ n1: error position in input line
641: \ addr1 u1: input line
642:
643: cr error-stack @
644: IF
645: ." in file included from "
646: type ." :" dec.r drop 2drop
647: ELSE
648: type ." :" dec.r ." : " 3 pick .error-string cr
649: dup 2over type cr drop
650: nip -trailing 1- ( line-start index2 )
651: 0 >r BEGIN
652: 2dup + c@ bl > WHILE
653: r> 1+ >r 1- dup 0< UNTIL THEN 1+
654: ( line-start index1 )
655: typewhite
656: r> 1 max 0 ?do \ we want at least one "^", even if the length is 0
657: [char] ^ emit
658: loop
659: THEN ;
660:
661: : (DoError) ( throw-code -- )
662: [ has? os [IF] ]
663: >stderr
664: [ [THEN] ]
665: sourceline# IF
666: source >in @ sourceline# 0 0 .error-frame
667: THEN
668: error-stack @ 0 ?DO
669: -1 error-stack +!
670: error-stack dup @ 6 * cells + cell+
671: 6 cells bounds DO
672: I @
673: cell +LOOP
674: .error-frame
675: LOOP
676: drop dobacktrace
677: normal-dp dpp ! ;
678:
679: ' (DoError) IS DoError
680:
681: : quit ( ?? -- ?? ) \ core
682: \G Empty the return stack, make the user input device
683: \G the input source, enter interpret state and start
684: \G the text interpreter.
685: rp0 @ rp! handler off clear-tibstack >tib @ >r
686: BEGIN
687: [ has? compiler [IF] ]
688: postpone [
689: [ [THEN] ]
690: ['] 'quit CATCH dup
691: WHILE
692: <# \ reset hold area, or we may get another error
693: DoError r@ >tib ! r@ tibstack !
694: REPEAT
695: drop r> >tib ! ;
696:
697: \ \ Cold Boot 13feb93py
698:
699: : (bootmessage)
700: ." GForth " version-string type
701: ." , Copyright (C) 1998 Free Software Foundation, Inc." cr
702: ." GForth comes with ABSOLUTELY NO WARRANTY; for details type `license'"
703: [ has? os [IF] ]
704: cr ." Type `bye' to exit"
705: [ [THEN] ] ;
706:
707: defer bootmessage
708: defer process-args
709:
710: ' (bootmessage) IS bootmessage
711:
712: Defer 'cold ( -- ) \ gforth tick-cold
713: \ hook (deferred word) for things to do right before interpreting the
714: \ command-line arguments
715: ' noop IS 'cold
716:
717: include ./../chains.fs
718:
719: Variable init8
720:
721: : cold ( -- ) \ gforth
722: [ has? file [IF] ]
723: pathstring 2@ fpath only-path
724: init-included-files
725: [ [THEN] ]
726: 'cold
727: init8 chainperform
728: [ has? file [IF] ]
729: process-args
730: loadline off
731: [ [THEN] ]
732: bootmessage
733: quit ;
734:
735: : clear-tibstack ( -- )
736: [ has? glocals [IF] ]
737: lp@ forthstart 7 cells + @ -
738: [ [ELSE] ]
739: [ has? os [IF] ]
740: r0 @ forthstart 6 cells + @ -
741: [ [ELSE] ]
742: sp@ $10 cells +
743: [ [THEN] ]
744: [ [THEN] ]
745: dup >tib ! tibstack ! #tib off >in off ;
746:
747: : boot ( path **argv argc -- )
748: main-task up!
749: [ has? os [IF] ]
750: stdout TO outfile-id
751: stdin TO infile-id
752: \ !! [ [THEN] ]
753: \ !! [ has? file [IF] ]
754: argc ! argv ! pathstring 2!
755: [ [THEN] ]
756: sp@ sp0 !
757: clear-tibstack
758: rp@ rp0 !
759: [ has? floating [IF] ]
760: fp@ fp0 !
761: [ [THEN] ]
762: ['] cold catch DoError cr
763: [ has? os [IF] ]
764: bye
765: [ [THEN] ]
766: ;
767:
768: has? os [IF]
769: : bye ( -- ) \ tools-ext
770: [ has? file [IF] ]
771: script? 0= IF cr THEN
772: [ [ELSE] ]
773: cr
774: [ [THEN] ]
775: 0 (bye) ;
776: [THEN]
777:
778: \ **argv may be scanned by the C starter to get some important
779: \ information, as -display and -geometry for an X client FORTH
780: \ or space and stackspace overrides
781:
782: \ 0 arg contains, however, the name of the program.
783:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>