[comp.lang.forth] Record Structure Package for forth

oster@dewey.soe.berkeley.edu (David Phillip Oster) (07/22/87)

As promised, here is a simple, pascal flavored record sturcture package for
forth. It lets you define record structure types, create variables of that
type, and address the fields of those variables.

Inheritance, and message passing are left as exercises for the reader.
----------------------------
( Pascalish Record Package,for FORTH 83  dpo 7/22/87 )

VARIABLE INRECORD  ( Holds a flag )

( DOOFFSETR - Runtime of .PascalField )
( must be a separate word, so that DOES> will see semicolon )
: DOOFFSETR DOES> ( adrRecord adrOffset - adrRecord+Offset )
      @  + ;

( DOPASREC - run time actions for PascalType: )
( two major cases: declaring a .PascalField, declaring a var )
: DOPASREC  ( -- ) DOES> @ CREATE  INRECORD @ IF
                        OVER , DOOFFSETR +  ELSE
                                      ALLOT THEN ;

\ define a type that is NOT composed of smaller types. n = length in bytes
: MAKEREC: ( n - ; name )  CREATE , DOPASREC ;

\ begin a record definition
: RECORD ( - 0 | intialize vars ) INRECORD ON  0 ;

\ end a record definition
: ENDREC:  ( n - ; name )         INRECORD OFF MAKEREC: ;

\ turn a type name into its size
: SIZEOF< ( - n ; name ) ' >BODY @ 
     STATE @ IF COMPILE (LIT) , THEN ; IMMEDIATE

( Macintosh primitive types. Lengths in bytes 12/26/84 dpo)
4 MAKEREC: LongInt:
2 MAKEREC: Integer:    
1 MAKEREC: Boolean:
8 MAKEREC: Pattern:
4 MAKEREC: RgnHandle:
4 MAKEREC: Handle:      
4 MAKEREC: PTR:

(some Macintosh compound types )
  RECORD
    Integer: .ASCENT
    Integer: .DESCENT
    Integer: .WIDMAX
    Integer: .LEADING
  ENDREC: FontInfoRec:

  RECORD
    Integer: .v
    Integer: .h
  ENDREC: Point:

  RECORD
    Point: .topLeft
    Point: .botRight
  ENDREC: Rect:

: .top    .topLeft .v ;
: .left   .topLeft .h ;
: .bottom .botRight .v ;
: .right  .botRight .h ;

( some variable definitions)
Rect: myRect1
Handle: myHandle

( an example of using variables and field selectors )
4  myRect1 .top !
4  myRect1 .left !
40 myRect1 .bottom !
40 myRect1 .right !

myRect1 FrameRect

sizeof< Rect: NewHandle myHandle !

----------------------------------------
Points to note --  names that end in ':' are defining words. 

Type names, (created with EndRec:) when used in the context of a record 
definition, define field selectors, otherwise, they define variables.

Field selectors take an address, and adjust that address to point at their
field.

SizeOf< takes a type name from the input stream, and returns the length of
the type.
--- David Phillip Oster            --My Good News: "I'm a perfectionist."
Arpa: oster@dewey.soe.berkeley.edu --My Bad News: "I don't charge by the hour."
Uucp: {seismo,decvax,...}!ucbvax!oster%dewey.soe.berkeley.edu