Lil Terminal is a command-line interface for the Lil programming language, allowing easy experimentation outside of Decker. Lilt also includes bindings for basic CLI and filesystem IO, making it potentially usable for shell scripting and other applications.
The source code for Lilt is available On GitHub.
Lilt depends upon the C standard library and some POSIX extensions. It should work on OSX or most Linux distros. To build and install Lilt, run the included
make script. By default, a binary is installed in
make lilt && make install
$ lilt [FILE.lil...] [-e EXPR...] if present, execute a FILE and exit -e : evaluate EXPR and exit -h : display this information
EXPR argument will not automatically produce any output. Use
print to produce results on stdout:
$ lilt -e "show[100+range 5]" (100,101,102,103,104) $ lilt -e "print[sys.version]" 0.6
EXPR argument has not been provided, Lilt will run in interactive "REPL" mode, which can be exited with Ctrl+C or the
$ lilt 2+3 5 exit $
For convenience, after each line is executed at the REPL, the result will be stored in a variable named
1,2,3 (1,2,3) 10+_ (11,12,13) _/5 (2.2,2.4,2.6)
You can write reasonably portable shell scripts by starting a file with a "shebang" something like:
If an environment variable named
LIL_HOME is set, Lilt will search that directory path at startup, executing any
.lil files. These could in turn easily load datasets or other useful definitions every time you open a REPL. Startup scripts are always loaded prior to executing
| ||List of CLI arguments to Lilt as strings.|
| ||Dictionary of POSIX Environment variables.|
| ||An Interface which exposes information about the Lilt runtime.|
| ||An Interface with routines for working with rich text.|
| ||An Interface with routines for bit-wise manipulation of numbers.|
| ||The ratio of a circle's circumference to its diameter. Roughly 3.141.|
| ||Euler's number; the base of the natural logarithm. Roughly 2.718.|
| ||A dictionary of named pattern indices.|
| || Read a line from stdin as a string, optionally displaying ||Console|
| || Print a human-comprehensible representation of the value ||Console|
| || Print a string ||Console|
| || Print a string ||Console|
| ||List the content of a directory as a table.(1)||Files|
| || Canonical path ||Files|
| || Read a file ||Files|
| || Write a value ||Files|
| || Stop execution with exit code ||System|
| || Execute string ||System|
| || Parse and execute a string ||System|
| || Execute a ||System|
| || Choose ||System|
| || Turn a RFC-4180 CSV string ||Data|
| || Turn a Lil table ||Data|
| ||Turn a useful subset of XML/HTML into a Lil structure.(5)||Data|
| || Turn a Lil structure ||Data|
| || Produce a deck interface from a file at path ||Decker|
| || Serialize a deck interface ||Decker|
| || Create a new array with size ||Decker|
| || Create a new image interface with size ||Decker|
| || Create a new sound interface with size ||Decker|
error are given a single array interface as an argument, the raw bytes of that array will be sent to stdout or stderr, respectively, with no trailing newline added. In this way it is possible to print characters which do not have a valid representation as Lil strings, like Unicode block characters.
dir of a file results in an empty table. Directory tables contain:
dir: if an item is a directory
1, and otherwise
name: the filename of the item.
type: the extension including a dot (like
.txt), if any, always converted to lowercase.
read[x hint] recognizes several types of file by extension and will interpret each appropriately:
hintargument is the string
"array", the file will be read as an array interface with a default
.giffiles are read as image interfaces (or a dictionary containing image interfaces, as noted below).
.wavfiles are read as sound interfaces.
\r(Carriage-Return) characters are removed, tabs become a single space, "smart-quotes" are straightened, and anything else outside the range of valid Lil characters becomes a question mark (
There are several possible
hint arguments to control the interpretation of colors in an image:
"color"(or no hint): convert to Decker's 16-color palette (patterns 32-47). Read only the first frame of an animated GIF.
"gray": convert to 256 grays based on a perceptual weighting of the RGB channels. Read only the first frame of an animated GIF.
"frames": 16 colors, but read all frames of an animated GIF.
"gray_frames": 256 grays, but read all frames of an animated GIF.
"gray_frames" hints will cause
read of a GIF to return a dictionary containing the following keys:
frames: a list of images.
delays: a list of integers representing interframe delays in 1/100ths of a second.
If an image contains transparent pixels, they will be read as pattern 0.
The WAV file format is much more complex than one might imagine. For this reason, and in order to avoid drawing in large dependencies,
read in Lilt accepts only a very specific subset of valid WAV files corresponding to the output of
write: monophonic, 8khz, with 8-bit unsigned PCM samples and no optional headers. Any other format (or an altogether invalid audio file) will be read as a
sound with a
size of 0. For reference, you can convert nearly any audio file into a compatible format using ffmpeg like so:
ffmpeg -i input.mp3 -bitexact -map_metadata -1 -ac 1 -ar 8000 -acodec pcm_u8 output.wav
write recognizes several types of Lil value and will serialize each appropriately:
frames(a list of image interfaces) and
delays(a list of integers representing interframe delays in 1/100ths of a second).
shell returns a dictionary containing:
exit: the exit code of the process, as a number. If the process halted abnormally (i.e. due to a signal), this will be -1.
out: stdout of the process, as a string.
5) See the Decker Manual for details of
6) If the path given to
writedeck ends in a
.html suffix, the deck will be written as a "standalone" deck with a bundled HTML+JS runtime. Otherwise, the deck will be written as a "bare" deck, which is smaller.
writedeck functions allow Lilt to operate on Decker documents. Lilt can load, create, and manipulate multiple decks simultaneously, providing options for automated testing, data import/export, accessibility, and interacting with other technology from outside the Decker ecosystem.
Just as in Decker, you can simulate "injecting" events into widgets, cards, or the deck with the
x.event[name args...] function they provide, running the appropriate scripts to completion and producing any appropriate side-effects on the deck. For example, clicking on the first widget on the active card:
d:readdeck["demo.deck"] (first d.card.widgets).event["click"]
readhints for decoding the frames of animated GIF images.
errorto accept a array interfaces as arguments.
importto simplify building multi-file scripts.