Difference between revisions of "Lua"

From TRCCompSci - AQA Computer Science
Jump to: navigation, search
(Comments)
(Conditional)
 
(38 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
=Comments=
 
=Comments=
 +
Lua implements comments by:
 +
 
<syntaxhighlight lang=lua>
 
<syntaxhighlight lang=lua>
 
-- Two dashes start a one-line comment.
 
-- Two dashes start a one-line comment.
Line 8: Line 10:
 
--]]
 
--]]
  
 +
</syntaxhighlight>
 +
 +
=Write to Console=
 +
Lua provides 2 ways to write to the console:
 +
 +
<syntaxhighlight lang=lua>
 +
print("helloworld")
 +
io.write('helloworld')
 +
</syntaxhighlight>
 +
 +
===Escape Characters===
 +
These can also include escape characters in the string, eg '\n':
 +
 +
<syntaxhighlight lang=lua>
 +
io.write('helloworld\n')
 +
</syntaxhighlight>
 +
 +
=Read from Console=
 +
Lua can read from the keyboard (ie Console.ReadLine() in C# or input() in Python), you can also convert this input to a number:
 +
 +
<syntaxhighlight lang=lua>
 +
input = io.read()
 +
-- Convert input to a number
 +
num = tonumber(io.read())
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
=Variables=
 
=Variables=
 +
Lua uses variables similar to python, you don't need to specify a data type:
 
===Numbers===
 
===Numbers===
 +
<syntaxhighlight lang=lua>
 
num = 42  -- All numbers are doubles.
 
num = 42  -- All numbers are doubles.
 +
</syntaxhighlight>
  
 
===Strings===
 
===Strings===
 +
<syntaxhighlight lang=lua>
 
s = 'walternate'  -- Immutable strings like Python.
 
s = 'walternate'  -- Immutable strings like Python.
 
t = "double-quotes are also fine"
 
t = "double-quotes are also fine"
Line 20: Line 50:
 
       start and end
 
       start and end
 
       multi-line strings.]]
 
       multi-line strings.]]
 +
-- String concatenation uses the .. operator:
 +
message = 'Winter is coming, ' .. line
 +
</syntaxhighlight>
  
 
===Empty / Null===
 
===Empty / Null===
 +
<syntaxhighlight lang=lua>
 
t = nil  -- Undefines t; Lua has garbage collection.
 
t = nil  -- Undefines t; Lua has garbage collection.
 +
</syntaxhighlight>
  
 
+
===Global Variables===
 
+
The default in Lua is that all variables are global (in python all variables are local):
-- If clauses:
+
<syntaxhighlight lang=lua>
if num > 40 then
 
  print('over 40')
 
elseif s ~= 'walternate' then  -- ~= is not equals.
 
  -- Equality check is == like Python; ok for strs.
 
  io.write('not over 40\n') -- Defaults to stdout.
 
else
 
 
   -- Variables are global by default.
 
   -- Variables are global by default.
 
   thisIsGlobal = 5  -- Camel case is common.
 
   thisIsGlobal = 5  -- Camel case is common.
 +
</syntaxhighlight>
 +
 +
===Local Variables===
 +
To specify a variable is only local, you need to include 'local' before the variable name:
  
 +
<syntaxhighlight lang=lua>
 
   -- How to make a variable local:
 
   -- How to make a variable local:
 
   local line = io.read()  -- Reads next stdin line.
 
   local line = io.read()  -- Reads next stdin line.
 +
</syntaxhighlight>
 +
 +
=If Statement=
 +
Lua implements IF statements, but doesn't implement a Switch Case statement. An example if is shown below:
  
   -- String concatenation uses the .. operator:
+
<syntaxhighlight lang=lua>
   print('Winter is coming, ' .. line)
+
if num < 40 then
 +
  print('below 40')
 +
elseif name ~= 'wayne' then 
 +
   -- ~= is not equals.
 +
  -- Equality check is == like Python; ok for strs.
 +
   io.write('over 40 and Name is wayne\n')  -- Defaults to stdout.
 +
else
 +
  print('above 40')
 
end
 
end
 +
</syntaxhighlight>
  
-- Undefined variables return nil.
+
=Operators=
-- This is not an error:
+
Within if statements and also within loops, the following relational and conditional operates exist:
foo = anUnknownVariable  -- Now foo = nil.
 
  
aBoolValue = false
+
===Relational===
 +
{| class="wikitable"
 +
|-
 +
! Symbols !! Explanation
 +
|-
 +
| == || Equal
 +
|-
 +
| ~= || Not equal
 +
|-
 +
| <= || Less than or equal
 +
|-
 +
| >= || Greater than or equal
 +
|-
 +
| < || Less than
 +
|-
 +
| > || Greater than
 +
|}
 +
