Lesson 5: Constants, Variables, Values, and Arrays
This is a pretty big lesson, but the material is all closely related. The individual segments are pretty short though.
Constants
For data that does not change, a constant can be created as follows:
100 is-data OneHundred " /home/crc/htdocs/" is-data docroot
The first example takes the number 100, and assigns a name (OneHundred) to it. The name can now be used as a symbolic constant at the listener or inside a quote. The second example creates a named pointer to a string, which can also be used at the listener or inside quotes.
The use of constants is encouraged as it makes code easier to read and maintain. They have minimal impact on performance, and are significantly faster to use than variables.
Variables
To hold data for longer periods of time than is practical with the stack, variables can be used. Variables are pointers to memory locations large enough to hold a number. There are two primary ways to create variables:
variable foo variable bar variable baz
The above would create three new variables, named foo, bar, and baz. When creating multiple variables, it is more readable to use variable| though:
variable| foo bar baz |
You can use @ (fetch) and ! (store) to alter the contents of a variable:
variable foo 100 foo ! foo @ .
For reading/writing character-sized values, c@ and c! are also provided. A full list of functions for working with variables follows:
variable ( "- ) Parse ahead and create a named entry
corresponding to a memory location
variable| ( |- ) Parse and create variables until |
is encountered.
@ ( a-n ) Fetch the value from variable 'a'
! ( na- ) Store 'n' to variable 'a'
c@ ( a-n ) Fetch a byte from variable 'a'
c! ( na- ) Store byte 'n' to variable 'a'
Values
Values are a special form of variable that may be more readable in many situations. They have a default action of @, so you do not have to manually fetch their values. The value stored in them can be updated using to. For example,
value foo foo . 100 to foo foo .
Arrays
The standard bootstrap adds support for arrays. These are a superset of variables, and hold either character or numeric data.
The words provided are:
is-array n"- Create an array of size n. Parses for the name.
array.put nia- Put value (n) into array (a) at index (i)
array.get ia-n Get the value (n) from array (a) at index (i)
array.putChar nia- Put character value (n) into array (a) at index (i)
array.getChar ia-n Get the character value (n) from array (a) at
index (i)
Example:
10 cells is-array foo 0 foo array.get . 100 0 foo array.put 10 1 foo array.put 0 foo array.get . 1 foo array.get .
Tips
- The command line arguments are stored in an array (arglist).
- At 0 is the name of the script
- Actual arguments start at 1.
- Be careful not to exceed the length of your array when giving an index
A Word on Data Types
Toka has one data type, called the cell. This is a machine dependent sized memory area that can hold a single number or pointer. On 32-bit systems, cells are 4 bytes in length, and on 64-bit systems, they take 8 bytes. A constant, cell-size, returns the exact length provided by Toka on your system.
Cells can hold numbers, pointers to allocated memory, and pointers to quotes. When Toka encounters a number or a pointer, it is placed on the stack. For more permanent storage, you can store cell values into memory locations for later use.
This is where a number of abstractions arise. Memory allocated for storage of values is called variables. Memory allocated for sequences of values are called arrays. And a special class of array is used for sequences of characters. These are called strings.
In all of these, when you reference them, a pointer is left on the stack. Pointers are simply numbers corresponding to an actual memory address. It is up to you to know what abstract data type a pointer represents.
Tips
- You are strongly encouraged to use cell-size and char-size instead of hard coding the sizes for data. Doing so helps ensure readability and portability.