16.10.2013 Views

5 - Forth Interest Group

5 - Forth Interest Group

5 - Forth Interest Group

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!