===Conditional===
 +
{| class="wikitable"
 +
|-
 +
! Operator !!Description !! Example
 +
|-
 +
| and || Called Logical AND operator. If both the operands are non zero then condition becomes true.||(A and B) is false
 +
|-
 +
| or || Called Logical OR Operator. If any of the two operands is non zero then condition becomes true. || (A or B) is true.
 +
|-
 +
| not || Called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false. || not(A and B) is true.
 +
|}
  
-- Only nil and false are falsy; 0 and '' are true!
+
=Loops=
if not aBoolValue then print('twas false') end
+
Just like other languages Lua has the standard 3 types of loop. While will run 0 or more times (may never run), Repeat will run at least once, For will run an exact number of times:
  
-- 'or' and 'and' are short-circuited.
+
===While===
-- This is similar to the a?b:c operator in C/js:
+
<syntaxhighlight lang=lua>
ans = aBoolValue and 'yes' or 'no'  --> 'no'
 
 
 
=Loops=
 
==While==
 
 
-- Blocks are denoted with keywords like do/end:
 
-- Blocks are denoted with keywords like do/end:
 
while num < 50 do
 
while num < 50 do
 
   num = num + 1  -- No ++ or += type operators.
 
   num = num + 1  -- No ++ or += type operators.
 
end
 
end
 +
</syntaxhighlight>
  
==For==
+
===For===
 +
<syntaxhighlight lang=lua>
 
karlSum = 0
 
karlSum = 0
 
for i = 1, 100 do  -- The range includes both ends.
 
for i = 1, 100 do  -- The range includes both ends.
Line 71: Line 141:
 
-- Use "100, 1, -1" as the range to count down:
 
-- Use "100, 1, -1" as the range to count down:
 
fredSum = 0
 
fredSum = 0
for j = 100, 1, -1 do fredSum = fredSum + j end
+
for j = 100, 1, -1 do  
 +
  fredSum = fredSum + j  
 +
end
  
 
-- In general, the range is begin, end[, step].
 
-- In general, the range is begin, end[, step].
 +
</syntaxhighlight>
  
==Repeat / Do While==
+
===Repeat / Do While===
 +
<syntaxhighlight lang=lua>
 
-- Another loop construct:
 
-- Another loop construct:
 
repeat
 
repeat
Line 81: Line 155:
 
   num = num - 1
 
   num = num - 1
 
until num == 0
 
until num == 0
 +
</syntaxhighlight>
  
 +
=Functions=
 +
===Declaring a function===
 +
You can declare a function using the command 'function', the parameters will be within the round brackets '()'. The use of 'local' is not really required:
 +
<syntaxhighlight lang=lua>
 +
local function add(first_number, second_number)
 +
print(first_number + second_number)
 +
end
  
=Functions=
+
add(2, 3) -- calling a method
 +
</syntaxhighlight>
 +
 
 +
===Returning a value===
 +
You can return a value from a function by using 'return'
 +
<syntaxhighlight lang=lua>
 +
local function add(first_number, second_number)
 +
return first_number + second_number
 +
end
 +
 
 +
print(add(5, 6))
 +
</syntaxhighlight>
 +
 
 +
=Classes - Table Based=
 +
Just like other programming languages, Lua is can be used in an OOP way. Lua calls '{}' tables or meta tables, but they are the same as a class really:
 +
 
 +
===Define a class===
 +
<syntaxhighlight lang=lua>
 +
-- Meta class, class defined with {}, variables can be set like 'area'
 +
Shape = {area = 0}
 +
 
 +
-- Base class is named, followed by ':' to create a method for the class
 +
function Shape:new (o,side)
 +
  o = o or {} -- if an object is passed, use it or create an empty one
 +
  setmetatable(o, self)
 +
  self.__index = self
 +
  side = side or 0 -- if side is passed, use it or set side to 0
 +
  self.area = side*side;
 +
  return o
 +
end
 +
 
 +
-- Base class method printArea
 +
function Shape:printArea ()
 +
  print("The area is ",self.area)
 +
end
 +
</syntaxhighlight>
 +
 
 +
===Creating an object===
 +
<syntaxhighlight lang=lua>
 +
-- Creating an object
 +
myshape = Shape:new(nil,10)
 +
 
 +
--to access the methods of the object you need to use ':'
 +
myshape:printArea()
 +
</syntaxhighlight>
 +
 
 +
===Inheritance===
 +
<syntaxhighlight lang=lua>
 +
Square = Shape:new()
 +
 
 +
-- Derived class method new
 +
 
 +
function Square:new (o,side)
 +
  o = o or Shape:new(o,side) -- if an object is passed, use it or create a new shape
 +
  setmetatable(o, self)
 +
  self.__index = self
 +
  return o
 +
end
 +
</syntaxhighlight>
 +
 
 +
