Variables can identify two types of values: real numbers (no suffix appended to variable name) and character strings (“$” suffix appended).
Variables in action:
pi = 3.1416
name$ = "Bob"
Scalars
Scalars are variables that can hold only one value:
town$ = "Tinyville"
population = 100
Scalars need not be declared prior to use, but note that an error will be reported if a program tries to access a scalar variable that has not previously been assigned a value.
Arrays
Arrays are variables that can hold more than one value:
town$ (1) = "Randomville"
population (1) = 30000
town$ (2) = "Somewhereton"
population (2) = 20000
Arrays can have any number of dimensions.
The position of an element in an array is specified using indices. Given an index n, an upper bound b, and assuming that n and b are both members of the set of integers, 0 must be less than or equal to n, and n in turn must be less than or equal to b.
Arrays need not be declared prior to use, but note that an error will be reported if a program tries to access an array element that has not previously been assigned a value.
Structures and user-defined types
User-defined types (UDTs) are “templates” for structures. They can be built out of scalars, arrays, and structures.
Structures can be explicitly created:
struct some_structure
some_component
end struct
or made from UDTs:
type some_type
some_component
end type
struct some_structure_1 as some_type
struct some_structure_2 as some_type
For example:
type crate
name$
apples
oranges
pears
end type
struct crate (2) as crate
crate (1).name$ = "CR001"
crate (1).apples = 30
crate (1).oranges = 50
crate (1).pears = 40
crate (2).name$ = "CR002"
crate (2).apples = 40
crate (2).oranges = 25
crate (2).pears = 50
Subroutine arguments/parameters
Arguments passed to subroutines are stored in variable parameters:
v (1) = 3
values (1, 2, v ())
sub values (a, b, c ())
print a, b, c (1) // output will be "1 2 3"
return
end sub
Each argument must correspond to a variable parameter, and vice-versa; an error will be reported if too many or too few arguments are passed to a subroutine.
By default, scalar arguments are passed “by value”, and arrays are passed “by reference”; however, the keywords byval and byref can be used to override this:
a = 2
print a // output will be "2"
assign (a, 7)
print a // output will be "7"
sub assign (byref scalar, byval value)
scalar = 7
return
end sub
Structures can be passed as subroutine arguments:
crate.apples = 30
crate.oranges = 50
crate.pears = 40
count_fruit (crate)
sub count_fruit (crate)
print crate.apples, "apples" // output will be "30 apples"
print crate.oranges, "oranges" // output will be "50 oranges"
print crate.pears, "pears" // output will be "40 pears"
return
end sub
Global, local, and static variables
(Note: For the purpose of clarification, and in light of some flaws in my own thinking, I have edited this section multiple times.)
By default, variables are “global”; that is, they can be accessed both from within the main program body and from inside subroutines.
Variables inside subroutines can be declared “local”. A local variable can only be accessed from inside its own subroutine; also, a local variable, if one exists, will be always used within a subroutine in preference to a global variable of the same name. For example:
a = 1
print example_1 (), a // will print "2 2"
a = 1
print example_2 (), a // will print "2 1"
sub example_1 ()
a = 2 // changes the value of the global "a"
return a
end sub
sub example_2 ()
local a
a = 2 // changes the value of the local "a", not that of the global "a"
return a
end sub
By default, a local variable will lose its value when its subroutine returns. A “static” variable is a special form of local variable that keeps its value when the subroutine that it is in returns. For example:
increment_values () // output will be "1 2"
increment_values () // output will be "2 3"
sub increment_values ()
static a = 1, b = 2, c () = { 1 }
print a, b
return
end sub
Static variables must be assigned an initial value.