File:
[gforth] /
gforth /
kernel /
comp.fs
Revision
1.15:
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: \ compiler definitions 14sep97jaw
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: \ \ Revisions-Log
22:
23: \ put in seperate file 14sep97jaw
24:
25: \ \ here allot , c, A, 17dec92py
26:
27: [IFUNDEF] allot
28: [IFUNDEF] forthstart
29: : allot ( n -- ) \ core
30: \G Reserve or release @i{n} address units of data space; @i{n}
31: \G is a signed number. There are restrictions on releasing data
32: \G space.
33: dup unused u> -8 and throw
34: dp +! ;
35: [THEN]
36: [THEN]
37:
38: \ we default to this version if we have nothing else 05May99jaw
39: [IFUNDEF] allot
40: : allot ( n -- ) \ core
41: \G Reserve or release @i{n} address units of data space; @i{n}
42: \G is a signed number. There are restrictions on releasing data
43: \G space.
44: here +
45: dup 1- usable-dictionary-end forthstart within -8 and throw
46: dp ! ;
47: [THEN]
48:
49: : c, ( c -- ) \ core
50: \G Reserve data space for one char and store @i{c} in the space.
51: here 1 chars allot c! ;
52:
53: : , ( w -- ) \ core
54: \G Reserve data space for one cell and store @i{w} in the space.
55: here cell allot ! ;
56:
57: : 2, ( w1 w2 -- ) \ gforth
58: \G Reserve data space for two cells and store the double @i{w1
59: \G w2} in the space.
60: here 2 cells allot 2! ;
61:
62: \ : aligned ( addr -- addr' ) \ core
63: \ [ cell 1- ] Literal + [ -1 cells ] Literal and ;
64:
65: : align ( -- ) \ core
66: \G If the data-space pointer is not aligned, reserve enough space to align it.
67: here dup aligned swap ?DO bl c, LOOP ;
68:
69: \ : faligned ( addr -- f-addr ) \ float
70: \ [ 1 floats 1- ] Literal + [ -1 floats ] Literal and ;
71:
72: : falign ( -- ) \ float
73: \G If the data-space pointer is not float-aligned, reserve
74: \G enough space to align it.
75: here dup faligned swap
76: ?DO
77: bl c,
78: LOOP ;
79:
80: : maxalign ( -- ) \ gforth
81: here dup maxaligned swap
82: ?DO
83: bl c,
84: LOOP ;
85:
86: \ the code field is aligned if its body is maxaligned
87: ' maxalign Alias cfalign ( -- ) \ gforth
88:
89: ' , alias A, ( addr -- ) \ gforth
90:
91: ' NOOP ALIAS const
92:
93: \ \ Header 23feb93py
94:
95: \ input-stream, nextname and noname are quite ugly (passing
96: \ information through global variables), but they are useful for dealing
97: \ with existing/independent defining words
98:
99: defer (header)
100: defer header ( -- ) \ gforth
101: ' (header) IS header
102:
103: : string, ( c-addr u -- ) \ gforth
104: \G puts down string as cstring
105: dup c, here swap chars dup allot move ;
106:
107: : header, ( c-addr u -- ) \ gforth
108: name-too-long?
109: align here last !
110: current @ 1 or A, \ link field; before revealing, it contains the
111: \ tagged reveal-into wordlist
112: string, cfalign
113: alias-mask lastflags cset ;
114:
115: : input-stream-header ( "name" -- )
116: name name-too-short? header, ;
117:
118: : input-stream ( -- ) \ general
119: \G switches back to getting the name from the input stream ;
120: ['] input-stream-header IS (header) ;
121:
122: ' input-stream-header IS (header)
123:
124: \ !! make that a 2variable
125: create nextname-buffer 32 chars allot
126:
127: : nextname-header ( -- )
128: nextname-buffer count header,
129: input-stream ;
130:
131: \ the next name is given in the string
132:
133: : nextname ( c-addr u -- ) \ gforth
134: name-too-long?
135: nextname-buffer c! ( c-addr )
136: nextname-buffer count move
137: ['] nextname-header IS (header) ;
138:
139: : noname-header ( -- )
140: 0 last ! cfalign
141: input-stream ;
142:
143: : noname ( -- ) \ gforth
144: \ the next defined word remains anonymous. The xt of that word is given by lastxt
145: ['] noname-header IS (header) ;
146:
147: : lastxt ( -- xt ) \ gforth
148: \G @i{xt} is the execution token of the last word defined.
149: \ The main purpose of this word is to get the xt of words defined using noname
150: lastcfa @ ;
151:
152: \ \ literals 17dec92py
153:
154: : Literal ( compilation n -- ; run-time -- n ) \ core
155: \G Compile appropriate code such that, at run-time, @i{n} is placed
156: \G on the stack. Interpretation semantics are undefined.
157: [ [IFDEF] lit, ]
158: lit,
159: [ [ELSE] ]
160: postpone lit ,
161: [ [THEN] ] ; immediate restrict
162:
163: : ALiteral ( compilation addr -- ; run-time -- addr ) \ gforth
164: [ [IFDEF] alit, ]
165: alit,
166: [ [ELSE] ]
167: postpone lit A,
168: [ [THEN] ] ; immediate restrict
169:
170: : char ( '<spaces>ccc' -- c ) \ core
171: \G Skip leading spaces. Parse the string @i{ccc} and return @i{c}, the
172: \G display code representing the first character of @i{ccc}.
173: bl word char+ c@ ;
174:
175: : [char] ( compilation '<spaces>ccc' -- ; run-time -- c ) \ core bracket-char
176: \G Compilation: skip leading spaces. Parse the string
177: \G @i{ccc}. Run-time: return @i{c}, the display code
178: \G representing the first character of @i{ccc}. Interpretation
179: \G semantics for this word are undefined.
180: char postpone Literal ; immediate restrict
181:
182: \ \ threading 17mar93py
183:
184: : cfa, ( code-address -- ) \ gforth cfa-comma
185: here
186: dup lastcfa !
187: 0 A, 0 , code-address! ;
188:
189: [IFUNDEF] compile,
190: : compile, ( xt -- ) \ core-ext compile-comma
191: \G Compile the word represented by the execution token, @i{xt},
192: \G into the current definition.
193: A, ;
194: [THEN]
195:
196: : !does ( addr -- ) \ gforth store-does
197: lastxt does-code! ;
198:
199: : (does>) ( R: addr -- )
200: r> cfaligned /does-handler + !does ;
201:
202: : dodoes, ( -- )
203: cfalign here /does-handler allot does-handler! ;
204:
205: : (compile) ( -- ) \ gforth
206: r> dup cell+ >r @ compile, ;
207:
208: : postpone, ( w xt -- ) \ gforth postpone-comma
209: \g Compile the compilation semantics represented by @i{w xt}.
210: dup ['] execute =
211: if
212: drop compile,
213: else
214: dup ['] compile, =
215: if
216: drop POSTPONE (compile) a,
217: else
218: swap POSTPONE aliteral compile,
219: then
220: then ;
221:
222: : POSTPONE ( "name" -- ) \ core
223: \g Compiles the compilation semantics of @i{name}.
224: COMP' postpone, ; immediate restrict
225:
226: struct
227: >body
228: cell% field interpret/compile-int
229: cell% field interpret/compile-comp
230: end-struct interpret/compile-struct
231:
232: : interpret/compile: ( interp-xt comp-xt "name" -- ) \ gforth
233: Create immediate swap A, A,
234: DOES>
235: abort" executed primary cfa of an interpret/compile: word" ;
236: \ state @ IF cell+ THEN perform ;
237:
238: \ \ ticks
239:
240: : name>comp ( nt -- w xt ) \ gforth
241: \G @i{w xt} is the compilation token for the word @i{nt}.
242: (name>comp)
243: 1 = if
244: ['] execute
245: else
246: ['] compile,
247: then ;
248:
249: : [(')] ( compilation "name" -- ; run-time -- nt ) \ gforth bracket-paren-tick
250: (') postpone ALiteral ; immediate restrict
251:
252: : ['] ( compilation. "name" -- ; run-time. -- xt ) \ core bracket-tick
253: \g @i{xt} represents @i{name}'s interpretation
254: \g semantics. Perform @code{-14 throw} if the word has no
255: \g interpretation semantics.
256: ' postpone ALiteral ; immediate restrict
257:
258: : COMP' ( "name" -- w xt ) \ gforth comp-tick
259: \g Compilation token @i{w xt} represents @i{name}'s compilation semantics.
260: (') name>comp ;
261:
262: : [COMP'] ( compilation "name" -- ; run-time -- w xt ) \ gforth bracket-comp-tick
263: \g Compilation token @i{w xt} represents @i{name}'s compilation semantics.
264: COMP' swap POSTPONE Aliteral POSTPONE ALiteral ; immediate restrict
265:
266: \ \ recurse 17may93jaw
267:
268: : recurse ( compilation -- ; run-time ?? -- ?? ) \ core
269: \g Call the current definition.
270: lastxt compile, ; immediate restrict
271:
272: \ \ compiler loop
273:
274: : compiler ( c-addr u -- )
275: 2dup find-name dup
276: if ( c-addr u nt )
277: nip nip name>comp execute
278: else
279: drop
280: 2dup snumber? dup
281: IF
282: 0>
283: IF
284: swap postpone Literal
285: THEN
286: postpone Literal
287: 2drop
288: ELSE
289: drop compiler-notfound
290: THEN
291: then ;
292:
293: : [ ( -- ) \ core left-bracket
294: \G Enter interpretation state. Immediate word.
295: ['] interpreter IS parser state off ; immediate
296:
297: : ] ( -- ) \ core right-bracket
298: \G Enter compilation state.
299: ['] compiler IS parser state on ;
300:
301: \ \ Strings 22feb93py
302:
303: : ," ( "string"<"> -- ) [char] " parse
304: here over char+ allot place align ;
305:
306: : SLiteral ( Compilation c-addr1 u ; run-time -- c-addr2 u ) \ string
307: \G Compilation: compile the string specified by @i{c-addr1},
308: \G @i{u} into the current definition. Run-time: return
309: \G @i{c-addr2 u} describing the address and length of the
310: \G string.
311: postpone (S") here over char+ allot place align ;
312: immediate restrict
313:
314: \ \ abort" 22feb93py
315:
316: : abort" ( compilation 'ccc"' -- ; run-time f -- ) \ core,exception-ext abort-quote
317: \G If any bit of @i{f} is non-zero, perform the function of @code{-2 throw},
318: \G displaying the string @i{ccc} if there is no exception frame on the
319: \G exception stack.
320: postpone (abort") ," ; immediate restrict
321:
322: \ \ Header states 23feb93py
323:
324: : cset ( bmask c-addr -- )
325: tuck c@ or swap c! ;
326:
327: : creset ( bmask c-addr -- )
328: tuck c@ swap invert and swap c! ;
329:
330: : ctoggle ( bmask c-addr -- )
331: tuck c@ xor swap c! ;
332:
333: : lastflags ( -- c-addr )
334: \ the address of the flags byte in the last header
335: \ aborts if the last defined word was headerless
336: last @ dup 0= abort" last word was headerless" cell+ ;
337:
338: : immediate ( -- ) \ core
339: \G Make the compilation semantics of a word be to @code{execute}
340: \G the execution semantics.
341: immediate-mask lastflags cset ;
342:
343: : restrict ( -- ) \ gforth
344: \G A synonym for @code{compile-only}
345: restrict-mask lastflags cset ;
346: ' restrict alias compile-only ( -- ) \ gforth
347: \G Remove the interpretation semantics of a word.
348:
349: \ \ Create Variable User Constant 17mar93py
350:
351: : Alias ( xt "name" -- ) \ gforth
352: \ 29Apr1999nac The stack comment for this was cfa -- I changed it to xt because
353: \ they are the same thing in Gforth, and xt is a more appropriate thing to
354: \ document.
355: Header reveal
356: alias-mask lastflags creset
357: dup A, lastcfa ! ;
358:
359: doer? :dovar [IF]
360:
361: : Create ( "name" -- ) \ core
362: Header reveal dovar: cfa, ;
363: [ELSE]
364:
365: : Create ( "name" -- ) \ core
366: Header reveal here lastcfa ! 0 A, 0 , DOES> ;
367: [THEN]
368:
369: : Variable ( "name" -- ) \ core
370: Create 0 , ;
371:
372: : AVariable ( "name" -- ) \ gforth
373: Create 0 A, ;
374:
375: : 2Variable ( "name" -- ) \ double
376: create 0 , 0 , ;
377:
378: : uallot ( n -- ) udp @ swap udp +! ;
379:
380: doer? :douser [IF]
381:
382: : User ( "name" -- ) \ gforth
383: Header reveal douser: cfa, cell uallot , ;
384:
385: : AUser ( "name" -- ) \ gforth
386: User ;
387: [ELSE]
388:
389: : User Create cell uallot , DOES> @ up @ + ;
390:
391: : AUser User ;
392: [THEN]
393:
394: doer? :docon [IF]
395: : (Constant) Header reveal docon: cfa, ;
396: [ELSE]
397: : (Constant) Create DOES> @ ;
398: [THEN]
399:
400: : Constant ( w "name" -- ) \ core
401: \G Define a constant @i{name} with value @i{w}.
402: \G
403: \G @i{name} execution: @i{-- w}
404: (Constant) , ;
405:
406: : AConstant ( addr "name" -- ) \ gforth
407: (Constant) A, ;
408:
409: : Value ( w "name" -- ) \ core-ext
410: (Constant) , ;
411:
412: : 2Constant ( w1 w2 "name" -- ) \ double
413: Create ( w1 w2 "name" -- )
414: 2,
415: DOES> ( -- w1 w2 )
416: 2@ ;
417:
418: doer? :dofield [IF]
419: : (Field) Header reveal dofield: cfa, ;
420: [ELSE]
421: : (Field) Create DOES> @ + ;
422: [THEN]
423: \ IS Defer What's Defers TO 24feb93py
424:
425: doer? :dodefer [IF]
426:
427: : Defer ( "name" -- ) \ gforth
428: \ !! shouldn't it be initialized with abort or something similar?
429: Header Reveal dodefer: cfa,
430: ['] noop A, ;
431: [ELSE]
432:
433: : Defer ( "name" -- ) \ gforth
434: Create ['] noop A,
435: DOES> @ execute ;
436: [THEN]
437:
438: : Defers ( "name" -- ) \ gforth
439: ' >body @ compile, ; immediate
440:
441: \ \ : ; 24feb93py
442:
443: defer :-hook ( sys1 -- sys2 )
444:
445: defer ;-hook ( sys2 -- sys1 )
446:
447: [IFDEF] docol,
448: : (:noname) ( -- colon-sys )
449: \ common factor of : and :noname
450: docol, ]comp defstart ] :-hook ;
451: [ELSE]
452: : (:noname) ( -- colon-sys )
453: \ common factor of : and :noname
454: docol: cfa, defstart ] :-hook ;
455: [THEN]
456:
457: : : ( "name" -- colon-sys ) \ core colon
458: Header (:noname) ;
459:
460: : :noname ( -- xt colon-sys ) \ core-ext colon-no-name
461: 0 last !
462: cfalign here (:noname) ;
463:
464: [IFDEF] fini,
465: : ; ( compilation colon-sys -- ; run-time nest-sys ) \ core semicolon
466: ;-hook ?struc fini, comp[ reveal postpone [ ; immediate restrict
467: [ELSE]
468: : ; ( compilation colon-sys -- ; run-time nest-sys ) \ core semicolon
469: ;-hook ?struc postpone exit reveal postpone [ ; immediate restrict
470: [THEN]
471:
472: \ \ Search list handling: reveal words, recursive 23feb93py
473:
474: : last? ( -- false / nfa nfa )
475: last @ ?dup ;
476:
477: : (reveal) ( nt wid -- )
478: wordlist-id dup >r
479: @ over ( name>link ) !
480: r> ! ;
481:
482: \ make entry in wordlist-map
483: ' (reveal) f83search reveal-method !
484:
485: Variable warnings ( -- addr ) \ gforth
486: G -1 warnings T !
487:
488: : check-shadow ( addr count wid -- )
489: \G prints a warning if the string is already present in the wordlist
490: >r 2dup 2dup r> (search-wordlist) warnings @ and ?dup if
491: >stderr
492: ." redefined " name>string 2dup type
493: compare 0<> if
494: ." with " type
495: else
496: 2drop
497: then
498: space space EXIT
499: then
500: 2drop 2drop ;
501:
502: : reveal ( -- ) \ gforth
503: last?
504: if \ the last word has a header
505: dup ( name>link ) @ 1 and
506: if \ it is still hidden
507: dup ( name>link ) @ 1 xor ( nt wid )
508: 2dup >r name>string r> check-shadow ( nt wid )
509: dup wordlist-map @ reveal-method perform
510: else
511: drop
512: then
513: then ;
514:
515: : rehash ( wid -- )
516: dup wordlist-map @ rehash-method perform ;
517:
518: ' reveal alias recursive ( compilation -- ; run-time -- ) \ gforth
519: \g Make the current definition visible, enabling it to call itself
520: \g recursively.
521: immediate restrict
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>