Lua Standard Library
The tables and functions documented in here should be considered an extension to the standard Lua library, in some cases replacing those implementations with better or more flexible implementations. As such they adhere to the normal Lua naming conventions.
The Lua standard library isn't automatically imported at program startup time any longer, so if you want to use these facilities you'll need to import them. You can either use:
require "std"
to get them all or import the individual modules as needed after loading support for the new std.import module via:
require "std.import"
You must require at least one of these modules or the other standard library modules will fail to load due to the missing import function.
Unfortunately the implementation of require in Strata Design 3D CX version 6.0 and 6.0.1 is broken for file names with dot '.' separators, so the Lua standard library isn't usable until later. Once that's fixed we'll move the following text between double dividers into the reference documentation home page.
Another open source effort which has been integrated into the Strata implementation of the Lua language. Most of its functionality is available immediately at application launch time.
Although there really isn't a Lua standard library per se, this early effort has some nice elements.
Assertions and Warnings
import "std.assert"
assert (v, ...)
Extend to allow formatted arguments
v: value
...: arguments for format
returns
v: value
warn (...)
Give warning with the name of program and file (if any)
...: arguments for format
die (...)
Die with error
...: arguments for format
Base
import "std.base"
metamethod (x, n)
Return given metamethod, if any, or nil
x: object to get metamethod of
n: name of metamethod to get
returns
m: metamethod function or nil if no metamethod or not a function
print (arg)
Make print use tostring, so that improvements to tostring are picked up.
arg: objects to print
tostring (x)
Extend tostring to work better on tables
x: object to convert to string
returns
s: string representation
totable (x)
Turn an object into a table according to __totable metamethod.
x: object to turn into a table
returns
t: table or nil
pickle (x)
Convert a value to a string. The string can be passed to dostring to retrieve the value. Does not work for recursive tables.
x: object to pickle
returns
s: string such that eval (s) is the same value as x
id (...)
Identity, returns exactly what was passed.
...: the arguments to be returned
returns
...: the arguments passed to the function
pack (...)
Turn a tuple into a list
...: tuple
returns
l: list
bind (f, a1 ... an)
Partially apply a function
f: function to apply partially
a1 ... an: arguments to bind
returns
g: function with ai already bound
curry (f, n)
Curry a function
f: function to curry
n: number of arguments
returns
g: curried version of f
compose (f1 ... fn)
Compose functions
f1 ... fn: functions to compose
returns
g: composition of f1 ... fn
With each function taking as an argument the result of the next function,
and with fn taking the arguments passed to the result g
args: arguments
returns
f1 (... fn (args) ...)
eval (s)
Evaluate a string
s: string
returns
v: value of string
listable (f)
Make a function which can take its arguments as a list.
f: function (if it only takes one argument, it must not be a table)
returns
g: function that can take its arguments either as normal or in a list
pathSubscript (t, s)
Subscript a table with a string containing dots.
t: table
s: subscript of the form s1.s2. ... .sn
returns
v: t.s1.s2. ... .sn
lookup (t, l)
Do a late-bound table lookup
t: table to look up in
l: list of indices {l1 ... ln}
returns
u: t[l1] ... [ln]
Bitwise Logic
import "std.bit"
bit.even (n)
Returns true if n is even, false otherwise
n: an integer value
returns
r: the boolean result
bit.odd (n)
Returns true if n is odd, false otherwise
n: an integer value
returns
r: the boolean result
bit.bnot (n)
Computes the bit-wise "not" of n
n: an integer value
returns
r: the integer result
bit.band (n1 ... nn)
Computes the bit-wise "and" of all the integer parameters
n1 ... nn: integer values
returns
r: the integer result
bit.bor (n1 ... nn)
Computes the bit-wise "or" of all the integer parameters
n1 ... nn: integer values
returns
r: the integer result
bit.bxor (n1 ... nn)
Computes the bit-wise "xor" of all the integer parameters
n1 ... nn: integer values
returns
r: the integer result
bit.lshift (n, m)
Computes the left shifted integer value n by m places
n: the integer value to left shift
m: the number of bit positions to shift over
returns
r: the integer result
bit.rshift (n, m)
Computes the right shifted integer value n by m places
n: the integer value to right shift
m: the number of bit positions to shift over
returns
r: the integer result
bit.arshift (n, m)
Computes the arithmetic right shifted integer value n by m places
n: the integer value to arithmetically right shift
m: the number of bit positions to shift over
returns
r: the integer result
bit.mod (n, m)
Computes the modulo remainder of the integer value n divided by m
n: the integer value numerator
m: the integer value denominator
returns
r: the integer result
Debugging
import "std.debug"
debug.say ([n], ...)
Print a debugging message
[n]: debugging level [1]
...: objects to print (as for print)
debug.traceCall (event)
Trace function calls
event: event causing the call
Use debug.sethook (debug.traceCall, "cr") before a function call to trace the execution of that call.
The debug table also has a metatable entry __call set to debug.say so that calling debug() is the same as calling debug.say()
Files
import "std.io"
or
import "std.io.file"
io.length (f)
Find the length of a file
f: file name
returns
len: length of file
io.exists (f)
Finds whether a file exists
f: file name
returns
r: non-nil if f exists, nil otherwise
Input/Output
import "std.io"
or
import "std.io.io"
io.readLines ([h])
Read a file into a list of lines and close it
[h]: file handle or name [io.input ()]
returns
l: list of lines
io.writeLine ([h], ...)
Write values adding a newline after each line
[h]: file handle [io.output ()]
...: values to write (as for write)
io.changeSuffix (from, to, name)
Change the suffix of a filename
from: suffix to change (".-" for any suffix)
to: suffix to replace with
name: file name to change
returns
name_: file name with new suffix
io.addSuffix (suff, name)
Add a suffix to a filename if not already present
suff: suffix to add
name: file name to change
returns
name_: file name with new suffix
LCS Algorithm
After pseudo-code in http://www.ics.uci.edu/~eppstein/161/960229.html Lecture notes by David Eppstein, eppstein@ics.uci.edu
The interface provided by this module is a little unwieldy at first glance, but is quite easy to use: the best way is probably to define a wrapper for lcs.longestCommonSubseq for each type on which you wish to use it.
I used function parameters rather than metamethods because strings don't have metamethods and there is no standard length metamethod.
import "std.algorithm"
or
import "std.algorithm.lcs"
lcs.commonSubseqs (a, b, sub, len)
find common subsequences
a, b: two sequences of type T
sub (s, i):
subscription operator on T
s: a sequence of type T
i: a number
returns
e: the ith element of s
len (s):
length operator on T
s: a sequence of type T
returns
l: the length of s
returns
l_: list of common subsequences
m: the length of a
n: the length of b
lcs.longestCommonSubseq (a, b, sub, len, concat, s)
find the LCS of two sequences
a, b: two sequences of some type T
sub (s, i):
subscription operator on T
s: a sequence of type T
i: a number
returns
e: the ith element of s
len (s):
length operator on T
s: a sequence of type T
returns
l: the length of s
concat (s, t):
concatenation operator on T
s, t: two sequences of type T
returns
u: t appended to s
s: an empty sequence of type T
returns
s_: the LCS of a and b
Lists
import "std.list"
list.cons (x, l)
Prepend an item to a list
x: item
l: list
returns
r: {x, unpack (l)}
list.append (x, l)
Append an item to a list
x: item
l: list
returns
r: {unpack (l), x}
list.map (f, l)
Map a function over a list
f: function
l: list
returns
m: result list {f (l[1]) ... f (l[table.getn (l)])}
list.mapWith (f, ls)
Map a function over a list of lists
f: function
ls: list of lists
returns
m: result list {f (unpack (ls[1]))) ... f (unpack (ls[table.getn (ls)]))}
list.filter (p, l)
Filter a list according to a predicate
p (a):
Predicate function
a: argument
returns
f: flag
l: list
returns
m: result list containing elements e of l for which p (e) is true
list.slice (l, [from], [to])
Slice a list
l: list
[from], [to]: start and end of slice from defaults to 1 and to to table.getn (l); negative values count from the end
returns
m: {l[from] ... l[to]}
list.tail (l)
Return a list with its first element removed
l: list
returns
m: {l[2] ... l[table.getn (l)]}
list.foldl (f, e, l)
Fold a binary function through a list left associatively
f: function
e: element to place in left-most position
l: list
returns
r: result
list.foldr (f, e, l)
Fold a binary function through a list right associatively
f: function
e: element to place in right-most position
l: list
returns
r: result
list.concat (l1, l2, ... ln)
Concatenate lists
l1, l2, ... ln: lists
returns
r: result {l1[1] ... l1[table.getn (l1)], ... , ln[1] ... ln[table.getn (ln)]}
list.reverse (l)
Reverse a list
l: list
returns
m: list {l[table.getn (l)] ... l[1]}
list.transpose (ls)
Transpose a list of lists
ls: {{l11 ... l1c} ... {lr1 ... lrc}}
returns
ms: {{l11 ... lr1} ... {l1c ... lrc}} Also give aliases list.zip and list.unzip
list.zipWith (f, ls)
Zip lists together with a function
f: function
ls: list of lists
returns
m: {f (ls[1][1] ... ls[table.getn (ls)][1]) ... f (ls[1][N] ... ls[table.getn (ls)][N]) where N = max {list.map (table.getn, ls)}
list.project (f, l)
Project a list of fields from a list of tables
f: field to project
l: list of tables
returns
m: list of f fields
list.enpair (t)
Turn a table into a list of pairs
t: table {i1=v1 ... in=vn}
returns
ls: list {{i1, v1} ... {in, vn}}
list.depair (ls)
Turn a list of pairs into a table
ls: list {{i1, v1} ... {in, vn}}
returns
t: table {i1=v1 ... in=vn}
list.indexKey (f, l)
Make an index of a list of tables on a given field
f: field
l: list of tables {t1 ... tn}
returns
ind: index {t1[f]=1 ... tn[f]=n}
list.indexValue (f, l)
Copy a list of tables, indexed on a given field
f: field whose value should be used as index
l: list of tables {i1=t1 ... in=tn}
returns
m: index {t1[f]=t1 ... tn[f]=tn}
list.lcs (a, b)
Find the longest common subsequence of two lists
a, b: lists
returns
l: LCS of a and b
Math
import "std.math"
math._INTEGER_BITS
Calculated number of bits in an integer
math.max (l or v1 ... vn)
Extend to work on lists
l: list
or
v1 ... vn: values
returns
m: max value
math.min (l or v1 ... vn)
Extend to work on lists
l: list
or
v1 ... vn: values
returns
m: min value
math.floor (n, [p])
Extend to take the number of decimal places
n: number
[p]: number of decimal places to truncate to [0]
returns
r: n truncated to p decimal places
math.round (n, [p])
Round a number to p decimal places
n: number
[p]: number of decimal places to truncate to [0]
returns
r: n to p decimal places
math.sqr (n)
Squares the argument
n: number
returns
r: n * n
Prototype-based Objects
For an alternative object oriented programming model you can use:
import "std.object"
This gives you facilities supporting object orientation via prototyping.
Usage:
An object's metatable is itself. In the initializer, unnamed values are assigned to the fields given by _init (assuming the default _clone). Private fields and methods start with an underscore.
Create an object/class:
object/class = parent {value, ...; field = value ...}
Access an object field:
object.field
Call an object method:
object:method (...)
Call a class method:
class.method (self, ...)
Add a field:
object.field = x
Add a method:
function object:method (...) ... end
Root object:
Object:_clone (values, _init)
Object constructor
values: initial values for fields in
_init
returns
object: new object
Object:__call ()
Sugar instance creation
Sets
import "std.set"
set:add (e)
Add item(s) to a set
self: set
e: element(s)
returns
r: self with elements added
set:remove (e)
Remove item(s) from a set
self: set
e: element(s)
returns
r: self with elements removed
set:member (e)
Test whether an item is in a set
self: set
e: element
returns
r: self with elements of t removed
set:elements (e)
Return all of the set elements as results
self: set
e: element(s)
returns
r: all of the unpacked elements
set:minus (t)
Find the difference of two sets. Also available as infix operator -
self: set
t: set
returns
r: self with elements of t removed
set:intersect (t)
Find the intersection of two sets. Also available as infix operator *
self: set
t: set
returns
r: set intersection of self and t
set:union (t)
Find the union of two sets. Also available as infix operator +
self: set
t: set
returns
r: set union of self and t
set:subset (t)
Find whether one set is a subset of another. Also available as infix operator <=
self: set
t: set
returns
r: true if self is a subset of t, false otherwise
set:propersubset (t)
Find whether one set is a proper subset of another. Also available as infix operator <
self: set
t: set
returns
r: true if s is a proper subset of t, false otherwise
set:equal (t)
Find whether two sets are equal. Also available as infix operator ==
self: set
t: set
returns
r: true if sets are equal, false otherwise
Formatting Text
import "std.string"
or
import "std.string.format"
string.format (f, ...)
Extend to work better with one argument. If only one argument is passed, no formatting is attempted.
f: format
...: arguments to format
returns
s: formatted string
string.pad (s, w, [p])
Justify a string. When the string is longer than w, it is truncated (left or right according to the sign of w)
s: string to justify
w: width to justify to (-ve means right-justify; +ve means left-justify)
[p]: string to pad with [" "]
returns
s_: justified string
string.wrap (s, w, ind, ind1)
Wrap a string into a paragraph
s: string to wrap
w: width to wrap to [78]
ind: indent [0]
ind1: indent of first line [ind]
returns
s_: wrapped paragraph
string.numbertosi (n)
Write a number using SI suffixes. The number is always written to 3 s.f.
n: number
returns
n_: string
Regular Expressions
import "std.string"
or
import "std.string.regex"
string.findl (s, p, [init], [plain])
Do string.find, returning captures as a list
s: target string
p: pattern
[init]: start position [1]
[plain]: inhibit magic characters [nil]
returns
from, to: start and finish of match
capt: table of captures
string.finds (s, p, [init], [plain])
Do multiple string.find's on a string
s: target string
p: pattern
[init]: start position [1]
[plain]: inhibit magic characters [nil]
returns
t: table of {from=from, to=to; capt = {captures}}
string.gsubs (s, sub, [n])
Perform multiple calls to string.gsub
s: string to call string.gsub on
sub: {pattern1=replacement1 ...}
[n]: upper limit on replacements [infinite]
returns
s_: result string
r: number of replacements made
string.split ([sep], s)
Split a string at a given separator
[sep]: separator regex ["%s+"]
s: string to split
returns
l: list of strings
string.ltrim ([r], s)
Remove leading matter from a string
[r]: leading regex ["%s+"]
s: string
returns
s_: string without leading r
string.rtrim ([r], s)
Remove trailing matter from a string
[r]: trailing regex ["%s+"]
s: string
returns
s_: string without trailing r
string.trim ([r], s)
Remove leading and trailing matter from a string.
[r]: leading/trailing regex ["%s+"]
s: string
returns
s_: string without leading/trailing r
Strings
import "std.string"
or
import "std.string.string"
string.concat (s1, s2, ..., sn)
Give a name to .. for strings
s1, s2, ..., sn: strings
returns
s_: s1 .. s2 .. ... .. sn
string.caps (s)
Capitalize each word in a string
s: string
returns
s_: capitalized string
string.chomp (s)
Remove any final newline from a string
s: string to process
returns
s_: processed string
string.escapePattern (s)
Escape a string to be used as a pattern
s: string to process
returns
s_: processed string
string.escapeShell (s)
Escape a string to be used as a shell token. Quotes spaces, parentheses and \\s
s: string to process
returns
s_: processed string
string.ordinalSuffix (n)
Return the English suffix for an ordinal
n: number of the day
returns
s: suffix
string.lcs (a, b)
Find the longest common subsequence of two strings.
a, b: strings
returns
s: longest common subsequence
Tables
import "std.table"
table.sort (t, c)
Make table.sort return its result
t: table
c: comparator function
returns
t: sorted table
table.subscript (t, s)
Expose [] as a function
t: table
s: subscript
returns
v: t[s]
table.empty (t)
Say whether table is empty
t: table
returns
f: true if empty or false otherwise
table.size (t)
Find the number of elements in a table
t: table
returns
n: number of elements in t
table.indices (t)
Make the list of indices of a table
t: table
returns
u: list of indices
table.values (t)
Make the list of values of a table
t: table
returns
u: list of values
table.invert (t)
Invert a table
t: table {i=v ...}
returns
u: inverted table {v=i ...}
table.permute (p, t)
Permute some indices of a table
p: table {oldindex=newindex ...}
t: table to permute
returns
u: permuted table
table.clone (t)
Make a shallow copy of a table, including any metatable.
t: table
returns
u: copy of table
table.merge (t, u)
Merge two tables. If there are duplicate fields, u's will be used. The metatable of the returned table is that of t.
t, u: tables
returns
r: the merged table
table.newDefault (x, [t])
Make a table with a default value
x: default value
[t]: initial table [{}]
returns
u: table for which u[i] is x if u[i] does not exist