Diff for /gforth/doc/gforth.ds between versions 1.58 and 1.59

version 1.58, 2000/07/14 09:24:06 version 1.59, 2000/07/16 20:09:37
Line 309  Defining Words Line 309  Defining Words
 * Aliases::  * Aliases::
 * Supplying names::  * Supplying names::
   
   User-defined Defining Words
   
   * CREATE..DOES> applications::  
   * CREATE..DOES> details::       
   * Advanced does> usage example::  
   
 Interpretation and Compilation Semantics  Interpretation and Compilation Semantics
   
 * Combined words::  * Combined words::
Line 351  Programming Tools Line 357  Programming Tools
 * Assertions::                  Making your programs self-checking.  * Assertions::                  Making your programs self-checking.
 * Singlestep Debugger::         Executing your program word by word.  * Singlestep Debugger::         Executing your program word by word.
   
   Assembler and Code Words
   
   * Code and ;code::              
   * Common Assembler::            Assembler Syntax
   * Common Disassembler::         
   * 386 Assembler::               Deviations and special cases
   * Alpha Assembler::             Deviations and special cases
   * MIPS assembler::              Deviations and special cases
   * Other assemblers::            How to write them
   
 Locals  Locals
   
 * Gforth locals::                 * Gforth locals::               
Line 6271  locals declarations for stack effect spe Line 6287  locals declarations for stack effect spe
 @menu  @menu
 * CREATE..DOES> applications::    * CREATE..DOES> applications::  
 * CREATE..DOES> details::         * CREATE..DOES> details::       
 * Advanced does> usage::          * Advanced does> usage example::  
 @end menu  @end menu
   
 @node CREATE..DOES> applications, CREATE..DOES> details, User-defined Defining Words, User-defined Defining Words  @node CREATE..DOES> applications, CREATE..DOES> details, User-defined Defining Words, User-defined Defining Words
Line 6321  DOES> ( n2 -- n1+n2 ) Line 6337  DOES> ( n2 -- n1+n2 )
 -2 curry+ 2-  -2 curry+ 2-
 @end example  @end example
   
 @node CREATE..DOES> details, Advanced does> usage, CREATE..DOES> applications, User-defined Defining Words  @node CREATE..DOES> details, Advanced does> usage example, CREATE..DOES> applications, User-defined Defining Words
 @subsubsection The gory details of @code{CREATE..DOES>}  @subsubsection The gory details of @code{CREATE..DOES>}
 @cindex @code{CREATE} ... @code{DOES>}, details  @cindex @code{CREATE} ... @code{DOES>}, details
   
