November 2002
Tutorial
A Simple KMAL Program
METHOD Simple() RETURNS Object_Class
PrintString_Instruction(string="Hello World");
RETURN Nothing;
END Simple
METHOD declarations require a name (Simple), a parameter list in parenthesis (of which there are none), and a return type (Object_Class). The body of this method has two statements. The first calls the PrintString_Instuction function (denoted by colon prefix) with the string "Hello World". The second returns the Nothing object.
KMAL is case sensitive with all-caps words being built-in language keywords. Everything else in this KMAL program refers to objects in the DBOS, or is defining those objects. The use of "Nothing" does not refer to a special null object, but rather is an ordinary object with no interesting features; it's only purpose is to act as a return value. In fact the concept of null is not allowed in KMAL because null is not an object.
KMAL is not whitespace dependent, except only to distinguish between words and compound symbols. This means that the programmer is free to format his code as he sees fit. You will notice that there is no need for a "BEGIN"-like keyword to declare code blocks in KMAL; lexical context is sufficient to do that.
All statements end with a semicolon.
Data Types
KMAL is a strong, static typed language (someday it will be dynamic, but that depends on user priorities). Until then, every variable must have a declared type. Since KMAL makes no real distinction between classes and types, this subject is as big as the DBOS class hierarchy, so only the most common are presented here:
Boolean
Two objects are used to represent TRUE
and FALSE. Both are instances of the class Boolean_Value.
Integers
Positive and negative integers can be specified, and are instances of Integer_Class. Integers are also objects, so can be passed messages if the programmer has some diabolical need to do so.
Characters
Characters are abstract objects that can be referred to by name, just like any other object in the DBOS. Characters are not limited to ASCII or even Unicode and the list of characters can be extended to by the programer. DBOS currently has the ASCII characters as instances of Character_Class.
Strings
Strings are sequences of characters and are instances of String_Class. They are delimited by double-quotes in KMAL and have some escape sequences. More on strings later.
Objects
All objects are instances of Object_Class.
Classes
Any instance of the Class_Class declares a type, and can have instances. This means Boolean_Value, Integer_Class, Object_Class and even Class_Class itself are all instances of Class_Class.
Fields and Variables
KMAL uses the term "field" to refer to variables. Both a method field and a class field are declared in identical formats:
"FIELD" <name> "AS" <type> ";"
Declaring a field requires the FIELD and AS keywords. The name can start with a letter and have any number of letters, digits or underscores following. The type is the name of any object that is an instance of Class_Class.
Examples:
FIELD isGood AS Boolean_Value;
FIELD result AS Integer_Class;
Assignment
After declaring a method field, it should be given a value. The right-hand side must be an expression that evaluates to the a subtype (not necessarily strict) of the left:
isGood=TRUE;
result=addInteger_Instruction(right=45, left=-27);
Operators
I am currently working on adding operators. You will notice that YAY allows for easy addition of operators to KMAL syntax. Please put your order in now.
Compare
As a proof of concept, the compare operator "==" (double equals) acts on objects. Only identical objects will result in TRUE.
(2==2) is TRUE
(3==4) is FALSE
("hi"=="hi") is FALSE (for now)
(FALSE==FALSE) is TRUE
(Nothing==Nothing) is TRUE
Control Flow
Simple Conditional
The simplest conditional statement has the form
"IF" "(" <Condition> ")" <Single Statement>
This form is only meant for a single statement to follow. The single statement is executed only if the condition is TRUE.
Example
IF (a==0) a=1;
Complex Conditional
Most conditional statments will require multiple statements, so the programmer must either use CASE or delimit the statements with BLOCK.
"IF" "(" <Condition> ")" "BLOCK"
<Statements>
"END" "BLOCK"
"CASE" "(" <Condition> ")"
<Statements>
"ELSE"
<Else Statements>
"END" "CASE"
The CASE statement is superior because it will execute the ELSE statement in the event that the condition is false. CASE can also be cascaded to test multiple conditions
Example
FIELD compareResult AS Integer_Class;
compareResult=:CompareInteger_Instruction(Value1=A, Value2=B);
CASE (compareResult==0)
PrintString_Instruction(string="A and B are the same\n");
CASE (compareResult>0)
PrintString_Instruction(string="A is larger than B\n");
ELSE
PrintString_Instruction(string="A is smaller than B\n");
END CASE
For each CASE cascade there can only be one ELSE statement, and can be omitted if it is not required.
Loops
To repeat a set of statements, the FOR statement is used.:
"FOR" "(" <Parameters> ")" <Statements> "END" "FOR"
"FOR" <Name> "(" <Parameters> ")" <Statements> "END" <Name>
If the loop is given a name then the END must also specify the same name. The parameters are variables that span some given set. In the event that there are no parameters, the FOR statment will loop until an EXIT command is executed. Naming a FOR loop allows the programmer to EXIT out of nested loops easily.
Example (count to 10 the hard way)
FIELD count AS Integer_Class;
count=0;
FOR ()
count=AddInteger_Instruction(right=count, left=1);
IF (count==10) EXIT FOR;
END FOR
Example (print out the addreeses in myAddressList)
FOR (address IN myAddressList AS Address)
println(string=address.getString());
END FOR
Example (print out the variables of an object)
FOR A (object IN myProject AS Object_Class)
println(string=object.getName());
FOR B (variable IN object.getAllVariable() AS Variable_Class)
IF (variable.getValue()==Nothing) EXIT A;
print("Name=");
print(variable.getField().getName());
print(" Value=");
println(variable.getValue().getName());
END B
END A
Declaring Methods
Methods declared in the body of the class are called message handlers. A message handler can only be executed when a message is passed to an object and it is meant to handle that message. Methods can also be declared on their own, and are called Instructions. Instructions can be executed at any time.
Standard Method Specification
"METHOD" <name> "(" <parameters> ")" "RETURNS" <type>
<statements>
RETURN <expression>;
<more statements>
"END" <name>
All fields declared in the body of a method are limited in scope to that method. The RETURN statement must be used, possibly in more than once place, to exit the method with a return value specified by an expression.
Abstract Method
"METHOD" <name> "(" <parameters> ")" "RETURNS" <type> ";"
Abstract methods are useful for specifying interfaces. Abstract methods are considered invisible to the message handling logic. This means that messages are deferred to the most relevant non-abstract method. In most cases this is the Base_Message_Handler which returns a MessageNotHandled_Exception.
Partial Evaluation (not implemented yet)
"METHOD" <new name> "=" <old name> "(" <partial parameters> ")" ";"
Anonymous Method (not implemented yet)
<name> "=" "METHOD" "(" <parameters> ")" "RETURNS" <type> ";"
Classes
The class definition is not used in the SITH; the object browser is used instead. Class syntax is important for importing and exporting classes from the DBOS.
Standard Method Specification
"CLASS" <name> "AS" <type> "EXTENDS" <parent list>
<body>
"END" <name>
The AS clause is optional, and when left out assumes the defined class is an instance of Class_Class. The body of a class can contain class fields, and class methods. Interfaces are simply classes with abstract message handlers. Abstract classes can be declared like
Abstract Method
"CLASS" <name> "AS" <type> "EXTENDS" <parent list> ";"
Again, the AS clause is optional.
Example (an Interface)
CLASS List_Class AS List_Type EXTENDS Object_Class
FIELD Head AS List_Element_Class;
FIELD Last AS List_Element_Class;
METHOD prepend(object AS Object_Class) RETURNS List_Class;
METHOD append(object AS Object_Class) RETURNS List_Class;
END List_Class
<NOT COMPLETE>
Exceptions
Expressions
<function>(<param>)//EVALUATION OF METHOD
<template>(<param>)//EVALUATION OF TEMPLATE
<object>.<subexpression>//EVALUATION OF ATTRIBUTE
Object Definition
OBJECT <name> AS <type>;
The object definition differs from that of the field definition in that a FIELD is a (changeable) reference to an object and an OBJECT is what it says it is.
Macro
MACRO is similar to METHOD in definition, but makes many assumptions about parameters, return types, and whether code is executed.
MACRO <name> (<param>) <definition>
;