The Price is Right!

2 The Moto Language

Moto is an embedded language. That means that any text file, HTML page, or XML document is by default a legal moto file. The contents of such a file would pass through the moto interpreter and print out unmodified. Moto actually does something when, in the process of parsing a file, it runs into a moto construct. These are special directives that begin with the character $.


To comment out a block of text you want moto to ignore, surround that text by $* and *$ . Unlike HTML comments, commented text will not appear in the output of either the moto compiler or interpreter.

$* comment *$  

2.2 Using the $ in Moto

To use the dollar sign $ in your moto file without what follows being interpreted as a macro or malformed moto construct you must escape it with a backslash


Note that backslashes not followed by a dollar sign are treated as literal and need not be escaped. Thus the code used to produce the previous example was


2.3 Local Variables

Moto supports the use of local variables. Prior to use, a local variable must first be declared.

$declare(variable type variable name)  

The initial value of a variable may also be set at declaration time.

$declare(variable type variable name = initial value )  

You may not declare a variable with the same name more than once in a page. That means that you may not declare a variable with the same name in a macro that is used on the page or in a file that is included in the page. Unlike C, moto does not require all declarations to be at the beginning of a page , but it's still good practice.

The storage for local variables is lost after executing a page. Thus these variables are said to have a page lifetime. Variables declared within a loop or conditional block may not be used after (outside of) that conditional block or loop. Such variable have a scope lifetime.

Variables may be of basic types or object types. Basic types include:

double may be assigned any byte, char, int, float, long or double value
float may be assigned any byte, char, int, float, long or double value
long may be assigned any byte, char, int, float, long or double value. Moto longs are 64 bits in length thus the maximum and minimum values are 9223372036854775807 and -9223372036854775808 respectively
int may be assigned any byte, char, int, float, long or double value. Moto ints are 32 bits thus the maximum and minimum values are 2147483647 and -2147483648 respectively
byte may be assigned any byte, char, int, float, long or double value. Bytes are signed ints 8 bits long thus the maximum and minimum values are 127 and -128 respectively
boolean may be assigned true or false or the value of a relational expression
char may be assigned any character in sigle quotes '' including standard C escape characters such as '\n' '\r' or '\t'. It may also be assigned a value in hex or octal representation e.g. '\x41' == '\101' == 'A' as well as any numeric value

The char, byte, double, float, long, and int types collectively make up the supported basic numerical types. They can be combined to form expressions via the following operations:

A + B adds A and B together or converts one variable to a String and concatenates it to the other if the other is already a String.
A - B subtracts B from A
A * B multiplies A and B
A / B divides A by B. When B is 0 a division by zero exception will be thrown
A % B provides A mod B (only works if A and B are longs or ints

When numeric variables of different types appear in an expression, expanding casts are used so that the most precise answer is maintained (i.e. a long plus an int yields a long, an int divided by a float yields a float etc...). Only numeric variables and chars are implicitly cast, booleans are not. The set of boolean operators will be described in the section on conditionals.

The integral types byte, char, int, and long may also be acted on by bit manipulation operators

A | B Bitwise OR will turn any bit to 1 in the expression result that was 1 in either A or B. The corresponding bit in the result will be 0 otherwise
A & B Bitwise AND will turn any bit to 1 in the expression result that was 1 in both A and B. The corresponding bit in the result will be 0 otherwise
A ^ B Bitwise XOR will turn any bit to 1 in the expression result that was 1 in either A and B but not both. The corresponding bit in the result will be 0 otherwise
~A Bitwise NOT will turn any bit to 1 in the expression result that was 0 in A. Otherwise the corresponding bit in the result will be 0
A << B Left shift shifts the bits of A B bits to the left and fills the rightmost B bits with 0. The A << 2 would multiply A by 4
A >> B Right shift shifts the bits of A B bits to the right and fills the leftmost B bits with 0. The A >> 2 would divide A by 4

Object types are anything else. As a rule, all basic types begin with a lower case letter all object types begin with an uppercase letter. There is language level support for three types of objects :

String may be assigned a character string between double quotes ""
Regex may be assigned a regular expression between forward slashes /.../
Object may be assigned an object of any typed

The plus operator may also be used to append Strings together. When basic types are added to strings they are automatically converted to strings first.

Other types of objects become available via the $use keyword.

When creating a new object use the new keyword and then call that objects constructor

$declare(Hashtable htab = new Hashtable())  

Objects you create may need to be deleted later depending upon which memory manager you are using. This is done using the delete keyword.

delete htab  

All object types may also be assigned the special value null

$declare(Hashtable htab = null)  

The capital 'O' Object type is special in that it may be assigned a value of any other object type.

$declare(Object htab = new Hashtable())  

This is important for objects that are designed to store other objects such as Vectors or Stacks. There are no methods that can be called on a pure Object type. Rather, before an Object can be used it must be cast to the appropriate type.

$declare(Object obj = new Hashtable())
$declare(Hashtable htab = <Hashtable>obj)

2.4 Doing things

$do( expression )  

To call a function or assign a value to a previously declared variable use the $do construct. The following operators assign values to variables:

A = B The variable A is assigned the value of expression B
A += B If A and B are both numeric types the variable A is incremented by the result of expression B. If A is a String then the result of evaluating expression B is converted to a String and appended to A.
A -= B The variable A is decremented by the result of expression B (note that A and B must both be numeric types)
A *= B The variable A is multiplied by the result of expression B (note that A and B must both be numeric types)
A /= B The variable A is divided by the result of expression B (note that A and B must both be numeric types)
A++ The integer, long, byte, or char variable A is incremented by 1
A-- The integer, long, byte, or char variable A is decremented by 1
++A The integer, long, byte, or char variable A is incremented by 1
--A The integer, long, byte, or char variable A is decremented by 1

2.4.1 The Comma Operator

There are times when you might want to do 'more than one thing at once' . For this you can use the comma operator. The comma operator allows you to execute multiple expressions one after another as a single expression. The result and type of the compound expression is determined solely by the last expression executed:


2.5 Output

$( expression)  

Read 'dollar print', this construct is used to output an expression or result of a function call. All non String expression results are converted to Strings prior to being output.

2.6 Conditionals

2.6.1 If construct

   code to be executed if condition is true
$elseif(some other condition)
   code to be executed if other condition is true
   code to be executed if previous conditions are false

As in other languages, the basic conditional statement consists of an opening if construct, followed by any number of else if conditions, followed by an optional else construct, then a mandatory endif. Unlike languages such as C however, conditions in moto must be booleans. The following comparison operators return boolean values:

A > B numeric variable A is greater than numeric variable B
A >= B numeric variable A is greater than or equal to numeric variable B
A < B numeric variable A is less than numeric variable B
A <= B numeric variable A is less than or equal to numeric variable B
A == B the value of basic variable A equals the value of basic variable B OR the reference variable A refers to the same object as the reference variable B
A != B the value of basic variable A does not equal the value of basic variable B OR the reference variable A does not refer to the same object as the reference variable B
A eq B the String variable A has the same content as the String variable B
A ne B the String variable A does not have the same content as the String variable B
A lt B The String A would come before B when sorted alphabetically
A gt B The String A would come after B when sorted alphabetically
A lte B The String A would come before B when sorted alphabetically OR A has the same content as B
A gte B The String A would come after B when sorted alphabetically OR A has the same content as B
A =~ B the regular expression B matches a substring of the String A
A !~ B the regular expression B does not match any substring of the String A

In addition the following operations can be used on boolean expressions to create more complex boolean typed expressions.

A && B Expression is true if and only if subexpressions A and B are true
A || B Expression is true if either subexpression A or B is true
!A Expression is true if subexpression A is false

Like C, short circuit evaluation is used when evaluating compound boolean operators.

2.6.2 Switch construct

   code for default case
$case(value 1)
   code for case 1
$case(value 2)
   code for case 2
$case(value 3)
   code for case 3

You can switch on any basic type expression as well as Strings. Unlike C, execution does not 'fall through' cases, rather the next case ends the previous. Another important difference from C is the lack of an explicitly specified default case. In moto, the default behavior is to execute whatever code is specified between the switch statement and the first case. The following example illustrates how switch statements are used to display the examples used in this document.


$declare(String example = getFile("/content/moto/"))
$declare(StringBuffer displayExample = new StringBuffer())

$declare(int i=0)
$declare(char lastchar = '\0')

     $* default *$
     $case(' ')
        $if(lastchar == ' ')
           $do(displayExample.append(' '))
  $do(lastchar = example.charAt(i))


2.6.3 The Ternary Operator

condition ? A : B  

Not a construct, but an operator, the ternary operator may be used to within an expression to return one of two same typed outputs. In the example above the expression returns the subexpression A if the specified condition evaluates true, B otherwise.

2.7 Loops

2.7.1 For loops

For loops in moto work very similar to for loops in C, C++, or Java.

   code to be repeated

The initialization expression is executed prior to looping. It is used to set up the initial conditions for the loop itself. The condition expression is tested on each iteration of the loop (including the first iteration immediately after initialization). Unline C or C++ the condition expression must be a boolean expression. The increment expression is executed after each iteration of the loop. It is immediately after the increment expression is executed that the condtion is tested again. When the condition expression becomes false the loop terminates. For instance to execute a loop ten times you might write

   code to be repeated

This assumes the variable 'i' was declared prior to being used in the loop. Like Java a variable may be declared within the initialization expression.

$for(int i=0;i<10;i++)
   code to be repeated

2.7.2 While loops

   code to be repeated

Executes the code to be repeated while the boolean condition remains true.

2.7.3 Break and Continue

   code to be repeated
   $if(some other condition)
      $break    $endif    more code to be repeated

Breaks out of the last open loops (continues after the next $endfor or $endwhile)

$while(1st condition)
   code to be repeated
   $if(2nd condition)
      $continue    $endif    code to be repeated only if 2nd condition is false

Returns to the first line of the most recently opened loop (and increments the counter in a for loop).

2.8 Re-Use Constructs

2.8.1 Moto Functions

To define a function in moto use the $define construct. In it you must specify the return type of the function (use the return type void if the function returns nothing). Follow the return type with the name of the function and then the arguments the function will take in parenthesis. The argument list should take the form type argument-name,type argument-name, ... for as many arguments as you have. You can specify an empty argument list.

$define(return-type name(argument list))

Function definition in moto must occur in the top scope. You cannot define a new function inside a condition, iterative, or scoping block. You can however use functions before they are defined within a moto page. Unlike C there is no need (and no way) to explicitly prototype functions before using them.

To return a value from a function use the $return construct. The type of the expression returned must however match the specified type of the function. $return must be inside a $define ... $enddef scope or else it is a syntax error.

You can specify multiple functions with the same name as long as they take a different number of arguments, or different argument types, or the same argument types in a different order.

Functions in moto do not normally have access to variables declared outside of them. Only variables declared as global before the function definition can be used within a moto function. Otherwise only arguments to that function and variables declared within the body of the function can be used. To declare a variable as global use the global type qualifier

$declare(global int statements=0)  

Like functions, globals can only be declared at the top level and are not allowed in nested scopes.

2.8.2 Moto Classes

A Class is used to aggregate data of different types into a new type and associate with that new type methods which act on the aggregated data. Once a class is defined, variables can be declared of type Class Name. These variables can then be assigned instances of the Class also called Objects.

Class definition must occur in the top scope. You cannot define a new Class inside a condition, iterative, function definition, or scoping block. A Class is defined with the following syntax:

$class(<class name>)
   <member variable declarations>
   <method definitions>

Variable declarations inside a Class definition become member variables of that Class. Functions defined within Class Definitions become methods of the Class. Methods with the same name as the Class are called constructors. Constructors must not specify a return type.

Assignments to member variables at declaration time become part of the Class's Implicit Constructor. These assignments will take place whenever an instance of the Class is created. Class instances are created by using the 'new' keyword.

$declare(<class name> <var name> = new <class name>(<constructor arguments>))  

Three distinct operations occur when an Object is instantiated:

  • Storage is allocated for the Object
  • The implicit constructor is called assigning initial values to the Object's member variables
  • The explicit constructor (the constructor whose arguments match those passed in) is called to do further initialization of member variables.
If no no-arg constructor is explicitly defined then calling

$declare(<class name> <var name> = new <class name>())  

will still succeed and the implicit constructor alone will be called. If arguments are passed to the constructor then and explicit constructor with matching arguments must be defined

Member variables are retrieved using the dereference operator '.'.

$do( <variable name>.<member variable name> = <value>)  

Class member variables are used within method definitions by using the member variable's name. However, member variables may be shadowed within a method if the method takes an argument or declares a local variable of the same name. Even this case member variables can still be accessed by making use of the special variable 'this'. The value of the variable 'this' is always the instance of the class the method is being called on. Thus within a method definition the expression 'this.<member variable name> will return the specified member variable. The variable 'this' may not be shadowed or assigned to or re-declared as a local variable or argument.

Methods are called on Objects by using the dereference operator '.'.

$do( <variable name>.<method name>(<method arguments>))  

2.8.3 Extension Libraries


The $use construct provides access to extension libraries. These libraries, located on disk under the mx directory of your moto installation, provide definitions for a number of objects and functions. The extensions included with the moto distribution are

moto This extension library contains the definition for String objects as well as object wrappers for the fundamental types (Boolean, Character, Double, Float, Integer, and Long). This extension is used automatically by moto and does not need to be explicitly used in a moto page.
cstdlib This extension library makes a number of functions from the C standard libraries available to moto programmers
codex.util This extension library provides interfaces to the codex library of utility objects. These objects include : Enumeration, FileIO, Hashset, Hashtable, IntEnumeration, Inthashtable, IntSet, IntStack, ItoIHashtable, KMPString, Stack, StringBuffer, Stringset, SymbolTable, Tokenizer and Vector.
codex.http This extension library provides objects for session and state management in web applications, as well as basic function libraries for interoperating with the Apache webserver. The interfaces included are: Context, Session State, and HTTPRequest. This extension library provides objects for interacting with a Posix file system. Objects included are: PosixFileSystem.
codex.db.mysql This extension library provides objects for interacting with a MySQL database. Objects included are: MySQLConnection and MySQLResultSet.
codex.db.pgsql This extension library provides objects for interacting with a Postgres database . Objects included are: PGConnection and PGResultSet.

The $use construct can only be placed in the top level scope of a moto page and may not be placed inside any conditional, iterative, or scoping block.

New extensions can be added by the creation of subdirectories under the mx directory. Objects may be added to an extension via the creation of an interface (.i) file for that object.

2.9 Arrays

In Moto, arrays are also considered a subclass of Object.

You cannot however instantiate an object of type "Array", rather you must declare and instantiate an array based upon the sub-type it stores.

$declare(int foo[] = new int[5])  

The above example declares an int array 'foo' and then allocates the storage for five ints with the new keyword

To get or set the value of of one of the indexes in the array you use the subscript operator '[' ']'

$do(foo[1] = 3)

All array indexes start at 0 so in the above example 0 through 4 would be valid indexes in the array 'foo'. If foo[5] was accessed at runtime an ArrayBoundsException would be thrown. Only integer typed expressions can be used for array access, thus in moto only expresions of type int or type long may be used.

If you know the contents of the array at declaration time you can specify it inline as follows.

$declare(int[] bar = {1,2,3})  

Note that the above example is really just shorthand for assigning the array 'bar' new int[3] and then setting the individual elements of that array to 1,2, and 3 from first to last. The allocation still occurs dynamically on the heap.

You can use similar syntax to construct instances of pre-defined arrays anywhere in your code. This is done using the cast operator.

$(new String(<char []>{'h','e','l','l','o',' ','w','o','r','l','d'}))  

Moto also allows for the declaration and instantiation of multi-dimensionsal arrays.

$declare(char bar[][] = new char [3][2])  

The above example declares the variable bar to be a two dimensional array of characters, then assigns to it a new two dimensional array for characters size 3 by 2. Multi-dimensionsal arrays in Moto work the same way they do in Java. Instead of allocating one Object of size dim 1 * dim 2 * dim 3 etc. multiple Objects are allocated so that the above new statement actually creates the following 4 Objects:

This allows the flexibility of declaring arrays where the dimensions of nested arrays are not equal (to represent adjacency lists for example)

$declare(char bar[][] = new char[3][])
$do(bar[0] = new char[3])
$do(bar[1] = new char[1])
$do(bar[2] = new char[2])

Since arrays are objects, sub-arrays of multi-dimensional Array may even correspond to the same Array

$declare(char bar[][] = new char[3][])
$do(bar[0] = bar[1] = bar[2] = new char[2])

Arrays are passed to Moto functions by reference. Thus moto functions may alter the values of array subscripts.

$define(void foo(int bar[]))
$do(bar[0] = 27)

$declare(int maka[] = new int[3])

Therefore the above example would output '27'.

The length of any array may be retrieved at runtime with the length() function thus

$declare(char bar[][] = new char[3][])

would output '3' .

Arrays may be implicitly cast to Objects for the purposes of function calls. Moreover arrays of subclasses of Objects and multidimensional arrays may be implicitly cast / assigned to object arrays (Object[]).

Character and byte arrays have special handling in the moto language. Both may be output using the print $() construct. Both may be appended to Strings with the string addition operators. Both may be converted to Strings directly using the String constructor or the str() function.

2.10 Exceptional Conditions

Sometimes things go wrong at runtime. For instance a program might request input from a user that is used to subscript an array at a certain index, but the index is outside of array bounds. Or perhaps the array was never initialized and is null. Both of these errors may be checked for ahead of time in the code, but others are not so easy to check for ahead of time. For instance when a program performs a long database query and halfway through the connection to the database is severed. Or a program needs to wrtie a file to disk but the disk is full, or write permissions haven't been properly granted to the program. In these last two examples the condition that causes the error could either not have been checked for ahead of time, or there are so many possible reasons the action might fail that checking for all of them individually just isn't code efficient.

2.10.1 Exception Handling Basics

In all of these cases moto will throw an Exception . Throwing and exception is a lot like returning from a function early. However when an exception is thrown, the active functions or methods on the moto stack will keep returning until the Exception is caught or until there is no possible code left to catch them at which point an Uncaught Exception error will be displayed.

What this really boils down to is that if you have a treacherous piece of code that may throw an Exception at runtime, that you want to be able to deal with, you must wrap that code in a try-catch block. Take for example the array bounds case from earlier.

$declare(char bar[] = new char[3])
$do(bar[4] = 'd')

The above cade segment will surely fail since we are accessing an array index outside of declared bounds. However, were we to write the following :

$declare(char bar[] = new char[3])
   $do(bar[4] = 'd')
   $("I did a bad thing")
$catch(Exception e)
   $("I caught an exception!")

The above code will not fail but instead will output 'I caught an exception!' . It will not output 'I did a bad thing' because as soon as the exceptional condition occurred the program started looking for a catch statement that would handle it.

From the syntax of of the $catch statement you may have already guessed that Exceptions are a type of Object. The catch statement declares a local variable within the catch block that references the exception so that important information may be gleaned from it and perhaps presented to the user. In the previous example we declared the exception e to refer to the Exception that was caught. All exceptions have at least the following methods :

Method Description
Exception Exception() Constructs a new Exception object
Exception Exception(String message) Constructs a new exception object with the specified message.
String toString() Returns the type of the exception and any message included in the exception as a String
String getFile() Returns the name of the file from which the Exception was thrown
int getLine() Returns the line number of the file where the Exception occurred
String getStackTrace() Returns a string representation of the call stack as it was when the Exception was thrown

Re-writing the previous example to use these methods we have:

$declare(char bar[] = new char[3])
   $do(bar[4] = 'd')
   $("I did a bad thing")
$catch(Exception e)
   $("I caught an exception!")

This program would output :

ArrayBoundsException : Attempt to subscript array outside of declared bounds

Notice that the type of the Exception is ArrayBoundsException. Yet what we caught was just Exception. This works because all Exceptions are sub-classes of Exception so simply catching an Exception will catch all runtime exceptional conditions. If we had wanted too, than in the above catach we could have caught ArrayBoundsException specifically. Only rarely do you want to catch all possible types of Exceptions. Rather a program should catch only the Exceptions that the program can handle.

$declare(char bar[] = new char[3])
$declare(String foo = null)
$declare(boolean keepTrying = true)
$declare(int index = 4)
      $do(bar[index] = 'd')
      $do(keepTrying = false)
   $catch(ArrayBoundsException e)
      $("I caught an ArrayBoundsException, better set index!")
   $catch(NullPointerException e)
      $("I caught a NullPointerException, better set foo!")

When either an ArrayBoundsException or a NullPointerException is thrown in the above example the program takes the action neccessary to make sure that they are not thrown again. It keeps looping until all the statements in the try block execute successfully. This program outputs :

I caught an ArrayBoundsException, better set index!
I caught a NullPointerException, better set foo!

What the above program demonstrates is that a program can and should take different actions depending on the exception that is thrown. It also makes use of the third type of built in moto exception. While most Exceptions are thrown from extension function or method calls, Moto code may throw the following types of Exception at runtime :

Exception The superclass for all other exceptions, when caught handles all other Exceptions
NullPointerException Thrown whenever an null array is subscripted or a method is called on a null object or a null object is dereferenced
ArrayBoundsException Thrown whenever an array is subscripted outside its declared bounds.
MathException Thrown whenever a numeric type is divided by zero.

2.10.2 Throwing Exceptions

Perhaps you have written some code that has it's own set of unique exceptional conditions and you want to throw your own exceptions. This is accomplished by first constructing a new Exception, and second throwing it with the $throw construct.

$throw(new Exception("You shouldn't have done that"))

You may also throw any of the Exception subtypes loaded from different extensions. A common exception you might throw is an IllegalArgumentException. It should be thrown when a function or method gets passed an argument that it is not designed to work with.

$define(String getAreaCode(String phoneNumber))
   $declare(Regex phoneRx = /[(]([0-9][0-9][0-9])[)][0-9][0-9][0-9][\-][0-9][0-9][0-9][0-9]/)
   $if(phoneNumber == null)
      $throw(new IllegalArgumentException("The phone number string provided may not be null"))
   $declare(Match match = phoneRx.match(phoneNumber))
   $if(match.subMatch(1) == null)
      $throw(new IllegalArgumentException("The phone number provided is in an incorrect format"))

2.10.3 Finally

Often times it is important to have operations that are guaranteed to take place regardless of the success or failure of the preceeding operations. A common example of this occurs when dealing with pools of objects. The methodolgy for using an object pool is to grab an object out of it, call some methods on that object, and when you're done, return the object to the pool. During the course of calling methods on the object an exception may be thrown. Some types of exceptions you might want to catch, others you might not. In all cases you want to make sure that the object gets returned to the pool. If it is not your program will have a resource leak.

To specify code to execute regardless of the success or failure of the code you're trying to execute you must use the $finally keyword.

   code we want to try to execute
$catch(FooException f)
   code to be executed if a FooException got thrown
$catch(BarException b)
   code to be executed if a BarException got thrown
   code we want executed regardless of whether an exception occurred even if we caught it

A finally block gets executed no matter what. If the try block is inside of a function call and the function returns from inside the try block or a catch block, the finally block will still get executed. If the try block is inside a loop and the break or continue statement is used, the finally block code will still get executed. If an exception gets thrown but not caught and passes through three different try-catch-finally blocks, the finally blocks of all three will be executed.

2.10.4 In Depth Exception Handling Semantics

The semantics of Moto Exception handling are the same as Exception handling in Java. An exception, once thrown will jump to the end of the most recently opened try block. Its type will be compared with the types of exceptions caught in any catch block opened after that try block. If its type matches than that exception is said to have been handled and the code for that catch block is executed. Regardless of whether the exception was handled or not, or whether or not there was an exception, the finally block code, if present, is then executed. If there was an exception thrown and it was not handled then once any finally block code has been executed the exception is re-thrown.

If an exception is thrown from within a catch block, and it is not handled (by way of a nested try-catch block) than that exception overrides the current exception. However exceptions thrown from within catch blocks are not compared with the types of Exceptions handleable by the current try-catch block. Rather the finally code is executed and the new exception is re-thrown.

If an exception is thrown from within a finally block, and it is not handled by way of a nested try-catch block, than that exception overrides the current exception if there is one and it is immediately re-thrown. If an exception is generated from within a finally block but is handled by that same finally block (by way of a nested try catch) but another exception had already been generated and not handled before entering the finally block, than after finally block execution the original exception is re-thrown.

If a break, return, or continue is generated from within a try block than the finally block is executed and the break, return, or continue action takes place. If however within the finally block there is a different sort of jump statement such as another break, return, or continue, or even an exception getting thrown, than that action overrides the action specified within the try block. If a break, return, or continue action is generated from within a catch block than it can still be overridden by an action in the finally block.