Line 6379  CREATE name EXECUTE ( ... -- ... ) Line 6395  CREATE name EXECUTE ( ... -- ... )
   
 doc->body  doc->body
   
 @node Advanced does> usage,  , CREATE..DOES> details, User-defined Defining Words  @node Advanced does> usage example,  , CREATE..DOES> details, User-defined Defining Words
 @subsubsection Advanced does> usage  @subsubsection Advanced does> usage example
   
   The MIPS disassembler (@file{arch/mips/disasm.fs}) contains many words
   for disassembling instructions, that follow a very repetetive scheme:
   
   @example
   :noname @var{disasm-operands} s" @var{inst-name}" type ;
   @var{entry-num} cells @var{table} + !
   @end example
   
   Of course, this inspires the idea to factor out the commonalities to
   allow a definition like
   
   @example
   @var{disasm-operands} @var{entry-num} @var{table} define-inst @var{inst-name}
   @end example
   
   The parameters @var{disasm-operands} and @var{table} are usually
   correlated.  Moreover, there existed code defining instructions like
   this:
   
   @example
   @var{entry-num} @var{inst-format} @var{inst-name}
   @end example
   
   This code comes from the assembler and resides in
   @file{arch/mips/insts.fs}.
   
   So I had to define the @var{inst-format} words that performed the scheme
   above when executed.  At first I chose to use run-time code-generation:
   
   @example
   : @var{inst-format} ( entry-num "name" -- ; compiled code: addr w -- )
     :noname Postpone @var{disasm-operands}
     name Postpone sliteral Postpone type Postpone ;
     swap cells @var{table} + ! ;
   @end example
   
   Note that this supplies the other two parameters of the scheme above.
   
   An alternative would have been to write this using
   @code{create}/@code{does>}:
   
   @example
   : @var{inst-format} ( entry-num "name" -- )
     here name string, ( entry-num c-addr ) \ parse and save "name"
     noname create , ( entry-num )
     lastxt swap cells @var{table} + !
   does> ( addr w -- )
     \ disassemble instruction w at addr
     @@ >r 
     @var{disasm-operands}
     r> count type ;
   @end example
   
   Somehow the first solution is simpler, mainly because it's simpler to
   shift a string from definition-time to use-time with @code{sliteral}
   than with @code{string,} and friends.
   
   I wrote a lot of words following this scheme and soon thought about
   factoring out the commonalities among them.  Note that this uses a
   two-level defining word, i.e., a word that defines ordinary defining
   words.
   
   This time a solution involving @code{postpone} and friends seemed more
   difficult (try it as an exercise), so I decided to use a
   @code{create}/@code{does>} word; since I was already at it, I also used
   @code{create}/@code{does>} for the lower level (try using
   @code{postpone} etc. as an exercise), resulting in the following
   definition:
   
   @example
   : define-format ( disasm-xt table-xt -- )
       \ define an instruction format that uses disasm-xt for
       \ disassembling and enters the defined instructions into table
       \ table-xt
       create 2,
   does> ( u "inst" -- )
       \ defines an anonymous word for disassembling instruction inst,
       \ and enters it as u-th entry into table-xt
       2@@ swap here name string, ( u table-xt disasm-xt c-addr ) \ remember string
       noname create 2,      \ define anonymous word
       execute lastxt swap ! \ enter xt of defined word into table-xt
   does> ( addr w -- )
       \ disassemble instruction w at addr
       2@@ >r ( addr w disasm-xt R: c-addr )
       execute ( R: c-addr ) \ disassemble operands
       r> count type ; \ print name 
   @end example
   
   Note that the tables here (in contrast to above) do the @code{cells +}
   by themselves (that's why you have to pass an xt).  This word is used in
   the following way:
   
   @example
   ' @var{disasm-operands} ' @var{table} define-format @var{inst-format}
   @end example
   
   In terms of currying, this kind of two-level defining word provides the
   parameters in three stages: first @var{disasm-operands} and @var{table},
   then @var{entry-num} and @var{inst-name}, finally @code{addr w}, i.e.,
   the instruction to be disassembled.  
   
   Of course this did not quite fit all the instruction format names used
   in @file{insts.fs}, so I had to define a few wrappers that conditioned
   the parameters into the right form.
   
   If you have trouble following this section, don't worry.  First, this is
   involved and takes time (and probably some playing around) to
   understand; second, this is the first two-level
   @code{create}/@code{does>} word I have written in seventeen years of
   Forth; and if I did not have @file{insts.fs} to start with, I may well
   have elected to use just a one-level defining word (with some repeating
   of parameters when using the defining word). So it is not necessary to
   understand this, but it may improve your understanding of Forth.
   
   
 @node Deferred words, Aliases, User-defined Defining Words, Defining Words  @node Deferred words, Aliases, User-defined Defining Words, Defining Words
Line 8879  suite that contains all instructions.  O Line 9008  suite that contains all instructions.  O
 easy.  For actual coding you can take a look at  easy.  For actual coding you can take a look at
 @file{arch/mips/disasm.fs} to get some ideas on how to use data for both  @file{arch/mips/disasm.fs} to get some ideas on how to use data for both
 the assembler and disassembler, avoiding redundancy and some potential  the assembler and disassembler, avoiding redundancy and some potential
 bugs.  You can also look at that file (and @pxref{Advanced does> usage})  bugs.  You can also look at that file (and @pxref{Advanced does> usage
 to get ideas how to factor a disassembler.  example}) to get ideas how to factor a disassembler.
   
 Start with the disassembler, because it's easier to reuse data from the  Start with the disassembler, because it's easier to reuse data from the
 disassembler for the assembler than the other way round.  disassembler for the assembler than the other way round.

Removed from v.1.58  
changed lines
  Added in v.1.59


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>