Monkey language reference
This manual describes the syntax and general concepts behind the core Monkey language.
Contents
About this reference
Programs and declarations
Strict mode
Comments
Identifiers
Types
Variables
Constants
Expressions
Statements
Functions
Methods
Classes
Generics
Interfaces
Exceptions
Modules
Public and private
External declarations
Memory management
Preprocessor
A monospaced font is used for program code examples, for example:
Function Main() Print "Hello World!" End
Language syntax explanations are generally formatted as follows:
bold
indicates literal text. For example: Function
means the actual text 'Function'.
Step
] means the literal text Step
is optional.
To
| Until
means you can use To
or Until
- but not both.
These rules are not strictly followed. Where it makes sense to do so, syntax may be shown in a simplified form with explanatory notes.
A Monkey program consists of one or more modules, each of which is a separate file, consisting of a series of declarations.
A declaration associates a 'meaning' with an identifier. For example, this declaration...
Global x:Int
...indicates that the identifier 'x' is a global variable of type 'Int' (an integer).
Monkey supports the following kinds of declarations:
A module is itself a kind of declaration and is represented by a single source file. The name of the module is taken from the name of the source file. For example, if your file is named "particles.monkey" then the module will be called "particles".
Modules may 'import' other modules, which may in turn import other modules and so on.
Every Monkey program has a 'main module' that must contain a public function called Main that takes no parameters and returns an integer. For example:
Function Main() Print "That's all folks!" End
This is the entry point of the program and is where program execution begins.
If you are using the mojo framework of modules, you must create a new class (which extends the base mojo.app class) and create a new instance of it in the Main function. See the mojo.app Module Reference for more information. An example of this is:
Import mojo.app Import mojo.graphics Class MyApp Extends App Method OnRender() DrawText "Hello World!",0,0 End End Function Main() New MyApp End
By default, Monkey allows you to take certain shortcuts when programming.
However, Monkey also offers a special Strict mode for programmers who prefer a stricter language definition.
The differences between strict and non-strict mode are:
To use strict mode, a Strict directive must be placed at the very top of your module. For example:
Strict Function Main:Int() 'in Strict mode, the :Int type definition is compulsory Print( "Strict mode is...strict!" ) 'in Strict mode, all function calls require brackets. Return 0 'in strict mode, we MUST return a value. End
The examples in this document will be presented in non-strict form.
You can add line comments to your programs using the ' (apostrophe) character. Everything following the ' character until the end of the line will be ignored.
You can add block comments to your programs using #rem and #end. These must appear at the start of a new line, although they may optionally have whitespace characters in front. Everything between #rem and #end will be ignored. Block comments can also be nested.
Here is an example of using comments:
Print "Hello World" 'This is a line comment!rem 'start of a block comment
Print "The sound of silence!" 'inside a block commentend 'end of a block comment
Identifiers must start with an alphabetic character, or a single underscore followed by an alphabetic character. The rest of the identifier may contain any combination of alphanumeric characters and/or underscores.
Identifiers are case sensitive (except for language keywords - see below). For example, player, Player, PLAYER and PLayER are all different identifiers. This allows you to reuse the same name for different purposes. For example, Actor may refer to a class while actor refers to an object of that class.
Here are some examples of valid Monkey identifiers:
score player1 player_up _internal helloworld HelloWorld
Language keywords and reserved identifiers
The following identifiers are language keywords and are reserved for use by the Monkey language:
Void Strict Public Private Property Bool Int Float String Array Object Mod Continue Exit Import Extern New Self Super Try Catch Eachin True False Not Extends Abstract Final Select Case Default Const Local Global Field Method Function Class And Or Shl Shr End If Then Else ElseIf EndIf While Wend Repeat Until Forever For To Step Next Return Module Interface Implements Inline Throw
Language keywords are case insensitive - for example, you may use the keyword function, Function or indeed even fUNCTION (not recommended) to declare a function.
The keywords Module, Inline and Array are not currently used by the Monkey language but are reserved for future use.
Monkey naming conventions
The standard Monkey modules use a simple naming convention:
You are of course free to use your own convention, but for the sake of consistency it is recommended that this convention be used for the public interface of any modules you create intended for use by the Monkey community.
Monkey is a statically typed language, which means that all variables, function parameters, function return values and expressions have an associated type that is known at compile time.
The following types are supported:
Boolean
Integer
Floating point
String
Array
Object
The Bool type
Values of type Bool are boolean values used to express the result of conditional expressions, such as the comparison operators, and to represent a true/false 'state' in general. A boolean value can only be either True or False.
The syntax used for declaring values and variables of boolean type is Bool
. For example:
Local gamePaused:Bool = False
Boolean values are usually generated by the use of the comparison operators, for example:
If livesLeft<>0 doSomething() End
However, in some circumstances Monkey will automatically convert a non-bool value to bool. This will occur when evaluating an expression for use with the If or While statements; the Until part of a Repeat loop; and when evaluating the arguments for the Not, Or and And operators. For example:
If livesLeft doSomething() End
See the conversions section in the expressions chapter for more information.
Also, notice that the Bool identifiers can also be declared by using the ?
character. This two lines of source code are both valid and syntactically correct:
Local myVariable:Bool = True Local myVariable? = True
The Int type
Values of type Int are signed integer values - that is, values with no fractional part. The range of integer values supported is target dependent, but is at least 32 bits. A 32 bit int can represent a range of values from: -2,147,483,648 to 2,147,483,647 The syntax used for declaring values and variables of integer type isInt
. For example:
Local x:Int = 5
Integer literals are sequences of digits without a fractional part. Hexadecimal literals are also supported with the $ prefix. For example, the following are all valid integer literals:
0 1234 $3D0DEAD $CAFEBABE
Also, notice that integer identifiers can also be declared by using the %
character. This two lines of source code are both valid and syntactically correct:
Local myVariable:Int = 1024 Local myVariable% = 1024
The Float type
Values of type Float are signed numeric values with both an integer and fractional part. The range of floating point values support is target dependent, but is at least 32 bits. The syntax used for declaring values and variables of floating point type isFloat
. For example:
Local gravity:Float = 9.81
Floating point literals are sequences of digits that include a fractional part, for example:
.0 0.0 .5 0.5 1.0 1.5 1.00001 3.14159265
Also, notice that floating point identifiers can also be declared by using the #
character. This two lines of source code are both valid and syntactically correct:
Local myVariable:Float = 3.141516 Local myVariable# = 3.141516
The String type
Values of type String are used to represent sequences of characters, such as text. The size of each character in a string value is target dependent, but is at least 8 bits. The syntax used for declaring values and variables of string type isString
. For example:
Local name:String = "John Smith"
Strings are immutable meaning that once they are created they cannot be modified. Operations that 'modify' a string will always return a new string.
String literals are sequences of characters enclosed in "" (quotation marks). String literals may also include escape sequences - special sequences of characters used to represent unprintable characters.
You can use the following escape sequences in string literals:
| Escape sequence | Character code |
|---|---|
~q | 34 (quotate mark ") |
~n | 10 (newline) |
~r | 13 (return) |
~t | 9 (tab) |
~z | 0 (null> |
~~ | 126 (tilde ~) |
Here are some examples of string literals:
"Hello World" "~qHello World~q" "~tIndented~n"
Strings can also be indexed and sliced.
The syntax for indexing a string is: StringExpression [
IndexExpression ]
Indexing a string returns the character code of the character at IndexExpression. Index 0 is the first character in the string.
IndexExpression must be greater than or equal to 0 and less than the length of StringExpression otherwise an error occurs.
Here are some examples of indexing a string:
Print "ABC"[0] 'prints 65 - the character code of 'A' Print "ABC"[1] 'prints 66 - the character code of 'B' Print "Hi~n"[2] 'prints 10 - the character code of '~n'
The syntax for slicing a string is: StringExpression[
StartExpression..
EndExpression ]
Slicing a string returns a new string consisting of the characters within StringExpression starting at index StartExpression and ending at index EndExpression.
Both StartExpression and EndExpression are optional. If StartExpression is omitted, it defaults to 0. If EndExpression is omitted, it defaults to the length of the string.
StartExpression and EndExpression can also be negative, in which case they refer to offsets from the end of the string.
Here are some examples of slicing a string:
Print "Hello World"[4..7] 'prints "o W' Print "Hello World"[..5] 'prints "Hello" Print "Hello World"[5..] 'prints "World" Print "Hello World"[..] 'prints "Hello World"
Strings also support a number of 'pseudo' methods and functions:
| Method/Function | Description |
|---|---|
| Method Length() Property | Returns the number of characters in the string. |
| Method Compare( str:String ) | Returns a value <0 if the current string is less than str, a value>0 if the current string is greater than str or 0 if this string is equal to str. |
| Method Find( subString:String ) | Returns the index of the first occurance of subString within the current string. |
| Method Find( subString:String, startIndex ) | Returns the index of the first occurance of subString within the current string, starting at index startIndex. |
| Method FindLast( subString:String ) | Returns the index of the last occurance of subString within the current string. |
| Method FindLast( subString:String, startIndex ) | Returns the index of the last occurance of subString within the current string, starting at index startIndex. |
| Method Contains( subString:String ) | Returns true if the current string contains subString. |
| Method StartsWith( subString:String ) | Returns true if the current string starts with subString. |
| Method EndsWith( subString:String ) | Returns true if the current string ends with subString. |
| Method ToLower:String() | Returns the current string converted to lowercase. |
| Method ToUpper:String() | Returns the current string converted to uppercase. |
| Method Trim:String() | Returns the current string with all leading and trailing whitespace characters removed. |
| Method Split:String[]( separator:String ) | Returns an array of strings that contains the substrings in the current string deliminated by separator. |
| Method ToChars:Int[]() | Converts string to an array of character codes. |
| Method Join:String( pieces:String[] ) | Returns the elements of pieces concatened together with the current string inserted between each substring. |
| Function FromChar:String( char ) | Returns a string of length 1 consisting of a single character code. |
| Function FromChars:String( chars:Int[] ) | Creates a string from an array of character codes. |
For example:
Print " Hello World ~n".Trim() 'prints "Hello World" Print "Hello World".ToUpper() 'prints "HELLO WORLD"
Also, notice that string identifiers can also be declared by using the $
character. This two lines of source code are both valid and syntactically correct:
Local message:String = "Hello world" Local message$ = "Hello world"
The Array type
An array is a linear sequence of values that can be addressed using an integer index. Each array has an associated element type - that is, the type of the elements actually contained in the array. Due to the nature of Monkey, an array's element type is a purely static property. It is only known at compile time so arrays cannot be downcast at runtime. The syntax used for declaring values and variables of array type is: ElementType[]
For example:
Local box:Int[] 'an array of ints Local ratio:Float[] 'an array of floats Local thing:Int[][] 'an array of arrays of ints
An array literal is a (possibly empty) comma separated sequence of expressions enclosed with [ and ]. The expressions used in an array literal must be of the same type. For example:
Local box:Int[]=[] 'an empty array literal Local scores:Int[]=[10,20,30] 'a comma separated sequence Local text:String[]=["Hello","There","World"] 'a comma separated sequence
The syntax for indexing an array is: ArrayExpression [
IndexExpression ]
. For example:
Local score:Int[]=[10,20,30] 'a comma separated sequence Print score[1] 'prints "20"
Indexing an array yields a 'pseudo variable' of the array's element type that can be both read from and written to.
IndexExpression must be an integer expression greater than or equal to 0 and less than the length of the array otherwise an error occurs.
Like strings, arrays can also be sliced. The syntax for slicing an array is: ArrayExpression [
StartExpression ..
EndExpression ]
.
Slicing an array returns 'sub array' of ArrayExpression starting at index StartExpression and ending at index EndExpression.
Both StartExpression and EndExpression are optional. If StartExpression is omitted, it defaults to 0. If EndExpression is omitted, it defaults to the length of the array.
StartExpression and EndExpression can also be negative, in which case they refer to offsets from the end of the array.
Here is an example of slicing an array:
Local text:String[]=["Cruel","Hello","World","There"] 'a comma separated sequence Local helloWorld:=text[1..3] 'contains ["Hello","World"]
Arrays also support a number of pseudo methods:
| Method | Description |
|---|---|
| Method Length() Property | The number of elements in the array. |
| Method Resize:Array( newLength ) | Copies the first newLength elements of the current array into a new array of length newLength, and returns the new array. |
For example:
Local text:String[]=["Hello","There","World"] 'a comma separated sequence Print text.Length 'prints '3' text=text.Resize( 2 ) Print text.Length 'prints '2'
The Object type
An object is an instance of a class, and contains a set of constants, variables, methods and functions.
The syntax used for declaring values and variables of object type is: ClassIdentifier
For example:
Local mine:MyClass = New MyClass
Please see the classes section for more information on declaring classes and creating objects.
A variable is a storage location used to hold values that change while your program runs.
All variables have an identifier, a type, and an optional initializer - an expression used to set the variable to an initial value.
The type of a variable can either be declared literally, or can be deduced from the variable's initializer.
Local variables
Local variables are temporary variables that disappear when the local scope they are declared in is destroyed.
Local variables may be declared within any local scope.
Each of the following creates a local scope:
The syntax for declaring a local variable is:
Local
Identifier :
Type [ =
Expression ]
Or...
Local
Identifier :=
Expression
For example:
Local age:Int=10 Local age:=10
Global variables
Global variables are variables that persist during the execution of your program.
Global variables may be declared at module scope, or within a class declaration.
The syntax for declaring a global variable is:
Global
Identifier :
Type [ =
Expression ]
Or...
Global
Identifier :=
Expression
For example:
Global isPlayerAlive:Bool = True
Field variables
Field variables are variables that persist as long as the object they belong to.
Field variables can only be declared within a class declaration.
The syntax for declaring a field variable is:
Field
Identifier :
Type [ =
Expression ]
Or...
Field
Identifier :=
Expression
A constant is a value that is evaluated at compile time, and that does not change throughout the execution of a program.
Constants may be declared at module scope, within class scope or within any local scope.
The syntax for declaring a constant is:
Const
Identifier :
Type =
Expression
Or...
Const
Identifier :=
Expression
Expressions are the parts of a program that perform calculations, make logical comparisons and return values from methods or functions.
Operators
| Operator Syntax | Description |
|---|---|
New ClassType | Create a new Object |
Null | The null object |
True | Boolean true |
False | Boolean false |
Self | Self |
Super | Super |
| Literal | Literal |
| Identifier | Identifier |
. Identifier | Scope member access |
( ExpressionSeq ) | Invoke |
[ Expression ] | Index |
+ | Unary plus |
- | Unary minus |
~ | Bitwise complement |
Not | Boolean inverse |
* | Multiplication |
/ | Division |
Mod | Modulus |
Shl | Bitwise shift left |
Shr | Bitwise shift left (signed) |
+ | Addition |
- | Subtraction |
& | Bitwise 'and' |
~ | Bitwise 'xor' |
| | Bitwise 'or' |
= | Equals |
< | Less than |
> | Greater than |
<= | Less than or equals |
>= | Greater than or equals |
<> | Not equals |
And | Condititonal 'and' |
Or | Conditional 'or' |
Operators are grouped by priority.
Balancing argument types
When performing binary arithmetic (*, /, Mod, +, -) or comparison operations (=, <, >, <=, >=, <>), operator arguments are 'balanced' according to the following rules:
In the case of arithmetic operations, arguments are first implicitly converted to the balanced type if necessary, and the result is also of the balanced type.
In the case of comparison operations, arguments are first implicitly converted to the balanced type if necessary, and the result is boolean.
The only valid arithmetic operation that can be performed on strings is addition, which performs string concatentation on the arguments.
Conditional operators
The arguments of conditional operations (And, Or) are first converted to boolean if necessary and the result is boolean.
In the case of Or, if the left-hand-side expression evaluates to true, the right-hand-side expression is not evaluated.
For example:
If car<>Null Or GetSpeed()>10 Then...
In the above example, if car is not Null, then the right-hand-side of the Or is not evaluated - ie: the GetSpeed function is never called.
In the case of And, if the left-hand-side expression evaluates to false, the right-hand-side expression is not evaluated.
For example:
If enemies.Count > 0 And HasEnemyInSight() Then ...
In the above example, if enemies.Count is <= 0, then the right-hand-side of the And is not evaluated - ie: the hasEnemyInSight function is never called.
Bitwise operators
When performing bitwise (Shl Shr & | ~) operations, arguments are first implicitly converted to integers if necessary before the operation is performed. The result is also an integer.
Implicit conversions
Implicit conversions are automatic conversions performed when assigning a value to a variable, passing parameters to a function, returning a value from a function or when balancing operator operands.
Monkey supports the following implicit conversions:
| Source type | Target type | Notes |
|---|---|---|
| Boolean | Integer | Return 1 if boolean value is true, 0 if false. |
| Integer | Floating point | |
| Integer | String | |
| Floating point | Integer | Value is converted by discarding fractional part. |
| Floating point | String | Conversion is target dependent. |
| Derived class object | Base class object | Upcast operation. |
Explicit conversions
Explicit conversions are conversions from one type to another type which can be performed manually by the programmer .
The syntax for performing an explicit conversion is: TargetType (
Expression )
For example:
Local energyFloat:Float =<PHONE_NUMBER>001 Local energyInt:Int = Int(energyFloat) 'Is 120 now
You can perform the following explicit conversions in Monkey:
| Source type | Target type | Notes |
|---|---|---|
| Integer | Boolean | Result is true if source<>0, else false. |
| Floating point | Boolean | Result is true if source<>0.0, else false. |
| Array | Boolean | Result is true if source.Length<>0, else false. |
| Object | Boolean | Result is true if source<>Null, else false. |
| String | Boolean | Result is true if source<>"", else false. |
| String | Integer | Conversion is target dependant. |
| String | Floating point | Conversion is target dependant. |
| Base class object | Derived class object | Result is null if source is not a superclass of derived class. |
In some circumstances, Monkey will automatically perform an explicit conversion of a non-bool value to bool for you. This will occur when evaluating an expression for use with the If and While statements; the Until part of a Repeat loop; and when evaluating the arguments for the Not, Or and And operators. This allows you to use 'shortcut' code such as: If x Then y without the need to compare x with 0, "", [] or null.
Boxing and unboxing conversions
A 'box' object is an object designed to contain a single primitive int, float or string value. The process of placing a value into a box object is known as 'boxing', while extracting a value from an object is known as 'unboxing'. To help with writing box objects, Monkey provides some simple features for boxing and unboxing values:
For example, here is a simple box class designed to hold an integer value:
Class IntBox Field value:Int Method New( value:Int ) Self.value=value End Method ToInt:Int() Return value End End Function Main() Local box:IntBox box=10 Local t:Int=box Print t End
Program statements may only appear within method or function declarations.
A ; character may optionally appear after any statement, and multiple statements may be placed on the same source code line if separated by the ; character.
If statement
The If statement allows you to conditionally execute a block of statements depending on the result of a series of boolean expressions.
The first boolean expression that evaluates to true will cause the associated block of statements to be executed. No further boolean expressions will be evaluated.
If no boolean expression evaluates to true, then the final else block will be executed if present.
The syntax for the If statement is:
If
Expression [ Then
]
Statements...
ElseIf
Expression [ Then
]
Statements...
Else
Statements...
EndIf
There may be any number of ElseIf blocks, or none. The final Else block is optional.
End
or End If
may be used instead of EndIf
, and Else If
may be used instead of ElseIf
.
In addtion, a simple one line version of If is also supported:
If
Expression [ Then
] Statement [ Else
statement ]
The Select statement
The Select statement allows you to execute a block of statements depending on a series of comparisons.
The first comparison to produce a match will cause the associated block of statements to be executed.
If no comparisons produce a match, then the final default block will be executed if present.
The syntax for the Select statement is:
Select
Expression
Case
Expression [ ,
Expression... ]
Statements...
Default
Statements...
End
[ Select
]
There may be any number of Case blocks, or none. The final Default block is optional. If the default block is present, it must appear after all Case blocks.
While loop
The While loop allows you to execute a block of statements repeatedly while a boolean expression evaluates to true.
Note that a While loop may never actually execute any of it's statements if the expression evaluates to false when the loop is entered.
The syntax for the While loop is:
While
Expression
Statements...
Wend
End
or End While
may be used instead of Wend
.
Exit and Continue may be used within a While loop to abruptly terminate or continue loop execution.
Repeat loop
Like the While loop, the Repeat loop also allows you to execute a block of statement repeatedly while a boolean expression evaluates to true.
However, unlike a While loop, a Repeat loop is guaranteed to execute at least once, as the boolean expression is not evaluated until the end of the loop.
The syntax for Repeat/Until loops is:
Repeat
Statements...
Until
Expression
Or...
Repeat
Statements...
Forever
Exit and Continue may be used within a While loop to abruptly terminate or continue loop execution.
Numeric For loop
A numeric For loop will continue executing until the value of a numeric index variable reaches an exit value.
The index variable is automatically updated every loop iteration by adding a constant step value.
The syntax for a numeric For loop is:
For
[ Local
] IndexVariable =
FirstValue To
| Until
LastValue [ Step
StepValue ]
Statements...
Next
End
or End For
may be used instead of Next
.
If present, Local will create a new local index variable that only exists for the duration of the loop. In addition, IndexVariable must include the variable type, or := must be used instead of = to implicitly set the variable's type.
If Local is not present, IndexVariable must be a valid, existing variable.
The use of To or Until determines whether LastValue should be inclusive or exclusive.
If To is used, the loop will exit once the index variable is greater than LastValue (or less than if StepValue is negative).
If Until is used, the loop will exit once the index variable is greater than or equal to LastValue (or less than or equal to if StepValue is negative).
If omitted, StepValue defaults to 1.
Exit and Continue may be used within a numeric For loop to abruptly terminate or continue loop execution.
For EachIn loop
A For EachIn loop allows you to iterate through the elements of a collection.
A collection is either an array, a string, or a specially designed object.
The syntax for a For EachIn loop is:
For
[ Local
] IndexVariable =
EachIn
Collection
Statements...
Next
End
or End For
may be used instead of Next
.
If present, Local
will create a new local index variable that only exists for the duration of the loop. In addition, IndexVariable must include the variable type, or := must be used instead of = to implicitly set the variable's type.
If Local is not present, IndexVariable must be a valid, existing variable.
If Collection is an array, the loop will iterate through each element of the array, and the type of the index variable must match the element type of the array.
If Collection is a string, the loop will iterate through each each character code of the string, and the type of the index variable must be numeric.
If Collection is an object, it must provide the following method:
Method ObjectEnumerator:Object()
The object returned by this method must itself provide the following methods:
Method HasNext:Bool() Method NextObject:Object()
This allows you to build 'collection' style objects, such as the List and Map classes included in the standard Monkey modules that can be iterated through using For EachIn loops.
Exit and Continue
Exit
can be used within While, Repeat and For loops to abruptly exit the loop before the loop termination condition has been met.
Continue
can be used within While, Repeat and For loops to force the loop to abruptly skip to the next loop iteration, skipping over any statements that may be remaining in the current loop iteration.
Assignment statements
An assignment statement modifies a variable's value, and has the syntax:
VarExpression Operator Expression
Where VarExpression is an expression that evaluates to a variable, and Operator is one of the following:
=
*=
/=
Shl=
Shr=
Mod=
+=
-=
&=
~=
|=
The =
operator is used for plain assignment, while the remaining operators are used for update assignments.
Expression statements
You may also use certain expressions as program statements. These are:
A function is a self contained block of statements that can be called (or invoked) repeatedly from elsewhere in the program. Functions can also be passed parameters and return a result.
The syntax for declaring a function is:
Function
Identifier :
ReturnType (
Parameters )
Statements...
End
[ Function
]
For example:
Function Eat:Void( amount:Int ) ... End
Parameters is a comma separated sequence of function parameters:
Identifier :
Type [ =
InitExpression ]
Or...
Identifier :=
InitExpression
If you provide an InitExpression when declaring a function parameter, this means that the parameter has a default value and that the parameter can be optionally omitted when the function is called.
Once you have declared a function, it can be called with the syntax:
FunctionIdentifier
(
Arguments )
where Arguments is a comma separated sequence of expressions.
For example:
Function Sum:Int( x:Int,y:Int ) Return x+y End Function Main() Print Sum( 10,20 ) End
Here is an example of using default parameters:
Function Sum( x:Int=0,y:Int=0,z:Int=0 ) Print x+y+z End Function Main() Print Sum() 'same as calling Sum( 0,0,0 ) Print Sum( 10,20 ) 'same as calling Sum( 10,20,0 ) Print Sum( 10,,30 ) 'same as calling Sum( 10,0,30 ) End
Function overloading
Functions can also be overloaded. This means that multiple declarations can share the same name, as long as they each have different parameters. Methods can be overloaded in exactly the same way as functions.
When a function is called, Monkey looks at the number and type of the parameters used in the call and looks for a matching overloaded version to use. For example:
Function Add( value:Int ) End Function Add( value:Float ) End Function Add( value:String ) End Function Main() Add( 10 ) 'calls first version as 10 is of type Int Add( 10.0 ) 'calls second version as 10.0 is of type Float Add( "10" ) 'calls third version as "10" is of type String End
The number of parameters can also be used to differentiate between overloaded functions. For example:
Function Set( x ) End Function Set( x, y ) End Function Main() Set( 10 ) 'calls first version Set( 10,20 ) 'calls second version as it has two parameters End
When determining which overloaded version to actually use, Monkey uses the following logic:
For example:
Function Add( value:Int ) End Function Add( value:String ) End Function Main() Add( 10 ) 'OK, calls first version Add( "10" ) 'OK, calls second version Add( 10.0 ) 'error - unable to determine which version to call End
The error is caused by the fact that the function call parameter - '10.0' - is a floating point value and can therefore be implicitly converted to either an integer or a string, so Monkey cannot decide which overload to use.
To solve this problem, you would need to explicitly cast the parameter to either an integer or a string to give Monkey a 'hint' about which version you want used. For example:
Add( Int(10.0) ) 'Casts the float to an integer, calls first version
A Method is a function that is bound to a class. A method has implicit access to all members of its class, such as fields, globals and other methods and functions..
The syntax for declaring a method is similar to that for declaring a function:
Method
Identifier :
ReturnType (
Parameters )
[ Property
]
Statements...
End
[ Method
]
Within a method you can also use the special Self
and Super
variables:
Self
may be used within a method to access the object the method is associated with.
Super
may be used within a method to call 'super class' methods.
The optional Property
keyword can be used to declare a 'property method'.
A property method with 0 parameters can be invoked without any brackets. A property method with 1 parameter can be invoked be using it as the left-hand-side of an assignment statement, in which case the right-hand-side expression of the assignment is passed to the property method.
You can therefore create methods that behave like fields, but actually execute code when they are read or written. You can use method overloading to provide both read and write property methods, or provide just a read method, or even just a write method.
It is illegal to declare a property method with 2 or more parameters.
A class is a kind of 'blueprint' for creating objects at runtime.
The syntax for declaring a class is:
Class
Identifier [ < Parameters > ] [ Extends
Class ] [ Implements
Interfaces ]
Declarations...
End
[ Class
]
Classes can contain field, method, constant, global and function declarations.
If no base class is specified using Extends, the class defaults to extending the built in Object class.
The Implements keyword is used to implement interfaces, and must be followed by a comma separated list of interface names. Please refer to the Interfaces section for more on interfaces.
A class is also a valid scope, and any constants, globals and functions declared within a class can be accessed outside of the class using the scope member access operator '.'. For example:
Class C Global T End Function Main() C.T=10 End
Once you have declared a class, you can create objects of that class at runtime using the New operator. For example:
Class MyClass Field x,y,z End Function Main() Local myObject:=New MyClass myObject.x=10 myObject.y=20 myObject.z=30 End
Constructors
Constructors are special methods that are called each time an object is created with New.
To declare a constructor, you simply declare a class method and name it New.
Constructors can take parameters and can be overloaded.
To invoke a super class constructor within a constructor, use the special Super
variable.
Generic classes allow you to write code that is not specific to a single data type.
A generic class is declared in a similar way to a normal class, only with an additional set of 'type parameters' enclosed within <
and >
.
For example:
Class Pointer<T> Method Set( data:T ) _data=data End
Method Get:T() Return _data End
Private Field _data:T End
Type parameters can be any valid identifier. Here, T is such a type parameter.
Within the declaration of a generic class, type parameters may be used anywhere a type is normally expected, for example, when declaring variables and function return types, and when creating new objects or arrays.
When it comes to actually using a generic class, you must provide actual types to be used in place of type parameters. Types parameters can be of any valid type, including int, float, string and array.
For example:
Class Actor End Function Main() Local pointer:Pointer<Actor> pointer=New Pointer<Actor> pointer.Set New Actor Local actor:=pointer.Get() End
The syntax Pointer<Actor> indicates an 'instantiation' of the generic class Pointer<T>.
This is in itself a unique class, so each time you use the Pointer<T> class with a different type for T, you are actually creating a whole new class.
Generic classes are commonly used for writing container classes such as lists, stacks and so on, and the standard Monkey modules provide a set of simple generic container classes.
An interface is similar to a class, except that it can only contain constants and abstract methods.
Classes can implement an interface using the Implements keyword in the class declaration.
Classes that implement an interface must declare each method declared in the interface.
An interface can be used where ever a class is expected, for example when declaring the types of variables, or function return types. An interface cannot however be used with New.
An Interface can also optionally extend existing interfaces, in which cases all methods in all extended interfaces must be declared by any implementing classes.
Interfaces can not be generic.
The syntax for declaring an interface is:
Interface
Identifier [ Extends
Interfaces ]
Declarations...
End
[ Interface
]
All methods declared inside an interface are automatically treated as abstract, and can therefore have no 'body'.
Here is an example of using interfaces:
Interface Moveable Method Move() End Interface Drawable Method Draw() End Class Actor Implements Moveable,Drawable Method Move() Print "Actor.Move()" End Method Draw() Print "Actor.Draw()" End End Function Move( moveable:Moveable ) moveable.Move End Function Draw( drawable:Drawable ) drawable.Draw End Function Main() Local actor:=New Actor Move actor Draw actor End
Exceptions are special objects that can be 'thrown' to inform your program of unusual or abnormal behavior.
By placing code inside a 'try' block, you can catch thrown exceptions with a corresponding 'catch' block. For example...
Function Main() Try Print "Hello World!" Throw New Throwable Print "Where am I?" Catch ex:Throwable Print "Caught a Throwable!" End End
Try this with and without the throw statement.
Throw statements may appear anywhere in your application, not just inside a try block. When an object is thrown, it is thrown to the most recently executed try block capable of catching the object.
The class of objects used with throw and catch must extend the special built-in class Throwable. The Throwable class itself simply extends Object and provides no new methods or fields, so you may wish to extend Throwable to create your own exception classes with more functionality.
You can also catch multiple classes of exception object per try block, for example:
Class Ex1 Extends Throwable End Class Ex2 Extends Throwable End Function Main() For Local i:=1 To 10 Try If (i & 1) Throw New Ex1 Else Throw New Ex2 Catch ex:Ex1 Print "Caught an ex1!" Catch ex:Ex2 Print "Caught an ex2!" End Next End
When a try block has multiple catch blocks and an exception is thrown, the first catch block capable of handling the exception is executed. If no suitable catch block can be found, the exception is passed to the next most recently executed try block, and so on.
If no catch block can be found to catch an exception, a runtime error occurs and the application is terminated.
A Monkey module corresponds to a single Monkey source file, and provides a named scope for the constants, globals, functions and classes declared in that file. Every Monkey source file declares a module, and every module has an associated source file.
The name of the module scope is the same as the name of the file (minus the directory path and file extension), so the names of Monkey source files must also be valid Monkey identifiers.
It is also strongly recommend that file/module names be completely lowercase - both to prevent any issues with cased/uncased filesystems and to provide consistency with the standard module set.
One module may import another using the import statement. All import statements must appear at the top of a module before any declarations. The syntax for an import statement is:
Import
ModulePath
Where ModulePath describes the file location of the Monkey module to import. This must be a sequence of 'dot' separated identifiers, and is treated as a relative filesystem path with dots representing directory separators. The last component in the path represents either an actual .monkey source file, or a directory containing a .monkey source file of the same name.
Given a module's relative path, Monkey will look for an actual module to import in the following locations (and in this order):
For example, given the following import directive:
Import myutil.mycolor
Monkey will first look for the files myutil/mycolor.monkey and myutil/mycolor/mycolor.monkey in the current directory.
(Note: the reason modules are allowed to be represented as either a single .monkey file, or as a .monkey file within a directory of the same name is for pure convenience. Sometimes it's more convenient for a module to consist of a single file, while sometimes it's more convenient for a module to have its own directory.)
If either is found, it is imported into the current module and the search ends.
If both are found, an error is generated.
If neither is found the search continues with the project directory and, failing that, the modules directory.
If the module is not found anywhere, an error is generated.
Once successfully imported, the importing module can access the declarations made in the imported module, by using the imported module's name as a scope.
Here is a simple import example:
'----- file1.monkey ----- Import file2 'after this, file2 can be used as a scope Function Main() Print file2.X 'access global X in file2 module file2.Test 'access function Test in file2 module End '---- file2.monkey ---- Global X:=1 Function Test() Print "file2.Test" End
When accessing identifiers in imported modules, Monkey allows you to omit the module scope as long as there are no 'clashes' between identifiers in multiple modules. For example:
'----- file1.monkey ---- Import file2 Import file3 Function Main() Print X 'OK, accesses file2.X Print Y 'OK, accesses file3.Y Test 'ERROR! Which Test? file2.Test or file3.Test? file2.Test 'OK, I now know which module to get Test from End '----- file2.monkey ----- Global X:=1 Function Test() Print "file2.Test" End '----- file3.monkey ----- Global Y:=2 Function Test() Print "file3.Test" End
By default, any imports made by a module are automatically made available to importers of that module. That is, if module X imports module Y, and module Y imports module Z, the result is that module X effectively imports module Z.
However, if an import is declared to be private, that import is NOT made available. For example:
'----- file1.monkey ----- Import file2 Function Main() Print X 'OK, accesses file2.X Print Y 'OK, accesses file3.Y Print Z 'ERROR! can't see file.Z End '----- file2.monkey ----- Import file3 'Public import: When you import file2, you also import file3 Private Import file4 'Private - ie: internal use only. Only file2 can access file4. file1 cannot access file4. Public Global X:=1 '----- file3.monkey ----- Global Y:=2 '----- file4.monkey ----- Global Z:=3
Modules can be stored in a directory hierarchy and imported using a 'dotted' module path, for example:
'----- file1.monkey ----- Import file2 Import util.file3 Function Main() Print file2.X Print file3.Y End '----- util/file2.monkey ---- Global X:=1 '----- util/file3.monkey ----- Global Y:=2
Note that the directory path (in this case, 'util') is not used in any way except to locate the module. The module name is still just 'file3' - not 'util.file3'.
The Alias directive
The Alias directive allows you to assign a local name to a constant, global, function or class declared in another module. This can be used to create 'shortcuts' for clashing identifiers.
The syntax for Alias is:
Alias
Identifier =
ModulePath .
Identifier
Alias directives must appear in the 'import' section of a module, before any code.
For example:
'----- file1.monkey ----- Import file2 Import file3 Alias T=file2.T 'which 'T' to use Function Main() Print T 'Prints '1' End '----- file2.monkey ----- Global T:=1 '----- file3.monkey ----- Global T:=2
The Public and Private directives are used to control the visibility of subsequent declarations in a module or class.
If the Public directive is used in the main body of a module, all subsequent declarations will be public, and will be visible outside of the current module.
If the Private directive is used in the main body of a module, all subsequent declarations will be private and will not be visible outside of the current module.
For example:
Private Global x,y,z 'These are private to the current module Public Global P,Q,R 'These can be used by any module
When used inside a class declaration, Public and Private work in a similar way to control the visibility of subsequent member declarations. For example:
Class MyClass Private Field x,y,z 'these are NOT visible outside of this module.
Public Field P,Q,R 'these ARE visible outside of this module. End
Note that private class members are not private to the class, but to the entire module. This means that code outside of the class but within the same module can still access class private members.
The Extern directive is used to connect Monkey code to non-Monkey code. It lets you mix Monkey code (to be translated into the target platform language) with native target platform code.
When the Extern directive is used in the main body of a module, all subsequent global, function and class declarations will be treated as external declarations.
External declarations are assumed to be implemented elsewhere in native code, and as such may not contain a 'body'.
In the case of external global variables, this means the global may not be initialized - it is assumed to be initialized by native code.
In the case of external functions, this means the function may not contain any code, and must not be terminated with an End directive.
In the case of external classes, this means any globals or methods declared in the class may not contain a 'body' either.
External declarations may however be assigned a 'symbol' in the form of a string literal. This is the native symbol to be used by the Monkey translator when the declaration is referenced by Monkey code.
By default, external declarations are public. You can use Extern Private to prevent external declarations from being visible outside the current module.
Here are some examples of using extern:
Extern Global ActiveDriver:Driver="xyzActiveDriver" 'Native name of this global is xyzActiveDriver Class Driver="xyzDriver" 'The native name of this class is 'xyzDriver'. Method Method1() 'By default, native name is same as declaration name - Method1 here. Method Method2() 'native name is Method2 End Public 'return to public declarations
Monkey is a garbage collected language, and depends on the underlying target language to provide memory management.
Finalizers are not supported. If you need an object to be 'destroyable', you will need to add a 'Destroy' type method.
The garbage collector is capable of collecting cyclic data structures such as linked lists automatically.
The current C++ garbage collector will only collect garbage when control is returned to the OS. In the case of C++ Mojo targets such as IOS and GLFW, this occurs after any of the 'On' methods such as OnCreate, OnUpdate etc return.
In general, the best way to use the garbage collector is to ignore it! Although such practices as 'nulling out' object references are common, they are seldom required.
But it's a good idea to monitor your apps memory requirements as you develop anyway. This will allow you to catch any memory issues, GC related or otherwise, early on.
Monkey contains a very simple built-in preprocessor based on the syntax of the Monkey If statement that allows you to enable or disable blocks of code from being generated or translated, based on certain conditions.
The following preprocessor directives are supported:
#If
#ElseIf
#Else
#End
#Rem
#Print
#Error
Preprocessor directives must appear at the start of a line, and may be preceded by optional whitespace.
The #If and #Else If directives must be followed by a constant Monkey expression. If this expression evaluates to true, then code generation is enabled, otherwise it is disabled.
The following built in constants may be used in preprocessor expressions:
| Constant | Possible values |
|---|---|
| HOST | winnt macos |
| LANG | js as cs java cpp |
| TARGET | html5 flash xna android ios glfw stdcpp |
| CONFIG | debug release |
The #Rem directive is exactly the same as #If False - it unconditionally disables code generation. Note that this allows 'block rems' to be 'nested'.


|
Figure 1
|
( a) ZnO nanospikes grown from Zn spheres via the flame-tran ... |
|
Figure 2
|
The preparation steps of ZnO nanospike cross-sections using ... |
|
Figure 3
|
( a) HRTEM micrograph of a ZnO nanospike tip, showing the ch ... |
|
Figure 4
|
( a), ( b) HRTEM and ( c) low-resolution STEM micrographs of ... |
|
Figure 5
|
The construction of a supercell following the individual ste ... |
|
Figure 6
|
Qualitative comparisons of (left) experimental FFT images re ... |
|
Figure 7
|
(Left) HRTEM images of the twin interfaces and (right) simul ... |
|
Figure 8
|
( a) The new model for the atomic twin interface was tilted ... |


Put that cranberry sauce to good use!
These mushrooms are addicting.
The ultimate summer snack has arrived.
This version has all the creaminess of its more classic relative, with just enough smoky heat to keep you coming back for another dip.

Can't make it to Texas Roadhouse but craving their popular and delicious appetizer Rattlesnake Bites? Make them at home with this simple recipe!
There's fruit in it so it should be healthy, right?
Donut even think about eating regular fries as a snack!


NIR application of K 3LuSi 2O 7:Eu based pc-LEDs. a Photographs and PL spectrum of as-fabricated pc-LED combining a commercial blue LED and K 3LuSi 2O 7:0.01Eu 2+ phosphor. b PL spectra of the pc-LED upon various forward bias currents. c Photographs under natural light and NIR pc-LED light captured by the corresponding visible camera and a NIR camera


End of the Project Gutenberg EBook of Notre-Dame de Paris, by Victor Hugo *** END OF THIS PROJECT GUTENBERG EBOOK NOTRE-DAME DE PARIS *** ***** This file should be named 2610-h.htm or 2610-h.zip ***** This and all associated files of various formats will be found in: http://www.gutenberg.org/2/6/1/2610/ Produced by Peter Snow Cao, and David Widger Updated editions will replace the previous one--the old editions will be renamed. Creating the works from public domain print editions means that no one owns a United States copyright in these works, so the Foundation (and you!) can copy and distribute it in the United States without permission and without paying copyright royalties. Special rules, set forth in the General Terms of Use part of this license, apply to copying and distributing Project Gutenberg-tm electronic works to protect the PROJECT GUTENBERG-tm concept and trademark. Project Gutenberg is a registered trademark, and may not be used if you charge for the eBooks, unless you receive specific permission. If you do not charge anything for copies of this eBook, complying with the rules is very easy. You may use this eBook for nearly any purpose such as creation of derivative works, reports, performances and research. They may be modified and printed and given away--you may do practically ANYTHING with public domain eBooks. Redistribution is subject to the trademark license, especially commercial redistribution. *** START: FULL LICENSE *** THE FULL PROJECT GUTENBERG LICENSE PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK To protect the Project Gutenberg-tm mission of promoting the free distribution of electronic works, by using or distributing this work (or any other work associated in any way with the phrase “Project Gutenberg”), you agree to comply with all the terms of the Full Project Gutenberg-tm License (available with this file or online at http://gutenberg.org/license). Section 1. General Terms of Use and Redistributing Project Gutenberg-tm electronic works 1.A. By reading or using any part of this Project Gutenberg-tm electronic work, you indicate that you have read, understand, agree to and accept all the terms of this license and intellectual property (trademark/copyright) agreement. If you do not agree to abide by all the terms of this agreement, you must cease using and return or destroy all copies of Project Gutenberg-tm electronic works in your possession. If you paid a fee for obtaining a copy of or access to a Project Gutenberg-tm electronic work and you do not agree to be bound by the terms of this agreement, you may obtain a refund from the person or entity to whom you paid the fee as set forth in paragraph 1.E.8. 1.B. “Project Gutenberg” is a registered trademark. It may only be used on or associated in any way with an electronic work by people who agree to be bound by the terms of this agreement. There are a few things that you can do with most Project Gutenberg-tm electronic works even without complying with the full terms of this agreement. See paragraph 1.C below. There are a lot of things you can do with Project Gutenberg-tm electronic works if you follow the terms of this agreement and help preserve free future access to Project Gutenberg-tm electronic works. See paragraph 1.E below. 1.C. The Project Gutenberg Literary Archive Foundation (“the Foundation” or PGLAF), owns a compilation copyright in the collection of Project Gutenberg-tm electronic works. Nearly all the individual works in the collection are in the public domain in the United States. If an individual work is in the public domain in the United States and you are located in the United States, we do not claim a right to prevent you from copying, distributing, performing, displaying or creating derivative works based on the work as long as all references to Project Gutenberg are removed. Of course, we hope that you will support the Project Gutenberg-tm mission of promoting free access to electronic works by freely sharing Project Gutenberg-tm works in compliance with the terms of this agreement for keeping the Project Gutenberg-tm name associated with the work. You can easily comply with the terms of this agreement by keeping this work in the same format with its attached full Project Gutenberg-tm License when you share it without charge with others. 1.D. The copyright laws of the place where you are located also govern what you can do with this work. Copyright laws in most countries are in a constant state of change. If you are outside the United States, check the laws of your country in addition to the terms of this agreement before downloading, copying, displaying, performing, distributing or creating derivative works based on this work or any other Project Gutenberg-tm work. The Foundation makes no representations concerning the copyright status of any work in any country outside the United States. 1.E. Unless you have removed all references to Project Gutenberg: 1.E.1. The following sentence, with active links to, or other immediate access to, the full Project Gutenberg-tm License must appear prominently whenever any copy of a Project Gutenberg-tm work (any work on which the phrase “Project Gutenberg” appears, or with which the phrase “Project Gutenberg” is associated) is accessed, displayed, performed, viewed, copied or distributed: This eBook is for the use of anyone anywhere at no cost and with almost no restrictions whatsoever. You may copy it, give it away or re-use it under the terms of the Project Gutenberg License included with this eBook or online at www.gutenberg.org 1.E.2. If an individual Project Gutenberg-tm electronic work is derived from the public domain (does not contain a notice indicating that it is posted with permission of the copyright holder), the work can be copied and distributed to anyone in the United States without paying any fees or charges. If you are redistributing or providing access to a work with the phrase “Project Gutenberg” associated with or appearing on the work, you must comply either with the requirements of paragraphs 1.E.1 through 1.E.7 or obtain permission for the use of the work and the Project Gutenberg-tm trademark as set forth in paragraphs 1.E.8 or 1.E.9. 1.E.3. If an individual Project Gutenberg-tm electronic work is posted with the permission of the copyright holder, your use and distribution must comply with both paragraphs 1.E.1 through 1.E.7 and any additional terms imposed by the copyright holder. Additional terms will be linked to the Project Gutenberg-tm License for all works posted with the permission of the copyright holder found at the beginning of this work. 1.E.4. Do not unlink or detach or remove the full Project Gutenberg-tm License terms from this work, or any files containing a part of this work or any other work associated with Project Gutenberg-tm. 1.E.5. Do not copy, display, perform, distribute or redistribute this electronic work, or any part of this electronic work, without prominently displaying the sentence set forth in paragraph 1.E.1 with active links or immediate access to the full terms of the Project Gutenberg-tm License. 1.E.6. You may convert to and distribute this work in any binary, compressed, marked up, nonproprietary or proprietary form, including any word processing or hypertext form. However, if you provide access to or distribute copies of a Project Gutenberg-tm work in a format other than “Plain Vanilla ASCII” or other format used in the official version posted on the official Project Gutenberg-tm web site (www.gutenberg.org), you must, at no additional cost, fee or expense to the user, provide a copy, a means of exporting a copy, or a means of obtaining a copy upon request, of the work in its original “Plain Vanilla ASCII” or other form. Any alternate format must include the full Project Gutenberg-tm License as specified in paragraph 1.E.1. 1.E.7. Do not charge a fee for access to, viewing, displaying, performing, copying or distributing any Project Gutenberg-tm works unless you comply with paragraph 1.E.8 or 1.E.9. 1.E.8. You may charge a reasonable fee for copies of or providing access to or distributing Project Gutenberg-tm electronic works provided that - You pay a royalty fee of 20% of the gross profits you derive from the use of Project Gutenberg-tm works calculated using the method you already use to calculate your applicable taxes. The fee is owed to the owner of the Project Gutenberg-tm trademark, but he has agreed to donate royalties under this paragraph to the Project Gutenberg Literary Archive Foundation. Royalty payments must be paid within 60 days following each date on which you prepare (or are legally required to prepare) your periodic tax returns. Royalty payments should be clearly marked as such and sent to the Project Gutenberg Literary Archive Foundation at the address specified in Section 4, “Information about donations to the Project Gutenberg Literary Archive Foundation.” - You provide a full refund of any money paid by a user who notifies you in writing (or by e-mail) within 30 days of receipt that s/he does not agree to the terms of the full Project Gutenberg-tm License. You must require such a user to return or destroy all copies of the works possessed in a physical medium and discontinue all use of and all access to other copies of Project Gutenberg-tm works. - You provide, in accordance with paragraph 1.F.3, a full refund of any money paid for a work or a replacement copy, if a defect in the electronic work is discovered and reported to you within 90 days of receipt of the work. - You comply with all other terms of this agreement for free distribution of Project Gutenberg-tm works. 1.E.9. If you wish to charge a fee or distribute a Project Gutenberg-tm electronic work or group of works on different terms than are set forth in this agreement, you must obtain permission in writing from both the Project Gutenberg Literary Archive Foundation and Michael Hart, the owner of the Project Gutenberg-tm trademark. Contact the Foundation as set forth in Section 3 below. 1.F. 1.F.1. Project Gutenberg volunteers and employees expend considerable effort to identify, do copyright research on, transcribe and proofread public domain works in creating the Project Gutenberg-tm collection. Despite these efforts, Project Gutenberg-tm electronic works, and the medium on which they may be stored, may contain “Defects,” such as, but not limited to, incomplete, inaccurate or corrupt data, transcription errors, a copyright or other intellectual property infringement, a defective or damaged disk or other medium, a computer virus, or computer codes that damage or cannot be read by your equipment. 1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the “Right of Replacement or Refund” described in paragraph 1.F.3, the Project Gutenberg Literary Archive Foundation, the owner of the Project Gutenberg-tm trademark, and any other party distributing a Project Gutenberg-tm electronic work under this agreement, disclaim all liability to you for damages, costs and expenses, including legal fees.   LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a defect in this electronic work within 90 days of receiving it, you can receive a refund of the money (if any) you paid for it by sending a written explanation to the person you received the work from. If you received the work on a physical medium, you must return the medium with your written explanation. The person or entity that provided you with the defective work may elect to provide a replacement copy in lieu of a refund. If you received the work electronically, the person or entity providing it to you may choose to give you a second opportunity to receive the work electronically in lieu of a refund. If the second copy is also defective, you may demand a refund in writing without further opportunities to fix the problem. 1.F.4. Except for the limited right of replacement or refund set forth in paragraph 1.F.3, this work is provided to you ‘AS-IS’ WITH NO OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR ANY PURPOSE. 1.F.5. Some states do not allow disclaimers of certain implied warranties or the exclusion or limitation of certain types of damages. If any disclaimer or limitation set forth in this agreement violates the law of the state applicable to this agreement, the agreement shall be interpreted to make the maximum disclaimer or limitation permitted by the applicable state law. The invalidity or unenforceability of any provision of this agreement shall not void the remaining provisions. 1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation, the trademark owner, any agent or employee of the Foundation, anyone providing copies of Project Gutenberg-tm electronic works in accordance with this agreement, and any volunteers associated with the production, promotion and distribution of Project Gutenberg-tm electronic works, harmless from all liability, costs and expenses, including legal fees, that arise directly or indirectly from any of the following which you do or cause to occur: (a) distribution of this or any Project Gutenberg-tm work, (b) alteration, modification, or additions or deletions to any Project Gutenberg-tm work, and (c) any Defect you cause. Section 2. Information about the Mission of Project Gutenberg-tm Project Gutenberg-tm is synonymous with the free distribution of electronic works in formats readable by the widest variety of computers including obsolete, old, middle-aged and new computers. It exists because of the efforts of hundreds of volunteers and donations from people in all walks of life. Volunteers and financial support to provide volunteers with the assistance they need, are critical to reaching Project Gutenberg-tm’s goals and ensuring that the Project Gutenberg-tm collection will remain freely available for generations to come. In 2001, the Project Gutenberg Literary Archive Foundation was created to provide a secure and permanent future for Project Gutenberg-tm and future generations. To learn more about the Project Gutenberg Literary Archive Foundation and how your efforts and donations can help, see Sections 3 and 4 and the Foundation web page at http://www.pglaf.org. Section 3. Information about the Project Gutenberg Literary Archive Foundation The Project Gutenberg Literary Archive Foundation is a non profit 501(c)(3) educational corporation organized under the laws of the state of Mississippi and granted tax exempt status by the Internal Revenue Service. The Foundation’s EIN or federal tax identification number is 64-6221541. Its 501(c)(3) letter is posted at http://pglaf.org/fundraising. Contributions to the Project Gutenberg Literary Archive Foundation are tax deductible to the full extent permitted by U.S. federal laws and your state’s laws. The Foundation’s principal office is located at 4557 Melan Dr. S. Fairbanks, AK, 99712., but its volunteers and employees are scattered throughout numerous locations. Its business office is located at 809 North 1500 West, Salt Lake City, UT 84116,<PHONE_NUMBER>, email<EMAIL_ADDRESS>Email contact links and up to date contact information can be found at the Foundation’s web site and official page at http://pglaf.org For additional contact information: Dr. Gregory B. Newby Chief Executive and Director<EMAIL_ADDRESS>Section 4. Information about Donations to the Project Gutenberg Literary Archive Foundation Project Gutenberg-tm depends upon and cannot survive without wide spread public support and donations to carry out its mission of increasing the number of public domain and licensed works that can be freely distributed in machine readable form accessible by the widest array of equipment including outdated equipment. Many small donations ($1 to $5,000) are particularly important to maintaining tax exempt status with the IRS. The Foundation is committed to complying with the laws regulating charities and charitable donations in all 50 states of the United States. Compliance requirements are not uniform and it takes a considerable effort, much paperwork and many fees to meet and keep up with these requirements. We do not solicit donations in locations where we have not received written confirmation of compliance. To SEND DONATIONS or determine the status of compliance for any particular state visit http://pglaf.org While we cannot and do not solicit contributions from states where we have not met the solicitation requirements, we know of no prohibition against accepting unsolicited donations from donors in such states who approach us with offers to donate. International donations are gratefully accepted, but we cannot make any statements concerning tax treatment of donations received from outside the United States. U.S. laws alone swamp our small staff. Please check the Project Gutenberg Web pages for current donation methods and addresses. Donations are accepted in a number of other ways including checks, online payments and credit card donations. To donate, please visit: http://pglaf.org/donate Section 5. General Information About Project Gutenberg-tm electronic works. Professor Michael S. Hart is the originator of the Project Gutenberg-tm concept of a library of electronic works that could be freely shared with anyone. For thirty years, he produced and distributed Project Gutenberg-tm eBooks with only a loose network of volunteer support. Project Gutenberg-tm eBooks are often created from several printed editions, all of which are confirmed as Public Domain in the U.S. unless a copyright notice is included. Thus, we do not necessarily keep eBooks in compliance with any particular paper edition. Most people start at our Web site which has the main PG search facility: http://www.gutenberg.org This Web site includes information about Project Gutenberg-tm, including how to make donations to the Project Gutenberg Literary Archive Foundation, how to help produce our new eBooks, and how to subscribe to our email newsletter to hear about new eBooks.


public class Leek
extends java.lang.Object
| Modifier and Type | Class and Description |
|---|---|
static class |
Leek.WindowLocation |
| Modifier and Type | Field and Description |
|---|---|
protected CollisionEventManager |
cem
Manager for collision events.
|
protected Level |
currLevel
The current level that is being displayed.
|
protected LeekGuiHelper |
guiHelper
GUI helper for Leek.
|
protected boolean |
shouldChangeLevel
Whether or not the level should change.
|
protected Level |
toChange
The level to change to, if it should change levels.
|
protected Leek.WindowLocation |
wl
The location of the window on the screen.
|
| Constructor and Description |
|---|
Leek()
Leek instantiation
|
| Modifier and Type | Method and Description |
|---|---|
boolean |
enterMainLoop()
Enter the main game loop.
|
void |
init(java.lang.String windowName)
Initialization functions for Leek.
|
void |
init(java.lang.String windowName,
Leek.WindowLocation windowLocation)
Initialization functions for Leek.
|
void |
init(java.lang.String windowName,
Leek.WindowLocation windowLocation,
java.awt.Image windowIcon)
Initialization functions for Leek.
|
protected void |
loadInitialLevel(Level l)
Load the initial level.
|
protected boolean |
mainLoop(int targetFPS) |
void |
requestChangeLevel(Level l)
Request to change the level.
|
protected LeekGuiHelper guiHelper
protected CollisionEventManager cem
protected Level currLevel
protected boolean shouldChangeLevel
protected Level toChange
protected Leek.WindowLocation wl
public void init(java.lang.String windowName)
windowName
- The name of the window.public void init(java.lang.String windowName, Leek.WindowLocation windowLocation)
windowName
- The name of the window.windowLocation
- Where the window is on the screen.public void init(java.lang.String windowName, Leek.WindowLocation windowLocation, java.awt.Image windowIcon)
windowName
- The name of the window.windowLocation
- Where the window is on the screen.windowIcon
- The icon of the window.public boolean enterMainLoop()
protected boolean mainLoop(int targetFPS)
protected void loadInitialLevel(Level l)
l
- Level to load.public void requestChangeLevel(Level l)
l
- The level to change to.