Lua Beginners Guide
Lua is a lightweight, high-level programming language designed for embedded use in applications. This guide covers the essential concepts you need to know to write Lua scripts in CoCoCo.
Variables and Data Types
Basic Variables
lua
-- Variables don't need type declarations
local name = "John Doe" -- String
local age = 30 -- Number (integer)
local price = 99.99 -- Number (float)
local is_active = true -- Boolean
local nothing = nil -- Nil (absence of value)
-- Local vs global variables
local x = 10 -- Local variable (recommended)
y = 20 -- Global variable (avoid when possible)
-- Multiple assignment
local a, b, c = 1, 2, 3
local x, y = y, x -- Swap valuesStrings
lua
-- String creation
local single = 'Single quotes'
local double = "Double quotes"
local multiline = [[
This is a
multiline string
]]
-- String concatenation
local first = "Hello"
local last = "World"
local message = first .. " " .. last -- "Hello World"
-- String functions
local text = "Hello World"
print(string.len(text)) -- 11
print(string.upper(text)) -- "HELLO WORLD"
print(string.lower(text)) -- "hello world"
print(string.sub(text, 1, 5)) -- "Hello"
print(string.find(text, "World")) -- 7, 11
print(string.gsub(text, "World", "Lua")) -- "Hello Lua"
-- String formatting
local formatted = string.format("Name: %s, Age: %d, Price: $%.2f",
"John", 30, 99.99)
-- "Name: John, Age: 30, Price: $99.99"Numbers
lua
-- All numbers are floating point
local integer = 42
local float = 3.14159
local scientific = 1.5e10
local hex = 0xff -- 255 in decimal
-- Arithmetic operations
local sum = 10 + 5 -- 15
local diff = 10 - 5 -- 5
local product = 10 * 5 -- 50
local quotient = 10 / 5 -- 2
local remainder = 10 % 3 -- 1
local power = 2 ^ 3 -- 8
-- Math functions
print(math.floor(3.7)) -- 3
print(math.ceil(3.2)) -- 4
print(math.abs(-5)) -- 5
print(math.sqrt(16)) -- 4
print(math.random()) -- Random between 0 and 1
print(math.random(1, 10)) -- Random integer between 1 and 10
print(math.min(3, 1, 5)) -- 1
print(math.max(3, 1, 5)) -- 5Tables (Arrays and Dictionaries)
Tables are Lua's only data structure and serve as arrays, dictionaries, and objects.
Arrays (Sequential Tables)
lua
-- Creating arrays (1-indexed!)
local fruits = {"apple", "banana", "orange"}
local numbers = {10, 20, 30, 40, 50}
-- Accessing elements (starts at 1, not 0!)
print(fruits[1]) -- "apple"
print(fruits[2]) -- "banana"
-- Adding elements
fruits[4] = "grape"
table.insert(fruits, "mango") -- Adds to end
table.insert(fruits, 2, "pear") -- Insert at position 2
-- Removing elements
table.remove(fruits) -- Removes last element
table.remove(fruits, 2) -- Removes element at position 2
-- Array length
print(#fruits) -- Number of elements
-- Iterating arrays
for i = 1, #fruits do
print(i, fruits[i])
end
-- Using ipairs for iteration
for index, value in ipairs(fruits) do
print(index, value)
endDictionaries (Associative Tables)
lua
-- Creating dictionaries
local person = {
name = "John Doe",
age = 30,
email = "john@example.com"
}
-- Alternative syntax
local product = {}
product.name = "Widget"
product.price = 99.99
product["in_stock"] = true
-- Accessing values
print(person.name) -- "John Doe"
print(person["age"]) -- 30
-- Nested tables
local company = {
name = "Acme Corp",
address = {
street = "123 Main St",
city = "Springfield",
zip = "12345"
},
employees = {
{name = "Alice", role = "Manager"},
{name = "Bob", role = "Developer"}
}
}
print(company.address.city) -- "Springfield"
print(company.employees[1].name) -- "Alice"
-- Iterating dictionaries
for key, value in pairs(person) do
print(key .. ": " .. tostring(value))
end
-- Checking if key exists
if person.phone then
print("Has phone")
else
print("No phone")
endControl Flow
If Statements
lua
local age = 18
if age >= 18 then
print("Adult")
else
print("Minor")
end
-- Multiple conditions
local score = 85
if score >= 90 then
print("A")
elseif score >= 80 then
print("B")
elseif score >= 70 then
print("C")
else
print("F")
end
-- Logical operators
local x = 10
local y = 20
if x > 5 and y < 30 then
print("Both conditions true")
end
if x > 100 or y > 15 then
print("At least one condition true")
end
if not (x == y) then
print("x is not equal to y")
end
-- Ternary-like operation (using and/or)
local status = age >= 18 and "adult" or "minor"Loops
lua
-- While loop
local count = 1
while count <= 5 do
print("Count: " .. count)
count = count + 1
end
-- Repeat-until loop (executes at least once)
local num = 0
repeat
num = num + 1
print("Number: " .. num)
until num >= 5
-- For loop (numeric)
for i = 1, 10 do
print(i)
end
-- For loop with step
for i = 0, 100, 10 do -- 0, 10, 20, ..., 100
print(i)
end
-- For loop (counting down)
for i = 10, 1, -1 do
print(i)
end
-- Break and continue (Lua doesn't have continue)
for i = 1, 10 do
if i == 5 then
break -- Exit loop
end
print(i)
end
-- Simulating continue with goto (Lua 5.2+)
for i = 1, 10 do
if i % 2 == 0 then
goto continue
end
print(i) -- Only prints odd numbers
::continue::
endFunctions
Basic Functions
lua
-- Function definition
function greet(name)
return "Hello, " .. name
end
-- Alternative syntax
local greet = function(name)
return "Hello, " .. name
end
-- Calling functions
local message = greet("World")
print(message) -- "Hello, World"
-- Multiple parameters
function add(a, b)
return a + b
end
local sum = add(5, 3) -- 8
-- Multiple return values
function divide(a, b)
local quotient = math.floor(a / b)
local remainder = a % b
return quotient, remainder
end
local q, r = divide(10, 3)
print("Quotient: " .. q .. ", Remainder: " .. r)
-- "Quotient: 3, Remainder: 1"
-- Variable arguments
function sum_all(...)
local args = {...}
local total = 0
for _, v in ipairs(args) do
total = total + v
end
return total
end
print(sum_all(1, 2, 3, 4, 5)) -- 15
-- Default parameters (using or)
function greet_with_default(name)
name = name or "Guest"
return "Hello, " .. name
end
print(greet_with_default()) -- "Hello, Guest"
print(greet_with_default("John")) -- "Hello, John"Anonymous Functions and Closures
lua
-- Anonymous function
local multiply = function(x, y)
return x * y
end
-- Functions as arguments
local function apply_operation(a, b, operation)
return operation(a, b)
end
local result = apply_operation(10, 5, function(x, y)
return x - y
end)
print(result) -- 5
-- Closures (functions that capture variables)
function create_counter()
local count = 0
return function()
count = count + 1
return count
end
end
local counter = create_counter()
print(counter()) -- 1
print(counter()) -- 2
print(counter()) -- 3
-- Higher-order functions
function map(array, func)
local result = {}
for i, v in ipairs(array) do
result[i] = func(v)
end
return result
end
local numbers = {1, 2, 3, 4, 5}
local doubled = map(numbers, function(x) return x * 2 end)
-- doubled = {2, 4, 6, 8, 10}Error Handling
lua
-- Protected calls with pcall
function risky_operation(x)
if x < 0 then
error("Cannot process negative numbers")
end
return math.sqrt(x)
end
-- Using pcall to catch errors
local success, result = pcall(risky_operation, -5)
if success then
print("Result: " .. result)
else
print("Error: " .. result) -- result contains error message
end
-- Custom error handling
function safe_divide(a, b)
if b == 0 then
return nil, "Division by zero"
end
return a / b, nil
end
local result, err = safe_divide(10, 0)
if err then
print("Error: " .. err)
else
print("Result: " .. result)
end
-- Assert for debugging
local function process_positive(n)
assert(n > 0, "Number must be positive")
return n * 2
end
-- Type checking
function process_string(s)
if type(s) ~= "string" then
error("Expected string, got " .. type(s))
end
return string.upper(s)
endCommon Patterns
Object-Oriented Programming
lua
-- Simple object creation
function create_person(name, age)
local person = {
name = name,
age = age
}
function person:greet()
return "Hello, I'm " .. self.name
end
function person:have_birthday()
self.age = self.age + 1
end
return person
end
local john = create_person("John", 30)
print(john:greet()) -- "Hello, I'm John"
john:have_birthday()
print(john.age) -- 31
-- Metatables for OOP
local Person = {}
Person.__index = Person
function Person.new(name, age)
local self = setmetatable({}, Person)
self.name = name
self.age = age
return self
end
function Person:greet()
return "Hello, I'm " .. self.name
end
local jane = Person.new("Jane", 25)
print(jane:greet())Module Pattern
lua
-- Creating a module
local MyModule = {}
local private_var = "hidden"
local function private_function()
return "private"
end
function MyModule.public_function()
return "public: " .. private_function()
end
MyModule.public_var = "visible"
return MyModuleUseful Tips
- Table indices start at 1, not 0 like most languages
- Use
localfor all variables to avoid polluting global scope - Functions are first-class values - they can be stored in variables and passed around
- Only
nilandfalseare falsy - 0 and empty strings are truthy! - Use
pairs()for all tables,ipairs()only for sequential arrays - String concatenation uses
..not+ - Comments use
--for single line and--[[ ]]for multiline