Syntax

Expression Advanced 2 syntax slightly differs from that of LemonGate. Like it predecessor ExpAdv2's language is based on C#. Unlike its counterpart, E2, Expression Advanced 2 supports a full callback and event structure, as well as instanced variables and booleans.

Syntax Example Description
// #This is a comment Anything written after "//" on the same line will be treated as a comment (it will be ignored by the compiler).
/*comment*/ /*This is a multi-line comment*/ Anything between /**/ will be treated as a comment (it will be ignored by the compiler).
object.method( ... ) “abc”.sub(1,1) Calls a method on an object (was colon ':' in expadv1 and is now '.' period).
if ( ) { } if ( true ) { int i = 5} If the value (the condition) between the parentheses is true, then run the statements between the braces.
elseif ( ) { } elseif ( true ) { int i = 5} Must be preceded by if () {} or elseif () {}. If the previous condition was false and the value between the parentheses is true, then run the statements between the braces.
else { } else { int i = 5} Must be preceded by if () {} or elseif () {}. If the previous condition was false then run the statements between the braces.
( ? : ) int i = A ? B : C If A is true then return B otherwise return C.
&& if ( A && B ) Returns true if both A and B are true...
! if ( !A ) Must precede a value. Returns true if A is false.
~ if ( ~A ) [NOT IMPLEMENTED] Returns true is A has changed since the last ~A.
$ Delta = $A Returns the current value of the variable minus the value of the variable at the end of the last execution. Note: Will only produce results when used on the same instance of a variable.
# Length= #A Returns the length of a value like strings and arrays.
server { } server { print( true ) } If the code is running serverside then run the statements between the braces.
client { } client { print( true ) } If the code is running clientside then run the statements between the braces.
(type) value (string) 100 Casts (converts) a value of one type to another.

Server & client

Expression Advanced 2 entity's will run two variations of the same code, serverside and clientside. Each client (player) will have a separate instance of the same code and the server will have its own instance. Neither the server or client instances are synced with each other, this includes player to player, for such a result the user must sync these instances manually using net streams.

Some functions, methods, events and classes may only appear serverside where others may only appear clientside. for example apply force methods will only work serverside whilst render functions and events will only work clientside.

Anything that appears inside a 'server' statement will only execute serverside and the opposite is true of the 'client' statement. Anything outside of a server of client statement will be ran on both server and client also known as shared code.

Example:

server {
    print( "Hello, server" )
}

client {
    print( "Hello, client" )
}

It is also possible to prefix single statements, such as events, loops and variable definitions by excluding the braces, how ever this will not push the memory's scope for this statement.

Example:

server print( "Hello, server" )

client event tick( ) {
    print( "Tick." )
}

server number A = 1

Variables

In Expression Advanced variables must begin with a letter (both uppercase and lowercase are supported), all variables are given a new instance per event unless marked with a modifier. Unlike Expression Advanced 1 new instances are only created in events and functions called from outside the root execution.

Syntax Example Description
<type> var number i = 1 Creates a variable named i.
static <type> var static number i = 1 Creates a static variable named i.
global <type> var global number i = 1 Creates a global variable named i.
input <type> Var input number I Creates an input variable named i. Note: inputs must begin with a capital letter, can not be assigned and can only be defined serverside.
output <type> Var output number I Creates an output variable named i. Note: outputs must begin with a capital letter and can only be defined serverside.

Defining variables

Example of basic variable definition:

number i = 5

Example of multiple variable deceleration:

number i, j, k = 1, 2, 3

Advanced use:

number a, b, c = 2, a ^ 2, b * 20

Example wiremod input/output:

input number  In
output number Out = 5

It is important to remember that inputs and outputs can only be defined on the server inside either a server block or by prefixing the definition with the keyword server.

It is also possible to define variables as server and client only. This is done by prefixing the variable deceleration with the server or client keywords.

server static number i = 1

Variable statements

All variable assignments return the assigned value.

Syntax Example Description
Number++ i++ Returns the value of Number, before increment by 1.
++Number ++i Returns the value of Number, after increment by 1.
Number-- i-- Returns the value of Number, before decremented by 1.
--Number --i Returns the value of Number, after decremented by 1.
+= i += 5 Increments the variable by a value.
-= i -= 5 Decrements the variable by a value.

Events

Expression Advanced uses events that respond to certain conditions in game (players joining / leaving / chatting etc), only 1 event statement may exist per event and provide inputs in the form of parameters. You may also return from an event to control some aspect of the event. Events are similar to expression 2's runOnTick(n) and runOnchat(n) but cover a wider range of conditions.

Example:

event think() {
  print("I can think?")
}