You can override an inherited method by redeclaring it:
 +
<syntaxhighlight lang=lua>
 +
-- Derived class method printArea
  
function fib(n)
+
function Square:printArea ()
  if n < 2 then return 1 end
+
  print("The area of square is ",self.area)
  return fib(n - 2) + fib(n - 1)
 
 
end
 
end
 +
</syntaxhighlight>
  
-- Closures and anonymous functions are ok:
+
=Classes - Closure Based=
function adder(x)
+
Lua can implement classes in a second way:
   -- The returned function is created when adder is
+
===Define a Class===
   -- called, and remembers the value of x:
+
<syntaxhighlight lang=lua>
   return function (y) return x + y end
+
function MyClass(init)
 +
   -- the new instance
 +
  local self = {
 +
    -- public fields go in the instance table
 +
    public_field = 0
 +
  }
 +
 
 +
  -- private fields are implemented using locals
 +
   -- they are faster than table access, and are truly private, so the code that uses your class can't get them
 +
  local private_field = init
 +
 
 +
   function self.foo()
 +
    return self.public_field + private_field
 +
  end
 +
 
 +
  function self.bar()
 +
    private_field = private_field + 1
 +
  end
 +
 
 +
  -- return the instance
 +
  return self
 
end
 
end
a1 = adder(9)
+
</syntaxhighlight>
a2 = adder(36)
+
 
print(a1(16)) --> 25
+
===Creating an Object===
print(a2(64))  --> 100
+
Creating and using an instance can be done with:
 +
 
 +
<syntaxhighlight lang=lua>
 +
local i = MyClass(5)
 +
print(i.foo()) --> 5
 +
i.public_field = 3
 +
i.bar()
 +
</syntaxhighlight>
  
-- Returns, func calls, and assignments all work
+
===Inheritance===
-- with lists that may be mismatched in length.
+
This is the base class, and below a subclass derived from it:
-- Unmatched receivers are nil;
 
-- unmatched senders are discarded.
 
  
x, y, z = 1, 2, 3, 4
+
<syntaxhighlight lang=lua>
-- Now x = 1, y = 2, z = 3, and 4 is thrown away.
+
function BaseClass(init)
 +
  local self = {}
  
function bar(a, b, c)
+
  local private_field = init
   print(a, b, c)
+
 
   return 4, 8, 15, 16, 23, 42
+
  function self.foo()
 +
    return private_field
 +
   end
 +
 
 +
  function self.bar()
 +
    private_field = private_field + 1
 +
  end
 +
 
 +
  -- return the instance
 +
   return self
 
end
 
end
  
x, y = bar('zaphod') --> prints "zaphod  nil nil"
+
function DerivedClass(init, init2)
-- Now x = 4, y = 8, values 15..42 are discarded.
+
  local self = BaseClass(init)
  
-- Functions are first-class, may be local/global.
+
  -- Public fields can be added to the derived version
-- These are the same:
+
  self.public_field = init2
function f(x) return x * x end
 
f = function (x) return x * x end
 
  
-- And so are these:
+
  -- this is independent from the base class's private field that has the same name
local function g(x) return math.sin(x) end
+
  -- the derived value would be self.private_field
local g; g  = function (x) return math.sin(x) end
+
  local private_field = init2
-- the 'local g' decl makes g-self-references ok.
 
  
-- Trig funcs work in radians, by the way.
+
  -- save the base version of foo for use in the derived version
 +
  local base_foo = self.foo
  
-- Calls with one string param don't need parens:
+
  -- this function overrides the derived version
print 'hello'  -- Works fine.
+
  function self.foo()
 +
    return private_field + self.public_field + base_foo()
 +
  end
 +
 
 +
  -- return the instance
 +
  return self
 +
end
 +
</syntaxhighlight>

Latest revision as of 10:26, 4 July 2019

Comments

Lua implements comments by:

-- Two dashes start a one-line comment.

