*** This documentation is a work in progress ***
Methods
9.1 Example:
class myapp:myclass { // comment can go here
display(long my, long mx){ // comment can go here
// comments can be put on multiple lines
// like this
for i=1 to 10 // comments can be put on the end of code lines
? i
next
//
// comments can be put on a line by themselves
//
return i
} // and this comment is on the last code line
}
or
#app myapp
#class myclass
#method display
#parm long my
#parm long mx
for i=1 to 10
? i
next
return i
Note: The 2 examples above are compiled exactly the same. The second method is used by the IDE(Interactive Development Environment) to edit and compile just a single method of a class.
- The compiler directives set the default application to "myapp",
the default class name to "myclass", and the method name to "display",
and the name and type of each parameter to pass data with.
- The code for this method consists of only 4 lines.
- This code is automatically compiled when it is saved away.
- If there are any errors then a "*** Error 13 *** Variable has not been
defined." line will be inserted into the source code at the point the
compiler found an error and the compiled code property for the method will
be set to invalid.
- If an error message is inserted into the source code, it will be automatically
taken out when the code is next compiled.
- Only 1 error message will ever be put into the source code. (The problem
of cascading error messages makes only the first one normally valid in any
case.)
- In the above example the variable "i" is defined at the "for"
line and the "i=1" initializes that variable to 1. The variable
used in the "for" structure is always a 4 byte LONG integer so if
it is defined as anything else, it would be changed to a LONG at the "for"
structure line in any case.
- The brackets {} are used to show the start and end of a method.
- The first "{" must be at the end of the method declaration line.
(C allows you to place the "{" on the next line but that is not
ok in HAL)
- A comment can be put on the definition line by putting a "//"
and then the comment after the "{"
- The last bracket } must be at the start of a line with only white space
optionally in front. Comments can be put after a "//" on the "}"
line.
9.2 Method Variables:
- Variables do NOT have to be defined before they can be referenced, but a
runtime error will occur if you try to use data from a variable that has no
data in it.
- If a variable is defined explicitly in a method it's definition must come
before any code.
- It is good programming practise to define all variables at the top of the
method.
- Data can be stored in method variables in 3 ways.
- By defining them at the top of the method. (Sometimes! See examples.)
- By putting the variable in front of an equal sign, at the start of a line.
(assignment statement : the normal method)
- By using a method of the variable that puts a value in the variable.
- Character strings are variable length when they are defined in a method
but can only be fixed length when defined in an object.
- If a string is stored in a Char property of an object and it is larger than
the defined size of the Char property, then it is automatically truncated
to fit.
- All method code is compiled to a symbol table created at compile time. This
means that all data items that are referenced by the program must have an
entry in the method symbol table.
- Temporary constant variables are automatcially defined in the symbol table
just before they are used.
- References to the object properties that the current method is attached
to or references to any property of any object are accessed by an entry in
the methods' symbol table.
- Properties and methods of an object can be accessed by fully specifying
their name like "myapp:cust.name" or "myapp:cust.display(y,
x)".
- A period (.) denotes a Property of an Object unless the name is followed
by a "(" which means that you are specifying a Method.
- A colon ":" denotes either the Class or Object hierarchy.
Note: Assigning a value to an object property will NOT change it's type or size.
(Blobs are references so they can change in size) However, all method variable
types and sizes are set to whatever value is assigned to them using the "="
sign in an assignment statement. A method variable can change it's type during
the course of a method but the consequenses of this are left up to the programmer.
Examples:
// the following would create a variable but give it no value : a.is_null() is _TRUE
logical a
int a
long a
double a
number a
date a
char a
blob a
// the following would create the variable and create a new object or data string : .null is _FALSE
long a[5] // space allocated and all elements are set to zero
char a(20) // creates space for string and fills with \0 (binary zeros)
blob a(100) // creates blob of length 100 but size can be changed with "resize" method
object a(myclass) // creates a new object based on myclass : all properties are set to zero
index a(myclass) // creates a new index based on myclass : no entries
table a(myclass, 100) // creates a table based on myclass : record count is 0
// note: all vectors and matrixes are set to 0 at definition time : is_null() is _FALSE
// All vector and matrix variables are given the type "V" and have the properties of width and length.
// The value returned from them, however, is of the type of the vector or matrix variable, not type "V". (see 9.5 Vector and Matrixes)
All Methods Variables Contain These Properties:
The following information can be had from the default info() method of any
Method Variable.
NAME=A // name of the variable in the method : this isn't the full name of an object necessarily
TYPE=LONG // this is the variables type
SIZE=4 // this is the amount of space taken in the method : some variables use space elsewhere are so only a reference is stored
NULL=YES // this is YES if no data has been put in the variable : NO otherwise : useful for checking if a parameter passed any data
TEMP=NO // this is YES only if it is used for storing temporary results or constants
CLASS=TOOLS:LONG // all variables have a Class
Note: HAL contains the methods format(), info(), set(), and is_null() for all
variables. These are used to display the data (format), get information on the
variable(info), get and set the value of the varaible (set) and return whether
the variable has a value (is_null).
9.3 Constants:
- logical - _TRUE, _true, _FALSE, _false
- long - 5, -100, 10000000
- double - 1.1, 100.50
- char - "this is a string", 'this is also a string', 'this is David\'s
book'
- date[time] - "04-5-2004", "20040405", "2004-04-05",
"2004-04-05 14:32:10"
Note: In the string example a "\'" was used to put a "'" in the string even though that character was being used to define the string. See the appendix for a complete list of character escape sequences.
Note: There are no constants for the int, number, class, object, blob, index or
table variables.
9.4 Compiler Directives:
Each of the following statements tell the compiler information that is used
in compiling a method.
- If #app [app name] is put before the definition of a class, then that class
is defined in the application rather than in the global class.
- If #class [class hierarchy] is put before a property list then those properties
would be defined for that class. (All properties in the current class would
deleted)
- If #class [class hierarchy] is put before a class definition then the class
is defined in the class specified.
- If #object [object hierarchy] is put before an object creation statement,
that object is created in the object specified.
- A #method directive must be put after a #class directive. This is used to
edit a method without using the whole class definition.
- A #parm directive must be put after a #method directive. This is used to
declare a passing parameter of the method.
- If more than 1 #parm is used, then the number of parameters for this method
will be the number of #parm directives. (Order does matter.)
#include [file name]
#define [variable]=[object or class hierarchy]
#app [app name]
#class [class hierarchy]
#object [object hierarchy]
#method [method name]
#parm [parm definition]
9.5 Vectors and Matrixes:
Examples:
long a[5] // all 5 elements are set to 0
int b[10000] // all 10000 elements are set to 0
long c[2,3] // all 6 elements are set to 0
char d(20)[100] // vector is created and all strings are set to \0 (binary zero)
object mine(myclass)[20] // vector is created but no object is made
- All variable types can be defined as vectors like "a".
- All variable types can be defined as a matrix like "c" or "d".
"d" is a list of 100 char strings of maximum length 20.
- Vector and matrixes make 2 entries in the method symbol table.
- The first entry is the name of the variable and it's width, length
and location. The length of variable "c" is 2 and it's width
is 2. The length of "a" is 5 and it's width is 1.
- The second entry in the symbol table is a single example of what the
vector or matrix defines. The variable after "a" would be of
type "long" even though the type of "a" is "vector".
- When you specify an element of a vector, the compiler produces code
that will get the vector element(at execution time) and point to it's
value with the next symbol table entry.
- Even though the "b" variable in the above example is of vector
type, an assignment of an element of "b" to another variable would
show that variable type is "int" and not "vector". This
is because the symbol table entry just after the variable "b" has
a type of "int" and not "vector".
Examples:
a[2]=19000 // store 19,000 into 2 element of a
b[250]=a[2] // store 19,000 into 250th element of b after converting from 4 to a 2 byte integer
j=c[2] // create vector of length 3 called j and store row 2 of c in it
k=a // create vector k of length 5 and store all 5 elements of a in it
m=mine[10] // create object variable called m and put 10th element of mine into it (stores reference but doesn't create a new object)
Note: Look at the block structure for quickly traversing a vector or matrix.
long a[2,5]
block a
? a // this would print a row wise listing of matrix a
endb
long a[2,3],b[2,3],c[2,3]
block a,b,c // this block will loop for all the elements in the first variable
c=a+b // this would put the sum of each corresponding element of a and b into c
endb
long a[2,3]
b=0
block a
b=b+a // this puts the sum of all elements of a in b
endb
9.6 Tables:
Note: There is an exception to the above definition of vectors and matrixes.
(A "TABLE" variable CANNOT be defined as a vector or matrix.)
- A table is referenced by using [num1] to access the num1 row of the table
or [num1, num2] to access the num2 property of num1 row.
- How then can you make a vector of tables?
- A table is also an object, so you can store a list of tables as an object
vector.
- Unlike a normal matrix variable, a table can have different data types in
each column. Vectors and Matrix must be homogenious (have all the same type
of variables) but tables need not be.
Example:
class myclass {
char name(30)
char add_1(30)
char add_2(30)
char city(30)
char state(2)
char zip(10)
} // record length is 132 bytes
//
object a(table)[10] // this creates a vector of tables of length 10
=a[1].new(myclass, 100) // this would create the table based on myclass with cluster size 100
// and store the reference to it in the first element of a
#class xyz
#method display
//
table cust(myclass, 100) // this line creates a new table called cust using class myclass allocating 100 rows at a time
//
cust.name="David Clark" // one object of myclass is allocated for a table
=cust.append()
? cust[1,1] // displays "David Clark" Note: Records start at 1 not 0.
? cust[1].name // so would this
? cust[1] // display all data in the first row of cust
? cust.count() // would show 1 record in cust
//
// Note: By accessing a row or a field of a row, the data from that row is stored in the default object.
//
cust.name="Name 2"
=cust.append()
? cust.name // would show "Name 2"
? cust[2] // would display all data from row 2 including "Name 2"
? cust[1].name // would show "David Clark"
? cust.name // and so would this
=cust.append("David Clark,71 Whitehead Cres,,Brandon,ND,12345") // this would add this data to all the fields of record 3 in cust
// or
cust="David Clark,71 Whitehead Cres,,Brandon,ND,12345" // this would fill in the default object
=cust.append() // this would add record 3 to cust from the default data