====== require ======
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. {{words:quellcodebibliothekssystem.pdf|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. {{words:library.ans.zip|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 =====
\ 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 ( ccc c-addr len -- c-addr len false | true )
BL WORD COUNT desired ;
CREATE $library 256 CHARS ALLOT
: from ( ccc -- )
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 ( ccc -- )
BL WORD COUNT required ;
\ from extensions.f
from sample.lib
CR .( Simple Source Code Library System initialized! )
===== SAMPLE.LIB: Sample Library with sequential search =====
\ 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]
==== Abschnitte nachladen====
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
===== Hinweis =====
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.