SLIDE 1
The Lua Programming Language Background Created in 1993 - - PowerPoint PPT Presentation
The Lua Programming Language Background Created in 1993 - - PowerPoint PPT Presentation
Pantea Haghighatkhah, Laurens Post, Jelle Mulyadi, Norico Groeneveld, Nina Schoeber January 18, 2018 The Lua Programming Language Background Created in 1993 Petrobras (Brazil) Foreign software restricted In-house
SLIDE 2
SLIDE 3
History of Lua
- Created in 1993
- Petrobras (Brazil)
- Foreign software restricted
- In-house software
1
SLIDE 4
Creation
- Replacement of internal languages
- Tcl, Perl & Forth unsuitable
- Intentionally minimal and forgiving
- Very little original syntax
2
SLIDE 5
Creation (II)
- High performance due to data visualization
- Highly portable
- Easy to embed and extend
3
SLIDE 6
Result
- Interpreter written in C
- Very small codebase
- Fully modular
4
SLIDE 7
Advantages of Lua
- Easy to learn
- Extensibility
Dynamic associative arrays Reflective facilities Fallbacks
- Very minimal, unused features removed
5
SLIDE 8
Influence
Influenced by:
- C++
- Scheme
Influences:
- Javascript
- Julia
- Ruby
6
SLIDE 9
Properties
SLIDE 10
Lua properties
- Imperative
- Dynamically typed
- Lexically scoped locals, but global by default
- Strict evaluation
- The usual call-by-reference / call-by-value distinction
7
SLIDE 11
Primitives
- Nil
- Number (double)
- String
- Boolean (since 5.0)
- Function
- Table
All are first-class No classes, no arrays, no structs, no enums, no static / public / private, no integers(ish)
8
SLIDE 12
Semantics
SLIDE 13
Semantics
- Chunk: A series of statements. Separation by ‘;’ is optional.
1
a = 1
2
b = a*2
1
a = 1;
2
b = a*2;
1
a = 1 ; b = a*2
1
a = 1 b = a*2
- Operations:
- Arithmetic: Addition +, subtraction -, multiplication *, unary - and power ̂.
- Relational: <, >, <=, >=, ==, ~= Comparison by reference.
- Logical: and, or, not, only false and nil are considered false.
9
SLIDE 14
Semantics: Assignments
- Multiple assignments: Evaluates first
1
a, b = 10, 2*x
2
x, y = y, x --swaps x and y
- Adjusts the number of values
1
a, b, c = 0, 1
2
print(a,b,c) --> 0 1 nil
3
a, b = a+1, b+1, b+2 -- b+2 is ignored
4
print(a,b)
- -> 1 2
10
SLIDE 15
Semantics: Assignments
- Local variables: Only by using “local” statement
1
a, b = 1 , 2
2
while a < b do
3
x = 10
4
a = b
5
end
6
print (x) --> 10
1
a, b = 1 , 2
2
while a < b do
3
local x = 10
4
a = b
5
end
6
print (x) --> nil
- Have local parameters in a chunk.
1
local x , y = 2, 10 -- both x and y are local
2
if x < y do
3
x = y -- x becomes 10
4
end
11
SLIDE 16
Semantics: Functions
- Functions can have multiple results:
1
function foo ()
2
return 1, 2
3
end
4
a , b = foo()
- Variable arguments:
1
function product (...)
2
r = 1
3
for i, v in ipars(...) do
4
r = r* v
5
end
6
return r
7
end
12
SLIDE 17
Semantics: Closure
- First class functions & Lexical scoping
1
function startCounting (t)
2
local i = t
3
return function ()
4
i = i+1
5
return i end
6
end
i is called an external local variable or an upvalue.
- Make closures
1
s1 = startCounting(0) -- pass the arguments needed
2
s2 = startCounting(7)
3
print(s1()) --> 1
4
print(s2()) --> 8
13
SLIDE 18
Closure: Iterator
- Iterators are closures.
- Keeps the state after successive calls.
- Two steps:
- A factory function.
1
ipairs(...)
- The closure.
14
SLIDE 19
Iterator: Example
Factory for lists
1
function list_iter (t)
2
local i = 0
3
local n = table.getn(t)
4
return function ()
5
i = i + 1
6
if i <= n then return t[i] end
7
end
8
end
Closure
1
t = {10, 20, 30}
2
- -creating the iterator (closure)
3
iter = list_iter(t)
4
while true do
5
- - calling the iterator
6
local element = iter()
7
if element == nil then break end
8
print(element)
9
end
15
SLIDE 20
Iterator: Example
More simple way:
1
t = {10, 20, 30}
2
for element in list_iter(t) do
3
print(element)
4
end
16
SLIDE 21
Semantics: Tail recursion
- Call to another function as last action:
1
function f(x)
2
return g(x)
3
end
- Stores no information from the calling function.
- No extra stack space for a tail call =
⇒ no stack overflow.
17
SLIDE 22
Error handling
SLIDE 23
Error handling: raising
Raising an error
1
n = getInput()
2
if not n then error("invalid input") end
1
n = assert(getInput(), "invalid input")
2
- - returns first argument if it's not false or nil
3
- - otherwise throws error with optional second argument as message
Mind the strict evaluation Don’t build an error message with string concatenation
- r use the explicit error test
18
SLIDE 24
Error handling: catching
Put code that may raise an error in a function Catch errors with pcall
1
success, value = pcall(foo, argument)
2
if success then
3
- - no errors while running foo, value is return value of foo
4
...
5
else
6
- - foo raised an error, value is error message
7
...
8
end
19
SLIDE 25
Error handling: blaming
Error because of invalid function call
1
function iNeedAString(str)
2
... -- do something that needs a string
3
end
4 5
maybeAString = 1
6
iNeedAString(maybeAString)
Where should you check, before calling or inside the called function?
20
SLIDE 26
Error handling: blaming
The error isn’t caused by the called function
1
function foo (str)
2
if type(str) ~= "string" then
3
error("string expected", 2)
4
end
5
...
6
end
2 Is passed as level in the calling hierarchy, to blame the caller Default is 1
21
SLIDE 27
Metaprogramming
SLIDE 28
Metaprogramming
1
f = load("i = i + 1")
2
i = 1
3
f()
4
print(i) -- 2
Any code can be used But only string representation Not designed for advanced purposes
22
SLIDE 29
Coroutines
SLIDE 30
Coroutines
No threats in Lua Coroutines are a bit like threads Threads can be run concurrently Program with coroutines can only run one coroutine at a time But a running coroutine is only suspended when requested
23
SLIDE 31
Coroutines
1
co = coroutine.create(function ()
2
print("I'm running")
3
end)
4 5
print(co)
- - thread: 0x02670ba8
6
print(coroutine.status(co)) -- suspended
7
coroutine.resume(co)
- - I'm running
8
print(coroutine.status(co)) -- dead
Suspended -> running -> dead Just a function?
24
SLIDE 32
Coroutines
Suspending execution
1
co = coroutine.create(function ()
2
for i=1,10 do
3
print("Running #", i)
4
coroutine.yield()
5
end
6
end)
7 8
print(coroutine.status(co)) -- suspended
9
coroutine.resume(co)
- - Running # 1
10
print(coroutine.status(co)) -- suspended
11
coroutine.resume(co)
- - Running # 2
12
...
13
coroutine.resume(co)
- - Running # 10
14
coroutine.resume(co) -- (error: cannot resume dead coroutine)
25
SLIDE 33
Coroutines: exchanging data
Passing data with resume
1
co = coroutine.create(function (arg)
2
print(arg)
3
end)
4
coroutine.resume(co, 1) -- 1
26
SLIDE 34
Coroutines: exchanging data
Passing data with yield or return
1
co = coroutine.create(function ()
2
coroutine.yield(1, 2, 3)
3
end)
4
print(coroutine.resume(co)) -- true 1 2 3
1
co = coroutine.create(function ()
2
return 1, 2, 3
3
end)
4
print(coroutine.resume(co)) -- true 1 2 3
27
SLIDE 35
Coroutines
Similar to generators in Python, but coroutines can be suspended from auxiliary functions Coroutines enable non-preemptive multithreading Explicit synchronization
28
SLIDE 36
Language structure
SLIDE 37
Tables
Dynamic associative arrays Main data structure No fixed size Constructor expression
1
a = {} -- Empty table
2
x = "y"
3
a.x = 5 -- a["x"] = 5
4
a[x] = 10 -- a["y"] = 10
29
SLIDE 38
Tables
Dynamic associative arrays Main data structure No fixed size Constructor expression
1
a = {} -- Empty table
2
x = "y"
3
a.x = 5 -- a["x"] = 5
4
a[x] = 10 -- a["y"] = 10
29
SLIDE 39
Object Oriented Programming
Metatables Fallback methods Inheritance Overriding
30
SLIDE 40
Metatables
1
- - Prototype
2
Rectangle = {x = 5, -- default x
3
y = 10, -- default y
4
scale = function(self, factor)
5
self.x = self.x * factor
6
self.y = self.y * factor
7
end}
8 9
- - Constructor
10
function Rectangle:new(o)
11
- = o or {}
12
setmetatable(o, self)
13
self._index = self
14
return o
15
end
31
SLIDE 41
Metatables
1
- - Prototype
2
Rectangle = {x = 5, -- default x
3
y = 10, -- default y
4
scale = function(self, factor)
5
self.x = self.x * factor
6
self.y = self.y * factor
7
end}
8 9
- - Constructor
10
function Rectangle:new(o)
11
- = o or {}
12
setmetatable(o, self)
13
self._index = self
14
return o
15
end
31
SLIDE 42
Inheritance and overriding
1
myRectangle = Rectangle:new{x = 20} -- Table {x = 20} with metatable Rectangle
2
print(myRectangle.x) -- 20, overriden x
3
print(myRectangle.y) -- 10, default y, inherited from Rectangle
32
SLIDE 43
Garbage collection
Weak tables Do not prevent garbage collection
1
t = {}
2
setmetatable(t, {__mode = 'v'}) -- Weak values
3
setmetatable(t, {__mode = 'k'}) -- Weak keys
Example
1
do
2
local val = {}
3
t[key] = val
4
end
5
collectgarbage() -- Cannot collect 'val' unless weak values are enabled
33
SLIDE 44
Embedding
SLIDE 45
Why embed Lua?
- Allow extension
- Simplification
- Compiled at run-time
- Configuration and customization
- Example extension: AddOns in World of Warcraft
34
SLIDE 46
Communication between C and Lua
- C API
- Problem: Mismatch
- Dynamic vs static typing
- Automatic vs manual memory management
- Solution: Stack
- Seperate functions for pushing and recieving
- Stack managed by Lua
35
SLIDE 47
Exchanging values between C and stack
1
lua_push*()
2
lua_is*(int index)
3
lua_to*(int index)
(* can be any Lua type)
36
SLIDE 48
Calling Lua to push value
1
lua_getglobal(const char *name)
2
lua_setglobal(const char *name)
37
SLIDE 49
Generic operations
1
lua_gettop
2
lua_settop(int index)
3
lua_pushvalue(int index)
4
lua_pop(int n)
5
lua_remove(int index)
6
lua_insert(int index)
7
lua_replace(int index)
38
SLIDE 50
Example code: Simple configuration
1
- - Configuration file: crypto.lua
2
bitcoin = 2
3
ethereum = 20
1
lua_State *L = lua_open(); -- Opens the Lua package
2
luaL_loadfile(L, crypto.lua) -- Loads Lua chunk
3
lua_pcall(L, 0, 0, 0) -- Pops chunk and runs it
4 5
lua_getglobal(L, "bitcoin");
6
lua_getglobal(L, "ethereum");
7
*bitcoin = (int)lua_tonumber(L, -2);
8
*ethereum = (int)lua_tonumber(L, -1);
9
lua_close(L);
39
SLIDE 51
Example code: Simple function call
1
function cryptomillionaire (x)
2
if x >= 1000000 then
3
return 1
4
end
5
end
1
lua_getglobal(L, "cryptomillionaire");
2
lua_pushnumber(L, 30000);
3
lua_pcall(L, 1, 1, 0); -- call cryptomillionaire 1 argument, 1 result
4
z = lua_tonumber(L, -1);
5
lua_pop(L, 1);
40
SLIDE 52
Calling C from Lua
- C as library code
- Similar protocol
- Must register the function
- Can be defined as library
- Interface for C functions
- Private stacks
41
SLIDE 53
Simple example from the book
1
- - typedef int (*lua_CFunction) (lua_State *L) prototype must be
followed
2
static int l_sin(lua_State *L){
3
double d = lua_tonumber(L, 1);
4
lua_pushnumber(L, sin(d));
5
return 1;
6
}
1
lua_pushcfunction(L, l_sin)
2
lua_setglobal(l, "mysin")
42
SLIDE 54
Summarized
Lua is an
- embedded language
- extension language
- extensible language
43
SLIDE 55