event playerChat(player Player, string What) {
  print(Player.name() + " said " + What)
  return "I like trains!"
}

Note: Though we have have a load of requests to add a first() event this will not be added. The reason why is that the root of the code is only ran once and is the first execution making it the first event itself.

Loops

Syntax Example Description
while( ) { } while( Bool ) { B++ } Any instructions between the braces will repeat, as long as the condition between the parentheses is true. If the condition is false, the instructions will be skipped.
for( <type> = ; end; step) for( int i = 1; 10; 1) { } Defines a value at a start point will execute statements while value is less or equal to end, after every execution value will increment by step.
foreach( index; key: array) { } foreach( Var; Var; Array ) { } Any instructions between the braces will repeat for each key and matching value in the array.
continue if ( true ) { continue } Moves to the next execution of the loop.
break if ( true ) { break } Breaks out of the current loop.

Examples

number i = 0
while (i++ < 5) {
  print(i)
}

for (number i = 1; 10; 2) {
  print(i)
}

foreach (number key; string value: array) {
  print(key, ": ", value)
}

User-defined functions

Unlike Expression advanced 1's user functions, Expression Advanced 2 no longer uses the lambda calculus. It's also important to note that functions must be given a static return type or void.

function void hello() {
    print("Hello World")
}

Functions may also have parameters as shown in the following example:

function number someFunc(number A, number B, number C) {
    return A * B * C
}

Functions may also be passed around in memory.

function number myFunc = someFunc

Delegates

Because user functions are no longer first class objects, they must be casted to delegates. Delegates are basic function objects that can not be called. Delegates simply exist to freely pass user functions around as objects before being casted back to a user function.

delegate var = (delegate) someFunc

function number myFunc = (function) var

Variants

Variants are generic objects that are used in situations where being type strict is not suitable. Variants can have any variable assigned to them of any type. The casting operator must be used to translate Variants back to their actual type. Casting a Variant to a different type to its actual type will throw an exception.

Operator Return Description
(variant) Object Variant Casts any object to a variant.
(<type>) Variant <type> Casts a variant back to its native type, will throw an exception when casting to the wrong type.
Function Return Description
tostring(Variant) String Converts a variant to a string.
type(Variant) String Returns the type of the object held inside a variant.

Try-Catch-Final

When A unpredictable error occurs in Expression advanced the code will throw an exception upwards though the stack, this exception can be caught using the Try Catch statement and used for debugging.

Example:

try {
    //Protected code.    
} catch ( invoke, string Exception ) { //Catch a invoke or string exception.
    print( "Caught " + Exception:type() )
} catch ( table Exception ) { //Catch a table exception.
    print( "Caught " + Exception:type() )
} catch ( * Exception ) { // this si a wildcard and can catch anything.
    print( "Caught " + Exception:type() )
} final {
    //This will run after your try statement and any following catch, even if no exception is caught.
}

Directives

Expression advanced 2 uses directives to add advanced features and syntax's to the language. Directives will always start with an at symbol (@) followed by the directive name post fixed with a colon (:).

Definitions

Sometimes there will be times when you need to use the same expression in multiple places, this can be tedious and ugly to the eye. Where as creating a user function is a simple solution to this, user functions are in fact quite slow and expensive to call. The solution to this is the define directive. The define directive is given a keyword and an expression, when ever this keyword appears in the same section of code bellow where the definition is defined it will replace that keyword directly with that expression.

Example:

@define: randRGB random(0, 255)   
color myRandomcolor = color( randRGB, randRGB, randRGB, 255 )

The above example is the same as the following code:

color myRandomcolor = color( random(0, 255), random(0, 255), random(0, 255) )

Other Features

These features are considered bad practice since their functionality is not available in other languages. Whilst these features are bad practice they can be very useful to save time when writing repetitive or complex code.

Where as strings defined using (") must be terminated before the end of the current line.

"This is a string."

You can use (') to define a string over multiple lines.

'This is a multiple
lined string.'

When you need to compare one value multiple times in one expression you can do the following

if ( Var == [1,3,5,7] )

That condition will be true if Var is equal to any of the values specified between the square brackets ([]), you can also do

if ( Var != [1,3,5,7] )

That condition will be true if Var does not match any of the values between the square brackets ([]), these are known as multiple comparison operators.

When you need to check if something is in range of 2 values you can use the in range operation.

if ( Min < Value > Max )

You can use the connected operator (->) to detect is a wiremod port is wired.

input number InPort
if ( ->InPort )

For loops work with vectors as well as numbers.

for (vector v = vec(0,0,0); vec(2, 5, 10); vec(1,1,2)) { print(v) }

results matching ""

    No results matching ""