5 - Forth Interest Group
5 - Forth Interest Group
5 - Forth Interest Group
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
:class. The :class word<br />
uses a nested create ...<br />
does> structurde kind<br />
that makes my head hurt<br />
whenever I have to think<br />
about it. At compile time,<br />
:class buildsaclassheader<br />
structure as shown in Figure<br />
One.<br />
I have to take a moment<br />
here to describe something<br />
of the structure of UD <strong>Forth</strong>.<br />
Being on the IBM PC, UD<br />
<strong>Forth</strong> has a segmented archi-<br />
tecture. Executable code re-<br />
sides in the code segment,<br />
variables are stored in the<br />
variables segment, threading<br />
pointers are kept in the to-<br />
kens segment, and names<br />
are kept in the headers seg-<br />
ment. Names built using<br />
<strong>Forth</strong>'s create word return<br />
a pointer to a parameter field<br />
in the variables segment,<br />
hence the class pointer in<br />
that segment for a class defi-<br />
nition.<br />
The first field in the<br />
header-ivar space--tells<br />
the system how much space<br />
to set aside for instance vari-<br />
ables when an object is cre-<br />
ated. The second field is the<br />
head of a linked list that<br />
connects all the methods for<br />
a particular class. Next comes<br />
the superclass pointer field,<br />
which is set by the in :class. When you<br />
send an object a message,<br />
the system follows the pointer<br />
to the class header, then<br />
searches down the methods<br />
list chain (as descriid above)<br />
to determine what code to<br />
execute. Notice that the code<br />
for a method is absolutely<br />
headerless; a method doesn't<br />
even possess code field ad-<br />
dresses. A special word-<br />
(domethod) -executes a<br />
PCKerk LMng Four, continued.)<br />
\ Pop top word from method stack<br />
: mpop (--XI)<br />
mstack->dstack \ Fetch<br />
-2 mstack +! \ Decrement<br />
\ Initialize the object stack<br />
: ostack-init ( -- 1<br />
ostack dup !<br />
\ Push top word onto object stack<br />
: opush (n--)<br />
ostack @ 2+ ! \ Save item<br />
2 ostack +! \ Increment<br />
,<br />
\ Copy top of ostack to dstack<br />
: ostack->dstack ( -- n )<br />
ostack @ @<br />
,<br />
\ Pop top word from object stack<br />
: opop (--n)<br />
ostack->dstack<br />
-2 ostack +!<br />
,<br />
\ Dup top of object stack<br />
: odup ( -- )<br />
ostack->dstack<br />
opush<br />
\ Drop top of object stack<br />
: odrop ( -- )<br />
opop drop<br />
I<br />
\ Fetch<br />
\ Decrement<br />
\ Fetch top<br />
\ and push<br />
\ Clear both stacks.<br />
\ Use this if something aborts and you don't want the<br />
\ stacks growing forever.<br />
: clear-o&mstacks<br />
ostack-init<br />
mstack-init<br />
\ ........................<br />
\ ** TEMPORARY SEGMENTS **<br />
\ ........................<br />
\ The method names and instance variable names are kept in<br />
\ temporary segments. These segments are allocated<br />
\ from DOS. When you're done defining things and<br />
\ its time to make an executable, just free those<br />
\ segments. (The word 'end-objects', defined later,<br />
\ does all that.<br />
\ Compare two counted strings. segl addrl, seg2 addr2 point to<br />
\ segment and addresses of two strings with preceding count<br />
\ bytes. Returns 0 i f equal, else nonzero<br />
: ccompl ( segl addrl seg2 addr2 -- n )<br />
\ First check byte counts<br />
countl >r 2swap countl r@ =<br />
January 1992 February 10 <strong>Forth</strong> Dimensions