Nasal Core Library

Data Structure Basics

append(vector, elements...)
The first argument specifies a vector. Appends the remaining arguments to the end of the vector.
setsize(vector, size)
Sets the size of a vector. The first argument specifies a vector, the second a number representing the desired size of that vector. If the vector is currently larger than the specified size, it is truncated. If it is smaller, it is padded with nil entries. Returns the vector operated upon.
subvec(vector, start, length=nil)
Returns a sub-range of a vector. The first argument specifies a vector, the second a starting index, and the optional third argument indicates a length (the default is to the end of the vector).
contains(hash, key)
The first argument specifies a hash, the second must be a scalar. Returns 1 if the hash contains the scalar as a key, 0 if not.
delete(hash, key)
The first argument specifies a hash, the second must be a scalar key. Deletes the key from the hash if it exists. Operationally, this is identical to setting the hash value specified by the key to nil, but this variant potentially frees storage by deleting the reference to the key and by shrinking the hash.
int(value)
Returns the integer part of the numeric value of the single argument, or nil if none exists. Truncates towards zero, not negative infinity (i.e. it's implemented in C as a double to integer typecast).
num(value)
Returns the numeric value of the single argument, or nil if none exists.
keys(hash)
Returns a vector containing the list of keys found in the single hash argument.
pop(vector)
Removes and returns the last element of the single vector argument.
size(object)
Returns the size of the single argument. For strings, this is the length in bytes. For vectors, this is the number of elements. For hashes, it is the number of key/value pairs. Returns nil for number and nil arguments.
streq(a, b)
Tests the string values of the two arguments for equality. Needed because the == operator in Nasal tests for numeric equality, as in perl. So "0" == "0.0" is true, but streq("0", "0.0") is false. This is rarely required in typical code.
cmp(a, b)
Compares two strings, returning -1 if a is less than b, 0 if they are identical, and 1 if a is greater than b.
sort(vector, function)
Creates a new vector containing the elements in the input vector sorted in ascending order according to the rule given by function, which takes two arguments (elements of the input vector) and should return less than zero, zero, or greater than zero if the first argument is, respectively, less than, equal to, or greater than the second argument. Despite being implemented with ANSI C qsort(), the sort is stable; "equal" elements in the output vector will appear in the same relative order as they do in the input.
substr(string, start, length=nil)
Computes a substring. The first argument specifes a string, the second is an integer index of the start of a substring, the optional third argument specifies a length (the default is to return the remaining string). Example: substr("abcde", 1, 3) returns "bcd".
sprintf(format, varargs...)
Creates and returns a string formatted as per ANSI C sprintf().
find(needle, haystack)
Finds and returns the index of the first occurence of the string needle in the string haystack, or -1 if no such occurence was found.
split(delimeter, string)
Splits the input string into a vector of substrings bounded by occurences of the delimeter substring.
rand(seed=nil)
Returns a random number in the range [0:1) (that is, 0.0 is a possible return value. 1.0 is not). If a numeric argument is specified, it is used as a seed instead and the function returns nil. Implemented in terms of the C library's rand/srand functions; the result should have a full double-precision number's worth of randomness even on systems with a 15 bit rand().

Internals and Functional Programming

typeof(thing)
Returns a string indicating the type of the single argument, any of: nil, scalar, vector, hash, func, or ghost.
die(error)
Terminates execution and unwinds the stack. This invokes the same internal exception handler used for internal runtime errors. Use this to signal fatal errors, or to implement exception handling. The error thrown (including internal runtime errors) can be caught with call().
call(fn, args=[], me=nil, namespace=nil, error=nil)
Calls the given function with the given arguments and returns the result. The optional arguments can be used to specify the "me" reference for a function call and the local variable namespace. The error argument, if present, must be a vector. If the called function terminates due to a runtime error or die() call, the error (either a string or the argument to die() is appended to the vector, followed by the file name at which the error occurred, followed by the line number in that file, followed in order by each file/line number on the call stack.
caller(level=1)
Returns a record from the current call stack. Level zero is the currently executing function. Level one (the default) is the caller of the current function, etc... The result is a four element vector containing: the local variables hash table, the function object, the source file, and the line number.
compile(code, filename="<compile>")
Compiles the specified code string and returns a function object bound to the current lexical context. The file name of the function, if unspecified in the second argument, is simply "<compile>". On error, the function dies with a user-readable string error message as per die().
closure(fn, level=0)
Returns the hash table representing the lexical namespace of the given function. Level zero is the scope in which the func{...} expression was evaluated. Level one is the enclosing scope, etc...
bind(func, namespace=nil, outer_scope=nil)
The opposite of closure, bind() creates a new function object. A function in Nasal is three things: the first is the actual bytecode or C function pointer of the function (specified here via another function argument from which to extract the code). The second is the local variable namespace (a hash table) of the "super-function" that was running when the function was bound (i.e., when the func{...} expression was evaluated). The third is the closure object of that super-function from which the lexical environment of the super-super-function can be extracted, etc...

Math Library

math.sin(number)
Returns the sine of the single argument
math.cos(number)
Returns the cosine of the single argument
math.exp(number)
Returns e (Euler's constant) raised to the power specified by the single argument
math.ln(number)
Returns the natural logarithm of the single argument.
math.sqrt(number)
Returns the square root of the single argument.
math.atan2(x, y)
Returns the arctangent of y/x, with the correct sign for the quadrant. Wraps the ANSI C function of the same name.
math.e
Euler's constant: 2.7182818284590452354
math.pi
Pi: 3.14159265358979323846

Bitfield Library

bits.fld(string, startbit, length)
Interpreting the string str as bits, returns the bitfield of the specified length starting at startbit. Interprets the result as an unsigned integer.
bits.sfld(string, startbit, length)
As bits.fld(), but interprets the result as a 2's complement signed value.
bits.setfld(string, startbit, length, value)
Sets the specified value into the bit string at the specified position. The string must be mutable: either the result of a runtime concatenation (the ~ operator) or a call to bits.buf() (see below). Attempts to modify immutable strings (e.g. compile time constants) will produce a runtime error.
bits.buf(length)
Returns a zero-filled mutable string of the specified length.

UTF8 Library

utf8.chstr(unicode)
Returns a string containing the UTF8 representation of the specified unicode character value.
utf8.strc(string, index)
Returns the unicode character at the specified index within the UTF8 string. Dies on encoding error or overrun.
utf8.substr(string, start, len=nil)
As for regular substr(), but the indices are of UTF8 characters intead of bytes. Dies on encoding error or overflow.
utf8.size(string)
As for regular size() when called on a string, but returns the number of UTF8 unicode characters instead of bytes. Dies on encoding error.
utf8.validate(string, replace=`?`)
Checks the string for UTF8 validity. At every byte position where an encoding error is found, it replaces that byte with the specified replacement character (default is `?`). Note that the second argument is a number, not a string.

I/O Library

io.open(filename, mode="r")
Opens the file with the specified mode (as per ANSI fopen()) and returns a ghost object representing the filehandle. Failures are thrown as runtime errors as per die().
io.close(filehandle)
Closes the specified file as per ANSI fclose().
io.read(filehandle, buf, len)
Attempts to read length bytes from the filehandle into the beginning of the mutable string buf. Failures (including overruns when length > size(buf)) are thrown as runtime errors as per die(). Returns the number of bytes successfully read.
io.write(filehandle, str)
Attempts to write the entirety of the specified string to the filehandle. Failures are thrown as runtime errors as per die(). Returns the number of bytes successfully written.
io.seek(filehandle, position, whence)
As ANSI fseek(). Attempts to seek to the specified position based on the whence value (which must be one of io.SEEK_SET, io.SEEK_END, or io.SEEK_CUR).
io.tell(filehandle)
Returns the current seek position of the filehandle.
io.readln(filehandle)
Reads and returns a single text line from the filehandle. Interprets both "\n" and "\r\n" as end of line markers, and does not include the "\r" or "\n" bytes in the returned string. End of file or error is signaled by returning nil.
io.stat(filename)
Calls unix or win32 stat() on the specified file name and returns a seven element array whose contents are, in order: dev, ino, mode, nlink, uid, gid, rdef, size, atime, mtime, ctime. Errors are signaled as exceptions as per die().

Thread & Synchronization Library

Nasal's threadsafety implementation uses an internal, minimal synchronization library. The thread module exposes those primitives to script code.

thread.newthread(func)
Spawns a new thread that begins running in the specified function closure.
thread.newlock()
Creates and returns a new mutex lock.
thread.lock(lock)
Locks a mutex.
thread.unlock(lock)
Unlocks a mutex.
thread.newsem()
Creates and returns a new semaphore object.
thread.semdown(sem)
Executes a "down" operation on the semaphore, waiting until a separate thread calls semup() if needed.
thread.semup(sem)
Executes an "up" operation on the semaphore, increasing the internal count and waking up one waiting thread if needed.

Unix Library

unix.pipe()
Creates a pipe and returns a 2-element array containing the read and write filehandles. Runtime errors are signaled as per die().
unix.fork()
Forks the process as per the system call of the same name. Runtime errors are signaled as exceptions of the same name.
unix.dup2(oldfilehandle, newfilehandle)
Makes newfilehandle a copy of oldfilehandle as per the system call of the same name. Runtime errors are signaled as per die().
unix.exec(filename, argv, envp)
Calls unix execve() to replace this process with a new one. The argv and env arrays are passed to the new process. Runtime errors are signaled as per die().
unix.waitpid(pid, nohang=0)
Calls unix waitpid() to retrieve the exit code of a child process. The nohang flag causes WNOHANG to be passed to the system call. Runtime errors are signaled as per die().
unix.opendir(directorypath)
Opens the specified directory and returns a ghost handle. Runtime errors are signaled as per die().
unix.readdir(dirhandle)
Reads and returns the next filename from the directory handle. Runtime errors are signaled as per die().
unix.closedir(dirhandle)
Closes the specified directory handle.
unix.time()
Returns the current system time, in fractional epoch seconds. Uses gettimeofday() to achieve millisecond or better resolution.
unix.chdir(path)
Changes the current working directory. Runtime errors are signaled as per die().
unix.environ()
Returns the current unix environment as an array of strings of the form "VAR=value".

Regex (PCRE) Library

regex.comp(regex, opts="")
Calls pcre_compile()/pcre_study() and returns a ghost representing the compiled regular expression object. The opts string (corresponding to the "letters after the slash" in a perl regex) can contain the bytes: 'i' for caseless matching, 'm' for multiline behavior where '^$' can match next to a newline, 's' for single line behavior where the dot matches newlines, and 'x' for extended syntax allowing whitespace and comments.
regex.exec(regex, string, start=0)
Matches the regular expression against the string starting at the specified index. Returns a vector (the pcre "ovector") containing matches. Each match returned is stored as a start and one-past-end offset in the vector. An empty vector indicates no match. The first match is the entirety of the matched substring. Matches 1 and higher contain the parenthesized submatches, if any, in the order in which their opening parenthesis appears in the regular expression.

SQLite Library

Integration with the SQLite (www.sqlite.org) database engine.

sqlite.open(filename)
Opens a connection to a SQLite database in the specified file, creating the file if needed, and returns a db handle. Signals errors via die().
sqlite.close(db)
Closes the specified database connection. This call is generally optional; garbage collection will destroy stale connections.
sqlite.prepare(db, sql)
Creates a prepared statement on the specified database from the SQL code in the second argument. Signals errors via die().
sqlite.exec(db, stmt, [opt. callback], bind_args...)
Executes a SQL statement (either a string or a prepared statement returned from prepare()). The bind arguments are assigned in order to the "?" placeholders in the original SQL. Each row of the result, if any, is placed in a hash table indexed by field name. If the optional callback argument is specified, it is invoked once for each row, with the hash table as an argument. Otherwise, all rows returned are appended to a single vector and returned as the result of sqlite.exec(). Signals errors via die().
sqlite.finalize(stmt)
Finalizes and free storage associated with a prepared statement. This call is generally optional; garbage collection will destroy stale statements.

GNU Readline Library

Minimal but functional integration with GNU readline, allowing for runtime command line editing. This is used by the interactive module to implement the interactive nasal interpreter.

readline(prompt="> ")
Read and return a line of input from the user, or nil at end-of-stream.