Commit 1ea6d1f7 authored by paysan's avatar paysan
Browse files

Changed sources to be more consistent with current ANS Forth style

parent d16e2d99
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ SOURCES = thinking-forth.tex \
	preface.tex \
	preface94.tex \
	preface2004.tex \
	preface-ans.tex \
	chapter1.tex \
	chapter2.tex \
	chapter3.tex \
@@ -76,7 +77,7 @@ LINKCOLOR = blue
# 17x24 for 17cm x 24cm format (one of the standard metric formats)
# splitcover: if you only choose front and back, and the spine is done for you

VERSION = 1.0
VERSION = 2.0-pre1
CP = cp
TAR = tar jcf
MD = mkdir
+4 −4
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ portions of an applications, if at all.
Still another defining word is \forthb{CONSTANT},\index{C!CONSTANT} which
is used like this:
\begin{Code}
17 CONSTANT SEVENTEEN
17 Constant SEVENTEEN
\end{Code}
The new word \forth{SEVENTEEN} can now be used in place of the actual
number 17.
@@ -58,7 +58,7 @@ number 17.
The defining word \forth{VARIABLE}\index{V!VARIABLE} creates a location
for temporary data. \forth{VARIABLE} is used like this:
\begin{Code}
VARIABLE BANANAS
Variable BANANAS
\end{Code}
This reserves a location which is identified by the name \forth{BANANAS}.}

@@ -96,14 +96,14 @@ For this, \Forth{} employs a much simpler mechanism: the data stack.
When you type a number, it goes on the stack.  When you invoke a word
which has numeric input, it will take it from the stack.  Thus the phrase
\begin{Code}
17 SPACES
17 spaces
\end{Code}
will display seventeen blanks on the current output device.  ``17'' pushes
the binary value 17 onto the stack; the word \forthb{SPACES} consumes it.

A constant also pushes its value onto the stack; thus the phrase:
\begin{Code}
SEVENTEEN SPACES
SEVENTEEN spaces
\end{Code}
has the same effect.

+51 −51
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ place it on the return stack. That's all. \Forth{} execution then
continues with this address on the return stack, which will cause the
vectored function to be performed.  It's like saying (in '83-Standard)
\begin{Code}
' NOTHING >BODY >R <return>
' NOTHING >body >r <return>
\end{Code}
which executes \forth{NOTHING}.  (This trick only works with colon
definitions.)
@@ -48,7 +48,7 @@ DOER JOE & \\

