 
 Prev: Doing It Again & Again
Prev: Doing It Again & Again  
 
 Next: Floating Point
 Next: Floating Point 
    ok variable \volume
    ok variable \name 16 allot
Here we have created two variables, one named \volume and
another named \name.  We happen to prefix variables with a
backslash to distinguish them from words and other storage types.
Upon creation, \volume is automatically alloted one cell,
enough to store a number between -2^31 and 2^31. A cell is made up of
bytes, in the case of our 32 bit Forth, a cell is 4 bytes.  A 64 bit
Forth may define a cell to be 8 bytes and a 16 bit Forth might use 2
byte cells. \name gets created exactly the same way as \volume, except that we tell Forth to set aside 16 more bytes for storage for storage purposes. This method is commonly used to store strings.
To store and retrieve numbers to a variable, we have two commands at our disposal: ! and @, respectively called store and fetch. These two words operate on memory addresses. If you place a variable on the stack, its location in memory is left on the stack as a positive integer. You can store or fetch the variable's value with ! and @.
    ok name .s  \ .s shows the contents of the stack.
    119920
    ok 10 swap .s !
    10 119920
    ok .s
    Empty
    ok name @ .s
    10
variable ( "name" -- ) Create a variable with name
"name". allot ( n -- ) Allocate n bytes of memory for the most recently created variable.
! ( n addr -- ) Store n at memory location addr.
@ ( addr -- n ) Fetch the value stored at addr.
    ok 4096 constant #step.resolution \ # of steps/Volt.
    ok #step.resolution .s
    4096
Most of our code prefixes constant names with a "#" for much the same
reason as we prefix variable names with "\".  Most of our older code
has not undergone this change, though. constant ( n "name" -- ) Define a constant "name" with value n.
    ok " This is a typical string." .s
    119921 24   \ The 1st number is the address, the 2nd is the length.
    ok p" This is a packed string." .s
    119921 24 119920
    ok count .s \ count extracts the length of the packed string.
    119921 24 119921 24
    ok type     \ display the first n characters from address.
    This is a packed string.
    ok type
    This is a packed string.
    ok .s
    Empty
Something interesting and important has happened here.  If you look
carefully, we created two different strings, a normal string and a
packed string, but when we printed each string out the same string was
displayed.  This happened because there is one specific address where
temporary strings are stored, in this example the address is
119920. So, in order to maintain multiple strings we need to have a
way of storing them. 
    ok variable pstring 80 allot    \ To hold an 80 char packed string.
    ok variable nstring 80 allot    \ To hold an 80 char normal string.
    ok p" This is a packed string."
    ok pstring "copy
    ok pstring ".                   \ ". is a synonym for COUNT TYPE.
    This is a packed string.
    ok " This is a normal string." nstring swap cmove
    ok nstring 24 type
    This is a normal string.
Here we use "copy to copy the contents of a packed string
address into another address and cmove to copy just the
string itself to an address.  We end up with two variables each
containing different strings.  You can easily convert a normal string
to a packed string. 
    ok " This will be a packed string."
    ok pstring pack
    ok ".
    This will be a packed string.
"copy ( addr1 addr2 -- ) copies the packed string at
addr1 to addr2. cmove ( addr1 addr2 n -- ) copies n bytes from addr1 to addr2.
pack ( addr1 n addr2 -- addr2 ) makes a packed string out of addr1 for n bytes and stores it in addr2.
place ( addr1 n addr2 -- ) Same as pack except that addr2 is not left on the stack.
count ( pstr -- addr len ) Converts a packed string into an address and a length.
    ok 10 .                 \ "dot"
    10
    ok 10 20 .s             \ "dot-s"
    10 20
    ok : test-dot-quote     \ "dot-quote"
            ." This is a string."  ;
    ok test-dot-quote
    This is a string.
    ok .( Print this now!)  \ "dot-paren"
    Print this now!
type ( addr len -- ) displays len bytes from
addr. . ( n -- ) displays the top stack item, removing it in the process.
.s ( -- ) displays the current contents of the stack.
." ( "string<quote>" -- ) display the string located between ." and " during runtime (i.e. when a word is executed).
.( ( "string<paren>" -- ) display the string bounded by .( and ) immediately.
    76 constant detsize                     \ #  bytes in det structure
 
    create  (det)        detsize allot      \ det structure for running system
    create  (dummydet)   detsize allot      \ det structure for loading files
 
    defer   det     \ det structure itself - can be assigned to either of above
    ' (det) is det  \ Default: det set for running
 
        0   field   det \detname   \ detector file name
       12   field   det \clockpgm  \ dsp 56k clock program file name
       24   field   det \datapgm   \ dsp 56k data acquisition program
        4   field   det \nout      \ detector outputs        
    (etc...)
There is no way of knowing how space is reserved for a string, so
using a string entry correctly is difficult.  A new data structure
method devised by Nat Cowen, which you need not concern yourself with
just yet, will look something like: 
    struct-type: {}(det)   is" Detector Parameters"
        12 strfield:  \detfile    is" (file) detector parameters"
        12 strfield:  \clockpgm   is" (file) dsp clock program"
        12 strfield:  \datapgm    is" (file) dsp data program"
           intfield:  \nout       is" # detector outputs"
        (etc...)
    end-struct-type
    struct: {}(det)   {}det       is" Running System (not loading from file)"
Each {}det structure will be made up of new data types
strfield: and intfield: from which information about
each variable or string can be extracted.
 
 Prev: Doing It Again And Again
Prev: Doing It Again And Again  
 
 Next: Floating Point
 Next: Floating Point