Erre con erre cigarro
Erre con erre barril
Rápido ruedan los carros
En el ferrocarril

Support MaraDNS or listen to my music

Lunacy

Lunacy is a fork of the tiny scripting language Lua; it is based on the 5.1 release of Lua.

It is a scripting language that is able to do a good deal more than a “BASH + AWK” workflow while being a fraction of a size of “big” scripting languages such as Perl, PHP, Ruby, and Python. A fully functional 32-bit Windows compile of Lunacy is only 115,712 bytes in size.

Security

Lunacy is patched against all known security problems with Lua 5.1:
  • CVE-2014-5461 has been patched (even though the exploit test actually did not crash Lunacy).
  • The hash compression code uses a 32-bit SipHash variant to protect Lunacy against hash collision attacks.

Supported platforms

Lunacy is cross platform: It compiles both in Linux systems and in Windows (via MinGW) as a native Windows binary. All included libraries (lfs, etc.) have the same functionality in both Linux and Windows. In Windows, it has the performance of a native application (i.e. the Windows native build of Lunacy performs file I/O a good deal faster than the Cygwin build of Lunacy). While not tested, it should compile in UNIX and other UNIX clones such as MacOS. Heck, it should port to exotic stuff like VMS without issue.

Documentation

The project has a full manual (in text, HTML, PDF, and multiple e-Book formats). Click (or tap) here to read the HTML manual.

Download

In the download, in addition to all the manuals, a number of public domain scripts to provide the language “batteries”, a Windows binary, and full source code are included.

Being open source, Lunacy currently is and always will be a free download.

Lunacy is available at GitHub and Sourcehut. It is also available as a local download, either as a .zip file (sig), or a .tar.xz file (sig).

An example script

Here is the Lunacy version of awk '{print $2 " " $1}'
-- Code is public domain
-- Since Lunacy doesn't have split(), we make 
-- it ourselves
function pStrSplit(s, splitOn)
  if not splitOn then splitOn = "," end
  local place = true
  local out = {}
  local mark
  local last = 1
  while place do
    place, mark = string.find(s, splitOn, last, false)
    if place then
      table.insert(out,string.sub(s, last, place - 1))
      last = mark + 1
    end
  end
  table.insert(out,string.sub(s, last, -1))
  return out
end

-- This is code which reads and processes lines from 
-- standard input
l = io.read()
while l do
  -- Remove leading whitespace
  l = string.gsub(l,"^%s+","") 
  -- AWK-style split: f[1] is $1, etc.
  f = pStrSplit(l,"%s+") 
  if f[2] then -- Avoid raising error
    print(f[2] .. " " .. f[1]) -- print $2 " " $1
  else
    print(" " .. f[1]) -- Act like AWK script
  end
  l = io.read() -- Read next line. 
  -- Note that, in Lunacy (Lua), an empty string 
  -- (and the number 0) evaluate to "true"; only
  -- "false" and "nil" evaluate to "false"
end
-- END public domain code
Some things to observe:
  • Luancy is a “batteries not included” language. It doesn’t have Perl’s split keyword nor Python’s equivalent re.split() function, so we had to write our own implementation of split(), called pStrSplit here.
  • Lunacy uses -- instead of the *NIX standard # for comments.
  • Instead of using { and } for nesting, Lunacy uses keywords (usually ending a nested portion with the end keyboard).