Lua

LuaJIT (official website) is a Just-In-Time compiler for Lua (official website) which is embedded in Nift. LuaJIT is extremely fast, note that LuaJIT uses version 5.1 of Lua (reference manual).

There are lots of modules available for Lua that can be installed as self-contained packages called rocks. These can be installed using either LuaRocks or LuaDist. There is documentation below on how to use LuaRocks with most of the operating systems that Nift runs on, for other platforms try searching Google for os luarocks.

LuaJit logo
[contents]

Contents

Embedding regular versions of Lua

See here for information on how to compile Nift with regular (non-JIT) versions of Lua.

Lua interpreter

Nift has a Lua interpreter that you can start with either nsm interp -lua or nift interp -lua.

In Nift's interpreter mode the prompt will just tell you which language you are using. If you would like the prompt to also display the present working directory (up to using half the width of the console) you can switch to the shell mode using nsm_mode("sh"). You can switch back again with nsm_mode("interp").

You can switch to one of the other languages available in Nift's interpreter using nsm_lang("langStr") where langStr is one of f++, N++, lua or exprtk.

Running Lua scripts

If you have a Lua script saved in a file path/script-name.lua you can run it with either of the following:

nsm run path/script-name.lua
nift run path/script-name.lua

If the script has a different extension, say .ext, you can run the script with either of the following:

nsm run -lua path/script-name.ext
nift run -lua path/script-name.ext

ExprTk from Lua

You can run ExprTk code from Lua using:

exprtk("ExprTk code")

Note: When using the interpreter or running a script the ability to call ExprTk is added for you, if you want the ability at other times inside f++ first call lua_addnsmfns(), similarly for inside N++ first call @lua_addnsmfns().

Lua from f++

You can run Lua code from f++ using either of the following (without needing the comment syntax):

lua(--[[ line of Lua code ]]--)

lua
{
	-- block of Lua code
}

Lua from N++

You can run Lua code from N++ using either of the following (without needing the comment syntax):

@lua(--[[ line of Lua code ]]--)

@lua
{
	-- block of Lua code
}

Nift functions

The following functions specific to Nift may be made available inside Lua code. When running an interactive REPL session or running a Lua script these functions will be added for you, if you want to use them for Lua code inside f++ first call lua_addnsmfns(), similarly for inside f++ first call @lua_addnsmfns().

syntax example about
cd(string) cd("~/") change directory
exprtk(string) exprtk("println('hello, world!')") compile and evaluate ExprTk expression
exprtk_compile(string) exprtk_compile("println('hello, world!')") compile ExprTk expression
exprtk_compile(string, string) exprtk_compile("hello", "println('hello, world!')") compile ExprTk expression
exprtk_eval() exprtk_eval("println('hello, world!')") evaluate ExprTk expression
exprtk_eval(string) exprtk_eval("hello") evaluate ExprTk expression
exprtk_load(string) exprtk_load("hello") load ExprTk expression
exprtk_str() exprtk_str() return string of compiled ExprTk expression
exprtk_str(string) exprtk_str("hello") return string of compiled ExprTk expression
nsm_setnumber(string / lightuserdata, number) nsm_setnumber("i", 0) set Nift variable from number
nsm_setstring(string / lightuserdata, string) nsm_setstring("str", "hello!") set Nift variable from string
nsm_tolightuserdata(string) nsm_tolightuserdata("x") get pointer to Nift variable
nsm_tonumber(string) nsm_tonumber("i") get number from Nift variable
nsm_tostring(string) nsm_tostring("str") get string from Nift variable
nsm_write(ostream, params) nsm_write(console, "x: ", x, endl) write to console, output file (ofile), or a stream
sys(string) sys("ls *.txt") execute system call/command
syntax example about

An example of using nsm_setstring, nsm_tostring and nsm_wite with f++ is below:

string str="hello, world!"
lua_addnsmfns()
lua 
{
	nsm_write(console, nsm_tostring("str"), endl)
	nsm_setstring("str", "hello, mars!")
	nsm_write(console, nsm_tostring("str"), endl)
}

LuaRocks

As mentioned above, LuaRocks may be used to install all sorts of modules for Lua. There is information below about installing LuaRocks on different platforms and configuring your platform.

Note: Some rocks are to interface with other programs that you also need to have installed on your machine, for example LuaSQL-MySQL expects you to have MYSQL installed on your machine with the header mysql.h available somewhere in your PATH variable. Similarly lsqlite3 expects you to have SQLITE installed on your machine with the header sqlite3.h available somewhere in your PATH variable.

