home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / forth / pfe-0.000 / pfe-0 / pfe-0.9.13 / lib / struct.4th < prev    next >
Encoding:
Text File  |  1994-03-09  |  14.4 KB  |  471 lines

  1. \
  2. \    Structures and Bitmaps in Forth
  3. \
  4.  
  5. \ Copyright (c) 1993 Missing Link All Rights Reserved
  6. \ 975 East Ave, STE 112, California USA (916)343-8129
  7. \ Copying permitted for non-resale in complete unaltered
  8. \ form with the inclusion of this notice.
  9. \ Software comes without warranty of any kind. Missing Link
  10. \ disclaims all liability for damages of any kind resulting
  11. \ from its use.
  12.  
  13.  
  14. \ In order to understand the comments and datastructures in this tool
  15. \ the following precise definitions should be of assistance.
  16. \
  17. \ Definitions:
  18. \ Word        Description
  19. \
  20. \  Instance    An actual data structure created and allocated
  21. \        in the dictionary.  Live data.  Consists of the
  22. \        header, length cell, sizes of each dimention in the case
  23. \        of arrays, and reserved data space.  The instance is
  24. \        analogous with structures created by words created with
  25. \        the typedef declarator in C.
  26. \
  27. \  Type        A defining word that creates and allocates instances of
  28. \        a particular datastructure or creates element words of
  29. \        compound datastructures (i.e. other more complex types).
  30. \        The type can be optionally given one to three subscript
  31. \        expressions each within square brackets to indicate the type
  32. \        is to create a multi-dimensional array element or
  33. \        instance.  (Note: The square brackets must be used in
  34. \        interpreting mode else they will conflict with the Forth
  35. \        versions which turn on and off the compiler.  See below
  36. \        for examples)  The type is analogous to words created with
  37. \        the typedef operator in C.
  38. \
  39. \  Element    A word that when given an address at run time will add
  40. \        an internal offset to locate that sub-datastructure.  Can
  41. \        be given one to three optional subscripts in the case the
  42. \        element was defined as an array.  The element is analogous
  43. \        of the 'dot operators' of a C datastructure.
  44. \
  45. \  Simple    A non-array instance or element.
  46. \
  47. \  Complex    An array instance or element.
  48. \
  49. \  Row        A slice of the array that consists of the first index
  50. \        multiplied by the size of the type making up the array
  51. \        added to the starting address of the array.
  52. \
  53. \ Plane        A two dimensional slice of a three dimensional array
  54. \        analogous to the Row with an added dimension
  55. \
  56. \ Item        A single entry in an array.  Can consist of simple or
  57. \        compound structures which can themselves be arrayed.
  58. \
  59. \ End definitions
  60.  
  61. decimal forth definitions 
  62.  
  63. c" structures" find nip [if]  execute  [then]  marker structures
  64. c" defer" find nip 0= [if]  include library.4  [then]
  65.  
  66. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  67. \ \                                \
  68. \ \    Data Record Format                    \
  69. \ \                                \
  70. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  71.  
  72. \ Name: Type Record
  73. \
  74. \ cell    Description
  75. \ 0    whole size
  76. \
  77. \ Name: Simple Instance/Element
  78. \
  79. \ Cell    Description
  80. \ 0    whole size
  81. \ 1    data/offset
  82. \
  83. \
  84. \ Name: Bitfield Element
  85. \
  86. \ Cell    Description
  87. \ 0    whole size
  88. \ 1    mask
  89. \ 2    start bit location (1 byte long)
  90. \ 3    offset
  91. \
  92. \ Name: One Dimensional Array Instance/Element
  93. \
  94. \ Cell    Description
  95. \ 0    whole size
  96. \ 1    item size
  97. \ 2    data/offset
  98. \
  99. \ Name: Two Dimensional Array Instance/Element
  100. \
  101. \ Cell    Description
  102. \ 0    whole size
  103. \ 1    row size
  104. \ 2    item size
  105. \ 3    data/offset
  106. \
  107. \ Name: Three Dimensional Array Instance/Element
  108. \
  109. \ Cell    Description
  110. \ 0    whole size
  111. \ 1    plane size
  112. \ 2    row size
  113. \ 3    item size
  114. \ 4    data/offset
  115.  
  116.  
  117. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  118. \ \                                \
  119. \ \    Required Variables and Values                \
  120. \ \                                \
  121. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  122.  
  123. 0 value defining
  124.  
  125. \ subscript array
  126.  
  127. 3 1 cell-array subscript
  128.  
  129. \ number of bits requested in this element
  130.  
  131. 0 value (bits)
  132.  
  133. \ current bitfield length
  134.  
  135. 0 value bitfield-length
  136.  
  137. \ current bitfield next available bit
  138.  
  139. 0 value next-bit
  140.  
  141.  
  142. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  143. \ \                                \
  144. \ \    Variable Support Words                    \
  145. \ \                                \
  146. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  147.  
  148. \ initialize all these values and variables
  149.  
  150. : /bitfield ( n - n')   next-bit if   bitfield-length +   then  0 to (bits)
  151.    0 to bitfield-length   0 to next-bit ;
  152.  
  153. : /array   3 0 do   0 i subscript !   loop ;
  154.  
  155. : #subscripts ( - n)  3  3 0 do   i subscript @  0= if  drop i leave
  156.    then  loop ;
  157.  
  158. \ the interpreted version of [ evaluates the code before the ] and
  159. \ places the resultant value (the size of the array subscript) in the
  160. \ proper place in the subscript array
  161.  
  162. : [ ( ___ ']')    state @ if  postpone [  else  [char] ] word
  163.    count evaluate  #subscripts  subscript !   then ; immediate
  164.  
  165. : bit ( n)   to (bits) ;
  166.  
  167.  
  168. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  169. \ \                                \
  170. \ \    Bitfield Support Words                    \
  171. \ \                                \
  172. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  173.  
  174. \ Return bit value n3 from address a1 starting at bit n2 masked with mask n1
  175.  
  176. : b@ ( a1 n1 n2 - n3)  >r  swap @  and  r> rshift ;
  177.  
  178.  
  179. \ Store bit value n1 to address a1 with mask n2 starting at bit position n3
  180.  
  181. : b! ( n1 a1 n2 n3)  >r  rot  r> lshift  over and  >r  invert  over @
  182.    and  r> or   swap ! ;
  183.  
  184.  
  185. \ given the number of bits required, return the number of bits
  186. \ left over in the word.  Answer is negative if overflow.
  187.  
  188. : bits-left ( n1 - n2)   bitfield-length [ 1 cells ] literal min  8 *
  189.    swap next-bit +  - ;
  190.  
  191.  
  192. \ return the mask of the number of bits n1 and the start bit n2
  193.  
  194. : >mask ( n1 n2 - n')  2 swap ** swap ?dup if  1- 0 do  dup 1 lshift
  195.    or  loop  then ; 
  196.  
  197.  
  198. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  199. \ \                                \
  200. \ \    Instanciation Support Words                \
  201. \ \                                \
  202. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  203.  
  204.  
  205. \ return data address a3 given type record address (TRA) a2 and instance
  206. \ address a1
  207.  
  208. \ : (simple) ( a1 a2 - a3)   nip ;    \ not needed but included for
  209.                     \ possible future expantion
  210.  
  211.  
  212. \ given the index n, instance address a2 and TRA a1, return data address a3
  213.  
  214. : (1array) ( n a1 a2 - a3)  >r  [ 1 cells ] literal + @ *   r> + ;
  215.  
  216.  
  217. \ given indices n1, n2, instance address a2, TRA a1, return data address a3
  218.  
  219. : (2array) ( n1 n2 a1 a2 - a3)   >r  dup >r  [ 2 cells ] literal +  @  *
  220.    swap  r>  [ 1 cells ] literal +  @  *  + r>  + ;
  221.  
  222.  
  223. \ given indices n1, n2, n3, instance address a2, TRA a1, return data address
  224. \ a3
  225.  
  226. : (3array) ( n1 n2 n3 a1 a2 - a3)   >r dup >r  [ 3 cells ] literal +
  227.    @  *  swap r@ [ 2 cells ] literal + @  *  +  swap r> [ 1 cells ] literal
  228.    +  @  *  +  r>  + ;
  229.  
  230.  
  231. \ give instance address a2, TRA a1; return bitfield address a3, mask n1
  232. \ and start bit position n2
  233.  
  234. : (bitfield) ( a1 a2 - a3 n1 n2)   swap dup  [ 1 cells ] literal + @  swap 
  235.    [ 2 cells ] literal + c@ ;
  236.  
  237.  
  238. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  239. \ \                                \
  240. \ \    Defining Words                        \
  241. \ \                                \
  242. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  243.  
  244. \ Compile:
  245. \ given the address of a type, create a simple instance
  246. \ Run:
  247. \ given the address of the instance record a1; return the address of the
  248. \ instance data a2
  249.  
  250. : simple-instance: ( a _)   create   @ dup , here swap dup allot  erase 
  251.    does> ( a1 - a2)   \ should be:  dup [ 1 cells ] literal +  (simple) ;
  252.      [ 1 cells ] literal + ;    \ but this is much quicker
  253.  
  254. \ Compile:
  255. \ given the address of a type and a current offset, create a simple element
  256. \ and return the adjusted offset
  257. \ Run:
  258. \ given the data address a1 and the element record address a2, return the
  259. \ address of the live data a3
  260.  
  261. : simple-element: ( n a _ - n')   create  >r  /bitfield  r> @ dup , over , +
  262.    does> ( a1 a2 - a3)
  263.    \ should be: dup [ 1 cells ] literal + @  rot +   (simple) ;
  264.      [ 1 cells ] literal + @ + ;  \ but this is much quicker
  265.  
  266. \ Compile:
  267. \ given the current offset n within the type being defined and the TRA for
  268. \ the host type of the bitfield, create a bitfield element with the name
  269. \ in the input stream.  Return the adjusted offset n if the type is not
  270. \ the host type is not the same length or there are not enough bits left
  271. \ in the host type else leave n unchanged.
  272. \ Run:
  273. \ given the address of the instance a1 and the Element Record Address (ERA)
  274. \ a2; return the instance address a3, the bitmask n1, and the start bit number
  275. \ n2.
  276.  
  277.  
  278. : bitfield-element: ( n a _ - n')    create
  279.    @   dup bitfield-length -     \ has bitfield length changed?
  280.    (bits) dup >r  bits-left 0<    \ are there not enough bits left in this type?
  281.    or  if            \ at this point: ( offset len)  (r: bits)
  282.      swap  /bitfield  swap    \ advance offset value and reinitialize
  283.      [ 1 cells ] literal min  dup to bitfield-length
  284.    then  ,              \ the size of the type containing bitfield
  285.    r@   next-bit dup  r>  +  to next-bit    \ ( offset bits nextbit)
  286.    dup >r  >mask ,   r> c,    \ the mask and start bit location
  287.    dup ,   0 to (bits)        \ and the offset; 0 (bits) for next time
  288.    does> ( a1 a2 - a3 n1 n2)  dup   [ 2 cells 1+ ] literal + @  rot +
  289.    (bitfield) ;
  290.  
  291. \ Compile:
  292. \ given the address of a type a, create a one dimensional instance
  293. \ Run:
  294. \ given the address of the instance record a1, the index n; return the
  295. \ address of the instance data a2.
  296.  
  297. : 1array-instance: ( a _ - )   create  @  dup  [ 0 subscript ] literal @  *
  298.    dup >r ,  ,   here   r@ allot   r> erase
  299.    does> ( n a1 - a2) dup [ 2 cells ] literal +  (1array) ;
  300.  
  301. \ Compile:
  302. \ given the address of the type a and current offset n; from the input
  303. \ stream create a single dimensioned element returning the adjusted offset
  304. \ Run:
  305. \ given the subscript n, the address of the live data a1, and the address
  306. \ of the instance record a2, return the address of the desired array item
  307.  
  308. : 1array-element: ( n a _ - n')   create   @  [ 0 subscript ]  literal @
  309.    over *  dup >r ,   ,  dup ,  r> +
  310.    does> ( n a1 a2 - a3)  dup [ 2 cells ] literal + @  rot +  (1array) ;
  311.  
  312. \ Compile:
  313. \ given the address of a type a, create a two dimensional instance
  314. \ Run:
  315. \ given the address of the instance record a1, the indexes n1 and n2;
  316. \ return the address of the desired item a2
  317.  
  318. : 2array-instance: ( a _)   create  @   [ 1 subscript ] literal @  over *
  319.    [ 0 subscript ] literal @  over *   dup >r  , , ,  here r@ allot  r> erase
  320.    does> ( n1 n2 a1 - a2)  dup [ 3 cells ] literal +  (2array) ;
  321.  
  322. \ Compile:
  323. \ given the address of a type a and a current offset n; from the
  324. \ input stream create a two dimension element returning the adjusted
  325. \ offset
  326. \ Run:
  327. \ given the subscripts n1 and n2, the address of the live data a1, and the
  328. \ address of the element record a2, return the address of the desired array
  329. \ item a3
  330.  
  331. : 2array-element: ( n a _ - n')   create  @  [ 1 subscript ] literal @
  332.    over  *  [ 0 subscript ] literal @  over *  dup >r  , , ,  dup , r> + 
  333.    does> ( n1 n2 a1 a2 - a3)  dup [ 3 cells ] literal + @  rot + (2array) ;
  334.  
  335. \ Compile:
  336. \ given the address of type a, create a three dimensional instance
  337. \ Run:
  338. \ given the address of the instance record a1, the indexes n1, n2 and n3;
  339. \ return the address of the desired item a2
  340.  
  341. : 3array-instance: ( a _)   create  @   [ 2 subscript ] literal @  over *
  342.    [ 1 subscript ] literal @  over *  [ 0 subscript ] literal @
  343.    over *  dup >r  , , , ,   here r@ allot  r> erase
  344.    does> ( n1 n2 n3 a1 - a3)   dup [ 4 cells ] literal +  (3array) ;
  345.  
  346. \ Compile:
  347. \ given the address of type a, and a current offset n; from the input
  348. \ stream create a three dimension element returning the adjusted offset
  349. \ Run:
  350. \ given the subscripts n1 n2 and n3, the address of the live data a1,
  351. \ return the address of the desired array item a2.
  352.  
  353. : 3array-element: ( n a _ - n')   create  @ [ 2 subscript ] literal @
  354.    over *  [ 1 subscript ] literal @  over *  [ 0 subscript ] literal @
  355.    over *  dup >r  , , , ,  dup ,  r> + 
  356.    does> ( n1 n2 n3 a1 - a2)   dup  [ 4 cells ]  literal + @ rot +  (3array) ;
  357.  
  358. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  359. \ \                                \
  360. \ \    Integration                        \
  361. \ \                                \
  362. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  363.  
  364. \ Compile:
  365. \ given the offset in the case of defining a type, nothing in the case
  366. \ of creating an instance, based upon the contents of the subscript array
  367. \ and the defining value call the proper defining word above for arrays
  368. \ Run:
  369. \ varies depending on the above
  370.  
  371. : struct: ( _)   create  here 0 0 ,  true to defining
  372.    does> ( [n] a)
  373.     defining if  ( n a)
  374.         (bits) if
  375.             bitfield-element:
  376.         else
  377.             swap /bitfield swap
  378.             #subscripts case
  379.                 0 of    simple-element:        endof
  380.                 1 of    1array-element:        endof
  381.                 2 of    2array-element:        endof
  382.                 3 of    3array-element:        endof
  383.             endcase
  384.         then
  385.     else  ( a)
  386.         (bits) abort" ? Cannot define bitfield outside struct def"
  387.         swap /bitfield swap
  388.         #subscripts case
  389.             0 of    simple-instance:    endof
  390.             1 of    1array-instance:    endof
  391.             2 of    2array-instance:    endof
  392.             3 of    3array-instance:    endof
  393.         endcase
  394.     then
  395.    /array
  396. ;
  397.  
  398. : ;struct ( a n)   /bitfield  swap !   false to defining ;
  399.  
  400.  
  401. : sizeof: ( _ - n)   [compile] ' >body @   [compile] literal ; immediate
  402.  
  403. : (sub-array-sizeof:) ( n _)   create   cells  c,  immediate
  404.    does> ( n a _ - n)   c@ swap -   [compile] ' >body + @   state @ if
  405.    [compile] literal  then ;
  406.  
  407. 0 cells constant item    immediate
  408. 1 cells constant row     immediate
  409. 2 cells constant plane    immediate
  410.  
  411. 1 (sub-array-sizeof:) 1xSizeof:
  412. 2 (sub-array-sizeof:) 2xSizeof:
  413. 3 (sub-array-sizeof:) 3xSizeof:
  414.  
  415.  
  416. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  417. \ \                                \
  418. \ \    Example of Use                        \
  419. \ \                                \
  420. \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  421.  
  422. \ The current accumulated size of the structure is on the stack.
  423. \ With simple types the address of the data area is pointed to
  424. \ directly when instances created by the type is run.  With complex
  425. \ types one or more subscripts must be passed to the instance word
  426. \ to point to the proper item.  Pointers to complex types (that have
  427. \ been malloced for instance) must be implemented as elements. Through
  428. \ this mechanism every kind of C datastructure should be able to be
  429. \ implemented easily.
  430.  
  431.     struct: int:    1 cells +    ;struct
  432.     struct: byte:    1 +        ;struct
  433.     struct: short:    1 cells 2/ +    ;struct
  434.     struct: double:    8 +        ;struct
  435.     struct: single:    8 +        ;struct
  436.     struct: ptr:    1 cells +    ;struct
  437.  
  438.  
  439. \     struct: point:        \ as in a graphical point on a screen
  440. \            short:        x
  441. \            short:        y
  442. \        4 bit    byte:        color
  443. \        4 bit    byte:        intensity
  444. \            ptr: ( point: )    next.point
  445. \    ;struct
  446. \
  447. \    struct: line:        \ a line segment
  448. \            point:        start
  449. \            point:        end
  450. \            byte:        priority
  451. \            byte:        color
  452. \            ptr: ( line: )    next.line
  453. \    ;struct
  454. \
  455. \
  456. \    line: top  line: bot  line: left  line: right
  457. \
  458. \            10 10 top start >r  r@ y w!  r> x w!
  459. \            300 500 bot start >r  r@ y w!  r> x w!
  460. \            10 300 left start >r  r@ y w!  r> x w!
  461. \            ....
  462. \
  463. \    bot  top next.line !   left  bot next.line !
  464. \    right  left next.line !   top  right next.line !
  465. \
  466. \    bot next.line @ start x w@ .   10 ok
  467. \
  468. \
  469.  
  470. \ THIS FILE HAS NOT BEEN TRUNCATED
  471.