Syntax

Syntax for the Haasonline Script Editor

Local vs. Global

Variables in HaasScript can be defined as either global or local. The difference between these two is that the other is accessible globally and the other is not:

-- This is a global variable (accessible globally)
myVariable = 1

-- This is a local variable (accessible locally)
local myVariable = 1

This means, that any variables defined as global will be visible everywhere in the script's scope, whereas the variables defined as local are only visible inside the scope they were first defined in but also in their sub-scopes.

Scope

To give you an example what a scope is in HaasScript, here's a script with an if-statement and a function:

-- We are inside the script's scope.
-- Variables defined here, either global or local,
-- are visible in sub-scopes within this script.

if something then
    -- We are now inside the scope of an if-statement.
    -- Local variables defined here are not visible outside.
end

local someFunction = function()
    -- We are now inside the scope of a function.
    -- Local variables defined here are not visible outside.
end

Inside if-statements

if something then

    -- a global variable
    thisIsGlobal = 5
    
    -- a local variable
    local thisIsLocal = 5 * 2
end

Log(thisIsGlobal) -- Outputs 5
Log(thisIsLocal) -- ERROR: Unknown references: thisIsLocal

Inside functions

local myFunction = function(value)

    -- a global variable
    thisIsGlobal = value
    
    -- a local variable
    local thisIsLocal = value * 2
end

-- Call the function
myFunction(5)

Log(thisIsGlobal) -- Outputs 5
Log(thisIsLocal) -- ERROR: Unknown references: thisIsLocal

Conflicting variables

Example of bad practice:

text = "Awesome text!"

local changeText = function(value)
    text = value
end

changeText("..not anymore!")

Log(text) -- Outputs '..not anymore!'

Example of good practice:

local text = "Awesome text!"

local changeText = function(value)
    -- 'text' is visible within this sub-scope, even when defined as local
    Log(text) -- Outputs 'Awesome text!'
    
    -- Local 'text' variable for this sub-scope
    local text = value
end

changeText("..not anymore?")

Log(text) -- Outputs 'Awesome text!'

Overwriting variables in a function:

local text = "Awesome text!"

local changeText = function(text)
    -- The input parameter 'text' will be
    -- hiding the locally defined 'text',
    -- so this Log() prints what
    -- ever the input is.
    Log(text)
end

changeText("..not anymore?") -- Outputs '..not anymore?'

Log(text) -- Outputs 'Awesome text!'

If

if condition then

end

if condition == true then

end

if condition == false then

end

if not condition then

end

If & Else

if condition1 then

else

end

If & ElseIf

if condition1 then

elseif condition2 then

end

If (One-liner)

Syntax:

local value = condition and value_if_true or value_if_false

Example:

local condition = true
local text = condition and "Condition is true." or "Condition is false."

Log(text) -- Outputs: Condition is true.

Booleans!?

local condition1 = false
local condition2 = true

Log("condition1:")
Log(condition1 and false or true) -- Outputs: true
Log(condition1 and true or false) -- Outputs: false

Log("condition2:")
Log(condition2 and false or true) -- Outputs: true
Log(condition2 and true or false) -- Outputs: true

Nil values and assignments

local variable
Log( variable and 'variable is not nil' or 'variable is nil')
-- Output: variable is nil

local variable = nil
Log( variable and 'variable is not nil' or 'variable is nil')
-- Output: variable is nil

local variable = 0
Log( variable and 'variable is not nil' or 'variable is nil')
-- Output: variable is not nil

local variable = ''
Log( variable and 'variable is not nil' or 'variable is nil')
-- Output: variable is not nil

local variable = false
Log( variable and 'variable is true' or 'variable false')
-- Output: variable is false

local variable = true
Log( variable and 'variable is true' or 'variable false')
-- Output: variable is true

Loading without default values

-- Load defaults to 'nil'
local powerLevel = Load('pl')

if not powerLevel then -- or 'if powerLevel == nil then'
    powerLevel = 9001
    Log('Power level set.')
end

Save('pl', powerLevel)

For each

The for each iterator returns the value of each element in the collection.

closePrices = ClosePrices()

for value in closePrices do
    Log(value)
end