\noindent Now suppose we define:
\begin{Code}
: TEST   MAKE JOE  CR ;
: TEST   MAKE JOE  cr ;
\end{Code}
that is, we define a word that can vector \forth{JOE} to do a carriage
return.
@@ -68,7 +68,7 @@ TEST & (MAKE) & 0 & JOE & CR & EXIT \\ \hline\noalign{\vspace{2pt}}
\forthb{MAKE} inside a colon definition, \forthb{STATE} will be true, and
we'll execute the phrase:
\begin{Code}
COMPILE (MAKE)  HERE MARKER !  0 ,
COMPILE (MAKE)  here marker !  0 ,
\end{Code}
We can see how \forthb{MAKE} has compiled the address of the run-time
routine, \forthb{(MAKE)}, followed by a zero.  (We'll explain what the
@@ -112,7 +112,7 @@ That's the basic idea. But what about that cell containing zero? That's
for the use of \forthb{;AND}.  Suppose we changed \forth{TEST} to read:

\begin{Code}
: TEST   MAKE JOE  CR ;AND SPACE ;
: TEST   MAKE JOE  cr ;AND space ;
\end{Code}
That is, when we invoke \forth{TEST} we'll vector \forth{JOE} to do a
\forthb{CR}, and we'll do a \forthb{SPACE} right now.  Here's what this
@@ -130,7 +130,7 @@ TEST & (MAKE) & adr & JOE & CR & EXIT & SPACE & EXIT \\ \hline\noalign{\vspace{2
\end{center}
Here's the definition of \forthb{;AND}:
\begin{Code}
: ;AND   COMPILE  EXIT  HERE MARKER @ ! ;   IMMEDIATE
: ;AND   COMPILE  EXIT  here marker @ ! ;   immediate
\end{Code}
We can see that \forthb{;AND} has compiled an \forthb{EXIT}\index{E!EXIT},
just as semicolon would.
@@ -141,7 +141,7 @@ variable called \forthb{MARKER}. Now \forthb{;AND} stores \forthb{HERE}
into the cell previously containing zero.  Now \forthb{(MAKE)} has a
pointer to the place to resume execution.  The phrase
\begin{Code}
IF >R THEN
IF >r THEN
\end{Code}
will leave on the return stack the address of the code beginning with
\forthb{SPACE}.  Thus execution will skip over the code between
@@ -188,7 +188,7 @@ reason each time).
( DOER/MAKE   Shadow screen                      LPB 12/05/83 )
NOTHING   A no-opp
DOER      Defines a word whose behavior is vectorable.
MARKER    Saves adr for optional continuation pointer.
marker    Saves adr for optional continuation pointer.
(MAKE)    Stuffs the address of further code into the
          parameter field of a doer word.
MAKE      Used interpretively:  MAKE doer-name  forth-code ;
@@ -206,16 +206,16 @@ UNDO Usage: UNDO doer-name ; makes it safe to execute
\begin{Screen}
\ DOER/MAKE   FORTH-83 Laxen/Perry/Harris model  LPB 12/05/83 
: NOTHING ;
: DOER   CREATE  ['] NOTHING  >BODY ,  DOES> @ >R ;
VARIABLE MARKER
: (MAKE)  R>  DUP 2+  DUP 2+  SWAP @  >BODY !
   @ ?DUP IF >R THEN ;
: MAKE   STATE @ IF ( compiling)
   COMPILE (MAKE)  HERE MARKER !  0 ,
   ELSE  HERE  [COMPILE] '  >BODY !
   [COMPILE] ]  THEN ;   IMMEDIATE
: ;AND   COMPILE EXIT  HERE MARKER @ ! ;   IMMEDIATE
: UNDO   ['] NOTHING  >BODY  [COMPILE] '  >BODY ! ;
: DOER   Create  ['] NOTHING  >body ,  DOES> @ >r ;
Variable marker
: (MAKE)  r>  dup 2+  dup 2+  swap @  >body !
   @ ?dup IF >r THEN ;
: MAKE   state @ IF ( compiling)
   COMPILE (MAKE)  here marker !  0 ,
   ELSE  here  [compile] '  >body !
   [compile] ]  THEN ;   immediate
: ;AND   COMPILE EXIT  here marker @ ! ;   immediate
: UNDO   ['] NOTHING  >body  [compile] '  >body ! ;

\ The code in this screen is in the public domain.

@@ -225,16 +225,16 @@ VARIABLE MARKER
\begin{Screen}
( DOER/MAKE   FORTH-83 Lab. Micro PC/FORTH 2.0   LPB 12/05/83 )
: NOTHING ;
: DOER   CREATE  ['] NOTHING  >BODY ,  DOES> @ >R ;
VARIABLE MARKER
: (MAKE)  R>  DUP 2+  DUP 2+  SWAP @  >BODY !
   @ ?DUP IF >R THEN ;
: MAKE   STATE @ IF ( compiling)
   COMPILE (MAKE)  HERE MARKER !  0 ,
   ELSE  HERE  [COMPILE] '  >BODY !
   [COMPILE] ] UNSMUDGE  THEN ;   IMMEDIATE
: ;AND   COMPILE EXIT  HERE MARKER @ ! ;   IMMEDIATE
: UNDO   ['] NOTHING  >BODY  [COMPILE] '  >BODY ! ;
: DOER   Create  ['] NOTHING  >body ,  DOES> @ >r ;
Variable marker
: (MAKE)  r>  dup 2+  dup 2+  swap @  >body !
   @ ?dup IF >r THEN ;
: MAKE   state @ IF ( compiling)
   COMPILE (MAKE)  here marker !  0 ,
   ELSE  here  [compile] '  >body !
   [compile] ] UNSMUDGE  THEN ;   immediate
: ;AND   COMPILE EXIT  here marker @ ! ;   immediate
: UNDO   ['] NOTHING  >body  [compile] '  >body ! ;

( The code in this screen is in the public domain.)

@@ -245,17 +245,17 @@ VARIABLE MARKER
( DOER/MAKE   FIG model                          LPB 12/05/83 )
: NOTHING   ;
: DOES-PFA  ( pfa -- pfa of child of <BUILD-DOES> )   2+ ;
: DOER   <BUILDS  ' NOTHING ,  DOES> @ >R ;
0 VARIABLE MARKER
: (MAKE)  R>  DUP 2+  DUP 2+  SWAP @  2+ DOES-PFA !
   @ -DUP IF >R THEN ;
: MAKE  STATE @ IF ( compiling)
   COMPILE (MAKE)  HERE MARKER !  0 ,
   ELSE  HERE  [COMPILE] '  DOES-PFA !
   SMUDGE    [COMPILE] ] THEN ; IMMEDIATE
: ;AND   COMPILE ;S  HERE MARKER @ ! ;  IMMEDIATE
: UNDO   ' NOTHING  [COMPILE] '  DOES-PFA ! ;
;S
: DOER   <BUILDS  ' NOTHING ,  DOES> @ >r ;
0 Variable marker
: (MAKE)  r>  dup 2+  dup 2+  swap @  2+ DOES-PFA !
   @ -DUP IF >r THEN ;
: MAKE  state @ IF ( compiling)
   COMPILE (MAKE)  here marker !  0 ,
   ELSE  here  [compile] '  DOES-PFA !
   SMUDGE    [compile] ] THEN ; immediate
: ;AND   COMPILE ;s  here marker @ ! ;  immediate
: UNDO   ' NOTHING  [compile] '  DOES-PFA ! ;
;s
The code in this screen is in the public domain.

\end{Screen}
@@ -263,16 +263,16 @@ The code in this screen is in the public domain.
\begin{Screen}
( DOER/MAKE   79-Standard  MVP FORTH             LPB 12/05/83 )
: NOTHING ;
: DOER   CREATE  ' NOTHING  ,  DOES> @ >R ;
VARIABLE MARKER
: (MAKE)  R>  DUP 2+  DUP 2+  SWAP @  2+ ( pfa) !
   @ ?DUP IF >R THEN ;
: MAKE   STATE @ IF ( compiling)
   COMPILE (MAKE)  HERE MARKER !  0 ,
   ELSE  HERE  [COMPILE] ' !
    [COMPILE] ]  THEN ;   IMMEDIATE
: ;AND   COMPILE EXIT  HERE MARKER @ ! ;   IMMEDIATE
: UNDO   ['] NOTHING  [COMPILE] ' ! ;
: DOER   Create  ' NOTHING  ,  DOES> @ >r ;
Variable marker
: (MAKE)  r>  dup 2+  dup 2+  swap @  2+ ( pfa) !
   @ ?dup IF >r THEN ;
: MAKE   state @ IF ( compiling)
   COMPILE (MAKE)  here marker !  0 ,
   ELSE  here  [compile] ' !
    [compile] ]  THEN ;   immediate
: ;AND   COMPILE EXIT  here marker @ ! ;   immediate
: UNDO   ['] NOTHING  [compile] ' ! ;


( The code in this screen is in the public domain.)
@@ -283,7 +283,7 @@ VARIABLE MARKER
( TODDLER: Example of DOER/MAKE                      12/01/83 )
DOER ANSWER
: RECITAL
  CR ." Your daddy is standing on the table.  Ask him 'WHY?' "
  cr ." Your daddy is standing on the table.  Ask him 'WHY?' "
  MAKE ANSWER  ." To change the light bulb."
  BEGIN
  MAKE ANSWER  ." Because it's burned out."
@@ -294,8 +294,8 @@ DOER ANSWER
  MAKE ANSWER  ." Stop saying WHY?"
  MAKE ANSWER  ." Because it's driving me crazy."
  MAKE ANSWER  ." Just let me change this light bulb!"
  FALSE UNTIL ;
: WHY?   CR  ANSWER  QUIT ;
  false UNTIL ;
: WHY?   cr  ANSWER  quit ;
\end{Screen}
\index{D!DOER/MAKE|)}
\vfill
+17 −17
Original line number Diff line number Diff line
@@ -17,8 +17,8 @@ Standard is:
\begin{Code}
: ASCII  ( -- c)  \  Compile:  c  ( -- )
\ Interpret:   c   ( -- c)
     BL WORD 1+ C@  STATE @
     IF [COMPILE] LITERAL  THEN ; IMMEDIATE
     bl word 1+ c@  state @
     IF [compile] Literal  THEN ; immediate
\end{Code}

\section{From \Chap{5}}
@@ -26,44 +26,44 @@ Standard is:
The word \forthb{\bs}\index{S!Skip commands} can be defined as:
\begin{Code}
: \  ( skip rest of line)
     >IN @  64 / 1+  64 *  >IN ! ; IMMEDIATE
     >in @  64 / 1+  64 *  >in ! ; immediate
\end{Code}
If you decide not to use \forthb{EXIT} to terminate a screen, you can
define \forthb{\bs S} as:
\begin{Code}
: \S   1024 >IN ! ;
: \S   1024 >in ! ;
\end{Code}
\index{F!FH|(}%
The word \forthb{FH} can be defined simply as:
\begin{Code}
: FH   \   ( offset -- offset-block)   "from here"
    BLK @ + ;
    blk @ + ;
\end{Code}
This factoring allows you to use \forth{FH} in many ways, e.g.:
\begin{Code}
: TEST   [ 1 FH ] LITERAL LOAD ;
: TEST   [ 1 FH ] Literal load ;
\end{Code}
or
\begin{Code}
: SEE   [ 2 FH ] LITERAL LIST ;
: see   [ 2 FH ] Literal list ;
\end{Code}
A slightly more complicated version of \forth{FH} also lets you edit or
load a screen with a phrase such as ``\forth{14 FH LIST},'' relative to
the screen that you just listed (\forth{SCR}):
\begin{Code}
: FH   \   ( offset -- offset-block)   "from here"
     BLK @  ?DUP 0= IF  SCR @  THEN  + ;
     blk @  ?dup 0= IF  scr @  THEN  + ;
\end{Code}
\index{F!FH|)}
\forthb{BL}\index{B!Blank space (BL)} is a simple constant:
\begin{Code}
32 CONSTANT BL
32 Constant bl
\end{Code}
\forthb{TRUE}\index{T!TRUE} and \forthb{FALSE}\index{F!FALSE}
can be defined as:
\begin{Code}
0 CONSTANT FALSE
-1 CONSTANT TRUE
0 Constant false
-1 Constant true
\end{Code}
(\Forth{}'s control words such as \forth{IF} and \forth{UNTIL} interpret
zero as ``false'' and any non-zero value as ``true.''  Before \Forth{}
@@ -73,13 +73,13 @@ which is the signed number $-1$ (all bits set).

\forthb{WITHIN}\index{W!WITHIN} can be defined in high level like this:
\begin{Code}
: WITHIN  ( n lo hi+1 -- ?)
     >R  1- OVER <  SWAP R>  < AND ;
: within  ( n lo hi+1 -- ?)
     >r  1- over <  swap r>  < and ;
\end{Code}
or
\begin{Code}
: WITHIN ( n lo hi+1 -- ?)
   OVER -  >R - R> U< ;
: within ( n lo hi+1 -- ?)
   over -  >r - r> u< ;
\end{Code}

\section{From \Chap{8}}
@@ -89,11 +89,11 @@ system implements \forthb{DO} \forthb{LOOP}s. If \forthb{DO} keeps two
items on the return stack (the index and the limit), \forthb{LEAP} must
drop both of them plus one more return-stack item to exit:
\begin{Code}
: LEAP   R> R> 2DROP  R> DROP ;
: LEAP   r> r> 2drop  r> drop ;
\end{Code}
If \forthb{DO} keeps \emph{three} items on the return stack, it must be
defined:
\begin{Code}
: LEAP   R> R> 2DROP  R> R> 2DROP ;
: LEAP   r> r> 2drop  r> r> 2drop ;
\end{Code}
+9 −9
Original line number Diff line number Diff line
@@ -31,12 +31,12 @@ This syntax will remain the same whether we define it to allocate growing
upward:
\begin{Code}
: RAM-ALLOT  ( #bytes-to-allot -- starting-adr)
    >RAM @  DUP ROT +  >RAM ! ;
    >RAM @  dup rot +  >RAM ! ;
\end{Code}
or to allocate growing downward:
\begin{Code}
: RAM-ALLOT  ( #bytes-to-allot -- starting-adr)
    >RAM @  SWAP -  DUP >RAM ! ;
    >RAM @  swap -  dup >RAM ! ;
\end{Code}
\end{enumerate}

@@ -46,15 +46,15 @@ or to allocate growing downward:
\item\fi Our solution is as follows:
\begin{Code}
\ CARDS Shuffle                              6-20-83
52 CONSTANT #CARDS
CREATE DECK  #CARDS ALLOT   \ one card per byte
52 Constant #CARDS
Create DECK  #CARDS allot   \ one card per byte
: CARD ( i -- adr) DECK + ;
: INIT-DECK  #CARDS 0 DO  I  I CARD  C!  LOOP ;
: INIT-DECK  #CARDS 0 DO  i  i CARD  c!  LOOP ;
INIT-DECK
: 'CSWAP  ( a1 a2 -- )  \  swap bytes at a1 and a2
   2DUP C@  SWAP C@  ROT C!  SWAP C! ;
   2dup c@  swap c@  rot c!  swap c! ;
: SHUFFLE   \  shuffle deck of cards
   #CARDS 0 DO  I CARD  #CARDS CHOOSE CARD  'CSWAP
   #CARDS 0 DO  i CARD  #CARDS CHOOSE CARD  'CSWAP
   LOOP ;
\end{Code}
\ifeightyfour\end{enumerate}\fi
@@ -63,7 +63,7 @@ INIT-DECK
\ifeightyfour\begin{enumerate}
\item This will work:
\begin{Code}
20 CHOOSE  2 CHOOSE  IF NEGATE THEN
20 CHOOSE  2 CHOOSE  IF negate THEN
\end{Code}
But this is simpler:
\begin{Code}
@@ -71,7 +71,7 @@ But this is simpler:
\end{Code}
\end{enumerate}\else
\begin{Code}
: DIRECTION  ( n|-n|0 -- 1|-1|0)  DUP  IF  0< 1 OR  THEN ;
: DIRECTION  ( n|-n|0 -- 1|-1|0)  dup  IF  0< 1 or  THEN ;
\end{Code}
\fi

Loading