An Object Oriented Programming
Third Edition
Using Moka to assemble programs.
by
Frédéric Brown
Copyright (c) 2003 Frédéric Brown
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
All program code present in this documentation is released under the GNU General Public License (see license_GPL.txt for more information).
Introduction
Object oriented paradigm isn't new. The
concept originated in 1966 with a language used for simulations called Simula.
Then, many languages were developed featuring object oriented programming
capability from the early 70's Smalltalk to the 90's Java and the newest C#. In the 80's almost all
general purpose languages evolved to support object oriented programming (C evolved
to C++, Pascal to Turbo Pascal/Object Pascal, etc.). The object oriented
approach has many advantages over structured or procedural/functional languages. The major are abstraction - objects internal
mechanisms are encapsulated, reusability - a same pattern (or class) can be used to
instantiates many objects and classes can inherit from others, and correspondence to the problem domain - frequently an object in the program correspond to a
"real" object from the problem domain. However, if the reader has a good experience in programming (especially in C/C++ or Java)
and desire to learn about object oriented concepts, it would be better to read the first section before to jump in the Moka language
particularities.
This book is dedicated to the object oriented paradigm and the Moka object oriented language. The first section ("The object oriented paradigm")
relates to the object oriented concepts, the second to the Moka language as a
general purpose language, the third to Moka as an object oriented language, the
fourth to the Moka API and the fifth to the advanced features of Moka. The second section can be read before the first, it could be advisable for someone
that don't have a strong programming language because the "Moka, a general purpose programming language" chapter of this section introduces the
programming concepts as if the reader has no or a little programming experience.
At any time, to get more information about a class or one of its attribute,
field or method, use the javadoc HTML documentation accessible by opening the
Doc/Api/index.html document of the
Moka SDK installation. Also, take a look to the Examples folder.
Section 1,
The object oriented paradigm
An object oriented program consist of the symbiosis of objects interacting by sending messages to each others. Objects are obviously the key feature of object oriented programming. The closest equivalent of an object in a procedural language is the complex abstract data types such as structures and records. Like these constructs of procedural languages, objects contain data. In opposition to them, data manipulation is not handled by a sequential flux of function or procedure calls, objects "knowing" the use of their data because they encapsulates them and the code required to their manipulation. An object is defined in a class, more precisely, an object is an instance of a class. A class consist of methods and attributes that defines the behavior of an object. Attributes are the data contained in the object and their value sets the state of the object. As these attributes are hidden in the object, methods contain the code executed to change the state of an object when it receives a message.
Classes and inheritance
As said before, objects are instances of classes. These classes are organized in a hierarchical pattern. A new class can specialize an existing class by a process called inheritance. When a class inherit from an other, it keeps the attributes and methods of its parent class (called superclass). Then the child class (or subclass) can specialized its superclass by adding or replacing attributes and methods. Inheritance is a very powerful property of the object oriented model because it makes possible the selective reuse of the features of a superclass. An object oriented language may support multiple inheritance, which is the ability of a class to inherit from many superclasses.
Objects, methods and polymorphism
As instances of a subclass retains all the methods and attributes of the superclass of their class, they are also considered as - specialized - instances of their superclass. This property of objects - being able appear as instances of multiple classes - is called polymorphism. Any message understandable by an instance of a class is also understandable by all the instances of all the subclasses of that class. Methods are also polymorphic, as a same method can handle different sets of parameters or depend from instances of different classes, allowing a message to be sent to an object whose class is not known.
Interfaces, properties and encapsulation
Objects inner mechanism - data and executable code - are encapsulated. It means that the state of an object - defined by its attributes - cannot be set directly. In fact, the attributes of an object should only be accessible through its methods. A value of an object that is set or get by methods is said to be a property. A property may relate directly to an attribute (the "color" property of a "car" object would likely be implemented this way), but can also be associated to an abstract or calculated value (it is likely that the "total" property of a "bill" object would be implemented this way). This feature is essential for abstraction of implementation of the classes. Encapsulation is useful, because the implementation of a class can be changed - in order to bring improvements - without the knowing of a programmer that is using this class. In this case, an object can be compare to a black box, because you know what it can do, but not how it does it. An interface is a construct that describes what an instance of a class implementing it can do. So if a class implements an interface, it must provide all the facilities - by implementing specified methods - described by this interface.
Messages, methods and dynamic binding
When a message is received by an object, this object will search its methods for one that can be associated with the message. If it
is the case, it performs the binding and activates the method. If not, the object will query the superclass of its class, and so on.
This binding is qualified "dynamic", because it occurs at run time.
Now that you acquired a basic knowledge of object oriented paradigm, I recommend you to read the next sections to expend your knowledge by
focusing on
the learning of Moka, an implementation of object oriented language.
Section 2,
Moka, a general purpose language
Moka has been developed to be easy to learn and to use while featuring the power of the C programming language. Although designed as an object oriented language from the ground up, Moka offers nerveless all the facilities of structured and procedural languages. This section has been designed especially for programmers that has a little or no experience in programming. It has been structured like the TI BASIC section of the TI manual, to help the TI BASIC programmers. You need to have TIGCC SDK and Moka SDK installed. These software are -freely- downloadable from www.ticalc.org.
TI BASIC hint
A TI BASIC hint contains explanation for questions that could bring to the mind of TI BASIC programmers.
C hint
A C hint contains explanation for questions that could bring to the mind of C programmers.
OO hint
A OO (Object Oriented) hint contains explanation for questions that could bring to the mind of someone learning Moka as an object oriented language.
Nota bene
Nota bene (NB) section summaries the previous chapter.
Unit 1 - Your first cup of Moka (your first program)
This program asks the user for 2 values for 2 integer 'a' and 'b' and display the result of the division of those 2 numbers. Words in blue represents keywords, words in red represents Moka packages classes. This program uses 2 Moka API classes : moka.lang.System and moka.lang.Integer. System class is similar to a library that offers facilities to deal with input/output. Integer class deals with the integer primary type.TI BASIC hint
The int keyword is used to declare that variables a, b and p are
integers. Unlike BASIC, Moka is a strongly typed
language where all variables must be explicitly declared.
Also, Moka, is a free structured language, meaning that instructions ends with a
';' and can be spanned on multiple lines.
C hint
The int keyword correspond to a long int in C. Moka has been design to be close to Java, so the types differs slightly from C.
Moka's types will be discussed later.
OO hint
Moka, unlike other OO language, do not implements all data types as objects. Primary types exists in Moka and are very similar to
those of a procedural languages.
Nota bene
- A Moka program is composed by classes. The main class of a project contains a main method, which is executed when the program run.Unit 2 - Using parameters
Often, a program can takes arguments when it is called (Ex: prog(arg1, arg2)). In a Moka program, the class moka.lang.System can be used to retrieve and use these arguments. The following program is similar to the previous one, the only difference being that values for int a and b are provided as arguments instead to be asked interactively to the user. Note that in a TI-BASIC program, the TIOS variables a,b and q would be created and kept after the execution of a similar program unless they are defined as 'local'. As Moka is a compiled language, all variables are local to the program and only accessible by him. There is now danger to override an existing TIOS variable by executing a Moka program containing a variable with the same name in its instructions. Global or TIOS variables are considered as files in a Moka program. File I/O are discussed latter.Moka's Type | C equivalent | Memory representation | get<type> method | Wrapper class |
boolean | BOOL | 16 unsigned | N/A (use the same as short then cast if 0/1, or string
and parse if "true"/"false") Ex : boolean b = (boolean)System.getShort(); or boolean b = Boolean.parseBoolean(System.getString()); |
moka.lang.Boolean |
char | char | 8 signed | N/A (use the same as string then get the first character
of the returned string) Ex : String s = System.getString(); char c = s.charAt(0); |
moka.lang.Character |
float | float | 80-bit | float f = System.getDouble(); | moka.lang.Double |
double | double | 80-bit | double d = System.getDouble(); | moka.lang.Double |
byte | byte (defined as #define byte char) | 8 signed | N/A (use the same as short then cast) Ex : byte b = (byte) System.getShort(); |
moka.lang.Byte |
short | short int | 16 signed | short s = System.getShort(); | moka.lang.Short |
int | long int | 32 signed | long l = System.getLong(); | moka.lang.Double |
long | long long int | 64 signed | N/A (The user cannot provides a long as argument) | moka.lang.Double |
Nota bene
- To access a parameter in a Moka program, use the get<type> methods of the moka.lang.System class.Unit 3 - Programs without argument
A program may run without arguments or any other input. The following program use the random() method of the moka.lang.Math class to emulate a roulette game. The if structure used below will be discussed latter.Nota bene
- moka.lang.Math contains methods to deal with mathematics operation.
- To get a random number, use the Math.random() method with the following syntax :
Math.random()*(<max number> - <min number> + 1) + <min number>
Ex:
int
i = (int)(Math.random()
* 10) + 1; //Get a random number between 1 and 10
(inclusive)
int n = (int)(Math.random()
* 26) + 5; //Get a random number between 5 and 30
(inclusive)
Unit 4 - Returning a value
TI-BASIC allows the creation of functions (Func). These functions returns a value when they are done allowing to use that value in calculus. A Moka program can also returns a value when it exits, acting like a TI-BASIC function. The following program is a modified version of the previous ones which return the result instead of printing it.TI BASIC hint
Unlike TI-BASIC functions, Moka programs returning a value are not prohibited to
use I/O facilities.
Nota bene
- To end the program, use the following instruction :Unit 5 - Defining and calling methods
A main method (returning nothing - void - and taking no argument) is defined in
each Moka programs. The main method is the entry point of a program. A Moka
programmer divide its program into many simple methods to make it clearer to
read (or regroup instruction sequence in order to reuse at different moments in
the program). This is the syntax of a static method declaration :
public static <return
type> <name> (<parameters>) {
<instructions>
return <value>; //To return a value (if the method is not void)
}
The following program defines a print method that clears the screen, prints text
and wait for the user to press a key.
import moka.lang.System;
import moka.lang.String;
public class Example {
public static
void main () {
Example.print("Hi, welcome to this program !");//Calls
print to show a welcome message
Example.print(String.valueOf(Example.addOne(4)));//Calls
print to show the result returned by addOne (after converting it to string)
Example.print("Goodbye!");//Calls
print to show a goodbye message
}
public static int
addOne (int i) {
return i + 1;
}
public static
void print(String s) {
System.clrscr();//Clears
the screen
System.print(s);//Prints
s
System.read();//Wait
for the user to press a key
}
}
Follow the same steps as for the previous example to compile the program, then execute it.
Nota bene
- To clear the screen, use the following method :Unit 6 - Text I/O, from the keyboard to the screen
As Moka base classes have their package (moka.lang) classes used for I/O belongs to moka.io package. However when inputting or outputting text, the moka.lang.System class is involved, moka.io classes being used mainly for graphical, file and link I/O.As seen before, text input uses the following methods :
System.read();//Reads a single char, without echoing to the screen
System.readLine();//Reads a String, echoing to the screen
TI-BASIC hint
Instead of a TI-BASIC program, where text I/O occurs in a particular screen called PrgmIO and graphic
ones in another screen called GRAPH, a Moka program output is always done directly in the screen.
Type | Wrapper class | Method |
boolean | Boolean | Boolean.parseBoolean(<string>); |
char | Character | N/A (use the method charAt(0) of the string) Ex : char c = str.charAt(0); |
float | Double | Double.parseDouble(<string>); |
double | Double | Double.parseDouble(<string>); |
byte | Byte | Byte.parseByte(<string>); |
short | Short | Short.parseShort(<string>); |
int | Integer | Integer.parseInt(<string>); |
long | Long | Long.parseLong(<string>); |
OO hint
As Object, the root of the class hierarchy defines a toString method, all Moka
objects have one.
The following piece of code uses the method System.clrScr() to clear the
screen before writing a message in it.
import moka.lang.System;
import moka.lang.Integer;
public class Example {
public static
void main () {
System.clrscr();
System.println("Hello
there !");
System.read();
}
}
It could be useful to define the position of the 'pen', so new text output will
be done from specific coordinates in the screen. The following program
uses the moka.io.Graphics class to write a program that moves the pen to
coordinates (50, 25), then clears the screen and finally prints a message.
import moka.lang.System;
import moka.lang.Integer;
import moka.io.Graphics;//Note
that the Graphics belongs to the moka.io package
public class Example {
public static
void main () {
Graphics.moveTo(50, 25);
Graphics.clrScr();//Note that
this is the method from Graphics, which do not move the pen position after
clearing the screen
System.println("Hello
there !");
System.read();
}
}
Nota bene
To get text from keyboard input uses the following methods :Unit 7 - Using dialogs
Dialogs are handled in Moka by using the classes of the X API contained in the moka.x package. The X API is an application programming interface used to build user friendly interfaces similar of Windows programs. The X API will be discussed latter. For now, we'll use the OptionPane class of the moka.x package to show dialogs to the user.
Dialogs can be used to display a character string to the user. The following program uses the OptionPane.showMessageDialog(<string>) method to shows a isolated text message.Method | Description |
OptionPane.showMessageDialog(String message) | Shows a dialog titled 'Message' containing the specified message string. |
OptionPane.showMessageDialog(Container parent, String title, String message) | Shows a dialog titled from the specified title argument, containing the specified message string and centered on the specified parent container. To center the message on the screen use null as parent. |
Method | Description |
OptionPane.showInputDialog(String message) | Shows a dialog titled 'Input' containing the specified message string and featuring a text field for user input. |
OptionPane.showInputDialog(Container parent, String title, String message) | Shows a dialog titled from the specified title argument, containing the specified message string, featuring a text field for user input and centered on the specified parent container. To center the message on the screen use null as parent. |
Method | Description |
OptionPane.showConfirmDialog(String message) | Shows a dialog titled 'Select an Option' containing the specified message string and offering options Yes, No and Cancel. |
OptionPane.showConfirmDialog(Container parent, String title, String message, short option) | Shows a dialog titled from the specified title argument, containing
the specified message string, featuring the specified options and centered on the specified parent
container. To center the message on the screen use null as parent. Valid options are : OptionPane.OK_CANCEL_OPTION//Ok and Cancel options OptionPane.YES_NO_OPTION//Yes and No options OptionPane.YES_NO_CANCEL_OPTION//Yes, No and Cancel options |
Nota bene
- To show an informative message, use one of the following methods :Unit 8 - Getting the key currently pressed
The class moka.io.Keyboard is usefull to check which keys are currently pressed.Nota bene
- To get the key currently pressed by the user, use the following method :Unit 9 - Control statements
The most widely used control statement is the conditional statement :Operator | Description/Meaning |
---|---|
+ [unary] | Value of variable |
- [unary] | Negative of variable value |
~ | One's complement of the variable value |
++ [prefix] | Increment after evaluating variable |
++ [postfix] | Increment before evaluating variable |
-- [prefix] | Decrement after evaluating variable |
-- [postfix] | Decrement before evaluating variable |
+ [binary] - [binary] * [binary] / [binary] % [binary] |
add subtract multiply divide remainder |
a >> b a << b |
a, right-shifted b bits a, left-shifted b bits |
< > <= >= == != |
lesser than greater than lesser or equal greater or equal equal not equal |
a instanceof ClassName | evaluates true if a is an instance of class ClassName (or of one of its subclasses) |
& [binary] | ^ |
bitwise AND bitwise OR bitwise XOR |
&& || ! |
logical AND logical OR logical NOT |
<condition> ? <instruction> : <instruction> | ? - instruction if true : - instruction if false |
a = b a += b a -= b a *= b a /= b a %= b a >>= b a <<= b a &= b a |= b a ^= b |
assign the value to the variable assign the value of the addition of the variable to the value assign the value of the subtraction from the variable of the value assign the value of the multiplication of the variable by the value assign the value of the division of the variable by the value assign the remainder of the division of the variable by the value a, right-shifted b bits (assigned to a) a, left-shifted b bits (assigned to a) a AND b (assigned to a) a OR b (assigned to a) a XOR b (assigned to a) |
Loop statements can be used to repeat one or many instruction. The more common, and simple, Moka's loop statement is the
while statement :
while ( <condition> ) <instruction>
or
while ( <condition> ) {
<instructions>
}
Ex:
/* Writes 5 times "Hello !" */
x = 0;
while (x < 5) {
System.println("Hello !");
x = x + 1;
}
The do ... while loop execute the block before checking the condition :
do
<instruction> while ( <condition> ) ;
or
do {
<instructions>
}
while ( <condition> ) ;
Ex:
/* Writes 5 times "Hello !" */
x = 1;
do {
System.println("Hello !");
x = x + 1;
}
while (x < 5) ;
To exit a loop, use the following statement :
break;
Ex:
int x = 0;
while (true) {
if (x >= 5) {
break;
}
System.println("Hello !");
x = x + 1;
}
Correspond to :
/* Writes 5 times "Hello !" */
x = 0;
while (x < 5) {
System.println("Hello !");
x = x + 1;
}
Often, a counter is used in loop. The Moka's for statement is useful in that situation :
for ( <counter> = <initial value> ; <condition> ; <incrementation> ) <instruction>
or
for ( <counter> = <initial value> ; <condition> ; <incrementation> ) {
<instructions>
}
Ex:
/* Writes 5 times "Hello !" */
int x;
for (x = 0; x < 5; x++) {//++ is an incrementation unary operator; x++ means x = x + 1
System.print("Hello ");
System.println(x);
}
or
for (int i = 0; i < 5; i++) {//++ is an incrementation unary operator; i++ means i = i + 1
System.print("Hello ");
System.println(i);
}
C hint
As you see above, a local variable may be declared for the loop in the for statement, instead of having to declare it before the loop.
Nota bene
- To execute instructions under a conditional context, use the following instructions :Unit 10 - Strings and their manipulation
Moka implements character strings as objects. In Moka, all string are instances of the moka.lang.String class. This means that strings are manipulated using their own methods instead of external functions. This unit gives information about a number of methods, take a look in the API javadoc in HTML format to get the list of the methods of class String.In a structured language, comparing
two string would need a function accepting both strings as argument (ex:
strcmp(str1, str2) in C). In Moka, you use the method compareTo(String s) of the
string you wish to compare.
Ex:
/* This example will print "equal" */
String str1 = "Hi";
String str2 = "Hi";
if (str1.compareTo(str2) == 0) {//compareTo
returns 0 when the strings are equal, > 0 when str1 is lexicographically greater
than str2, < 0 when str1 is lexicographically lesser than str2
System.print("str1");
System.print(" equals ");
System.println("str2");
}
else {
System.print("str1");
System.print(" unequals ");
System.println("str2");
}
Using the '=' operator on string will always return false, unless a string
objects is compared to itself.
Ex:
/* This example will
print "unequal" */
String str1 = "Hi";
String str2 = "Hi";
if (str1 == str2) {//==
compares the memory addresses of
System.print("str1");
System.print(" equals ");
System.println("str2");
}
else {
System.print("str1");
System.print(" unequals ");
System.println("str2");
}
/* This example will print "equal", because str1 and str2
refers to the same string object. */
str1 = "Hi";
str2 = str1;
if (str1 == str2) {//==
compares the memory addresses of
System.print("str1");
System.print(" equals ");
System.println("str2");
}
else {
System.print("str1");
System.print(" unequals ");
System.println("str2");
}
The method equals(String str) can also be used when you only need to know if the
strings are equal.
/* This example will
print "equal" */
String str1 = "Hi";
String str2 = "Hi";
if (str1.equals(str2)) {//equals
returns true when the strings are equal, false otherwize
System.print("str1");
System.print(" equals ");
System.println("str2");
}
else {
System.print("str1");
System.print(" unequals ");
System.println("str2");
}
As in C, Moka character (char) values are considered as numeric types. It means
you can assign a legal numeric value to a char, or a char value to a numeric
type without having to invoke a conversion mechanism.
Ex:
char c = (char)35;
short numValue = c;
As seen in previous unit, concatenation of strings requires the use of the
concatenation operator ('+'). You can also use the method concat(String
str) of the string you wish to concatenate another string.
Ex:
str1 + str2;
or
str1.concat(str2);
To get the number of character a string has, use its length() method.
Ex:
short len = str.length();
To extract a part of a String, use its substring(int startIndex, int endIndex)
method. Note that the first character is at index 0 and that endIndex is
non-inclusive. The following program shows it.
import moka.lang.System;
import moka.lang.String;
public class Example
{
public static
void main () {
String str = "Hello there !";
System.println(str.substring(0, 5));
//Prints the first 5 characters (from index 0 up to index
4) : "Hello"
System.println(str.substring(5, 7));
//Prints 2 characters in the middle of the string (from
index 5 up to index 6) : " t"
System.println(str.substring(str.length() -
3, str.length())); //Prints the last 3 characters (from index
10 up to index 12), length - 1 being the last index : "e !"
str.finalize();//As string are objects, the resources they
use must be freed
System.read();//Wait
for the user to pres a key
}
}
Follow the same steps as for the previous example to compile the program, then execute it.
To search a string in another, use the indexOf(String str) method of the second
string. Which returns the index of the first character of the specified string
or -1 if the string has not been found. The following program provides some
examples using this method.
import moka.lang.System;
import moka.lang.String;
public class Example
{
public static
void main () {
String str = "The first
component in this Container.";
String str2;
str2 = "in";//Creates
a new string object having "in" as value
System.println(str.indexOf(str2,
0));
//Finds the first occurrence of "in"
System.println(str.indexOf(str2, 25));
//Finds the first occurrence of "in" starting from index
25
str2.finalize();//As string are
objects, the resources they use must be freed
str2 = "on";//Creates
a new string object having "on" as value
System.println(str.lastIndexOf(str2, str.length() - 1));
//Finds the first occurrence of "on", searching backward
from the end of the string
System.println(str.lastIndexOf(str2,
25));
//Finds the first occurrence of "on", searching backward
from the end of the string and starting at index 25
str2.finalize();//As string are
objects, the resources they use must be freed
str.finalize();//As string are objects, the resources they
use must be freed
System.read();//Wait
for the user to pres a key
}
}
Follow the same steps as for the previous example to compile the program, then execute it.
As seen in Unit 6, you can convert a String in any primary type using its
wrapping class' parse method. To convert a primary type into a string, use
the String.valueOf method.
Ex:
String str = String.valueOf(123);
or
String str = String.valueOf('v');
or
String str = String.valueOf(1.22);
Nota Bene
- To compare two strings, use the following methods :
<string 1>.equals(<string 2>)
//Returns true if string 1 is equal to string 2
<string 1>.compareTo(<string 2>) //Returns 0 when the strings are equal, > 0 when str1 is lexicographically greater
than str2, < 0 when str1 is lexicographically lesser than str2
- To concatenate two strings or an other type to a string, use the concatenation
operator ('+') or the concat method :
<string 1>.concat(<string 2>);
or
<string 1> + <string 2>;
Ex:
str1.concat("!");
str1 + "!";
str1 + 123;
str4 + 'C';
- To get the length of a string, use this method :
<string>.length()
- To get a substring from a string, use the following method :
<string>.substring(<begin>, <up to this
index>)
- To search a string in another, use one of the following methods :
<string 1>.indexOf(<string 2>, <start>)
<string 1>.lastIndexOf(<string 2>, <start>)
Unit 11 - Arrays
In Moka, as in any other compiled language, there is no "indirection" ('#'
operator in TI-BASIC). However, you can use arrays or object references (or even
pointers in native blocks). Arrays are declared using [] after the type :
<type>[] <name> = new
<type>[<size>];
Ex:
int[] array = new
int[5];//A array of 5 integers
To access an array member, use the array name followed by [<index>]. Keep in
mind that the first element of an array is at index 0 and the last at index size
- 1.
Ex:
System.println(array[3]);
//Prints the 4th member of the array
System.println(array[0]);
//Prints the 1st member of the array
System.println(array[4]);
//Prints the last member of the array, if 5 is the size of the array
When a new array is created, it uses resources that must be freed when no more
needed. Use the System.free method to free the resources used by an array.
Ex:
String[] strs = new
String[10];
System.free(strs);
Native blocks are a concept that is discussed latter.
Nota Bene
- To declare an array, use the [] symbols :
<type> [] <array name>
Ex:
int [] nums;//Declares an
array of integers
- To create an array, and specify its size, use the following syntax :
<array> = new <type>[<size>];
Ex:
int [] nums = new
int[10];//An array of 10
integers
- To access a member of an array, use the following syntax :
<name of the array>[<index>]
Ex:
nums[3] = 234;//Assign 234 as the third member of the
array
System.println(nums[3]);//Prints
the 4th member of the nums array
- To free the resources used by an array use the following method :
System.free(<name
of the array>);
Unit 12 - Graphical programming
Programs are not limited to display text. Many programs - including arcade games - use graphical functions to draw on the screen. Moka API class moka.io.Graphics proposes many methods to draw on the screen.
Coordinates systems use two axes : X and Y. Reference point is the upper left corner, at coordinates (0,0) - X = 0, Y = 0. Screen vary with the calculator model. The following table shows the characteristic of the different calculators :
Model | LCD width | Usable LCD height | X range | Y range |
TI-92Plus / Voyage 200 | 240 | 128 | 0 to 239 | 0 to 127 |
TI-89 | 160 | 100 | 0 to 159 | 0 to 99 |
You can check the model of calculator by comparing System.CALCULATOR with
System.CALCULATOR_TI89, CALCULATOR_TI92PLUS, CALCULATOR_V200.
Ex:
if (System.CALCULATOR
== System.CALCULATOR_TI89) {
xMax = 159;
yMax = 99;
}
else {
xMax = 239;
yMax = 127;
}
Alternately, you can use GEM.LCD_WIDTH and GEM.USABLE_HEIGHT to get the screen dimensions (providing you imported moka.x.GEM class).
The following table shows the basic graphic instructions :
Action | Method |
Invert the state of a pixel (black to white / white to black) | Graphics.drawPix(short x, short y, Graphics.XOR_ATTR) |
Turn on a pixel (draw a black dot) | Graphics.drawPix(short x, short y, Graphics.NORMAL_ATTR) |
Turn off a pixel (draw a white dot) | Graphics.drawPix(short x, short y, Graphics.REVERSE_ATTR) |
Get the state of a pixel (return true if the pixel is on, false otherwise) | Graphics.getPix(short x, short y) |
The following table shows the attributes and their effect :
Attribute | Effect |
Graphics.NORMAL_ATTR | Draw with destination pixels turned on. |
Graphics.AND_ATTR | AND the region to draw. |
Graphics.OR_ATTR | Draw with source pixels ORed with destination pixels. |
Graphics.REPLACE_ATTR | Draw with source pixels replace destination pixels. |
Graphics.REVERSE_ATTR | Draw with destination pixels turned off. |
Graphics.SHADE_H_ATTR | Draw the line using a horizontal shading pattern. |
Graphics.SHADE_NS_ATTR | Draw the line using a negative slope diagonal shading pattern. |
Graphics.SHADE_PS_ATTR | Draw the line using a positive slope diagonal shading pattern. |
Graphics.SHADE_V_ATTR | Draw the line using a vertical shading pattern. |
Graphics.SHADED_ATTR | Draw with destination pixels masked so that every other pixel turned off. |
Graphics.THICK1_ATTR | Draw a double thick line. |
Graphics.XOR_ATTR | Draw with source pixels XORed with destination pixels. |
The following table shows the principal graphic instructions :
Action | Method |
Draw a pixel | Graphics.drawPix(short x, short y, short attr) |
Draw a line (from coordinates (x0, y0) to (x1,y1)) | Graphics.drawLine(short x0, short y0, short x1, short y1, short attr) |
Draw an ellipse (center at coordinates (x,y) horizontal semi axe a, vertical semi axe b. if a == b, will draw a circle) | Graphics.drawEllipse(short x, short y, short a, short b, short attr) |
Draw a String | Graphics.drawPix(short x, short y, String str, short attr) |
Draw a char | Graphics.drawPix(short x, short y, char c, short attr) |
Draw a double | Graphics.drawPix(short x, short y, double d, short attr) |
Draw an long | Graphics.drawPix(short x, short y, long l, short attr) |
Draw a int | Graphics.drawPix(short x, short y, int i, short attr) |
Draw an short | Graphics.drawPix(short x, short y, short s, short attr) |
To save a part of the screen as a PIC variable, use the getPicVar(String
file, short x, short y, short width, short height) method.
Ex:
Graphics.getPicVar("img1",
100, 50, 25, 25);//Will save a 25x25 area beneath x=100,
y=50, to the PIC variable 'img1'.
To put a PIC variable on the screen, use the Graphics.picVarPut(String file,
short x, short y, short attr) method.
Ex:
Graphics.picVarPut("img1",
100, 50, Graphics.REPLACE_ATTR);//Will put the 'img1' PIC at x=100,
y=50, replacing the destination.
The following program shows the use of some features of the Graphics class. It
implements an "Etch a Sketch" where you can draw
a figure using arrow keys.
import moka.lang.System;
import moka.io.Graphics;
import moka.io.Keyboard;
import moka.x.GEM;
public class Example {
public static
void main () {
short mX, mY;//Max
pen coordinates
short cX, cY;//Current
pen coordinates
short key;
String picName;
mX = GEM.LCD_WIDTH;
mY = GEM.USABLE_HEIGHT;
System.clrscr();
System.println("Welcome to Etch
a Sketch");
System.println("Use the arrow
keys to draw");
System.println("your figure.");
System.println("To erase it,
press CLEAR.");
System.println("To save it to
'sketch' PIC var, press S.");
System.println("To exit, press
ESC.");
/*Wait for the user to press a key.*/
System.read();
/*Centers the pen and erases the
screen.*/
System.clrscr();
cX = mX / 2;
cY = mY / 2;
do {
key = Keyboard.ngetchx();
System.stEraseHelp();//Erases
the message in the status bar
if (key ==
System.KEY_UP && (cY - 10 >= 0)) {
Graphics.drawLine(cX,
cY, cX, cY - 10, Graphics.NORMAL_ATTR);
cY -= 10;
}
else
if (key == System.KEY_DOWN
&& (cY + 10 < mY)) {
Graphics.drawLine(cX,
cY, cX, cY + 10, Graphics.NORMAL_ATTR);
cY += 10;
}
else
if (key == System.KEY_LEFT
&& (cX - 10 >= 0)) {
Graphics.drawLine(cX,
cY, cX - 10, cY, Graphics.NORMAL_ATTR);
cX -= 10;
}
else
if (key == System.KEY_RIGHT
&& (cX + 10 < mX)) {
Graphics.drawLine(cX,
cY, cX + 10, cY, Graphics.NORMAL_ATTR);
cX += 10;
}
else
if (key == 's') {
Graphics.getPicVar("sketch",
0, 0, mX, mY);
System.setStHelpMsg("Figure
saved.");//Shows a message in the status bar
}
else
if (key == Keyboard.KEY_CLEAR)
{
/*Centers the
pen and erases the screen.*/
System.clrscr();
cX = mX / 2;
cY = mY / 2;
}
}
while (key !=
Keyboard.KEY_ESC) ;
}
}
Follow the same steps as for the previous example to compile the program, then execute it.
Legal values of grayscale level are shown here :
Value | Description |
Gray.OFF | Turns off grayscale (default value). |
Gray.BLACK | Sets the grayscale level to black. |
Gray.LIGHT_GRAY | Sets the grayscale level to light gray. |
Gray.DARK_GRAY | Sets the grayscale level to dark gray. |
To get the current grayscale level, check the Graphics.level attribute.
To turn off grayscale, use the following instruction :
Graphics.setGray(Gray.OFF);
The following program get a picture from a part of the screen and the paste
it 3 times, each time in a different color :
import moka.lang.System;
import moka.io.Graphics;
public class Example {
public static
void main () {
Graphics.getPicVar("img1", 0, 0,
25, 25);
Graphics.setGray(Gray.LIGHT_GRAY);
Graphics.picVarPut("img1", 10,
50, Graphics.NORMAL_ATTR);
Graphics.setGray(Gray.DARK_GRAY);
Graphics.picVarPut("img1", 40,
50, Graphics.NORMAL_ATTR);
Graphics.setGray(Gray.BLACK);
Graphics.picVarPut("img1", 80,
50, Graphics.NORMAL_ATTR);
System.read();
}
}
Follow the same steps as for the previous example to compile the program, then execute it.
Nota Bene
- To find the calculator model the program is running on, test the
System.CALCULATOR attribute.
- To find the screen dimensions, use the GEM.LCD_WIDTH and GEM.USABLE_HEIGHT
attributes.
- To draw graphics constructs on the screen use the moka.io.Graphics class'
methods.
Ex:
Graphics.drawEllipse(50, 25, 5, 5, Graphics.NORMAL_ATTR);
//Draws a circle at coordinates (50, 25) having a diameter
of 10 pixels
- To change the grayscale level, use the
following instruction :
Graphics.setGray(Gray.<grayscale level>);
Ex:
Graphics.setGray(Gray.DARK_GRAY);
Unit 13 - File I/O
The file input and output facilities are encapsulated in the moka.io.File API
class. To write to a file or read from it, you must first instantiates a file
object.
Ex:
File f = new
File("save");//Will
handle a var named "save" in the current directory.
Then, to read or write data, you must open the file for reading or writting.
Ex:
f.open(File.MODE_WRITE);//Opens file f for
writing
To check if a file is opened, check the opened attribute :
Ex:
if (!f.opened) {//If file f
is not already opened.
f.open();//Opens file f (in read only when no
argument is specified).
}
The following table shows the different open modes:
Mode | Description |
File.MODE_APPEND | Append; open for writing at end of file, or create for writing if the file does not exist. |
File.MODE_OPEN_READ | Open for reading only. |
File.MODE_OPEN_UPDATE | Open an existing file for update (reading and writing). |
File.MODE_UPDATE | Create a new file for update (reading and writing). |
File.MODE_UPDATE_APPEND | Open for append; open for update at the end of the file, or create if the file does not exist. |
File.MODE_WRITE | Create for writing. |
As File class is a subclass of IOStream, it implements all its methods for inputting or outputting. The following table shows the different input methods :
Method | Description |
readBoolean() | Reads a boolean. |
readByte() | Reads a byte. |
readBytes(char[] buffer, short len) | Copies to a buffer of bytes up to the specified length bytes read from the stream. |
readChar() | Reads a char. |
readDouble() | Reads a double. |
readInt() | Reads an int. |
readLong() | Reads a long. |
readObject() | Reads an Object. |
readShort() | Reads a Short. |
readString() | Reads a String object. |
The following table shows the different output methods :
Method | Description |
writeBoolean(boolean val) | Writes a boolean. |
writeByte(char val) | Writes a byte. |
writeBytes(char[] buffer, short len) | Writes a buffer of bytes up to the specified length. |
writeChar(char val) | Writes a char. |
writeDouble(double val) | Writes a double. |
writeInt(int val) | Writes a long. |
writeLong(long val) | Writes a long. |
writeObject(Object val) | Writes an Object. This object must be a subclass of Serializable. Serializable class is discussed latter. |
writeShort(short val) | Writes a Short. |
writeString(String val) | Writes a String object. |
The following method are useful when reading from a file or updating it :
Method | Description |
available() | Returns the number of bytes that can be read from this file. WARNING : The 'tag' of a var is appended at the end of a file when it is closed and takes 2 bytes. So if you want to loop until there is no more data in a file use while (f.available()>2) instead of while (f.available()>0). |
seek(int pos) | Sets the file-pointer offset, measured from the beginning of this file, at which the next read or write occurs. |
skip(int n) | Skips over n bytes of data from this file. |
To specify a TAG (the var type in the var link menu) for a file you are
writing into, sets the
type attribute of a file you have opened in write mode :
Ex:
f.type = "SCOR"; //Note that the TAG can not exceed 4
characters
Once you are done with a file stream, close it using its close method :
Ex:
f.close();
When you want to dispose of the file object, use its finalize method to free
its resources :
Ex:
f.finalize();
File class is also used to manipulate directories. To create a directory, use
the mkdir method :
Ex:
File d = new File("mydir");
d.mkdir();//Creates the directory 'mydir'
d.finalize();
To delete a directory, use the rmdir method :
Ex:
File d = new File("mydir");
d.rmdir();//Removes the directory 'mydir'
d.finalize();
To delete a file, use the delete method :
Ex:
File f = new File("myfile");
f.delete();//Removes the file 'myfile'
f.finalize();
File class also provides facilities to get information about a specific file. The following table shows these methods :
Method | Description |
isArchived() | Tests whether the file is archived. |
isHidden() | Tests whether the file is hidden. |
isLocked() | Tests whether the file is locked. |
length() | Returns the size of the file in bytes. |
exists() | Returns true if the file exists, false otherwise. |
Also, you can modify the attribute of a file using the following methods :
Method | Description |
setArchived(boolean b) | Sets if the file is archived (in the archive memory instead of the RAM). |
setHidden(boolean b) | Sets if the file is hidden (invisible for the TI-BASIC programs). |
setLocked(boolean b) | Sets if the file is locked (cannot be altered). |
renameTo(String dest) | Renames the file. |
To check if a file operation is successful, check the error attribute. The error
attribute is true when an error occurred in the last method call of a File
object.
Ex:
File f = new File("myfile");
f.delete();//Removes the file 'myfile'
if (f.error) {
System.println("myfile is already deleted
!");
}
f.finalize();
The following program is designed to be run twice. The first time it is run, it
writes some data to a file. The next time, it reads data from the file. The
program uses the exists method of the file object to check if the program has
already be ran.
import moka.lang.System;
import moka.io.File;
public class Example {
public static
void main () {
File f = new
File("save");//Creates a new
file object referring to the var 'save'
short i = 1;
if (f.exists()) {//If
the file exists (if the program has already been run)
f.open();//Opens the file
for read only (default mode)
System.clrscr();
System.println("High
Scores");
while (f.available()
> 2) {//While there is something to read from the file
System.print(i++);//Writes
the player rank, then increment i
System.print(":
");
System.print(f.readString());//Writes
the name of the player
System.print("
");
System.println(f.readShort());//Writes
the score of the player
}
System.read();
}
else {
f.open(File.MODE_WRITE);
f.writeString("A good player");
f.writeShort(1000);
f.writeString("A fair player");
f.writeShort(400);
f.writeString("A poor player");
f.writeShort(50);
}
f.close();
f.finalize();
}
}
Follow the same steps as for the previous example to compile the program, then execute it.
Method | Description |
File.exportExpr(String name, String expr) | Exports the expression expr to the variable designed by name. |
File.export(String name, String s) | Exports the string s to the variable designed by name. |
File.export(String name, long l) | Exports the long l to the variable designed by name. |
File.export(String name, int i) | Exports the int i to the variable designed by name. |
File.export(String name, short s) | Exports the short s to the variable designed by name. |
File.export(String name, byte b) | Exports the byte b to the variable designed by name. |
File.export(String name, char c) | Exports the char c to the variable designed by name. |
File.export(String name, boolean s) | Exports the boolean b to the variable designed by name. |
File.export(String name, double d) | Exports the double d to the variable designed by name. |
Nota bene
- To manipulate a file, instantiate a File object by passing a string
representing the file path to the constructor :
Ex:
File f = new
File("test");//The reference
f will represent the var named 'test'
- To check if a file exists, use the following instruction :
<file reference>.exists()
Ex:
File f = new
File("test");
if (f.exists() == true)
{
//do something
}
- To open a file, use the following method :
<file reference>.open(<open mode>);
- To output to a file, use the write<type> methods of a file object opened in
write or update mode.
- To read from a file, use the read<type> methods of a file object opened in read
or update mode.
- To export data to a TIOS variable, use the following method :
File.export("<variable
name>", <value to export>);
Ex:
File.export("var1", 123);
Unit 14 - Link I/O
Link I/O is encapsulated in the Moka API class moka.io.Socket. When using Socket
class, sending and receiving data via the link is similar to writing and reading
from a file.
To perform link I/O, you must first instantiate a Socket object :
Ex:
Socket s = new
Socket();
Then, you must invoke the open method of the socket object to read and write
from it :
Ex:
s.open();
Once you have an opened socket, you can use any read<type> or write<type> to
perform link input and output.
Ex:
s.writeInt(12);
char c = s.readChar();
As for any subclass of IOStream, use the close method to close the socket :
Ex:
s.open();
To dispose of a socket, use the finalize method :
Ex:
s.finalize();
To check if a socket is opened, check the opened attribute :
Ex:
if (!s.opened) {//If socket s
is not already opened.
s.open();//Opens socket s for input and output.
}
To set the time out delay of a socket object, modify the timeout attribute
(specified in 1/20th of second) :
Ex:
s.timeout = 10;//Sets the timeout for this socket to 10
1/20th of second
The major differences between File and link I/O is that link I/O must be
synchronized (an application must read the stream while an other is writing in
it) and, due to the way the Socket class is implemented, you can't read the
keyboard while a socket is opened.
Ex:
char c = Keyboard.ngetchx();
s.open();
s.writeChar(c);
s.close();
Instead of :
s.open();
char c = Keyboard.ngetchx();
s.writeChar(c);
s.close();
The following programs are an example of a simple client / server link
application. The client application if a key is pressed and, if it is the case,
send the key code to the server application. Both applications shows the
character represented by the key pressed and exit if ESC key is pressed.
The client application (Save the source file as Client.java) :
import moka.lang.System;
import moka.io.Socket;
import moka.io.Keyboard;
public class Client {
public static
void main () {
Socket sok =
new Socket();
short key = 0;
while (key !=
Keyboard.KEY_ESC) {//While
the user don't press ESC
key = Keyboard.ngetchx();
sok.open();
sok.writeShort(key);
sok.close();
if (key !=
Keyboard.KEY_ESC) {
System.print((char)key);
}
}
sok.finalize();
}
}
The server application (Save the source file as Server.java) :
import moka.lang.System;
import moka.io.Socket;
import moka.io.Keyboard;
public class Server {
public static
void main () {
Socket sok =
new Socket();
short key = 0;
while (key !=
Keyboard.KEY_ESC) {//While
the client don't sent ESC
sok.open();
key = sok.readShort();//Try
to read from the link, the error attribute of sok will be true if the operation
times out
if (!sok.error &&
(key != Keyboard.KEY_ESC)) {//If
something has been receive and the received code is not ESC
System.print((char)key);
}
sok.close();
key = Keyboard.getKey(1);//Read
the keyboard, gives a 1/20th second delay to the user to press a key
}
sok.finalize();
}
}
Section 3,
Moka, an object oriented language
Moka has been developed from the ground up to be a Java-like object oriented language. However, many Java features has been sacrificed to ensure that Moka compiles programs that are small and fast as other C programs. This section consider Moka as an implementation of object oriented language. Basic skills of Moka programming and understanding of the object oriented paradigm are needed to fully understand this section. Object oriented paradigm is discussed in section 1, programming in section 2. Take time to read some java tutorial after this one too, such as the SUN's Java Tutorial. Remember however that Moka has some limitation over Java (look in unit 2 about the 'this' keyword).
Unit 1 - Objects
Moka objects, as C structures, contain data. However, Objects are able to manipulate their data by themselves because, unlike structures, they also feature program code (methods).
They are created using the new keyword.
Object o = new Object();
They are destroyed by invoking their finalize method.
o.finalize();
Unit 2 - Classes
Moka classes serve as pattern for objects. They are defined using the class keyword.
public class NewObjectType {
}
+ Attributes
Attributes are encapsulated inside objects. As variables, they are typed and keep data.
They are defined in a class declaration.
public class NewObjectType {
public int i;
}
They are accessed using their name.
NewObjectType no = new NewObjectType();
no.i = 2;
+ Methods
Methods handle the messages received by the object. They contain program code used to manipulate the data encapsulated in their object.
They are declared in a class declaration.
public class NewObjectType {
public int i;
public void increment () {
this.i++;
}
}
The `this’ keyword refer the object who received the message.
A message is sent to an object by invoking one of its methods.
no.increment();
A good programming habit is to hide the attributes inside an object and offer method to set and get them. These methods are called accessors (setter and getter accessors).
public class NewObjectType {
private int i;
public int getI() {
return this.i;
}
public void setI(int paramI) {
return this.i = paramI;
}
…
}
This is essential to the object oriented concept of encapsulation, which allows changing a class implementation while keeping its facility (it prevents a program using the class to be redesigned). In the next chapter, “The Moka API”, you will realize that some classes expose internal attributes (properties) instead of providing accessors. The setter is not provided when changing the value of a property of the object does not provoke any side effect (changing the caption of a label provokes a side effect: the display is refreshed). The getter is not provided when the value of a property correspond directly to the value of an attribute. However, this is a BAD THING, in object oriented programming, because it induces dependency over the implementation of a class (one could not decide to banish an attribute to implement a property in another way without generating incompatibilities between the different versions of the class). The API has been designed that way to optimize the size and speed of the programs compiled using it, and with hope that the implementation of the said properties will not vary much.
This table shows the different visibility modifiers :
Keyword | Accessibility |
public | Accessible by any object or any classes. Ex: public void main () |
protected | Accessible by any class of the same package than this class or
extending this class, or by any instantiated object of these classes. Ex: protected int getTotal() |
private | Accessible only by this class, or by any instantiated object of this
class. Ex: private boolean mustRefresh() |
(default) | Accessible by any class of the same package than this class, or by
any instantiated object of these classes. Ex: void update() |
Objects usually need to be initialized before they are used. A set of special methods are designed to play this role. These methods are constructors.
A constructor, as a method, is defined in a class declaration. Unlike a method, it doesn’t have a return type and is named after the name of its class.
public class NewObjectType {
private int i;
public NewObjectType () {
this.i = 0;
}
…
}
If no constructor are specified for a class, a default one – doing nothing but calling the superclass’ constructor – is generated automatically.
Destructors are invoked to destroy an object (free its resources). They are defined as a void method named finalize and do not accept arguments.
public class NewObjectType {
…
public void finalize () {
super.finalize();
}
}
As every class is a subclass of Object, which implements a finalize method, providing a finalize method when designing a class is optional (unless there is a clean up to do when destroying an object of the class).
++ Method polymorphism
Moka supports method polymorphism. That means that two methods, with a different set of arguments, can have the same name.
This faculty is really important, especially when supplying multiple constructors.
public class NewObjectType {
private int i;
public NewObjectType () {
this.i = 0;
}
public NewObjectType (int initialValue) {
this.i = initialValue;
}
…
}
Polymorph methods are also used to provide different behaviors depending on the arguments provided.
public class NewObjectType {
private int i;
…
public void increment () {
this.i++;
}
public void increment (int value) {
this.i += value;
}
}
+Static members
Static members are attributes or methods common to all the instances of the class.
They are defined using the `static’ keyword in the member declaration.
public class NewObjectType {
private static int nbrInstances;
public static void doNothing() {
}
…
}
They are accessed using the class name instead of an instance reference.
public class NewObjectType {
private static int nbrInstances = 0;
public static void doNothing() {
}
public static void main() {
NewObjectType.doNothing();
}
…
public NewObjectType () {
this.i = 0;
NewObjectType.nbrInstances += 1;
}
…
public void finalize() {
NewObjectType.nbrInstances -= 1;
super.finalize();
}
}
Static methods, as instance ones, are polymorph.
Class static blocks are available to perform initialization tasks (they are run at the beginning of the program).
public class NewObjectType {
private static int nbrInstances;
static {
NewObjectType .nbrInstances = 0;
}
…
}
The static counterpart of destructors are class finally blocks (they are run when the program is about to terminate).
public class NewObjectType {
…
finally {
System.println(“See you latter!”);
}
…
}
Unit 3 - Inheritance
Classes are organized in a hierarchical manner. The root of this hierarchy is the Object class. Each class is a subclass of class Object or of one of its subclass.
The superclass is specified by the `extend’ keyword in the class declaration.
public class NewObjectType extends Object {
…
}
If no superclass is supplied, Object is the default.
When a class extends another, it takes all the instance methods and instance attributes defined in all its superclasses.
A subclass may define a method with the same signature of one of its superclasses, overriding it. When a class overrides a method, any message handled before by the implementation of the superclas will now be handled by the method implementation of this class.
public class NewObjectType {
private int i;
…
public String toString() {
return String.valueOf(this.i);
}
}
+ Packages
Classes are distributed among packages. A package usually regroups classes that have similar functionality or are collaborating closely.
The package is specified before the class declaration using the `package’ keyword.
package foo;
public class NewObjectType {
…
}
The classes of a package are kept in a directory of the name of the package. The root of the packages’ directories is the packages directory under the Moka SDK directory.
Ex: The class NewObjectType.java of package foo should be in
C:\mdk2.1\tigcc\packages\foo\ - Providing you installed MDK 2.1 in C:\mdk2.1\tigcc\packages\foo\
All the classes of the main class of a project are imported in the project automatically.
The default package (if the package is not specified) is constituted of all the classes in the project directory.
+ Instance polymorphism
Through inheritance, an instance of a class is also an instance of all its superclasses. It is able to receive any message its superclass can handle.
You can assign an instance of a class to any kind of reference that is typed after a superclass.
NewObjectType no = new NewObjectType();
Object o;
o = no;
System.println(o.toString());
When a class override a method, its implementation of the method is invoked, even if the object is referred by a reference typed after the superclass.
+ Invoking methods with `this’ and `super’
As seen before, the keyword `this’ is used in an instance method to invoke another method of the same instance or to access on of its attribute.
public class NewObjectType {
private int i;
public NewObjectType () {
this.i = 0;
}
public void increment (int value) {
this.i += value;
}
public void increment() {
this.increment(1);
}
…
}
The keyword `super’ is used in an instance method to invoke another method of the same instance but, unlike `this’, the method invoked must be inherited from a superclass. This keyword serves to invoke the superclass implementation of a specific method when the class override the method.
public class BrandNewObjectType {
…
/* Overrides the method in class NewObjectType. */
public void increment() {
/* Increment 4 times (by invoking the superclass method instead of this method */
for (int i = 0; i < 4; i ++) {
super.increment();
}
}
}
In a constructor, this(…) can be used to invoke an other constructor in the same class.
public class NewObjectType {
private int i;
public NewObjectType () {
this(0);
}
public NewObjectType (int initialValue) {
this.i = initialValue;
}
…
}
To invoke a constructor in the superclass, for initialization purpose, use super(…).
public class BrandNewObjectType {
public BrandNewObjectType () {
super(4);
}
…
}
+ Abstract classes and methods
Abstract classes cannot be instantiated. They implements methods and attribute in order to be extended by a class that will make a specialized use of them.
Abstract methods are defined in abstract classes to be overridden in subclasses.
++ Example
The following example shows how polymorphism and abstract classes and methods can be used.
+++ The superclass class `Animal’ defines all the facilities common to all the animals’ subclasses.
public abstract class Animal {
private int age = 0;
public int getAge() {
return this.age;
}
public void grow () {
this.age ++;
}
public abstract String shout() ;
}
+++ The subclass `Dog’ extends `Animal’ and implements the shout method.
public class Dog extends Animal {
/*Overrides method shout from superclass Animal*/
public String shout() {
return “Wouf! Wouf!”;
}
}
+++ The subclass `Cat’ extends `Animal’ and implements the shout method.
public class Cat extends Animal {
/*Overrides method shout from superclass Animal*/
public String shout() {
return “Miaou !”;
}
}
+++ The following instructions create a list of animals (dogs and cats) and perform various operations with them.
public static void main () {
Animal[] alist = new Animal[2];
alist [0] = new Cat();
alist [1] = new Dog();
/* Invokes the grow method (inherited from class Animal) of both objects.*/
for (int i = 0; i < 2; i ++) {
alist[i].grow();
}
/*Increments the age of the first animal.*/
alist[0].grow();
/* Prints the age and shout of both animals.*/
for (int i = 0; i < 2; i ++) {
System.print(i);
System.print(“ – “);
System.print(alist[i].getAge());
System.print(“, “);
System.println(alist[i].shout());
}
}
+++ Listing of the execution of the program
1 – 2, Miaou !
2 – 1, Wouf! Wouf!
Even if the objects are seen as Animal’s instances by the compiler, in runtime the message ’shout’ is dynamically bound with the overridden method.
You can diagnose if an object is an instance of a given class (or an instance of its subclasses) using the `instanceof’ keyword.
if (o instanceof String) {
//Do something
}
else if (o instanceof Object) {
//Do something
}
Keep in mind that all the objects, by inheritance, are instances of the Object class.
Interfaces
Interfaces describe a set of methods to be implemented by classes. It provides a protocol to use an instance of a class implementing it.
Interfaces are defined using the `interface’ keyword. They declare abstract methods only, which must be defined in any class implementing the interface.
public interface NewInterface {
public abstract void someMethod() ;
}
A class implements an interface using the `implements’ keyword in its declaration.
public class NewObjectType implements NewInterface {
public void someMethod() {
System.println(“Method invoked !”);
}
}
An interface hierarchy exists in parallel with the class hierarchy. An interface extends another using the `extends’ keyword.
public interface BrandNewInterface extends NewInterface {
public abstract void antherMethod() ;
}
+ Example
The following example shows the use of interfaces.
++ The interface `Answerable’ defines a bunch of abstract methods used to get information from any class that implements it.
public interface Answerable {
public abstract String whoAreYou () ;
public abstract String howOldAreYou () ;
}
++ The class `Animal’ extends Object and implements the interface Answerable
public abstract class Animal implements Answerable {
private int age = 0;
public int getAge() {
return this.age;
}
public void grow () {
this.age ++;
}
public abstract String shout() ;
public String whoAreYou () {
return “I’m an animal.”;
}
public int howOldAreYou () {
return this.getAge();
}
}
++ The class `Guard’ extends a hypothetic class Employee and implements the interface Answerable
public class Guard extends Employee implements Answerable {
public String whoAreYou () {
return “I’m a guard.”;
}
public int howOldAreYou () {
return 22; //Returns an arbitrary values
}
}
+ Hypothetic use
While class Guard is not a subclass of class Animal or vice-versa, we would normally need to identify the class of a given object and cast it into it before sending it a whoAreYou or howOldAreYou message.
Object o = new Animal(); //Or new Guard();
if (o instanceof Animal) {
System.println(((Animal)o).howOldAreYou());
}
else {
System.println( ((Guard)o). howOldAreYou());
}
As the two classes implement `Answerable’, their instance can be defined as Answerable objects which can handle whoAreYou or howOldAreYou messages.
Answerable o = new Guard(); //Or new Animal();
System.println(o.howOldAreYou());
Section 4,
The Moka's API
Presentation
The Moka API (application programming interface) is a large set of Moka classes. These classes encapsulate hardware features, such as the file I/O, encapsulate programming construct, such as strings, and implement some utilities, such as dynamic arrays or stacks. These classes are distributed among packages.
This section presents some features of a limited set of API classes. For an exhaustive list of classes, methods and fields, consult the HTML javadoc API documentation provided with the Moka SDK.
Five of these packages, provided with the standard Moka API, are described in this document:
- Package moka.lang : Base language classes (Object, String, …)
- Package moka.event : Classes supporting event driven programming (Event, Interrupt, …)
- Package moka.io : Classes encapsulating I/O features (File, Socket, …)
- Package moka.util : Classes implementing utilities (Vector, Timer, …)
- Pakcage moka.x : Classes supporting graphic environment programming (Component, GEM, …)
Package moka.lang
This package contains the bases classes of the Moka language.
+ Class Object
This class is at the root of the class hierarchy. The methods it defines are inherited by all the objects.
As all the classes are subclasses of this one, any object in a Moka program can be considered as an Object instance.
Object o = new String();
++ Method equals()
Any object can be compared for equality with another one using the method equal.
if (o1.equals(o2)) {
//Do something
}
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any reference values x and y, this method returns true if and only if x and y refer to the same object (x==y has the value true).
Subclasses of Object are encouraged to override this method when they have specific needs.
String s1 = “s”;
String s2 = “s”;
/*Class String overrides method equals, s1 equals s2 because they contains the same set of characters */
if (s1.equals(s2)) {
System.println(“Equality”);
}
++ Method finalize()
As seen before, the method finalize is invoked to dispose of an object.
The finalize method of class Object frees the memory occupied by the object itself.
Subclasses are encouraged to override this method to free any resource they have allocated.
public void finalize () {
this.nameString.finalize();
super.finalize();
}
++ Method getClassName()
This method returns a String representation of the class of an instance.
System.println(o.getClassName());
++ Method toString()
This method returns a String representation of the object.
The toString method of class Object returns the name of the instance’s class, concatenated with the at-sign (`@’) and the memory address of the object.
Subclasses are encouraged to override this method when they have specific needs.
String desc = o.toString();
+ Class System
This class contains several useful class fields and methods. It cannot be instantiated.
Among the facilities provided by the System class are input and output functions and most of the calc-dependent and AMS-dependent constants.
The uses of the System class are defined in the “Moka, a general purpose language” section.
+ Class String
The String class represents character strings. All string literals in Moka programs, such as "abc", should be implemented as instances of this class for easy manipulation. The compiler automatically instantiates a String object for each String literal present in a program.
String s = “abc”;
Correspond for the compiler to:
char[] charArray = new char[4];
charArray[0] = 'a';
charArray[1] = 'b';
charArray[2] = 'c';
charArray[3] = '\0';
String s = new String (charArray);
Many methods of the String class are defined in the “Moka, a general purpose language” section.
+ Class Math
The class Math contains methods for performing basic numeric operations such as the elementary exponential, logarithm, square root, and trigonometric functions.
The uses of the Math class are defined in the “Moka, a general purpose language” section.
+ Class Error
The Error class has been designed to deal with error handling. Only instances of Error, or of a subclass of Error, can be thrown in a try block, or catch in a catch block.
try {
//Protected instructions
}
catch (Error e) {
System.println(e);
}
An instance of error is thrown using the `throw’ keyword.
try {
throw new Error();
}
catch (Error e) {
System.println(e);
}
++ Constructors
The Error class has two constructors: one takes no argument, the other takes a error code as argument.
try {
throw new Error(3);
}
catch (Error e) {
System.println(e);
}
++ Method toString
The toString method of class Error returns a String object representing the error description.
+ Wrapping classes
Each primitive type has a wrapping class: Boolean, Character, Double, Integer, Long and short.
The uses of these classes are defined in the “Moka, a general purpose language” section.
++ Method equals
The equals methods of the wrapping class return true if the two object are instance of the same class and if the primitive value wrapped inside the objects are equals.
++ Method toString()
The toString methods of the wrapping class return the string representation of the primitive type, like static method of class String `valueof’.
++ Numeric primitive types’ methods
Numeric primitive types have specific methods in their wrapping class.
+++ Method byteValue()
Returns the primitive value wrapped inside the object as a byte.
+++ Method doubleValue()
Returns the primitive value wrapped inside the object as a double.
+++ Method intValue()
Returns the primitive value wrapped inside the object as an int.
+++ Method longValue()
Returns the primitive value wrapped inside the object as a long.
+++ Method shortValue()
Returns the primitive value wrapped inside the object as a short.
+++ Static method parseType(String str)
Methods parseType (replaceType by the class name) return a primitive value parsed from a String. Keep in mind that the string parsed is finalize before the method returns.
short s = Short.parseShort(“123”);
++ Character primitive type’s methods
Character primitive type has specific methods in its wrapping class. The Character class provides many methods used to manipulate ANSI character strings (advanced native C features, which will not be discussed in this section).
+++ Method charValue()
Returns the primitive char value wrapped inside the object.
+++ Static method isDigit(char c)
Return true if the character primitive provided as argument is a digit.
+++ Static method isLetter(char c)
Return true if the character primitive provided as argument is a letter.
+++ Static method isLowerCase(char c)
Return true if the character primitive provided as argument is a lowercase letter.
+++ Static method isUpperCase(char c)
Return true if the character primitive provided as argument is an uppercase letter.
+++ Static method toLowerCase(char c)
Return the specified char after converting it to a lowercase letter.
+++ Static method toUpperCase(char c)
Return the specified char after converting it to an uppercase letter.
Package moka.event
This package contains the classes used to support event driven programming. Event driven programming is a programming paradigm where events are dispatched in order to provoke instructions execution. As these events can happen at any time, programmer must rely on mechanism such as interrupts to control the program flux.
+ Class Interrupt
The Interrupt interfaces for executing code while a thread is running. An interrupt implements a method that will be executed when the main thread will be interrupted.
++ Static attribute busy
Switching this attribute to true will hold the execution of any attribute (used for synchronization purpose).
Interrupt.busy = true;
//Do something uninterrupted
Interrupt.busy = false;
++ Abstract method check()
Method check must be overridden in subclasses of Interrupt. The method must return true when the interrupt must be executed.
public class MyInt extends Interrupt {
public boolean doInterrupt = false;
public Boolean check () {
return this.doInterrupt;
}
…
}
++ Abstract method run()
Instructions in this method will be run when the interrupt will execute (when the check method will return true). Try to keep interruption fast, Moka being single threaded, if an infinite loop happen in an interrupt, it would freeze the program.
public class MyInt extends Interrupt {
public boolean doInterrupt = false;
public Boolean check () {
return this.doInterrupt;
}
public void run () {
System.println(“Interrupted !”);
}
}
++ Static method register (Interrupt i)
This method registers an instance of a subclass of Interrupt in the interruption vector. This vector regroups the interrupts to be checked for execution.
MyInt mi = new MyInt();
Interrupt.register(mi);
++ Static method unregister (Interrupt i)
This method removes an instance of a subclass of Interrupt from the interruption vector. This vector regroups the interrupts to be checked for execution, so an interrupt absent from it will never execute.
Interrupt.unregister(mi);
+ Class EventListener
The EventListener interfaces for receiving events. The class that is interested in processing an event implements this interface, and the object created with that class is registered with another object. When the event occurs, that object's eventTriggered method is invoked.
++ Method eventTriggered (Object sender)
This method is executed when an event is dispatched to this event listener.
public class MyListener extends EventListener {
public void eventTriggered (Object sender) {
sender.setVisible(false);
}
}
For examples of use, browse to the Timer class in the moka.util package chapter or to the moka.x package chapter.
Package moka.io
This package contains the Classes encapsulating the I/O features.
+ Class IOStream
This class is the base class of all the I/O classes. It defines methods to read and write different data types that are inherited by all its subclasses. When implementing an IOStream subclass, only 4 abstract method need to be implemented to interface with all the other I/O methods of this class.
++ Attribute error
This attribute value is true if the last I/O request to stream failed. It should be only read and never set.
if (ioObj.error) {
//Handle the error
}
++ Attribute opened
This attribute value is true if the stream is opened. It should be only read and never set.
if (ioObj.opened) {
ioObj.writeShort(233);
}
++ Abstract method writeByte (char val)
This method writes a single 8-bit (a byte length) char value to the stream. This method must be overridden in all the IOStream subclasses to provide interface to all the read/write methods.
ioObj.writeByte(‘a’);
++ Abstract method writeBytes (char[] buffer, short len)
This method writes a buffer of bytes up to the specified length to the stream. This method must be overridden in all the IOStream subclasses to provide interface to all the read/write methods.
char[] buf = new Char[3];
char[0] = ‘a’;
char[1] = ‘b;
char[2] = ‘c’;
ioObj.writeBytes(buf, 3);
++ Abstract method readByte()
This method reads a single 8-bit (a byte length) char value from the stream. This method must be overridden in all the IOStream subclasses to provide interface to all the read/write methods.
char c = ioObj.readByte();
++ Abstract method readBytes (char[] buffer, short len)
This method reads a buffer of bytes up to the specified length from the stream. This method must be overridden in all the IOStream subclasses to provide interface to all the read/write methods.
char[] buf = new Char[3];
ioObj.readBytes(buf, 3);
++ Abstract method open()
This method opens the stream. Its implementation is left to the subclass extending IOStream. When the stream is opened successfully, error flag must be false and open flag true.
ioObj.open();
++ Abstract method close()
This method closes the stream. Its implementation is left to the subclass extending IOStream. When the stream is closed successfully, error and open flags must be false.
ioObj.close();
++ Method finalize
This method disposes of the IOStream object. Subclasses of IOStream should not have to override the default implementation which closes the stream before finalizing the object.
ioObj.finalize();
++ Method readBoolean()
This method reads a boolean from the stream.
boolean b = ioObj.readBoolean();
++ Method readChar()
This method reads a char from the stream. In this hardware platform, you could use readByte() instead of readChar() to improve performance (readChar relies on readByte).
char c = ioObj.readChar();
++ Method readChars(short len)
This method reads a native C ANSI null-terminated string from the stream. In facts it allocates (len + 1) bytes, reads len char form the stream then appends the null character at the end of the string before returning a pointer to the beginning of the ANSI string.
native {
char * ansiStr;
}
ansiStr = ioObj.readChars(15);
++ Method readDouble()
This method reads a double from the stream.
double d = ioObj.readDouble();
++ Method readInt()
This method reads an int from the stream.
int i = ioObj.readInt();
++ Method readLong()
This method reads a double from the stream.
long l = ioObj.readLong();
++ Method readObject()
This method reads an object from the stream. This object must be a subclass of Serializable. See moka.io package Serializable class for more information.
Serializable = ioObj.readObject();
++ Method readShort ()
This method reads a short from the stream.
short s = ioObj.readShort();
++ Method readString()
This method reads a String object from the stream.
String s = ioObj.readString();
++ Method writeBoollean(boolean val)
Writes the boolean value val to the stream.
ioObj.writeBoolean(false);
++ Method writeChar(char val)
Writes the char value val to the stream. In this hardware platform, you could use writeByte(char val) instead of writeChar(char val) to improve performance (writeChar relies on readByte).
ioObj.writeChar(‘a’);
++ Method writeChanrs(char[] ansiString)
Writes a native C ANSI null-terminated string to the stream.
native {
char* ansiString = “Hello”;
}
ioObj.writeBoolean(ansiString);
++ Method writeDouble(double val)
Writes the double value val to the stream.
ioObj.writeDouble(545.44);
++ Method writeInt(int val)
Writes the int value val to the stream.
ioObj.writeInt (4477);
++ Method writeLong(long val)
Writes the long value val to the stream.
ioObj.writeLong(614891469236517205);
++ Method writeObject(Object val)
Writes the object val to the stream. The object must be a subclass of Serializable. See moka.io package Serializable class for more information.
SomeSerialClass ssc = new SomeSerialClass();
ioObj.writeObject(ssc);
++ Method writeShort(short val)
Writes the short value val to the stream.
ioObj.writeLong(123s);
++ Method writeString(String val)
Writes the String value val to the stream. Keep in mind that the string provided as argument is finalized before the method returns.
ioObj.writeString(“Hello”);
+ Class File
This class extends IOStream to provide file I/O support.
The uses of the File class are defined in the “Moka, a general purpose language” section.
+ Class Socket
This class extends IOStream to provide link I/O support.
The uses of the Socket class are defined in the “Moka, a general purpose language” section.
+ Class Graphics
The Graphics class encapsulates the display device operations and provides methods to deal with bitmaps. The class contains static methods which uses are defined in the “Moka, a general purpose language” section.
The instance of this class can be associated with a virtual display device that can be copied into the graphic memory latter (double buffering). See the javadoc entry for more information.
As the Graphics object represents a specific single-layer virtual screen, it cannot support greyscale drawing. Even when the greyscale level is set using Graphics.setGray(short g) static method, all drawing will happen normally in the Graphics objects’ virtual screen. Moreover, keep in mind that invoking any method of a Graphics object will set the graphic port to this object’s virtual screen.
++ Default constructor
The default constructor builds a Graphics object using the default display device memory address and size.
Graphics g = new Graphics();
++ Constructor Graphics(void* addr, short x, short y)
Creates a new Graphics object specifying the display device at address addr, width x and height y.
native {
void* buf = malloc(LCD_SIZE);
}
Graphics g = new Graphics(buf, 239, 127);
++ Method portSet()
Sets the virtual screen to the Graphics' display device screen. All graphic commands which are built-in into TIOS will therefore draw in this Graphics object memory.
+ Class Keyboard
Class Keyboard is used to get low-level input from the keyboard. The class contains static methods which uses are defined in the “Moka, a general purpose language” section.
Keyboard instances keep in memory which keys are pressed in a specific moment (when invoking one of the check methods of the object).
++ Key attributes
A Keyboard object is used to store the state of the keyboard. It store the state of each key in a attribute of type byte. If the byte representing a key equals 0 (false) the key is not pressed in this keyboard state. If the byte representing a key equals 1 (true), the key is pressed. Use the checkKeys and checkSysKeys to update the object state from the actual keyboard state.
if (kbd.key_A) { //If key A is pressed
//Do something
}
See the javadoc class Keyboard of package moka.io for an exhaustive listing of these attributes.
++ Method checkKeys()
Records in this object which keys are pressed on the keyboard when the method is invoked. Thereafter, it is possible to check which keys where pressed at this moment.
kbd.checkKeys();
++ Method checkSysKeys()
Records in this object which “system” keys are pressed on the keyboard when the method is invoked. It is a faster (but more limited) alternative of method checkKeys. The system keys are the arrows, APPS, ENTER, 2nd and so on … Thereafter, it is possible to check which keys where pressed at this moment.
kbd.checkSysKeys();
++ Method getKey()
Returns the key actually pressed (in the state of this Keyboard object). If two keys are pressed, the one with the lesser value is returned. If no key is pressed, the null character is returned.
short key = kbd.getKey();
++ Method hit()
Returns true if any key is pressed (in this Keyboard state), false otherwize.
/*Wait for the user to press a key.*/
while (!kbd.hit()) {
kbd.checkKeys();
}
++ Method ngetchx()
Waits for the user to press a key, then return the key.
/*Wait for the user to press a key.*/
kbd.ngetchx();
++ Method readAlpha()
Returns the first (in alphabetic order) of the alphabetic keys pressed (in this Keyboard object state). If no such key is pressed, the null character is returned.
char c = kbd.readAlpha();
+ Class Serializable
This class implements the ability to serialize and write an object to a stream and interfaces the ability to read and deserialize an object from a stream using methods readObject and writeObject of IOStream instances.
A subclass of Serializable can be written to a stream using the writeObject(Object o) method of an IOStream instance.
SerialSubclass ser = new SerialSubclass();
IoObj.writeObject(ser);
During the serialisation process, the class of the object is written to the stream first, then all its attribute are written to the stream.
A subclass of Serializable can be read from a stream using the readObject() method of an IOStream instance.
SerialSubclass ser = (SerialSubclass)ioObj.readObject();
During the deserialization process, the class of the object is read from the stream, a prototype (empty) object of the identified class is instantiated and then its fields are set by reading them from the stream.
Only primitive (long, char, and so on…) type, String instances or Serializable’s subclasses instances attributes are can be serialized and deserialized.
Package moka.util
This packages contains classes implementing utilities.
+ Class Enumeration
Class Enumeration represents an object generates a series of elements, one at a time. Successive calls to the nextElement method return successive elements of the series.
An Enumeration object is usually obtained using the elements() method of LinkedList, Vector or SerialList instances.
Enumeration enu = vectorInstance.elements();
++ Method hasMoreElements()
Returns true if there is more element in this Enumeration.
if (enu.hasMoreElement) {
//Do something
}
++ Method nextElement()
Returns the next element of this enumeration if this enumeration object has at least one more element to provide.
Object o = enu.nextElement();
+ Collection classes
Collection classes correspond to the LinkedList, SerialList and Vector classes. These classes provide facilities to manage dynamic arrays and to emulate queues and stacks. They share a number of similar methods.
++ Attribute size
This attribute value correspond to the actual size of the collection. It is maintained automatically and should be only read and never set.
++ Default constructor
Creates an empty collection.
LinkedList list = new LinkedList();
++ Constructor requiring an Enumeration as argument
Creates a collection composed by the elements of the specified enumeration. Beware that the enumeration is finalized during the process.
++ Method add (int index, Object o)
Inserts the specified element at the specified position in the collection.
++ Method clear()
Removes all of the elements from this collection.
++ Method contains(Object o)
Return true of the o is an element of this collection.
++ Method copyInto(Object[] array, int from, int to)
Copies elements in this collection from the specified index to the specified end index in array (array must be wide enought).
++ Method dequeue ()
Removes the object at the beginning of this queue and returns that object as the value of this function.
++ Method elements()
Returns an enumeration of the components of this collection.
++ Method enqueue()
Enqueues an item at the end of this queue.
++ Method get(int ind)
Returns the element at the specified position in this collection.
++ Method indexOf (Object o)
Returns the index in this collection of the first occurrence of the specified element, or -1 if this list does not contain this element.
++ Method indexOf(Object o, int ind)
Searches for the first occurence of the given argument, beginning the search at ind.
++ Method lastIndexOf(Object o)
Returns the index in this linked list of the last occurrence of the specified element, or -1 if this list does not contain this element.
++ Method lastIndexOf(Object o, int ind)
Searches backwards for the specified object, starting from the specified index, and returns an index to it.
++ Method peek ()
Looks at the object at the top of this stack without removing it from the stack.
++ Method pop ()
Removes the object at the top of this stack and returns that object as the value of this function.
++ Method push(Object o)
Pushes an item onto the top of this stack.
++ Method remove (int i)
Removes the element at the specified position in this collection.
++ Method remove (Object o)
Removes the first occurrence in this collection of the specified element. Returns true if the object is found in the collection, false otherwise.
++ Method set (int ind, Object o)
Replaces the element at the specified position in this collection with the specified element.
++ Method toString()
Returns a string representation of this collection, containing the String representation of each element.
+ Class LinkedList
The LinkedList class implements doubly-linked list. Like an array, it contains components that can be accessed using an integer index. However, the size of a LinkedList can grow or shrink as needed to accommodate adding and removing items after the LinkedList has been created.
Each linked lists tries to optimize storage management by reallocating memory every time the size of the array grows or shrinks (see Vector class for a different approach).
+ Class SerialList
The SerialList class implements a serializable list of serializable elements (See Serializable class of package moka.io for more detail on serialization process). Like an array, it contains components that can be accessed using an integer index. However, the size of a SerialList can grow or shrink as needed to accommodate adding and removing items after the SerialList has been created.
Each serializable linked lists tries to optimize storage management by reallocating memory every time the size of the array grows or shrinks (see Vector class for a different approach).
+ Class Vector
The Vector class implements a growable array of objects. Like an array, it contains components that can be accessed using an integer index. However, the size of a Vector can grow or shrink as needed to accommodate adding and removing items after the Vector has been created.
Each vector tries to optimize storage management by maintaining a capacity and a capacityIncrement. The capacity is always at least as large as the vector size; it is usually larger because as components are added to the vector, the vector's storage increases in chunks the size of capacityIncrement. An application can increase the capacity of a vector before inserting a large number of components; this reduces the amount of incremental reallocation (See LinkedList or SerialList for a different approach).
++ Attribute capacity
The actual capacity of the Vector. Is maintained automatically and should be only read, never set directly. To change its value, use the setCapacity(int capacity) accessor or trimToSize() method to set this value to the actual size of the vector. The value should always be >= to the actual size (size attribute).
++ Attribute capacityIncrement
The capacity increment of the Vector. Sould be >= 1. It represents the amount of space is allocated when the vector reach its capacity limit. A value of 3 means that when the vector will realize that it is full, it will allocate enough place for 3 more element. If this value is set high, the Vector instance will lose less time to allocate memory as it grows, but will take much more memory than it needs.
++ Constructor Vector(int capacity, int capacityIncrement)
Creates an empty Vector with the specified capacity and capacity increment.
Vector v = new Vector(5, 10);
++ Method setCapacity(int capacity)
Sets the capacity of this vector.
v.setCapacity(25);
++ Method trimToSize()
Trims the capacity of this vector to be the vector's current size. An application can use this operation to minimize the storage of a vector.
v.trimToSize();
+ Class Random
An instance of this class is used to generate a stream of pseudorandom numbers.
++ Attribute seed
The state associated with this pseudorandom number generator. The seed must be a short (16-bit integer).
rndObject.seed = 3245;
++ Default constructor
Creates a new random number generator. Its seed is initialized to a value based on the current time Two Random objects created within the same millisecond will have the same sequence of random numbers.
Random rndObject = new Random();
++ Constructor Random(short seed)
Creates a new random number generator using the specified seed.
Random rndObject = new Random(3245);
++ Method nextBoolean()
Generates the next pseudorandom boolean number.
boolean b = rndObject.nextBoolean();
++ Method nextBytes(byte[] array, short num)
Generates random bytes and places them into the user-supplied byte array. The number of random bytes produced is equal to the specified number.
byte[] array = new byte[5];
rndObject.nextBytes(array, 5);
++ Method nextDouble()
Generates the next pseudorandom double number.
double d = rndObj.nextDouble();
++ Method nextShort()
Generates the next pseudorandom short number.
short s = rndObj.nextShort();
Package moka.x
This package contains classes that support graphic environment programming. The Moka API offers a full featured graphic environment. This graphic environment relies on the X API 2.0 classes of the moka.x package. Many classes of this package represents graphic control such as windows (frames), buttons, menus and so on …
The Moka SDK comes with a large set of graphic environment applications in its examples.
+ Class Frame
A Frame instance represents a window. By default, this window is movable and shows a X-labelled button in the right of the title bar named close button (that disposes of the window when the user click on). To move the window, the user must move the cursor over the title bar and press the ENTER button. While the ENTER button remains pressed, the window will follow the cursor movement. Pressing simultaneously 2ND and F4 will close the window. In a multiple windows application (MWA), pressing simultaneously 2ND and APPS will switch between the windows.
Frame is a subclass of Container, which is discussed later.
++ Default constructor
The default constructor instantiates a blanc-titled window.
++ Constructor Frame(String str)
Creates a windows titled str.
One could simply instantiate a window and then sets its attributes before showing it up.
public static void main () {
Frame f = new Frame(“Hi!”);
f.setBounds(10, 10, 50, 50);
f.setVisible(true);
}
However, it is more usual to define a subclass of Frame and sets its attribute in the constructor.
public class MyFrame extends Frame {
public MyFrame() {
super(“Hi!”);
this.setBounds(10, 10, 50, 50);
}
public void main() {
MyFrame f = new MyFrame();
f.setVisible(true);
}
}
++ Attribute defaultCloseOperation
Specify the close operation for this frame (occurs when the user click X or close method is invoked). Valid values are (explicit enough) : Frame.DISPOSE_ON_CLOSE(default value), Frame.DO_NOTHING_ON_CLOSE, Frame.EXIT_ON_CLOSE, Frame.HIDE_ON_CLOSE.
f.defaultCloseOperation = Frame.EXIT_ON_CLOSE;
++ Attribute movable
The value of this flag specify if the frame can be moved by the user (if true – default value), or not (if false).
f.movable = false;
++ Attribute minimizeButtonVisible
This attribute specify if the minimize button is visible (true by default). Its value is maintained automatically, so it should be only read, never set. To set its value, use the accessor setMinimizeButtonVisible(boolean b).
f.setMinimizeButtonVisible(false);
++ Attribute closeButtonVisible
This attribute specify if the close button is visible (true by default). Its value is maintained automatically, so it should be only read, never set. To set its value, use the accessor setCloseButtonVisible(boolean b). See attribute minListen of GEM class of package moka.x for details on minimization.
f.setCloseButtonVisible(false);
++ Attribute modal
This attribute specify if the frame is modal (false by default). Its value is maintained automatically, so it should be only read, never set. To set its value, use the accessor setModal(boolean b).
++ Method dispose()
Disposes (finalize) this frame and all its children (the controls in it).
f.dispose();
++ Method setModal(boolean modal)
Sets if this frame is modal. A modal frame always keep the focus over the others.
f.setModal(true);
++ Method setVisible(boolean b)
Sets if this frame is visible (false by default). Sending setVisible(true) to a new instance of frame will show it automatically (this method register the frame to the GEM if it is not already done). See GEM class of package moka.x for more details on display management.
f.setVisible(true);
+ Class Component
This class is the base class of user interface controls. Components must be added to a container so they can be displayed and used.
The more common containers are instances of Frame class.
++ Default constructor
Creates a new instance of the component’s class. The initialization values greatly varies between subclasses of component. A component can be added to a container as soon as it is created.
public class MyFrame extends Frame {
private Button btnOk;
public MyFrame() {
super(“Hi!”);
this.setBounds(10, 10, 50, 50);
this.btnOk = new Button(“Hello!”);
this.add(btnOk);
}
public void main() {
MyFrame f = new MyFrame();
f.setVisible(true);
}
}
++ Attribute enabled
This attribute specifies if the component is enabled. Its value is maintained automatically, so it should be only read, never set. Use setEnabled(boolean b) to change its value.
cpn.setEnabled(false);
++ Positional and size attributes
These attributes specify the size and position of the component. The coordinates of a component depends on the coordinates of its parent. They are maintained automatically and should therefore be only read, never set. Use the available accessors to change their values.
x : the relative X coordinate of this component. Use setX(short x) to change its value.
y : the relative Y coordinate of this component. Use setY(short y) to change its value.
width : the width of the component. Use setWidth (short w) to change its value.
height : the height of the component. Use setHeight(short h) to change its value.
These values can all be set the same time with method setBounds(short x, short y, short width, short height).
cpn.setBounds(10, 10, 75, 50);
++ Attribute visible
Specifies if this component should is visible. A user cannot interact with an invisible component. Its value is maintained automatically, so it should be only read, never set. Use setVisible(boolean b) to change its value.
cpn.setVisible(false);
++ Attribute mnemonic
Specifies the mnemonic (keyboard shortcut) associated with this component. . Its value is maintained automatically, so it should be only read, never set. Use setMnemonic (char m) to change its value.
cpn.setMnemonic(‘a’);
++ Attribute listen
This attribute is a reference to an event listener (or null). When the user interacts with the component, an event is triggered.
Usually, an event listener serves for more than one component. Such as any component is a subclass of EventListener, a Frame is often use as event listener for its children.
public class MyFrame extends Frame {
private Button btnOk;
private Button btnCancel;
public MyFrame() {
super(“Hi!”);
this.setBounds(10, 10, 100, 75);
this.btnOk = new Button(“Ok”);
this.add(btnOk);
this.btnOk.setBounds(5, 15, 50, 20);
this.btnOk.listen = this;
this.btnCancel = new Button(“Cancel”);
this.add(btnCancel);
this.btnCancel.setBounds(5, 40, 50, 20);
this.btnCancel.listen = this;
}
public void main() {
MyFrame f = new MyFrame();
f.setVisible(true);
}
public void eventTriggered (Object sender) {
if (sender == this.btnOk) {
//Code to handle a user click on btnOk
}
else if (sender == this.btnCancel) {
//Code to handle a user click on btnCancel
}
}
}
++ Alignment methods
Several methods are offered to align the component, always in relation to its parent coordinates: right(), left(), center(), top(), bottom().
cpn.center();
cpn.top();
+ Class Container
This class is a subclass of Component. It extends its superclass in such way that a Container object can contain other component. As said before, the component position on the screen depends on the coordinate of their parent component, which is a Container. A container can contain another container.
++ Method add (Component c)
This method adds the specified component to the container.
f.add(btnOk);
++ Method remove (Component c)
This method removes the specified component to the container.
f.remove(btnOk);
+ Class GEM
The GEM, or Graphical Environment Manager is the engine of the graphic environment. It controls for the programmer the display and removal of components on the screen, the keyboard and mouse input from the user. GEM is a subclass of Container. All the programmer must do to control the graphic environment is to add or remove component from the GEM. Some class such as Frame register themselves automatically when setting them visible.
++ Attribute gem
This attribute is an instance of GEM automatically instantiated. It represents the current manager for this application.
GEM.gem.add(myFrame);
++ Attribute cursorSpeedX
Specifies the horizontal speed of the cursor.
GEM.gem.cursorSpeedX = 8;
++ Attribute cursorSpeedY
Specifies the vertical speed of the cursor.
GEM.gem.cursorSpeedY = 8;
++ Attribute cursorX
The x coordinate of the cursor. Should be only read when the cursor is visible.
++ Attribute cursorY
The y coordinate of the cursor. Should be only read when the cursor is visible.
++ Attribute minListen
A reference to a EventListener instance that should be notified when a frame is minimized (when the user click on the `-‘ button).
GEM.gem.minListen = myListen;
++ Attribute startListen
A reference to an EventListener instance that should be notified when the GEM is starting up.
GEM.gem.startListen = myListen;
++ Attribute systemFont
Specifies the system font. Should be only read as its value is maintained automatically. Use the setFont(short font) method to set its value.
++ Method getFontHeight()
Returns a short representing the current font height in pixels.
short h = GEM.gem.getFontHeight()
++ Static method getFontHeight(short font)
Returns the height in pixels of the specified font.
++ Method getFontWidth()
Returns a short representing the current font width in pixels.
short w = GEM.gem.getFontWidth();
++ Static method getFontWidth(short font)
Returns the width in pixels of the specified font.
++ Method setFont(short font)
Set the specified font as the system font. Legal values are Font.FONT_4x6, Font.FONT_6x8, Font.FONT_8x10 and Font.FONT_SYSTEM (which is the default value).
GEM.gem.setFont(Font.FONT_6x8);
+ Subclasses of CaptionedComponent
CaptionedComponent is a subclass of Component that implements Captioned interface. Its subclasses are controls which display a text caption.
++ Attribute caption
Represents the caption of the CaptionedComponent. Should be only read as its value is maintained automatically. Use the setCaption(String caption) method to set its value.
++ Attribute font
Represents the font of the CaptionedComponent. Should be only read as its value is maintained automatically. Use the setFont(short font) method to set its value. Legal values are Font.FONT_4x6, Font.FONT_6x8, Font.FONT_8x10 and Font.FONT_SYSTEM (which is the default value).
++ Constructor accepting a String
CaptionnedComponent subclass usually features a constructor accepting a String that initialize the caption of the component.
//One could use
Button b = new Button(“Title”);
//Instead of
Button b = new Button();
b.setCaption(“Title”);
++ Method setCaption(String caption)
Sets the caption of this CaptionedComponent.
cpn.setCaption(“Hello”);
++ Method setFont(short font)
Sets the font of this CaptionedComponent.
Cpn.setFont(Font.FONT_4x6);
Class Button – A push button component
Class Label – A text label component
++ Class TextField
A single line text field.
+++ Attribute inputType
Represents the type of input accepted by this text field. The legal values are TextField.CHAR_INPUT_TYPE, TextField.FLOAT_INPUT_TYPE, TextField.INT_INPUT_TYPE and TextField.NO_INPUT_TYPE.
txtFld.inputType = TextField.CHAR_INPUT_TYPE;
+++ Attribute mask
Specifies the mask of this textfield. The default value ‘\0’ (null character) specifies no mask.
+++ Attribute maxLength
Specifies the maximum length of text the textfield should accept. Its value must remains > 0.
++ Class TextArea
A multiple line spawned text area.
+++ Attribute maxLength
Specifies the maximum length of text the textfield should accept. Its value must remains > 0.
+++ Attribute warp
Specifies if the word should be warped. . Its value is maintained automatically so you should only read it. Use setWarp(boolean b) to change its state.
+++ Method setWarp(boolean b)
Sets if the words should be warped.
txtArea.setWarp(true);
++ Class CheckBox
Checkbox is a button that can be `checked’ by a click of the user.
+++ Attribute checked
This attribute specify if the CheckBox is checked. Its state is maintained automatically so you should only read it. Use setChecked(boolean b) to change its state.
+++ Method setChecked(boolean b)
This method sets if this CheckBox is checked or not.
chkbox.setChecked(true);
++ Class RadioButton
This class is a subclass of CheckBox. The main difference between CheckBoxes and RadioButtons is that the latter are organized in groups. Only one – or none – RadioButton can be checked in a group. If a RadioButton is clicked by the user, the previous checked button will be unchecked.
+++ Attribute group
Specifies the RadioGroup for this RadioButton. Should be only read as its value is maintained by the system. Use setGroup(RadioGroup group) to set its value.
+++ Method setGroup(RadioGroup group)
Sets the RadioGroup associated with this RadioButton.
radioBtn.setGroup(radioGroup1);
+++ Class RadioGroup
This class is not a component. It represents a group of RadioButtons.
++++ Attribute selected
Specifies which RadioButton is selected in this group. Its value is maintained by the system, so it should be only read. Use the setSelected(RadioButton button) method to set its value.
++++ Method setSelected(RadioButton radio)
Sets the selected RadioButton in this group. It is not usually invoked by the programmer, as the setChecked method of class RadioButton does it for him. See method setChecked of class RadioButton for details.
radioGroup1.setSelected(radioBtn1);
+ Class Menu
This subclass of CaptionedComponent represents a menu in a menu bar. It must be added to a MenuBar to be displayed. MenuItems can be added to a menu.
Menu fileMenu = new Menu(“File”);
menuBar.add(fileMenu);
++ Adds an item to this Menu.
MenuItem mi = new MenuItem(“Open…”);
fileMenu.add(mi);
++ Method remove (MenuItem i)
Removes an item to this Menu.
fileMenu.remove(mi);
Section 5,
Moka's advanced features
Moka advanced features
These features are only useful to API or system programmers which need to hack
+ C interoperability
As Moka is a Java to C translator, it fully supports C language source code integration. You can include C source code directly in the Moka classes’ source or include a C header file in the project. Only API programmers should use native C instructions in the conception of Moka classes to insure compatibility.
++ The `native’ keyword
The `native’ keyword plays a different role in Moka than in Java. In Java, `native’ is a method modifier that specifies that the method is compiled somewhere else in a native language (usually in C). In Moka, when `native’ modifies a method as in:
public native void doSomething () {
printf(“Hello world !”);
}
it specifies that method `doSomething’ is written in C.
The `native’ keyword is also use to include C instructions in a Moka method. Using this syntax, it instructs the converter to copy without any change a specific instruction:
public void doSomething () {
//Moka code
native.printf(“Hello world !”);
//Moka code
}
The same keyword can also be used to define a block of C instruction:
public void doSomething () {
//Moka code
native {
printf(“Hello world !”);
}
//Moka code
}
++ The `asm’ keyword
To include ASM instruction for the in-stream assembler, use the asm keyword:
public void doSomething () {
asm ("move.l 0xC8,%a0");
}
++ Header files
Header files are included automatically to a project during the process. A header is always associated to a class. When a class is imported in a project, the associated header will be automatically included in the project. The associate a header with a Moka class, create a `.h’ file using the same name of the class in the same directory. Ex:
Class file - C:\Project\Toto.java
Header file - C:\Project\Toto.h
+++ Defining aliases
The header files are useful to define aliases. Some static methods (such as System.clrscr()) of the Moka API are defined only to map native C functions. The more intuitive method to do this is to define a native static method that encapsulate the c function :
public static native void clrscr () {
clrscr();
}
But this technique slows the execution (two function calls instead of one) and is a waste of space.
An other technique is to define an abstract static method :
public abstract static void clrscr() ;
And then, in a header file of the same name of the class, to define a synonym for the static method (see the Conversion process section for naming standards):
#define System_clrscr clrscr
+ Conversion process
Moka converts java source code to C code in 5 steps :
Step 1: Read source files
All the files needed by the project are read. It comprises the user classes and all the classes imported by them. The converter begins with the main class, read all the classes imported by it and so on.
As all classes are subclasses of Object, this class is implicitly imported by all projects. If there is no Object class in the API, the compiler will terminate showing an error message.
Step 2: Decoding classes
At this step, the source files are read in order to create abstract entities such as classes, interfaces, constructors, methods, attributes, etc. These abstract realities are used to build the object oriented model, which will be used when converting the code.
Once this step is completed, only 2 types of data remains, object oriented model entities and Moka instructions (code in methods).
Step 3: Converting code
After the creation of an object oriented model in step 2, the Moka instructions can be converted into C statements. In other words, the Moka instructions – who manipulate the OO model entities - are replaced by C instructions who emulate OO language functionality.
Now the compiler has converted code associated with a collection of OO model entities.
Step 4: Optimization
In this step, the compiler will recursively browse the converted code (and the native C code) to identify the methods actually used in the project. The methods not used in the project are removed, reducing the size of the executable program.
The optimization is enabled by default, but can be disabled using the `!-o’ switch.
Step 5: Building the C source files.
In this step, the OO model is converted to Enhanced C Object Oriented Language (E COOL) and a TIGCC .tpr project file is created.
++ Naming convention
Each class has a header file containing the source code of its methods. The method prototypes are defined in the package header.
+++Objects
Classes are implemented using C structs. An object reference is, in fact, a pointer to a structure of the type of the objects. The type of an object is equal to `T’ followed by the name of its class. Ex :
The type of the instances of the `Object’ class is `TObject’.
Member access are translated using the `->’ operator. Ex :
//Object list has a size attribute
printf(“%d”, list->size);
If the member is a method, the pointer to the object must be transmitted as the first argument. Ex :
list->get_short_int(list, 10);
+++Methods
Methods in Moka are translated to C functions. To support polymorphism, the method signature (type of its arguments) is appended at the end of the method. Ex :
Ex :
public class Toto {
static public void get(short i) {
//Do something
}
}
C function :
TToto_get_short_int(TToto* this, short int i) {
//Do something
}
+++Static methods
The static methods are translated to C functions beginning by the name of the class followed by `_’. Ex :
public class Toto {
static public void method1() {
//Do something
}
}
C function :
Toto_method1_() {
//Do something
}
+++ Static attributes
Static attribute are translated the same way the static methods are. Ex :
public class Toto {
static int attr1;
}
C :
long int Toto_attr1;
`Serializable’ class
The moka.io.Serializable class is a convenient tool to write or read objects into IOStreams. Subclasses of Serializable can be directly, without any programming, be inputted from an IOStream or outputted to an IOStream using readObject(Object o) and writeObject(). If a Serializable object has a reference to another Serializable object, this object will be serialized to or deserialized from the stream automatically (be careful with infinite inclusion loop caused by self references).
`Use’ and `No’ interfaces set.
Package moka.lang contains a set of `Use…’ and `No…’ interfaces that can either modify the way the program is converted (optimization, garbage collection) or define some properties for the C compiler when they are implemented by the main class of a project.
+ Use_GarbageCollection
This interface should be used only for debugging (memory leaks) purpose or in case memory and speed are not a concern. When the main class of a project implements this interface, a garbage collection facility is included into the project. Each object created during the execution of the program will thereby be finalized before the program exits. Moreover, any block of memory acquired using System.malloc(int size) will be freed before the program exits. Object can be finalized manually, as usual. A block of memory acquired by System.malloc(int size) can also be freed manually using System.free(void* ptr). If free is used to liberate either an object memory or a block allocated using System.malloc(int size), the program will likely crash just before exiting, during garbage collection.
The work of the garbage collection facility is simple. When an object is instantiated, or a memory block is allocated, its memory address is added to an array used by the garbage collector. While the program is about to terminate, the objects in the garbage collector’s array are finalized and the memory blocks freed. If an object is finalized or a memory block freed using the proper facilities (finalize method and System.free(void* ptr)), its reference is removed from the garbage collector array.
+ Use_Optimization and No_Optimization
These interfaces, when implemented by the main class of a project override the compiler switch `-o’. This interface has no use in a normal program, it could however be used to overcome optimization bugs, if they ever exist.
+ No_GhostSpace
By default, to overcome some AMS limitation, Moka programs run in `Ghost space’. When applied to the main class of a program, the `No_GhostSpace’ interface prevents this and saves a 130 bytes overhead.
+ No_SaveScreen
By default, the screen state is restored after a Moka program ends its execution. To prevent Moka to restore the state of the screen before exiting, a Moka project’s main class must implement `No_SaveScreen’ interface.
GNU Free Documentation License
Version 1.2, November 2002
Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other
functional and useful document "free" in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or noncommercially.
Secondarily, this License preserves for the author and publisher a way
to get credit for their work, while not being considered responsible
for modifications made by others.
This License is a kind of "copyleft", which means that derivative
works of the document must themselves be free in the same sense. It
complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for free
software, because free software needs free documentation: a free
program should come with manuals providing the same freedoms that the
software does. But this License is not limited to software manuals;
it can be used for any textual work, regardless of subject matter or
whether it is published as a printed book. We recommend this License
principally for works whose purpose is instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium, that
contains a notice placed by the copyright holder saying it can be
distributed under the terms of this License. Such a notice grants a
world-wide, royalty-free license, unlimited in duration, to use that
work under the conditions stated herein. The "Document", below,
refers to any such manual or work. Any member of the public is a
licensee, and is addressed as "you". You accept the license if you
copy, modify or distribute the work in a way requiring permission
under copyright law.
A "Modified Version" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section of
the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall subject
(or to related matters) and contains nothing that could fall directly
within that overall subject. (Thus, if the Document is in part a
textbook of mathematics, a Secondary Section may not explain any
mathematics.) The relationship could be a matter of historical
connection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regarding
them.
The "Invariant Sections" are certain Secondary Sections whose titles
are designated, as being those of Invariant Sections, in the notice
that says that the Document is released under this License. If a
section does not fit the above definition of Secondary then it is not
allowed to be designated as Invariant. The Document may contain zero
Invariant Sections. If the Document does not identify any Invariant
Sections then there are none.
The "Cover Texts" are certain short passages of text that are listed,
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
the Document is released under this License. A Front-Cover Text may
be at most 5 words, and a Back-Cover Text may be at most 25 words.
A "Transparent" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed of
pixels) generic paint programs or (for drawings) some widely available
drawing editor, and that is suitable for input to text formatters or
for automatic translation to a variety of formats suitable for input
to text formatters. A copy made in an otherwise Transparent file
format whose markup, or absence of markup, has been arranged to thwart
or discourage subsequent modification by readers is not Transparent.
An image format is not Transparent if used for any substantial amount
of text. A copy that is not "Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format, SGML
or XML using a publicly available DTD, and standard-conforming simple
HTML, PostScript or PDF designed for human modification. Examples of
transparent image formats include PNG, XCF and JPG. Opaque formats
include proprietary formats that can be read and edited only by
proprietary word processors, SGML or XML for which the DTD and/or
processing tools are not generally available, and the
machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.
The "Title Page" means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page. For works in
formats which do not have any title page as such, "Title Page" means
the text near the most prominent appearance of the work's title,
preceding the beginning of the body of the text.
A section "Entitled XYZ" means a named subunit of the Document whose
title either is precisely XYZ or contains XYZ in parentheses following
text that translates XYZ in another language. (Here XYZ stands for a
specific section name mentioned below, such as "Acknowledgements",
"Dedications", "Endorsements", or "History".) To "Preserve the Title"
of such a section when you modify the Document means that it remains a
section "Entitled XYZ" according to this definition.
The Document may include Warranty Disclaimers next to the notice which
states that this License applies to the Document. These Warranty
Disclaimers are considered to be included by reference in this
License, but only as regards disclaiming warranties: any other
implication that these Warranty Disclaimers may have is void and has
no effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License applies
to the Document are reproduced in all copies, and that you add no other
conditions whatsoever to those of this License. You may not use
technical measures to obstruct or control the reading or further
copying of the copies you make or distribute. However, you may accept
compensation in exchange for copies. If you distribute a large enough
number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and
you may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have
printed covers) of the Document, numbering more than 100, and the
Document's license notice requires Cover Texts, you must enclose the
copies in covers that carry, clearly and legibly, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover. Both covers must also clearly and legibly identify
you as the publisher of these copies. The front cover must present
the full title with all words of the title equally prominent and
visible. You may add other material on the covers in addition.
Copying with changes limited to the covers, as long as they preserve
the title of the Document and satisfy these conditions, can be treated
as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto adjacent
pages.
If you publish or distribute Opaque copies of the Document numbering
more than 100, you must either include a machine-readable Transparent
copy along with each Opaque copy, or state in or with each Opaque copy
a computer-network location from which the general network-using
public has access to download using public-standard network protocols
a complete Transparent copy of the Document, free of added material.
If you use the latter option, you must take reasonably prudent steps,
when you begin distribution of Opaque copies in quantity, to ensure
that this Transparent copy will remain thus accessible at the stated
location until at least one year after the last time you distribute an
Opaque copy (directly or through your agents or retailers) of that
edition to the public.
It is requested, but not required, that you contact the authors of the
Document well before redistributing any large number of copies, to give
them a chance to provide you with an updated version of the Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document under
the conditions of sections 2 and 3 above, provided that you release
the Modified Version under precisely this License, with the Modified
Version filling the role of the Document, thus licensing distribution
and modification of the Modified Version to whoever possesses a copy
of it. In addition, you must do these things in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct
from that of the Document, and from those of previous versions
(which should, if there were any, be listed in the History section
of the Document). You may use the same title as a previous version
if the original publisher of that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities
responsible for authorship of the modifications in the Modified
Version, together with at least five of the principal authors of the
Document (all of its principal authors, if it has fewer than five),
unless they release you from this requirement.
C. State on the Title page the name of the publisher of the
Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license notice
giving the public permission to use the Modified Version under the
terms of this License, in the form shown in the Addendum below.
G. Preserve in that license notice the full lists of Invariant Sections
and required Cover Texts given in the Document's license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled "History", Preserve its Title, and add
to it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page. If
there is no section Entitled "History" in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.
J. Preserve the network location, if any, given in the Document for
public access to a Transparent copy of the Document, and likewise
the network locations given in the Document for previous versions
it was based on. These may be placed in the "History" section.
You may omit a network location for a work that was published at
least four years before the Document itself, or if the original
publisher of the version it refers to gives permission.
K. For any section Entitled "Acknowledgements" or "Dedications",
Preserve the Title of the section, and preserve in the section all
the substance and tone of each of the contributor acknowledgements
and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document,
unaltered in their text and in their titles. Section numbers
or the equivalent are not considered part of the section titles.
M. Delete any section Entitled "Endorsements". Such a section
may not be included in the Modified Version.
N. Do not retitle any existing section to be Entitled "Endorsements"
or to conflict in title with any Invariant Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all
of these sections as invariant. To do this, add their titles to the
list of Invariant Sections in the Modified Version's license notice.
These titles must be distinct from any other section titles.
You may add a section Entitled "Endorsements", provided it contains
nothing but endorsements of your Modified Version by various
parties--for example, statements of peer review or that the text has
been approved by an organization as the authoritative definition of a
standard.
You may add a passage of up to five words as a Front-Cover Text, and a
passage of up to 25 words as a Back-Cover Text, to the end of the list
of Cover Texts in the Modified Version. Only one passage of
Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document already
includes a cover text for the same cover, previously added by you or
by arrangement made by the same entity you are acting on behalf of,
you may not add another; but you may replace the old one, on explicit
permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License
give permission to use their names for publicity for or to assert or
imply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified
versions, provided that you include in the combination all of the
Invariant Sections of all of the original documents, unmodified, and
list them all as Invariant Sections of your combined work in its
license notice, and that you preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy. If there are multiple Invariant Sections with the same name but
different contents, make the title of each such section unique by
adding at the end of it, in parentheses, the name of the original
author or publisher of that section if known, or else a unique number.
Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled "History"
in the various original documents, forming one section Entitled
"History"; likewise combine any sections Entitled "Acknowledgements",
and any sections Entitled "Dedications". You must delete all sections
Entitled "Endorsements".
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents
released under this License, and replace the individual copies of this
License in the various documents with a single copy that is included in
the collection, provided that you follow the rules of this License for
verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute
it individually under this License, provided you insert a copy of this
License into the extracted document, and follow this License in all
other respects regarding verbatim copying of that document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate
and independent documents or works, in or on a volume of a storage or
distribution medium, is called an "aggregate" if the copyright
resulting from the compilation is not used to limit the legal rights
of the compilation's users beyond what the individual works permit.
When the Document is included in an aggregate, this License does not
apply to the other works in the aggregate which are not themselves
derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half of
the entire aggregate, the Document's Cover Texts may be placed on
covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic form.
Otherwise they must appear on printed covers that bracket the whole
aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section 4.
Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections. You may include a
translation of this License, and all the license notices in the
Document, and any Warranty Disclaimers, provided that you also include
the original English version of this License and the original versions
of those notices and disclaimers. In case of a disagreement between
the translation and the original version of this License or a notice
or disclaimer, the original version will prevail.
If a section in the Document is Entitled "Acknowledgements",
"Dedications", or "History", the requirement (section 4) to Preserve
its Title (section 1) will typically require changing the actual
title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except
as expressly provided for under this License. Any other attempt to
copy, modify, sublicense or distribute the Document is void, and will
automatically terminate your rights under this License. However,
parties who have received copies, or rights, from you under this
License will not have their licenses terminated so long as such
parties remain in full compliance.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions
of the GNU Free Documentation License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns. See
http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
License "or any later version" applies to it, you have the option of
following the terms and conditions either of that specified version or
of any later version that has been published (not as a draft) by the
Free Software Foundation. If the Document does not specify a version
number of this License, you may choose any version ever published (not
as a draft) by the Free Software Foundation.
ADDENDUM: How to use this License for your documents
To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and
license notices just after the title page:
Copyright (c) YEAR YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
replace the "with...Texts." line with this:
with the Invariant Sections being LIST THEIR TITLES, with the
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
free software license, such as the GNU General Public License,
to permit their use in free software.