The iterator can also be used with key,value, if the key is defined.

object = { keyA = 'valueA', keyB = 'valueB'}

for key,value in pairs(object) do
    Log(key .. " = " .. value)
end

Indexing

Lua's index is based on 1. You can use 0 as index in Lua, but HaasScript will throw you an error for it. This restriction is implemented to break any confusions.

prices = ClosePrices()
price = prices[1] -- First price value in 'prices'

Accessing object fields

object = { keyA = 'valueA', keyB = 'valueB'}

Log(object.keyA) -- Outputs 'valueA'
Log(object.keyB) -- Outputs 'valueB'
Log(object.keyC) -- Outputs 'nil' (doesn't exist)

-- You can create new fields in objects
-- by assigning a value into them.
object.keyC = 'valueC'
Log(object.keyC) -- Outputs 'valueC'

For loop

All the for loops are based on a default structure. The init and max/min value are always required and the increment is optional (default +1)

for init, max/min value, [increment] do
    -- Do something
end

Forward loop

Using # with the array variable will return the array size. This way we can easily loop over each value.

closePrices  = ClosePrices()

for i = 1, #closePrices  do
    Log(closePrices[i])
end

Backwards loop

For the backwards loop we swap start and end value and set the increment to -1.

closePrices  = ClosePrices()

for i = #closePrices, 1, -1  do
    Log(closePrices[i])
end 

Comments

HaasScript supports single- and multi-line comments.

-- Single-line comment

if commentingIsCool == true then
    --[[ Multi-line comment, that
    can continue through
    multiple lines and
    stop suddenly]] but = "allows code to continue"
end

--[[
This also works.
--]]

--[===[
And this.
--]===]

--[=[
This doesn't
--]==]

Arrays

Arrays are ordered arrangements of objects, which may be a one-dimensional array containing a collection of rows or a multi-dimensional array containing multiple rows and columns.

In HaasScript, arrays are implemented using indexing tables with integers. The size of an array is not fixed and it can grow based on your requirements, subject to memory constraints.

HaasScript also offers an alternative way for creating and manipulating arrays.

Array Helpers

One-dimensional array

A one-dimensional array can be represented using a simple table structure and can be initialized and read using a simple for loop. An example is shown below.

array = {"HaasScript", "Tutorial"}

for i = 0, 2 do
   Log(array[i])
end

When we run the above code, we will get the following output.

nil
HaasScript
Tutorial

As you can see in the above code, when we are trying to access an element in an index that is not there in the array, it returns nil. In HaasScript, indexing is limited to start at index 1. It is possible to create objects at index 0 and below 0 as well. Array using negative indices is shown below where we initialize the array using a for loop.

array = {}

for i= -2, 2 do
   array[i] = i * 2
end

for i = -2, 2 do
   Log(array[i])
end

When we run the above code, we will get the following output.

-4
-2
0
2
4

Multi-Dimensional Array

Multi-dimensional arrays can be implemented in two ways.

  • Array of arrays

  • Single dimensional array by manipulating indices

An example for multidimensional array of 3. 3 is shown below using array of arrays.

-- Initializing the array
array = {}

for i=1,3 do
   array[i] = {}
	
   for j=1,3 do
      array[i][j] = i*j
   end
	
end

-- Accessing the array

for i=1,3 do

   for j=1,3 do
      Log(array[i][j])
   end
	
end

When we run the above code, we will get the following output.

1
2
3
2
4
6
3
6
9

An example for multidimensional array is shown below using manipulating indices.

-- Initializing the array

array = {}

maxRows = 3
maxColumns = 3

for row=1,maxRows do

   for col=1,maxColumns do
      array[row*maxColumns +col] = row*col
   end
	
end

-- Accessing the array

for row=1,maxRows do

   for col=1,maxColumns do
      Log(array[row*maxColumns +col])
   end
	
end

When we run the above code, we will get the following output.

1
2
3
2
4
6
3
6
9

As you can see in the above example, data is stored based on indices. It is possible to place the elements in a sparse way and it is the way Lua implementation of a matrix works. Since it does not store nil values in Lua, it is possible to save lots of memory without any special technique in Lua as compared to special techniques used in other programming languages.

Last updated