Some of the rocks you might find useful with Nift are:

  • cloud_storage - access Google Cloud Storage from Lua
  • Lua-cURL - binding to libcurl (official website, GitHub)
  • lua-discount - binding to a fast C implementation of the Markdown text-to-html markup system (official website)
  • etlua - allows you to render ERB style templates but with Lua. Supports <% %>, <%=%> and <%- %> tags (with optional newline slurping) for embedding code
  • lua-cjson - fast JSON encoding/parsing support
  • luajwt - JSON Web Tokens for Lua, very fast and compatible with pyjwt, php-jwt and ruby-jwt
  • graphql - Lua GraphQL implementation (GitHub)
  • luahaml - implementation of the Haml markup language for Lua
  • http - HTTP library for Lua: optionally asynchronous (including DNS lookups and TLS), supports HTTP(S) version 1.0, 1.1 and 2, functionality for both client and server, cookie Management, websockets
  • lustache - allows you to use the Mustache templating standard in Lua by passing in a string, data, and partial templates. It precompiles and caches templates for speed, and allows you to build complex strings such as html pages by iterating through a table and inserting values (official website)
  • mailgun - send email with Mailgun
  • Markdown - pure-lua implementation of the Markdown text-to-html markup system
  • magick - bindings to ImageMagick for LuaJIT using FFI
  • moonscript - programmer friendly language that compiles to Lua (official website)
  • LuaSQL-MySQL - database connectivity for Lua (MySQL driver), enables a Lua program to connect to databases, execute arbitrary SQL statements and retrieve results in a row-by-row cursor fashion
  • lsqlite3 - a binding for Lua to the SQLite3 database library
  • LuaSQL-SQLite3 - database connectivity for Lua (SQLite3 driver), enables a Lua program to connect to databases, execute arbitrary SQL statements and retrieve results in a row-by-row cursor fashion
  • nixio - a multi-platform library offering a wide variety of features such as IPv4, IPv6 and UNIX networking, large file I/O, file system operations, system and process control, POSIX user/group management, basic cryptographical hashing, hmac and TLS support, bit operations and binary conversion (also see here)
  • pgmoon - PostgreSQL driver written in pure Lua for use with OpenResty's cosocket API. Can also be used in regular Lua with LuaSocket and LuaCrypto
  • redux-lua - implements redux using Lua language
  • lua-requests - HTTP requests made easy! Support for Basic Auth, Digest Auth. HTTP response parsing has never been easier (GitHub)
  • lua-resty-template - templating engine (HTML) for Lua and OpenResty
  • LuaSocket - an extension library that is composed by two parts: a C core that provides support for the TCP and UDP transport layers, and a set of Lua modules that add support for functionality commonly needed by applications that deal with the Internet
  • web_sanitize - library for sanitizing untrusted HTML
  • lua-vips - a binding for the libvips image processing library. it is usually faster and needs less memory than similar libraries
  • LuaFileSystem - offers a portable way to access the underlying directory structure and file attributes
  • lua-path - file system path manipulation library
  • lanes - multithreading support for Lua
  • lua-llthreads2 - low-level threads for Lua, in additional module supports: thread join with zero timeout; logging thread errors with custom logger; run detached joinable threads; pass cfunctions as argument to child thread
  • luasystem - platform independent system calls
  • sys - provides system functionalities for Torch
  • LPeg - new pattern-matching library for Lua, based on Parsing Expression Grammars (PEGs)
  • luaossl - most comprehensive OpenSSL module in the Luaverse
  • LuaCrypto - frontend to the OpenSSL cryptographic library, the OpenSSL features that are currently exposed are: digests (MD5, SHA-1, HMAC, and more), encryption, decryption and crypto-grade random number generators
  • MD5 - offers basic cryptographic facilities: a hash (digest) function, a pair crypt/decrypt based on MD5 and CFB, and a pair crypt/decrypt based on DES with 56-bit keys
  • luaposix - library binding various POSIX APIs (see also lunix)
  • xml - fast xml parser based on RapidXML
  • lyaml - libYAML binding for Lua, read and write YAML format files with Lua
  • yaml - Lua YAML serialization using LibYAML, LibYAML is generally considered to be the best C YAML 1.1 implementation

Other Lua resources worth checking out include:

  • Fengari - the Lua VM written in JavaScript, it uses JavaScript's garbage collector so that interoperability with the DOM is non-leaky (GitHub)
  • FFI Library - allows calling external C functions and using C data structures from pure Lua code
  • libgit2 - portable, pure C implementation of the Git core methods provided as a re-entrant linkable library with a solid API, allowing you to write native speed custom Git applications in any language which supports C bindings (luagit2 - Lua bindings for libgit2)
  • SciLua - Scientific computing with LuaJIT
  • Torch - a scientific computing framework with wide support for machine learning algorithms that puts GPUs first

You can also compile the following languages to Lua (see here for a longer list):

  • Amulet - simple, functional programming language in the ML tradition
  • CSharp.lua - C# to Lua compiler
  • Fennel - a programming language that brings together the speed, simplicity, and reach of Lua with the flexibility of a lisp syntax and macro system
  • Haxe - an open source high-level strictly-typed programming language with a fast optimizing cross-compiler
  • MoonScript - a dynamic scripting language that compiles into Lua
  • TypeScriptToLua - generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!
  • Urn - a Lisp dialect with a focus on minimalism

Installing LuaRocks on FreeBSD

Instructions for installing LuaRocks from source for Lua v5.1 can be found here. Alternatively, LuaRocks can be installed for Lua v5.2 through pkg using:

