home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / ntcode / jx4nt125 / obj4th / dimarray.utf (.txt) next >
Encoding:
Null Bytes Alternating  |  1995-05-19  |  12.0 KB  |  155 lines

  1. \ dimarray.utf ... n-dimensional self-indexing cell array
  2. \ ANS Forth compliant source code is Copyright (c)1994 by
  3. \ Jack J. Woehr, P.O. Box 51, Golden, Colorado 80402-0051
  4. \ jax@well.sf.ca.us 72203.1320@compuserve.com
  5. \ SYSOP RCFB (303) 278-0364 2400/9600/14400
  6. \ All Rights Reserved
  7. \ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  8. \ This is free software and can be modified and redistributed under
  9. \ certain conditions described in the file COPYING.TXT. The
  10. \ Disclaimer of Warranty and License for this free software are also
  11. \ contained in the file COPYING.TXT.
  12. \ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  13.  
  14. \ A Standard System still exists after this code is loaded.
  15.  
  16. \ the structure of a dimarray object:
  17. \ /#stored-indices/n1/n2/ .. /nn/ptr-to-data/
  18.  
  19. MARKER dimarray.utf
  20.  
  21. \ Execution engine
  22. : DO-DIMARRAY ( i*n a-addr1 -- a-addr2)
  23.     SWAP            \ index n does not need a multiplier
  24.     OVER            \ object address to TOS
  25.     @               \ get #dims
  26.     1- 0            \ that number, minus one is the number ...
  27.     ?DO             \ ... of multipliers to obtain
  28.         1 I 1+ 0    \ base multiplicand, for n times
  29.         ?DO         \ get size(n+i(m)) * size(n+i(m+1))
  30.             I 1+ CELLS 3 PICK + @ *
  31.         LOOP        \ prepare to shift multiplier out of way
  32.         >R ROT      \ then bring runtime index to top
  33.         R> *        \ bring back multiplier
  34.         +           \ add product to cumulative index
  35.     LOOP
  36.     CELLS           \ that many cells
  37.     SWAP
  38.     DUP @           \ plus those consumed by the compiled indices
  39.     1+ CELLS
  40.     +               \ yields data ptr address
  41.     @               \ data base address
  42.     +               \ added to caculated offset yields data address
  43. ;
  44.  
  45. \ This version works under RAM/ROM systems, e.g., VFSE-332.
  46. \ The non-standard words MODE? ( -- mid) and ?MODE ( mid --) 
  47. \ obtain and restore the current compilation mode, RAM or ROM.
  48. \ For more information on RAM and ROM see 
  49. \ : DIMARRAY ( i*n i --)
  50. \    DUP 1 < ABORT" Positive dimension count only."
  51. \    MODE? >R ROM       \ the overhead has to be ROMmed if a ROM system
  52. \    CREATE             \ create the dimarray object described above
  53. \    DUP ,              \ save the #indices
  54. \    DUP >R             \ keep a copy for later    R: -- n1 n2
  55. \    0
  56. \    ?DO
  57. \    I PICK ,           \ loop while embedding copies of indices ..
  58. \                       \ .. without removing originals from stack
  59. \    LOOP
  60. \    RAM HERE ROM ,     \ point to base of data storage
  61. \    R> 1- 0            \ get back number of indices    R: -- n1
  62. \    ?DO
  63. \      *                \ calculate data space requirements
  64. \    LOOP
  65. \    CELLS RAM ALLOT    \ ALLOT the data space
  66. \    R> ?MODE           \ restore data space pointer to before DIMARRAY R: --
  67. \    DOES> DO-DIMARRAY
  68. \ ;
  69.  
  70. \ This version works under RAM-only systems, e.g., Jax4th and ZEN.
  71. : DIMARRAY ( i*n i --)
  72.     DUP 1 <             \ If used in a program, substitute a THROW for ABORT"
  73.     ABORT" Positive dimension count only."
  74.     CREATE              \ create the dimarray object described above
  75.     DUP ,               \ store the #indices
  76.     DUP >R              \ and save a copy
  77.     0
  78.     ?DO
  79.     I PICK ,            \ embed indices without removing originals from stack
  80.     LOOP
  81.     HERE 1 CELLS + ,    \ point to base of data storage
  82.     R> 1- 0             \ get back number of indices
  83.     ?DO
  84.       *                 \ calculate data space requirements
  85.     LOOP
  86.     CELLS ALLOT         \ ALLOT the data space
  87.     DOES> DO-DIMARRAY
  88. ;
  89.  
  90. \ "So after you've created those multi-dimensional variable-length
  91. \ arrays with DIMARRAY, how do you keep track of the indices for
  92. \ error checking? The answer is DIMLIMS which
  93. \ checks indices for n-dimensioned array prior to 
  94. \ execution of the array-in-question's cfa.
  95. \ If indices out of bounds, abort with message.
  96.  
  97. : DO-DIMLIMS ( i*n xt -- a-addr)
  98.     DUP >R                  \ save that token! we'll need it later
  99.     >BODY                   \ address of indices & address overhead reside
  100.     DUP                     \ base addr of overhead, #indices field
  101.     @ DUP                   \ get # of indices
  102.     DEPTH 2 - < 0=          \ stack too shallow?
  103.     ABORT" Dimarray dimension error - stack depth"
  104.     0                       \ for #-of-indices iterations ...        
  105.     ?DO
  106.         I 1+ PICK           \ get one runtime index
  107.         OVER I 1+ CELLS + @ \ get corresponding compiled index
  108.         OVER >              \ is zero-based runtime less?
  109.         SWAP -1 >           \ is it non-negative?
  110.         AND 0=              \ but if test(s) fail ...
  111.     ABORT" Dimarray dimension error - index size" 
  112.     LOOP
  113.     DROP                    \ the overhead data address, but the xt ...
  114.     R> EXECUTE              \ ... gets executed as normal
  115. ;
  116.  
  117. : DIMLIMS \ index1 .. indexn --TIB-- ---
  118.     '                       \ execution token for the dimarray-created word
  119.     STATE @                 \ compiling?
  120.     IF                      \ yes
  121.         POSTPONE LITERAL POSTPONE DO-DIMLIMS
  122.     ELSE                    \ interpreting!
  123.         DO-DIMLIMS
  124.     THEN
  125. ; IMMEDIATE
  126.  
  127. \ USAGE ...
  128. \
  129. \        4 4 5 6 4 DIMARRAY MY-4D-ARRAY
  130. \
  131. \ creates a 4-dimensional array consisting of 4*4*5*6 cell-length
  132. \ entries organised into a zero-based indexing system which yields
  133. \ possible indices between 0-3 for the first dimension, 0-3 for
  134. \ the second dimension, 0-4 for the third and 0-5 for the last
  135. \ dimension in MY-4D-ARRAY. Now 
  136. \
  137. \        3 3 4 5 MY-4D-ARRAY
  138. \
  139. \ yields the address of the last entry in MY-4D-ARRAY, but typing
  140. \
  141. \        3 3 5 7 MY-4D-ARRAY
  142. \
  143. \ also yields an address, though an invalid one. So the usage
  144. \
  145. \        3 3 5 7 DIMLIMS MY-4D-ARRAY
  146. \
  147. \ will abort with an error message, instead of yielding a spurious
  148. \ address. DIMLIMS will also abort if any index is negative or on
  149. \ stack underflow.      
  150.  
  151. \ ~~~~~~~~~~~~~~~~~~~
  152. \ End of DIMARRAY.UTF
  153. \ ~~~~~~~~~~~~~~~~~~~
  154.  
  155.