In builtin function parameter lists, parameters set in italic are evaluated before use, while underlined parameters aren't.

STUTTER Builtins

Basic elements

Types

Lambda

Flow control

List manipulation

I/O

Math

String functions

Logic

Interpreter & Debug

Date/time

Array functions

OS

Blobs

Optional modules

SQLite

PostgreSQL

PCRE

Constants

nil and t

Constants meaning ( ) and true, respectively. These evaluate to the same nil and T object each time. If you need to create new instances, you can use (new-nil) and (new-t).

Error codes

The following constants are defined for error codes:

SE_UNDEFUndefined symbol (variable lookup failed).
SE_WTFReserved.
SE_PARMInvalid parameters (many builtins return this when they don't like their input).
SE_WFUNCInvalid function (trying to run a non-function).
SE_TYPEType mismatch.
SE_IPLISTNon-symbol in parameter list of function.
SE_PNUMInsufficient parameters (when calling a builtin or user function).
SE_IOI/O error (eg. upon failure to open a file to be loaded).
SE_PARSEParse error.
SE_NFNDNot found (the package asked for by require doesn't exist).
SE_LIMITRecursion limit exceeded.
SE_MEMMemory allocation error (shouldn't happen).
SE_MATHMath exception (eg. division by zero).
SE_COMMADeprecated.
SE_COMMA_SPLICEDeprecated.
SE_SQLITESQLite error.
SE_PGSQLPostgreSQL error.
SE_PCREPCRE/regex error.
SE_LASTThe first error code not used by the system.

Streams

Basic functions

(quote p)

Returns p unevaluated.

(set name value ...)

Evaluates name then sets the resulting symbol name to value. Multiple name-value pairs may be given; returns the value of the last assignment. Note that evaluation isn't atomic, it happens by pairs (so (set 'a 1 'a (+ a 1)) gives 2).

(setg name value)

Like set, except if it can't find the variable in the local variable context, it checks the parent variable context, and so on. It updates the first existing variable it can find; if there wasn't one, it sets the variable in the global context instead of the local one.

(scar cons value)

Set the CAR of the CONS to value. You can use this instead of setf.

(scdr cons value)

Accompanies scar: sets the CDR of the CONS to value.

(eval exp1 exp2 ...)

Evaluate all expressions twice, so that e.g. (eval '(+ 1 2)) will yield 3 (the first evaluation results in (+ 1 2), then that gets evaluated again). Returns the result of the last expression.

(subctx exp1 exp2 ...)

Creates a local variable context and executes all expressions in it. Returns the result of the last expression. The effect is not unlike that of a function call; sets will have only local effect.

(let assign exp1 exp2 ...)

Creates a local weak variable context, assigns some variables in it, then executes all expressions in it. Returns the result of the last expression. A let statement looks like this:

> (let ((a 2) 
        (b 3)
        (c 0))
    (set 'c (+ a b))
    c)
5

The assignment list is a list of lists. Each inner list has two elements: a symbol and a value.

Context weakness means that new bindings are forwarded to the parent context:

> (set 'a 1 'b 2) (let ((a 2)) (set 'a 3) (set 'b 1)) (cons a b)
(1 . 1)

(apply func list)

Calls the function func with list given as parameters. Returns the result. When func is a user function, the elements of the parameter list get evaluated, just like a normal function call. This helps macro and builtin functions work as expected.

(funcall func ...)

Calls the function func with the rest of the arguments given as parameters. Returns the result. The difference between this and (func ...) is that builtin object substitution isn't done (so (+ 1 2) doesn't get rewritten as (builtin:+ 1 2)).

(elev func list)

This is a variation of apply. It does the same thing, except the function is executed in the parent variable context. Note that while the evaluation of the parameter list argument to elev happens in the current variable context, the evaluation of each parameter (before passing to the function) is performed in the parent variable context.

(expand func args)

Returns the list the macro func would expand to if called with the args argument list.

(eq obj1 obj2 ...)

Returns T if all objs evaluate to the same object in memory.

(eql obj1 obj2 ...)

If the objects are all from the same type: integer, number, symbol or string, returns T if all objects have the same value. Otherwise, returns T if the objects are the same object in memory.

(equal obj1 obj2 ...)

Like eql, but checks objects (CONSes and arrays) deeply for value equivalence.

(begin exp1 exp2 ...)

Simply evaluates all its parameters and returns the last result.

Lambda

(lambda paramlist exp1 exp2 ...)

Returns a user function that receives parameters by the names listed in paramlist, with a body executing all expressions. The function will return the result of the last expression. For example:

(set 'square (lambda (x) (* x x)))
(square 3)
 9

(macro paramlist exp1 exp2 ...)

Returns a user macro. The result works like a function, except for two things: the parameters aren't evaluated as they're registered in the function variable context (i.e. if the user passes 'a, the macro gets 'a instead of a); and that the S-expression invoking the macro gets replaced by the results of the macro and is evaluated again.

This means that macros can be used to generate code using their arguments and execute it transparently. Here's a sample implementation of setq as a macro:

(set 'setq (macro (name value)
	(list 'set (list 'quote name) value)
))

(r-macro paramlist exp1 exp2 ...)

Works exactly like macro, except the result doesn't replace the invoking S-expression; the macro function is executed each time it's invoked.

(symbolic-macro paramlist exp1 exp2 ...)

Returns a symbolic macro function. This is a special object: when any symbol evaluates to such an object, the macro function body is executed (with no arguments), the result replaces the original symbol in the code and is evaluated again. Thus, by binding symbolic macros to symbols one can create "magic variables". For example:

> (set '*rnd-count* 0)
0
> (set 'rnd (symbolic-macro ()
                  `(list ,(setg '*rnd-count* (+ 1 *rnd-count*))
                         ,(random 100))))
m:RND()
> rnd
(1 58)
> rnd
(2 73)
> rnd
(3 50)

(r-symbolic-macro paramlist exp1 exp2 ...)

Exactly like symbolic-macro, except the macro result doesn't replace the invoking symbol; the macro function is executed each time the symbol is evaluated. Extending the previous example:

> (set 'getrnd (lambda () rnd))
l:GETRND()
> (getrnd)
(22 2)
> (getrnd)
(22 2)          ;; the same, since the symbol in the function has been replaced
                ;; use r-symbolic-macro to avoid this behavior

> (set 'rnd (r-symbolic-macro ()
                  `(list ,(setg '*rnd-count* (+ 1 *rnd-count*))
                         ,(random 100))))
m:RND()
> (set 'getrnd (lambda () rnd))
l:GETRND()
> (getrnd)
(23 26)
> (getrnd)
(24 33)

List manipulation

(cons a b)

Returns a CONS object: ( a . b ). Both parameters are mandatory.

(list n1 n2 ...)

Returns a list with all the parameters as elements.

(append n1 n2 ...)

All parameters must be lists, except the last one, which might be an atom. Returns the concatenation of all parameters into a single list (if the last parameter is an atom, it is used in the list as a terminator of the last CONS, instead of a nil).

(car obj)

Returns the left object of the obj CONS.

(cdr obj)

Returns the right object of the obj CONS.

(length list)

Returns the number of elements in a list.
If called with a string or a blob argument, returns the number of characters in the string or blob.

(mapcar func list1 list2 ...)

Calls func with consecutive parallel sets of elements from the lists until the shortest list runs out. Returns the list built from the return values.

(maplist func list1 list2 ...)

Like mapcar, except the parameters given to the function are the full remainders of the lists instead of cars.

(filter func list1 list2 ...)

Like mapcar, except the return list is built from those values of the lists for which the function returns true. If there's more than one list, the return list will contain lists of the parallel sets:

> (filter (lambda (x y) (> (+ x y) 5)) '(4 5 6) '(1 2 3))
((5 2) (6 3))

(filterlist func list1 list2 ...)

Like filter, except the parameters given to the function are the full remainders of the lists instead of cars. The return list is still built the same way.

Flow control

(if tval trueexp falseexp)

If tval isn't nil, executes trueexp. If tval is nil, the optional falseexp is executed if given. Returns the result of the executed expression.

(cond clause1 clause2 ...)

Each clause for cond has to be a list. The first element of the first clause is evaluated; if this results in non-nil, the rest of the elements in the clause are evaluated and the result of the last one is returned. Otherwise, processing moves on to the next clause. If there are no more clauses left (all tests returned nil), nil is returned.

(while exp body1 body2 ..)

This is a loop construct: first evaluates exp and exits if it's nil. After, it executes the (optional) body expressions, then repeats the cycle. Returns the result of the last evaluation of the truth exp, always nil that is; except when return was called inside to return a specific value.

(do assign test body1 body2 ...)

A do statement looks like this:

> (do ((x 1 (+ x 1))
       (y 1 (* y 2)))
      ((> x 5) y)
    (println y)
    (println 'working)
  )
1 
working 
2 
working 
4 
working 
8 
working
16 
working 
32 

The first part of a do specifies what variables to bind, what their initial values are, and how to update them. The second part specifies a termination condition and a return value. The last part is the body. A do form binds its variables to their initial values like a let, then checks the termination condition. As long as the condition is false, it executes the body repeatedly; when the condition becomes true, it returns the value of the return-value form (if given; otherwise it returns the non-nil value of the condition).

(catch codelist func exp1 exp2 ...)

Catch/process an error. codelist should contain a list of integers: codes for the errors one wishes to catch; or it can be T if everything (any error) needs to be caught. If evaluating the expressions generates a suitable error, func will be called with three parameters: error code, error message, and an error object if supplied (nil if not); the result is returned. If no error occurs, it evaluates all expressions and returns the result of the last one. If there's an uncaught error, it passes it down. (This means if an error occurs, caught or uncaught, no futher expressions will be evaluated.)
Example:

> (catch (list SE_PARM) (lambda (code msg obj) (list code msg obj)) (+ 1 2) (/ 2 0))
ERROR SE_MATH: Division by zero at stdin:1
> (catch (list SE_MATH) (lambda (code msg obj) (list code msg obj)) (+ 1 2) (/ 2 0))
(12 "Division by zero" nil)
> (catch (list SE_PARM) (lambda (code msg obj) (list code msg obj)) (throw SE_PARM "go away" '(1 2 3)))
(2 "go away" (1 2 3))

(throw code message object)

Create an error of code (integer, see error codes), with optional message and optional object.

(return val)

Throws a SE_RET with no message and the object set to val (if specified, nil otherwise).

Logic

(not obj)

Returns T if obj equals nil; otherwise, returns nil.

(and exp1 exp2 ...)

Returns the first nil parameter and doesn't evaluate the rest. If there's none, returns the value of the last parameter.

(or exp1 exp2 ...)

Returns the first non-nil parameter and doesn't evaluate the rest. If there's none, returns nil.

Math

+, -, *, /

Primitive algebraic functions. Without parameters + returns 0, * returns 1 (the identity). With one parameter given, - returns 0 - n, / returns (1 / n).
+ supports strings (concatenation).
There's a special kind of multiplication supported: string by integer (only in the (* string integer) special form). (* "abc" 3) gives "abcabcabc". Negative integers will flip the result: (* "abc" -3) gives "cbacbacba".

Where applicable, if floats are mixed with integers in the argument list, these functions will promote integers to floats. For example, (/ 5 2) gives 2 (an integer), but (/ 5 2.0) gives 2.5.

<, >, <=, >=, =

Algebraic predicates. If given one parameter, they all return T; otherwise, they return T only if the respective relation is true for any two neighboring parameter.
These predicates support strings and symbols (by case sensitive strcmp comparison). Integers and floats can be compared, but strings and symbols cannot (without type conversion).

(mod num1 num2 ...)

Returns num1 modulo num2 (modulo num3 etc).

(lognot int)

Returns ~int (bitwise negation).

(logior int1 int2 ...)

Returns the arguments bitwise OR-ed together (inclusive OR). When called with zero arguments, it returns 0 (identity).

(logand int1 int2 ...)

Returns the arguments bitwise AND-ed together. When called with zero arguments, it returns -1 (identity).

(logxor int1 int2 ...)

Returns the arguments bitwise XOR-ed together (exclusive OR). When called with zero arguments, it returns 0 (identity).

Standard math functions

The following standard mathematical functions are available:

(rand mult)

Returns a random floating point number between 0 and 1 (multiplied by mult, if supplied).

(random limit)

Returns a random integer between 0 (inclusive) and limit (exclusive). If limit is negative, all returned integers will be negative too.

If limit is a list, returns a random element.

Array functions

(make-array dimensions initializer)

Creates an array. Dimensions is a mandatory parameter: a list of integers that specifies the sizes of array dimensions. The maximum number of dimensions an array can have are limited at compile time.

The initializer is an optional list to initialize the array content. If the array has multiple dimensions, the list will have to be a nested list. The array is initialized to nils by default.

Here's an example involving a multidimensional array:

> (set 'ar (make-array '(2 2 3) '(((1 2 3) (4 5 6)) ((7 8 9) (10 11 12)))))
#A<<<1 2 3> <4 5 6>> <<7 8 9> <10 11 12>>>
> (aref ar 0 1 2)
6
> (aset ar 0 1 2 "!")
"!"
> ar
#A<<<1 2 3> <4 5 "!">> <<7 8 9> <10 11 12>>>

(aref array index1 index2 ...)

Returns an item from an array, located by the specified indices. The number of indices given must be equal to the number of dimensions of the array.

(aset array index1 index2 ... value)

Sets an item in an array located by the specified indices. The number of indices given must be equal to the number of dimensions of the array.

(adim array)

Returns the dimensions list of an array.

(make-dictionary)

Returns a new, empty dictionary. A dictionary maps arbitrary keys to values. Keys have to be atomic: use integers, floating point numbers, symbols and strings, nothing else.

(dref dictionary key)

Returns the value associated with key in the dictionary. If the key is not found, returns nil.

(dput dictionary key value)

Assigns the value to the key in the dictionary. If the dictionary already has a value bound to key, the binding is updated.

(ddel dictionary key)

Deletes an item from the dictionary (returns T if an item was found and deleted, nil otherwise).

(dictionary-keys dictionary)

Returns a list of all keys in the dictionary.

String functions

(substr string start len)

Returns a portion of string, beginning at start (default 0, the string is just copied), up to len characters (by default, until the end of the string). If start is negative, it's interpreted relative to the end of the string (e.g. (substr "stutter" -3) gives "ter"). If len is negative, it's also interpreted relative to the end of the string (e.g. (substr "stutter" 1 -3) gives "tut").

(toupper string)

Returns string with all characters capitalized.

(tolower string)

Returns string with all characters converted to lower case.

(explode separator string limit)

Returns a list of strings, each of which is a substring of string formed by splitting it on boundaries formed by the string separator. If limit is set, the returned list will contain a maximum of limit elements with the last element containing the rest of string.

If separator is an empty string, returns nil.

(trim string)

Returns the string with head and tail whitespace removed.

(char->code char)

Returns the byte from the character (as an integer).

(code->char code)

Returns a character of byte code.

(utf8-length string)

This function takes a UTF-8 encoded string and returns the number of characters in it.

Interpreter control

(consdump obj)

Prints the obj CONS object recursively, using the full dotted notation. Returns nil.

(dumpctx)

Dumps name-value bindings in the current variable context.

(gc)

Performs garbage collection. Returns number of objects freed.

(trace func)

Enables tracing for a user function.

(untrace func)

Disables tracing for a user function.

(load file1 file2 ...)

Parses the files in the global variable context. If there's a parse error, returns immediately; otherwise, returns the result of the last expression in the last file.

(loadhere file1 file2 ...)

Parses the files in the local variable context. If there's a parse error, returns immediately; otherwise, returns the result of the last expression in the last file.

(require package)

Looks for a file named package.stt in the specified include path and loads the first one found (in the global variable context).

(requirehere package)

Looks for a file named package.stt in the specified include path and loads the first one found (in the local variable context).

(limit recurslionlimit exp1 exp2 ...)

Evaluates the specified expressions while setting the recursion limit. Use it with trace to track down infinite recursion bugs.

Types

(->num obj)

Returns obj converted to a number, if it can.

(->int obj)

Returns obj converted to an integer, if it can.

(->str obj)

Returns obj converted to a string, if it can.

(->symbol obj)

Returns obj converted to a symbol, if it can.

(->blob obj)

Returns obj converted to a blob, if it can.

(atom obj)

Returns t if obj isn't a CONS.

(listp obj)

Returns t if obj is a valid list: nil, or a list that has nil in the last CDR.

(functionp obj)

Returns t if obj is a user-defined or builtin function.

(isset symbol)

Returns t if symbol resolves to a value in the current variable context (i.e. whether it's defined in the current context or any of its parents).

(islocal symbol)

Returns t if symbol is defined in the local variable context.

Type predicates

These additional predicates exist for checking types:

I/O

(print obj1 obj2 ...)

Prints the values of objects, separated by spaces. Returns the value of the last evaluated object.

(println obj1 obj2 ...)

Works exactly like print, except it prints a final newline.

(princ obj1 obj2 ...)

Prints the values of objects, separated by spaces. Returns the value of the last evaluated object. Doesn't print quotes around strings.

(princln obj1 obj2 ...)

Works exactly like princ, except it prints a final newline.

(read stream)

Reads and returns one expression; throws SE_PARSE on a parse error. Returns EOF on EOF. The stream parameter is optional, *input-stream* is used by default.

(read-char stream)

Reads a single character and returns it. Returns EOF on EOF. The stream parameter is optional, *input-stream* is used by default.

(read-line stream)

Reads a single line and returns it. Returns EOF on EOF. The stream parameter is optional, *input-stream* is used by default.

(unread-char stream char)

Unreads a character into a stream, so the next read from the stream will yield the character as the result. No two subsequent unreads may be done on a stream without an intermittent read.

(make-stream func)

Returns a user stream created from the lambda function.

(open-file name mode)

Opens a file and returns a stream. Both arguments have to be strings. The mode argument works like that of fopen (in fact, the function itself is mostly a wrapper for fopen), but is optional (defaults to "r"). Close this stream by close-file when you're done with it. Might throw SE_IO on error (if, for example, the file to be opened for reading doesn't exist).

(close-file stream)

Closes a file stream.

(string-bucket)

Returns a special, write-only stream that collects all output inside. You have to empty the container to retrieve the output (as a string or a blob) and to free up memory. After this, the bucket is fully reset and reusable.

(empty-bucket bucket-stream [blob?])

Returns the contents of a bucket stream as a string, and empties the bucket. If the blob? argument is given and true, the data is returned as a blob.

Date/time

(get-time)

Returns number of seconds since the Epoch (an integer).

(get-decoded-time time)

Returns time in a decoded form (the time parameter is an optional integer (number of seconds since the Epoch), if not supplied, the current time is used). You get a list of nine elements:

(seconds minutes hours day-of-month month year
 day-of-week daylight-savings-p time-zone)

0 is Monday for day-of-week. Time-zone is generally not supported and should be ignored.

(mktime year month day hr min sec)

Constructs unix time from a broken down representation.

(sleep t)

Sleep t (integer) seconds.

OS

(getenv name)

Returns the value of the environment variable by name, or nil if it's not found.

(rename name1 name2)

Renames/moves file "name1" to "name2". Throws SE_IO on error.

(unlink path)

Unlinks file. Throws SE_IO on error.

(readdir path)

Reads the directory at path; returns a cons with a car that's the list of directories, and a cdr that's the list of files found there. Throws SE_IO on error.

Blobs

(blob-dump blob)

Outputs the contents of the blob to *output-stream*.

(blob-read size)

Reads at most size bytes from *input-stream*, and returns the result as a blob. May return EOF if there was nothing to read.

(blob-slice blob [start [len]])

Returns a part of the blob. Semantics are similar to that of substr.

(blob-find haystack needle [right? [start]])

Find a blob inside another blob. Returns offset, or -1 if not found.

By default, returns the leftmost result. If the right? parameter is given and is true, returns the rightmost result.

If given, the start parameter specifies the position where to begin the search. When right? is true, should be given as the offset of the first byte after the last potential needle (in other words, the origin is the length of the haystack).

(blob-cmp blob1 blob2)

Compares two blobs (like memcmp; returns an integer).

(blob-string blob)

Tries to take the string value of a blob. Will throw SE_PARM if the blob contains a zero byte.