Syntax and Basic Semantics - Paramecium13/LSN GitHub Wiki

The syntactic elements of LSN can be divided into two categories. The first category, executable syntax elements, can, after being reified and loaded, be executed by the interpreter. The second category, declarative syntax elements, define types and functions that can be used in other parts of the code.

Executable Syntax Elements

LSN contains three main categories of executable syntax elements. Expressions are evaluated and return a value. They often contain other expressions. Expressions cannot be placed alone in a script or function body. Statements tell the interpreter to do something, such as assign a value to a variable or display a message. Most of them contain at least one expression. Control structures contain statements, other control structures (statements and control structures are collectively referred to as components) and often a set number of expressions. Control structures consist of two parts, the head, which contains the keyword(s) that identify it and often one or more expressions, and the body, which contains the components that are executed, depending on the results of the expression(s) in the head.

Expressions

LSN is a strongly typed language, all expressions have a type that is know at reification time.

Constant Expressions

Constant expressions consist of a constant value. Some types, such as strings and numbers, can be written directly in the source code, others, such as struct and record values, are only produced by reifier optimizations (namely Constant Folding). See the page on built in types (not yet added) for their syntax.

Variable Expressions

Variable expressions refer to the value of a specific variable. They are written simply as the name of the variable they refer to.

Arithmetic Expressions

LSN has all the arithmetic expressions that C# does, as well as the exponentiation expression, which uses the '^' symbol. The operator precedence and associativity follows standard practice (the associativity needs to be tested). Arithmetic expressions are of the form

⌈expression0⌋ ⌈operator⌋ ⌈expression1⌋

where the expressions have a return type of int or double (they do not have to match). Arithmetic expressions between two ints return an int and arithmetic expressions that have at least one double return a double.

Logical Expression

⌈expression0⌋ ⌈operator⌋ ⌈expression1⌋

Operator is '&&' or '||'...

Not Expression

!⌈expression⌋

Comparison Expressions

⌈expression0⌋ ⌈comparison⌋ ⌈expression1⌋

Comparison can be: '<', '>', '>=', '<=', '==', or '!='...

String Expressions

LSN supports string concatenation using the '+' operator with two expressions with a return type of string. LSN also has string multiplication using the '*' operator with an expression that returns a string on the left and one that returns an int on the right. String multiplication returns the string on the left concatenated with itself the value of the int times. Bad things may happen if the int is negative.

Field Expressions

Syntax

⌈expression for container⌋.⌈field name⌋

Collection Value Access Expression

⌈expression for collection⌋[⌈expression for index⌋]

Function Expressions

Syntax

⌈function name⌋(⌈expression for param 0⌋, ..., ⌈expression for param n⌋)


⌈function name⌋(⌈name of param i⌋ : ⌈expression for param i⌋, ...,⌈name of param j⌋ :  ⌈expression for param j⌋)

Method Expression

Syntax

⌈expression for object⌋.⌈method name⌋(⌈expression for param 0⌋, ..., ⌈expression for param n⌋)


⌈expression for object⌋.⌈method name⌋(⌈name of param i⌋ : ⌈expression for param i⌋, ...,⌈name of param j⌋ :  ⌈expression for param j⌋)

Record/Struct Constructor

Syntax

new ⌈type name⌋ (⌈field i name⌋ : ⌈expression for field i⌋, ..., ⌈field j name⌋ : ⌈expression for field j⌋)

new ⌈type name⌋ (⌈expression for field 1⌋, ...,⌈expression for field n⌋)

List Constructor

Syntax

new List<⌈type name⌋>()

Statements

Assignment Statement

Assignment statements assign the result of an expression to a new variable and optionally declare if the variable is mutable (if it can be assigned a different value later on). Syntax

let (mut) ⌈variable name⌋ = ⌈expression⌋;

If the key word 'mut' is present, it indicates that the variable is mutable. The type of the variable is inferred from the expression.

Reassignment Statement

Reassignment statements assign the result of an expression to an existing variable. The variable of a reassignment statement must already exist and be mutable. Additionally, the type of the expression must match the type of the variable.

Reassignment statements can also change the value of a field in a script class or a struct.

Syntax

⌈variable name⌋ = ⌈expression⌋;

LSN currently does not support the syntactic shortcuts '+=', '-=', etc.

Goto Statement

The goto statement changes the location of the player, or an other character on the current map or a different map.

Syntax

(actor) goto ⌈destination⌋;

There are currently five different possibilities for the destination parameters.

⌈map⌋
⌈map⌋ ` ⌈label⌋
⌈map⌋ ` ⌈x⌋ ` ⌈y⌋
⌈label⌋
⌈x⌋ ` ⌈y⌋

⌈map⌋ is an expression that returns the name of the map to go to.

⌈label⌋ is an expression that returns the name of the label to go to (on the current map or a different map). I plan to add the ability to place labels at points on maps.

⌈x⌋ is an expression that returns the x coordinate.

⌈y⌋ is an expression that returns the y coordinate.

Return Statement

Syntax

return ⌈value⌋;

