Xsys: Extended Lua System

A module that provides a small number of general purpose routines and extends the global table and string modules.

API - Generic

xsys = require "xsys"

Returns the loaded module (no global variable is set).

y = xsys.tonumber(x)

Checks if x.__tonumber is defined in which case it returns x:__tonumber(), otherwise it returns the global tonumber(x).

templatef = xsys.template(str)

This function is templet.loadstring() from Peter Colberg's Templet library which is embedded in this module (version 1.0.1). We refer to the official website for further documentation. Here is an example of dynamic C-code generation:


local dynamic = xsys.template[[
for (int i = 0; i < ${nparticle}; ++i) {
|for i = 1, #coord do
  r[i].${coord[i]} = r[i].${coord[i]} + v[i].${coord[i]} * ${timestep};
|end
}
]]
print(dynamic({ coord = { "x", "y", "z" }, nparticle = 500, timestep = 0.001 }))
--> for (int i = 0; i < 500; ++i) {
-->   r[i].x = r[i].x + v[i].x * 0.001;
-->   r[i].y = r[i].y + v[i].y * 0.001;
-->   r[i].z = r[i].z + v[i].z * 0.001;
--> }
... = xsys.exec(chunk, chunkname, fenv)

On success, this function is equivalent to executing the following chunk of code:


local f = loadstring(chunk, chunkname)
if fenv then
  setfenv(f, fenv)
end
return f()

Otherwise, in case loadstring() returns an error message or f() raises an error then an appropriate error message is thrown.

v1, v2, ..., vN = xsys.from(t, "k1, k2, ..., kN")

This function is equivalent to executing the following chunk of code:


local v1, v2, ..., vN = t.k1, t.k2, ..., t.kN

The advantage is purely cosmetic as using this function it's possible to easily 'import' module variables by copy&paste:


local exp, log, sqrt, cos, sin, min, max, sqrt = xsys.from(math, 
     "exp, log, sqrt, cos, sin, min, max, sqrt")

Please notice that this function is not optimized for performance.

API - Table

Extension: xsys.table extends the global table library, i.e. it's guaranteed to contain all its entries.

newtable = xsys.table.union(...)

All passed arguments must be tables (passing no arguments is allowed). Returns a new table which maps from the union of the keys, which must be unique among all passed arguments, to the corresponding values. The keys of each of the passed arguments are iterated via pairs(). Example:


local t = table.union({ a = 1, b = 2 }, { [8] = "red", [9] = "blue" })
for k,v in pairs(t) do print(k, v) end
--> b 2
--> 8 red
--> a 1
--> 9 blue
newarray = xsys.table.append(...)

All the passed arguments must be table arrays, i.e. a table for which all the values from 1 to the result of the # operator are not nil (passing no arguments is allowed). Returns a new table array which is constructed by appending all the values corresponding to the array part of all the passed arguments which are iterated via the indexing [i] and length # operators. Example:


local t = table.append({ 1, 2, 3, a = 1 }, { 4, 5 })
for _,v in ipairs(t) do print(v) end
--> 1
--> 2
--> 3
--> 4
--> 5
print(t.a) --> nil

API - String

Extension: xsys.string extends the global string library, i.e. it's guaranteed to contain all its entries.

splitted = xsys.string.split(str, sep)

Splits the string str into the table array splitted according to the separator sep. Example:


for _,v in ipairs(xsys.string.split("aa,bb,cc,dd", ",")) do 
  print(v) 
end
--> aa
--> bb
--> cc
--> dd
trimmed = xsys.string.trim(str)

Removes any sequence of white-spaces from the beginning and from the end of str. Example:


local totrim = "  LuaJIT "
print("<"..totrim..">")                   --> <  LuaJIT >
print("<"..xsys.string.trim(totrim)..">") --> 
fixstr = xsys.string.width(x, nchars = 9)

Returns a string with a fixed length equal to nchars characters (at least 9) representing x which must be of one of the following: a nil, a boolean, a string, a number, or either a table or an FFI cdata with a __tostring() member method defined which returns a number. The fixed length is achieved via right-justification or truncation depending on the case. The rules that determine the output are best illustrated via an example:


local width = xsys.string.width
-- Nil
print(width())
print(width(nil))
-->      nil
-->      nil
-- Boolean:
print(width(true))
print(width(false))
-->     true
-->    false
-- Strings:
print(width("12345"))
print(width("123456789"))
print(width("1234567890"))
-->     12345
--> 123456789
--> 1234567..
-- Numbers / with __tonumber():
print(width(10))
print(width(-10))
print(width(999999))
print(width(9999999))
print(width(0.000001))
print(width(0.0000001))
print(width(-1/0))
print(width(0/0))
--> +10.00000
--> -10.00000
--> +999999.0
--> +1.0e+007
--> +0.000001
--> +1.0e-007
-->      -inf
-->       nan