sudo pkg install devel/lua-luarocks

If you installed LuaRocks with pkg then the default command to run LuaRocks is luarocks-5.2 so you should add an alias called luarocks, and you need to change the configuration for Lua v5.1 instead of Lua v5.2. Run your alias luarocks which should give you the location of the system/global configuration file for LuaRocks and open it up with administator privileges in your favourit text editor, eg. (you can install micro with pkg):

sudo micro /usr/local/etc/luarocks/config-5.2.lua

Then modify the appropriate lines so that the configuration file has the following:

lua_interpreter = "lua5.1";
lua_version = "5.1";

variables = {
	LUA_DIR = "/usr/local";
	LUA_INCDIR = "/usr/local/include/lua51";
	LUA_BINDIR = "/usr/local/bin";
}

Once LuaRocks is configured for Lua v5.1, run luarocks path --bin and add the values for LUA_PATH and LUA_CPATH as environemnt variables on your machine (I find you typically do not need to add the value given for PATH to your path variable). For example if you use bash then for the current shell session you can run eval $(luarocks path --bin), and for future shell sessions you should be able to add the first two lines of output to ~/.bashrc.

You should then be able to install rocks using for example:

sudo luarocks install LuaFileSystem

LuaRocks should work fine with Nift installed from source or through pkg.

Installing LuaRocks on Linux

LuaRocks can typically be installed through the package manager for your distribution. For example on Ubuntu you can run:

sudo apt-get install luarocks

You should then be able to install rocks using for example:

sudo luarocks install LuaFileSystem

Once LuaRocks is installed run luarocks path --bin and add the lines for LUA_PATH and LUA_CPATH to the end of ~/.bashrc (I find you typically do not need to add the value given for PATH to your path variable).

LuaRocks should work fine with Nift installed from source or through Snapcraft, I have not had much luck yet getting it to work with installs through Flatpak however.

Installing LuaRocks on OSX

The easiest way to install LuaRocks on OSX is to use homebrew with:

brew install luarocks

Note however that this typically sets LuaRocks up for Lua v5.3 by default, whereas for LuaJIT we want it to install rocks for v5.1, it will tell you which version is configured near the bottom of the output from calling luarocks from the command line. When it is configured for Lua v5.3, when installing a rock you will need to add --lua-version=5.1, for example:

luarocks install moonscript --lua-version=5.1

To change the Homebrew install of LuaRocks to use Lua 5.1:

  1. run luarocks and note where the system configuration file is located;
  2. run sudo nano system-config-path and make sure it has the following two lines:
lua_interpreter = "lua5.1"
lua_version = "5.1"
Now you do not need --lua-version=5.1 when calling LuaRocks.

Once LuaRocks is installed and configured to use Lua 5.1 run luarocks path --bin and add the lines for LUA_PATH and LUA_CPATH to the end of ~/.bash_profile (I find you typically do not need to add the value given for PATH to your path variable).

Note: If you do not configure LuaRocks to use Lua 5.1 then you will need to use for example luarocks path --lua-version=5.1 --bin and sudo luarocks install --lua-version=5.1 lua-cjson.

Alternatively, assuming you have command line tools installed for XCode, you can download the latest .tar.gz version of the source for LuaRocks from here. Extract the contents of the archive, open the directory in a terminal window and run:

./configure --lua-version=5.1
make
sudo make install

Then you can install rocks using for example:

sudo luarocks install lua-cjson

Same as above, once LuaRocks is installed run luarocks path --bin and add the lines for LUA_PATH and LUA_CPATH to the end of ~/.bash_profile (I find you typically do not need to add the value given for PATH to your path variable).

LuaRocks should work fine with Nift installed from source or through Homebrew.

Installing LuaRocks on Windows

LuaRocks can be installed through Chocolatey with:

choco install luarocks
Note however that Chocolatey installs of LuaRocks expect you to have Visual Studio Code installed with its build tools for C++, which can take up quite a lot of disk space.

You can supposedly also install LuaRocks to use MingW for building rocks, see here for instructions. Note that when running the install script, use:

INSTALL.BAT /MW /L

You should then be able to install rocks using for example:

sudo luarocks install LuaFileSystem

Once LuaRocks is installed run luarocks path --bin and add the values for LUA_PATH and LUA_CPATH as environemnt variables on your machine (I find you typically do not need to add the value given for PATH to your path variable). To modify environment variables in Windows 10 you can type environment variables in to Cortana who should then give you a link straight to where you need to go in Control Panel.

LuaRocks should work fine with Nift installed from source or through Chocolatey, though so far I have not had much luck getting LuaRocks to build rocks on Windows, I will update this page once I figure out a reliable way to install LuaRocks on Windows.

Moonscript functions

Suppose you have a moonscript file functions.moon:

func1 = ->
	print "hello, world!"
	
func2 = ->
	print "hello, mars!"

{ :func }
{ :func2 }

Inside Lua code (in a file in the same directory) you can require functions.moon and use its functions as follows:

require "moonscript"
fns = require "functions"
fns.func()
fns.func2()