If the return statement is in a function or event that returns a value, then it must have a value. Additionally, the type of the value must match the return type specified by the function or method.

Break Statement

The break statement exits the innermost loop. It must not be used outside of a loop.

Syntax

break;

Next Statement

The next statement causes the innermost loop to go directly to its next iteration (, not pass go, and not collect $200). It must not be used outside of a loop.

Syntax

next;

Set State Statement

The Set State Statement can only be used in a method or event listener inside a script object or one of its states. It changes the current state of its containing script object. For more information on script objects and states, see the 'Script Objects' page on this wiki.

Syntax

SetState ⌈state⌋;

where 'state' is the name of the state to which the script object is set.

Control Structures

If-Else Structure

Syntax

if(⌈condition⌋) {
    ⌈body⌋
}
else if (⌈condition⌋){
    ⌈body⌋
}
else {
    ⌈body⌋
}

It can have any number of 'else if' blocks but can only have one 'else' block, which must be after all the 'else if' blocks.

For Loop

Syntax

for(⌈assignment⌋ ` ⌈condition⌋ ` ⌈reassignment⌋) {
    ⌈body⌋
}

I will be switching to the following syntax soon.

for ⌈variable name⌋ in ⌈collection or range⌋
{
    ⌈body⌋
}

Where 'collection' is an expression that returns a collection (vector or list) and range is a range expression, as shown below

⌈int expression 1⌋..⌈int expression 2⌋

Or, maybe also

⌈int expression 1⌋ to ⌈int expression 2⌋

While Loop

Syntax

while(⌈condition⌋){
    ⌈body⌋
}

Choice Structure

Syntax

choice {
    ⌈string expression⌋ -> {
        ⌈body⌋
    }
    ...
    ⌈condition (optional)⌋ : ⌈string expression⌋ -> {
        ⌈body⌋
    }
}

A branch consists of an optional condition (an expression that returns a bool), a prompt (an expression that returns a string), and a body (LSN code). A choice structure can have any number of branches.

Semantics

When executed, the choice structure displays the prompts for all branches whose condition evaluates to true or that lack a condition to the player. When the player selects a prompt, the corresponding body will be executed.

Match Structure

Not yet implemented...

Case Structure

Not yet implemented...

Declarative Syntax Elements

LSN currently supports five top level types of declarations: structs, records, functions, host interfaces, and script objects. Other declarations, such as enums and quests (maybe...) are planned. Host interface and script object declarations both include sub-declarations. Host interface declarations can contain two different sub-declarations: method definition declarations and event definition declarations. Script object declarations can contain five different types of sub-declarations: properties, fields, methods, event listeners, and states, which can contain methods and event listeners.

Structs

Syntax

struct ⌈name⌋ {
    ⌈Field_0 Name⌋ : ⌈Field_0 Type⌋,
    ...,
    ⌈Field_n Name⌋ : ⌈Field_n Type⌋
}

Records

Syntax

record ⌈name⌋ {
    ⌈Field_0 Name⌋ : ⌈Field_0 Type⌋,
    ...,
    ⌈Field_n Name⌋ : ⌈Field_n Type⌋
}

Functions

Syntax

fn ⌈name⌋(⌈param_0_name⌋ : ⌈param_0 type⌋, ..., ⌈param_n name⌋ : ⌈param_n type⌋) -> ⌈return type⌋ {
    ⌈Function Body⌋
}

The body of the function consists of the control structures and/or statements that are executed when it is called.

Host Interfaces

Syntax

HostInterface ⌈name⌋ {
    ⌈body⌋
}

The body of a host interface consists of its method definitions and/or event definitions. For information on the meaning and use of host interfaces, see the associated page(s) on this wiki.

Method Definitions

Syntax

fn ⌈name⌋(⌈param_0 name⌋ : ⌈param_0 type⌋, ..., ⌈param_n name⌋ : ⌈param_n type⌋) -> ⌈return type⌋;

Event Definitions

Syntax

event ⌈name⌋(⌈param_0 name⌋ : ⌈param_0 type⌋, ..., ⌈param_n name⌋ : ⌈param_n type⌋);

Script Objects

Syntax

ScriptObject ⌈name⌋ < ⌈HostInterface⌋ {
    ⌈body⌋
}

For information on the meaning and use of script objects, see the associated page(s) on this wiki.

Properties

Syntax

property ⌈name⌋ : ⌈type⌋;

Fields

Syntax

mut ⌈name⌋ : ⌈type⌋;

Methods

Syntax

fn ⌈name⌋(⌈param_0 name⌋ : ⌈param_0 type⌋, ..., ⌈param_n name⌋ : ⌈param_n type⌋) -> ⌈return type⌋{
    ⌈body⌋
}

Event Listeners

Syntax

on ⌈name⌋(⌈param_0 name⌋ : ⌈param_0 type⌋, ..., ⌈param_n name⌋ : ⌈param_n type⌋){
    ⌈body⌋
}

States

Syntax

state ⌈name⌋{
    ⌈body⌋
}
⚠️ **GitHub.com Fallback** ⚠️