Auf der Suche nach nehmen, laden, geht–Bibliotheken hat Ulrich Hoffmann seinen Weg, den er seit 1995 geht, auf der Forthtagung 2008 in Roggenburg noch einmal vorgestellt. Vortrag zum Quellcode-Bibliothekssystem
Über den äußeren Textinterpreter des Forth (Outer–Interpreter) ist es möglich eine extrem einfache Implementierung zu schaffen, die Forthworte einzeln nachlädt. Diese kann leicht in jedes System integriert werden. quellcode library.ans
Ausgenutzt wird dabei die Eigenschaft des Forth, eine Datei interpretieren zu können. Die Vorgaben im Kopf der Bibliotheks-Datei sample.lib
sorgen dafür, dass nur das gesuchte Wort compiliert wird, weil es zwischen [if]
und [then]
eingeschlossen ist. Und das \\
sorgt dafür, dass die Suche in der Datei beendet wird. Dieser Mechanismus ist schnell, da auf diese Weise weite Bereiche der Bibliothek übersprungen werden können.
Welche Bibliothek genommen wird, stellt man mittels from
ein. Dabei ist es egal, ob zu dem Zeitpunkt die Bibliothek schon im Suchpfad liegt. Diese Prüfung erfolgt erst, wenn tatsächlich ein Wort nachgeladen werden soll. So ist es möglich sein System über include
aufzubauen, beim Testen oder Ergänzen aber jederzeit auch einzelne Worte nachladen zu können.
\ LIBRARY.ANS: Simple Source Code Library system uho Mar 95 \ $Id: library.ans,v 1.3 2004/03/24 19:41:03 uho Exp $ : \\ ( -- ) SOURCE-ID 1+ 1 U> IF BEGIN REFILL 0= UNTIL THEN POSTPONE \ ; IMMEDIATE : desired ( c-addr1 len1 c-addr2 len2 -- c-addr1 len1 false | true ) 2OVER COMPARE 0= DUP IF NIP NIP THEN ; : desires ( <space>ccc<spaces> c-addr len -- c-addr len false | true ) BL WORD COUNT desired ; CREATE $library 256 CHARS ALLOT : from ( <spaces>ccc<spaces> -- ) BL WORD COUNT $library CHAR+ SWAP DUP >R CMOVE R> $library C! ; : required ( c-addr len -- ) DUP ALLOCATE THROW DUP >R SWAP 2DUP 2>R CMOVE 2R> $library COUNT DUP ALLOCATE THROW SWAP 2DUP 2>R 2DUP 2>R CMOVE 2R> ['] INCLUDED CATCH 2R> 2DUP $library CHAR+ SWAP CMOVE $library C! FREE THROW R> FREE THROW THROW ; : require ( <space>ccc<spaces> -- ) BL WORD COUNT required ; \ from extensions.f from sample.lib CR .( Simple Source Code Library System initialized! )
\ SAMPLE.LIB: Sample Library with sequential search uho Mar95 ( c-addr u -- ) \ do not look up, if identification string is already \ in dictionary 2DUP PAD CHAR+ SWAP MOVE DUP PAD C! PAD FIND NIP [IF] 2DROP \\ [THEN] CR .( looking for ) 2DUP TYPE SPACE desires case? [IF] \ ------------------------------------------ : case? ( flag -- ) OVER = DUP IF NIP THEN ; \\ [THEN] desires on [IF] \ --------------------------------------------- : on ( a-addr -- ) TRUE SWAP ! ; \\ [THEN] desires off [IF] \ -------------------------------------------- : off ( a-addr -- ) FALSE SWAP ! ; \\ [THEN]
Es lassen sich ohne weitere Änderungen auch Abschnitte zusammen fassen und komplett nachladen. Allerdings ist dazu (noch) Handarbeit nötig, um das abschnittsweise Laden zu formulieren. Füge folgendes in dein sample.lib ein:
\ ============================================================ desires spam-words [IF] require spam11 require spam22 require spam33 \\ [THEN] desires spam11 [IF] \ ---------------------------------------- : spam11 ( -- 11 ) 11 ; \\ [THEN] desires spam22 [IF] \ ---------------------------------------- : spam22 ( -- 22 ) 22 ; \\ [THEN] desires spam33 [IF] \ ---------------------------------------- : spam33 ( -- 33 ) 33 ; \\ [THEN] \ ============================================================ CR TYPE .( NOT provided! ) QUIT
Im gforth gibt mehrere Möglichkeiten ganze Dateien nachzuladen, aber keine um einzelne Definitionen aus einer Bibliothek-Datei zu entnehmen.
include mysouce.fs s" mysource.fs" included require mysource.fs needs mysource.fs s" mysource.fs" required
Während include
immer die gesamte Datei lädt, laden require
und needs
diese nur, falls sie noch fehlt. Hier gibt es also eine Überschneidung in der Namensgebung. Es bleibt daher dem Programmierer überlassen, sein require
seinem Geschmack nach zu wählen. Und in seinen Quellen deutlich zu machen, ob er komplette Dateien oder einzelne Worte aus einer Bibliothek-Datei nachlädt.