
## Basic File Structure

SAI code is written in plain text files. 

Leading white space is semantically relevant, and must be formed using spaces, not tabs.

If present, the **reference** section must appear first, before any **object** definition.

### Reference - Global Variables

Declares global variables for use within the scope of the file. This is the preferred location to use `require`.

    reference:
      [varName] [expression]
      ...
      
     reference:
       RED ‘ff0000’
       EXPRESS require(‘express’)

     set colour to RED
     set app from EXPRESS

Reference variables cannot define functions.

Stylistically, it is encouraged to ALLCAPS reference variables. 


### OBJECT - Object Definition

Except for reference variables, all other SAI code exists within the context of an object definition.

There can be only one object definition per file.

**Format**

	object [ObjectName] (singleton|main) ([semver])

**Example**

	object PhysicsEngine singelton 1.0.1


Stylistically, Object names should use CamelCase.


### INHERIT - Object Inheritance

Objects may inherit traits, tasks and contracts from other objects, and multiple-inheritance is supported.

    inherit: 
      '[ObjectName] [semver]'
      ...


### CONTRACT - ImplementationContracts

A list of attributes and tasks that children of this object agree to implement.

    contract: 
      [TaskName] {parameters?}
      ...

    contract:
      Get
      Set
      Iterator

Contract requirements are validated during the preparation of prototypes that inherit them. If the final prototype does not include concrete implementations of all contracted attributes and tasks, an exception is thrown.


### GIVEN - Fixed Attributes

Traits are static (unchanging) object attributes. Their names should start with a lowercase letter to distinguish them from object tasks.

Givens are immutable values that are attached to the prototype and frozen in place. They cannot be changed in code. They are compiled once on prototype preparation and do not impact instantiation time. Givens are useful for static data, initializers and so on.

    given:
      [traitName] [expression] 
      ...

    given [traitName] [expression]

Givens also cannot declare functions.

Stylistically, given traits should be all lower case.

### INSTANCE - Instance Traits

Instance traits are set on construction of an object instance. They are initialized to the value given here during the pre-construction phase, and are ready for use in all object code including the  `Instatiate` task.

    instance:
      [traitName] [expression]
      ...

You should declare all of your instance attributes so the compiler can perform scope checking for you.

Stylistically, instance attributes should be all lower case.


### GET/SET - Dynamic Traits

Traits can be implemented with code, on **set** accepting a single value, and on **get** returning a single value. If you omit a **set** code path, then the trait is read-only.

    [traitName] get
      [code block]
    set [parameter]
      [code block]
 
**Example:**

    angle get
      return Math.atan2(y,x)
    set given radians
      SetPolar magnitude, radians

    magnitude get
      return from Math.sqrt (x*x) + (y*y)
    set given units
      SetPolar units, angle


### TASK - Task Definition

Tasks are named object functions. Task names should start with Capital Letters to distinguish them from traits.

    [TaskName] task [parameters]
      [code block]

**Example:**

    SetPolar task given units, radians
      set x to Math.cos(radians) * units
      set @y to \~Math.sin(radians) * units