--[[
     Adding two ['s and ]'s makes it a
     multi-line comment.
--]]

Write to Console

Lua provides 2 ways to write to the console:

print("helloworld")
io.write('helloworld')

Escape Characters

These can also include escape characters in the string, eg '\n':

io.write('helloworld\n')

Read from Console

Lua can read from the keyboard (ie Console.ReadLine() in C# or input() in Python), you can also convert this input to a number:

input = io.read()
-- Convert input to a number
num = tonumber(io.read())

Variables

Lua uses variables similar to python, you don't need to specify a data type:

Numbers

num = 42  -- All numbers are doubles.

Strings

s = 'walternate'  -- Immutable strings like Python.
t = "double-quotes are also fine"
u = [[ Double brackets
       start and end
       multi-line strings.]]
-- String concatenation uses the .. operator:
message = 'Winter is coming, ' .. line

Empty / Null

t = nil  -- Undefines t; Lua has garbage collection.

Global Variables

The default in Lua is that all variables are global (in python all variables are local):

  -- Variables are global by default.
  thisIsGlobal = 5  -- Camel case is common.

Local Variables

To specify a variable is only local, you need to include 'local' before the variable name:

  -- How to make a variable local:
  local line = io.read()  -- Reads next stdin line.

If Statement

Lua implements IF statements, but doesn't implement a Switch Case statement. An example if is shown below:

if num < 40 then
  print('below 40')
elseif name ~= 'wayne' then  
  -- ~= is not equals.
  -- Equality check is == like Python; ok for strs.
  io.write('over 40 and Name is wayne\n')  -- Defaults to stdout.
else
  print('above 40')
end

Operators

Within if statements and also within loops, the following relational and conditional operates exist:

Relational

Symbols Explanation
== Equal
~= Not equal
<= Less than or equal
>= Greater than or equal
< Less than
> Greater than

Conditional

Operator Description Example
and Called Logical AND operator. If both the operands are non zero then condition becomes true. (A and B) is false
or Called Logical OR Operator. If any of the two operands is non zero then condition becomes true. (A or B) is true.
not Called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false. not(A and B) is true.

Loops

Just like other languages Lua has the standard 3 types of loop. While will run 0 or more times (may never run), Repeat will run at least once, For will run an exact number of times:

While

-- Blocks are denoted with keywords like do/end:
while num < 50 do
  num = num + 1  -- No ++ or += type operators.
end

For

karlSum = 0
for i = 1, 100 do  -- The range includes both ends.
  karlSum = karlSum + i
end

-- Use "100, 1, -1" as the range to count down:
fredSum = 0
for j = 100, 1, -1 do 
   fredSum = fredSum + j 
end

-- In general, the range is begin, end[, step].

Repeat / Do While

-- Another loop construct:
repeat
  print('the way of the future')
  num = num - 1
until num == 0

Functions

Declaring a function

You can declare a function using the command 'function', the parameters will be within the round brackets '()'. The use of 'local' is not really required:

local function add(first_number, second_number)
	print(first_number + second_number)
end

add(2, 3) -- calling a method

Returning a value

You can return a value from a function by using 'return'

local function add(first_number, second_number)
	return first_number + second_number
end

print(add(5, 6))

Classes - Table Based

Just like other programming languages, Lua is can be used in an OOP way. Lua calls '{}' tables or meta tables, but they are the same as a class really:

Define a class

-- Meta class, class defined with {}, variables can be set like 'area'
Shape = {area = 0} 

-- Base class is named, followed by ':' to create a method for the class
function Shape:new (o,side)
   o = o or {} -- if an object is passed, use it or create an empty one
   setmetatable(o, self)
   self.__index = self
   side = side or 0 -- if side is passed, use it or set side to 0
   self.area = side*side;
   return o
end

-- Base class method printArea
function Shape:printArea ()
   print("The area is ",self.area)
end

Creating an object

-- Creating an object
myshape = Shape:new(nil,10)

--to access the methods of the object you need to use ':'
myshape:printArea()

Inheritance

Square = Shape:new()

-- Derived class method new

function Square:new (o,side)
   o = o or Shape:new(o,side) -- if an object is passed, use it or create a new shape
   setmetatable(o, self)
   self.__index = self
   return o
end

You can override an inherited method by redeclaring it:

-- Derived class method printArea

function Square:printArea ()
   print("The area of square is ",self.area)
end

Classes - Closure Based

Lua can implement classes in a second way:

Define a Class

function MyClass(init)
  -- the new instance
  local self = {
    -- public fields go in the instance table
    public_field = 0
  }

  -- private fields are implemented using locals
  -- they are faster than table access, and are truly private, so the code that uses your class can't get them
  local private_field = init

  function self.foo()
    return self.public_field + private_field
  end

  function self.bar()
    private_field = private_field + 1
  end

  -- return the instance
  return self
end

Creating an Object

Creating and using an instance can be done with:

local i = MyClass(5)
print(i.foo()) --> 5
i.public_field = 3
i.bar()

Inheritance

This is the base class, and below a subclass derived from it:

function BaseClass(init)
  local self = {}

  local private_field = init

  function self.foo()
    return private_field
  end

  function self.bar()
    private_field = private_field + 1
  end

  -- return the instance
  return self
end

function DerivedClass(init, init2)
  local self = BaseClass(init)

  -- Public fields can be added to the derived version
  self.public_field = init2

  -- this is independent from the base class's private field that has the same name
  -- the derived value would be self.private_field
  local private_field = init2

  -- save the base version of foo for use in the derived version
  local base_foo = self.foo

  -- this function overrides the derived version
  function self.foo() 
    return private_field + self.public_field + base_foo()
  end

  -- return the instance
  return self
end