Supported OS
Supported CPU
Each line is a new statement and default scope is global
a = 1 -- global variable
local b = 2 -- prepend with 'local' to bind to lexical scopeStandard standard C and Pascal like binary operators
e = a + b -- add
e = a - b -- subtract
e = a * b -- multiply
e = a % b -- modulus
e = a ^ b -- a to power b
e = a == b -- equality
e = a ~= b -- inequality
e = a < b -- less than
e = a > b -- greater than
e = a <= b -- less than equal
e = a >= b; -- greater than equal
e = "ss" .. "XX"-- string concatenationMultiple assignment supported and multiple statements per line separated by ;
a, b = b, a -- this swaps the values of a and b
local c = 3; d = 4; -- multiple statements per line
-- define local variable e with no value bound to it
local e; -- ';' not necessary but OK.Logical operators a bit different (nil and false is false everything else is true)
-- stops on false or nil , returns last evaluated value
e = a and b -- if a true then b else false
-- stops on true (not false or nil ), returns last evaluated value
e = a or b -- if a true then a else b
-- Logically invert
e = not a -- if a false then true else false
-- using and and or for conditional assignment
e = IAmNotDefined or 'So default value' -- result is the string
e = IamNotDefined and IamNotDefined() -- this does not crash All values in Lua are first-class (stored in variables; passed as arguments; returned as results)
true or false.
nil and false counts as false everything else is true. number
double (could be char, short, int, float). string
char values.
'\0'
nil)
'Some\n "blah" string\' don't need to escape\''"Some\n 'blah' string\" don't need to escape \""Literal strings
local someString = [[
first new line is ignored
this is a new line but this \n is not
]]
local anotherString = [=[the string does not end here]]
[[some text]]
the string ends here]=]Indexing
a = t[1] -- access array element 1
a = t['blah'] -- access element string key 'blah'
a = t.blah -- syntactic sugar for t['blah']Constructors
-- empty table
t = {}
-- simple array elements are t[1], t[2], t[3]
t = {"blah", 1, true}
-- simple map elements t['blah'], t['foo']
t = {blah = 5, foo=true}
-- Explicit keys
t = {['blah'] = 5, [100] = true}
-- mixed elements at t[1], t[2], t[100], t.foo t.bar
t =
{ 'alpha', 'bravo'; -- element separator either , or ;
foo = 5; bar=4,
[100] = false,
}Insertion and deletion
t.foo = 5 -- Insert value 5 at key foo
t.foo = nil -- Delete key foo from tableFunction definition
function (arg1, arg2) return arg1 + arg2 endfunction(a1, a2, ...)endreturn returns functions resultGlobal function assignment
-- This is syntax sugar
function arb (arg1, arg2) return arg1 + arg2 end
-- for this assignment of a function to the global 'arb'
arb = function (arg1, arg2) return arg1 + arg2 end Local function assignment
-- This is syntax sugar
local function arb (arg1, arg2) return arg1 + arg2 end
-- for this assignment of a function to the local 'arb'
local arb = function (arg1, arg2) return arg1 + arg2 end Table function insertion
-- This is syntax sugar
function t.arb (arg1, arg2) return arg1 + arg2 end
-- for this insertion of a function into table t at key arb
t['arb'] = function (arg1, arg2) return arg1 + arg2 endTable function insertion with implicit self
-- This is syntax sugar
function t:arb (arg1, arg2)
return arg1 + arg2 + self[1]
end
-- for this insertion of a function into table t at key arb
-- and explicit self parameter
t['arb'] = function (self, arg1, arg2)
return arg1 + arg2 + self[1]
endFunction called by applying argument list to function value
local arb = function (a) return a + a end
local x = arb(2) -- x is 4Calling function implicitly passing self
local t = {
arb = function(self, a)
return self.x + a
end;
x = 1; -- trailing delimiter is fine
}
-- This is syntax sugar for
local b = t:arb(2)
-- this lookup of arb in t and passing it t and 2
local c = t.arb(t, 2)Parentheses optional when calling function with literal string
-- This is syntax sugar
print "blah"
-- for this
print("blah")Parentheses optional when calling function with table constructor
-- This is syntax sugar
ipairs {1,2,3,4}
-- for this
ipairs ({1,2,3,4})Function return types are dynamic
function arb(x)
if x == 1 then return 3,4
elseif x == 'j' then return 'bob',8
elseif x == 'm' then return nil,'s'
elseif x == 2 then return 4
else
-- returning nothing
end
end
a,b = arb(1) -- a == 3, b == 4
a,b = arb('j') -- a == 'bob', b == 8
a,b = arb('m') -- a == nil, b == 's'
a,b = arb(2) -- a == 4, b == nil
a,b = arb(3) -- a == nil, b == nilFunctions support closures
local function makeCounter()
local count = -1 -- local variable
return function () -- return the function
-- capture `count` updating on each invocation
return count = count + 1
end
end
local c1 = makeCounter()
local _1, _2, _3 = c1(), c1(), c1() -- _1 == 0, _2 == 1, _3 == 2
local c2 = makeCounter()
_1, _2, _3 = c2(), c1(), c2() -- _1 == 0, _2 == 4, _3 == 1Functions support tail call recursion
function fib(n)
local function _fib(fn2, fn1, at)
if at == n then
return fn1 + fn2
else
-- calls it self recursively as a tail call
-- so it will reuse the same stack frame
return _fib(fn1, fn1 + fn2, at+1)
end
end
if n <= 0 then return 0
elseif n == 1 then return 1
else return _fib(0, 1, 2) end
end
-- no stack overflow
-- prints : n4 = 2 n8 = 13 n1000 = 2.6863810024485e+208 n10000 = 1.#INF
print ('n4 = ' .. fib(4) .. ' n8 = '.. fib(8) .. ' n1000 = ' .. fib(1000)
.. ' n10000 = ' .. fib(10000))Introduces local scope
do
local onlyVisibleHere = 5
endif then else
Conditional branching with each branch introducing a local scope.
if a == b then -- start if branch
e = 2
elseif a == c then -- optional else if branch
e = 3
else -- optional else branch
e = 4
end -- required terminatorIf condition is true then repeatedly execute block until false
local a,b = 1,5
while a < b do
a = a + 1 -- executes 4 times
endrepeat
Execute block and if condition is true repeat until false
local a,b = 4,5
repeat
a = a + 1 -- executes 2 times
until a == bbreak
Forces enclosing looping structure to terminate immediately
local a = 1
while true do
break
a = a + 1 -- never executes a remains 1
endRepeat the block until initial value passes limit incrementing by optional step size. Default step size is 1.
local a = 1
for u=1,10 do
a = u -- executes 10 times (at end a == 10)
end
for u=10,1,-1 do
a = u -- executes 10 times (at end a == 1)
endThe generic for loop works over functions called iterators. On each iteration, the iterator function is called to produce a new value, stopping when this new value is nil.
local a = 1
for k,v in ipairs {0,1,2,3,4,5,6,7,8,9} do
a = k + v -- executes 10 times (at end a == 10 + 9)
endsetmetatable(t, mt) function__add, __sub etc.__eq, __lt and __le.__index and __newindex__call__gc must be set from Cnlocal mtFibber = {}
function makeFibber(n)
local f = {n = n}
setmetatable(f, mtFibber)
return f
end
do
function mtFibber:__call()
local n = math.max(self.n,0)
local function _fib(fn2, fn1, at)
if at == n then
return fn1 + fn2
else
return _fib(fn1, fn1 + fn2, at+1)
end
end
if n <= 0 then return 0
elseif n == 1 then return 1
else return _fib(0, 1, 2) end
end
function mtFibber.__add(lhs, rhs) return makeFibber(lhs.n + rhs.n) end
function mtFibber.__sub(lhs, rhs) return makeFibber(lhs.n - rhs.n) end
function mtFibber:__newindex(k,v) assert(false, "can't add members") end
end
local f1 = makeFibber(10)
local f2 = makeFibber(5)
local f3 = makeFibber(100)
local f4 = (f3 + f2 - f1)
-- The 95th fibonacci is 3.194043463499e+019
print ("The " .. f4.n .. "nth fibonacci number is " .. f4())
IUP Dialog
require "iuplua"
require "iupluacontrols"
local label
local text = ""
local function onText(self)
text = string.upper(self.value)
end
local function modifyLabel(self)
if label then
label.title = text
end
end
dlg = iup.dialog
{
iup.vbox
{
iup.label{title = 'A silly little dialog', map_cb = function(self) label = self end},
iup.vbox
{
iup.hbox
{
iup.label{title='Write text', size="80"},
iup.text{size="80", valuechanged_cb = onText}
;margin="0", gap="10"
};
iup.hbox
{
iup.button{title="Ok",size="40", action = modifyLabel},
iup.button{title="Cancel",size="40" , action = function () return iup.CLOSE end}
;margin="0", gap="10"
};
}
;margin="5x5", gap="5"
}
;title="Some dialog", resize="NO"
}
dlg:popup()local cosmo = require "cosmo"
mycards = { {rank="Ace", suit="Spades"}
, {rank="Queen", suit="Diamonds"}
, {rank="10", suit="Hearts"}
}
template = "$do_cards[[$rank of $suit, ]]"
-- prints Ace of Spades, Queen of Diamonds, 10 of Hearts,
print (cosmo.fill(template, {do_cards = mycards}))local List = require 'pl.List'
local func = require 'pl.func'
print (List{10,20,30}:map(_1+1):reduce '+') -- prints 63 class = require 'pl.class'
class.Animal()
function Animal:_init(name)
self.name = name
end
function Animal:__tostring()
return self.name..': '..self:speak()
end
class.Dog(Animal)
function Dog:speak()
return 'bark'
end
class.Cat(Animal)
function Cat:_init(name,breed)
self:super(name) -- must init base!
self.breed = breed
end
function Cat:speak()
return 'meow'
end
fido = Dog('Fido')
felix = Cat('Felix','Tabby')
print(fido,felix) -- Fido: bark Felix: meow
print(felix:is_a(Animal) -- true
print(felix:is_a(Dog)) -- false
print(felix:is_a(Cat)) -- true-{extension "clist"}
-- integers from 2 to 50, by steps of 2:
x = { i for i = 2, 50, 2 }
-- the same, obtained by filtering over all integers <= 50:
y = { i for i = 1, 50 if i%2==0 }
-{extension 'match'}
match { { 'o', 'k', '!' } } with
| { t } -> match t with
| { a, b } -> print 'KO'
| { a, b, ... } -> print (a..b)
| _ -> print 'KO'
end
| _ -> print 'KO'
endFLiDataCompiler
{INCLUDE_PCH = [[#include "fliModelsPCH.h"]];
INCLUDE_LIB = [[#include "../fliModelsLib.h"]];
EXPORT_DECL = [[fliMODELS_API]];
INCLUDES = {"dmlGoalState.dsd", "dmlGoalChildrenConstraint.dsd", "dmlTrigger.dmd"};
[[ @brief Goals are a hierarchical way to define what an entity is required to achieve.
]];
MODEL = {"fli::act::DGoal";
[[@brief String used to categorize the goal with categories seperated by / also used to identify the goal]];
{"Category", {"string", 1}};
[[@brief The current active state of the goal]];
{"State", {"EGoalState", 2, default='GOAL_INACTIVE'}};
[[@brief Constrain how the goal's children become active when it is active]];
{"ChildrenConstraint", {"EGoalChildrenConstraint", 3, default="GOAL_CHILDREN_ACTIVE_CONCURRENTLY"}};
[[@brief Child goals]];
{"Children", {"array<DGoal>", 4}};
...
...
[[@brief The number of times the goal has passed]];
{"PassedCount", {"int32", 9, set=false}};
[[@brief The number of times the goal has failed]];
{"FailedCount", {"int32", 10, set=false}};
};
};fli_data.ScopeModelCreate()
local DoNotRegister = true -- Do not register with fli::data::CManager
-----------------------------------------------------
-- Scenario world
-----------------------------------------------------
-- Define the whole world for the scenario defining which extensions the world has as well as all the entities which are
-- present in the world.
return Root(fli__ent__DWorld("World"), DoNotRegister)
{
Extensions =
{
-- Extension that defines information related to the scenario but not a specific entity
fli__ent__DScenarioInfo
{
Name = "Tutorial_03_SimpleVehicle";
FocusEntity = RefModel("World:Entities.1");
};
};
Entities =
{
Import(assert(RelToData "FLiTutorials/Tutorial_03_SimpleVehicle/Scripts/Terrain.lua"))
{
InInitialTimeOfDay = 16 * 60 * 60;
};
Import(assert(RelToData "FLiTutorials/Tutorial_03_SimpleVehicle/Scripts/SimpleEntityOfTutorial2.lua"))
{
InName = "My Imported Entity";
InPhysicsEnableDebugDrawing = true;
InPosition = {x=-100;y=50;z=0;};
InOrientation = QuaternionToTable( OrientFromYPRd(0, 0, 0) );
InVisualColour = {r=0, g=1, b=0, a=1};
};
Import(assert(RelToData "FLiTutorials/Tutorial_03_SimpleVehicle/Scripts/SimpleEntityOfTutorial2.lua"))
{
InName = "My Second Imported Entity";
InPhysicsEnableDebugDrawing = true;
InPosition = {x=-100;y=50;z=10;};
InOrientation = QuaternionToTable( OrientFromYPRd(DEG_TO_RAD(60), 0, 0) );
InVisualColour = {r=0, g=1, b=1, a=1};
};
Import(assert(RelToData "FLiTutorials/Tutorial_03_SimpleVehicle/Scripts/SimpleEntityOfTutorial2.lua"))
{
InName = "My Third Imported Entity";
InPhysicsEnableDebugDrawing = true;
InPosition = {x=-110;y=50;z=10;};
InOrientation = QuaternionToTable( OrientFromYPRd(0, 0, DEG_TO_RAD(30)) );
InVisualColour = {r=1, g=0, b=1, a=0.5};
};
};
}
Comments