A command in StackLang is stored as a string. Commands can be either quoted or unquoted. Unquoted commands on the stack are automatically evaluated, while quoted commands on the stack are treated as data. It is not possible to have an unquoted command at top level in the stack without it being evaluated, outside of error cases.
An EBNF definition of commands is given below.
alphabetic-character = ? Any ASCII character in the ranges (inclusive) a-z, A-Z ? ; numeric-character = ? Any ASCII character in the ranges (inclusive) 0-9 ? ; symbolic-character = "-" | "?" | "*" ; character = alphabetic-character | numeric-character | symbolic-character ; quoted-symbol = "`" ; quoted-command = quoted-symbol, alphabetic-character, {character} ; unquoted-command = alphabetic-character, {character} ; command = quoted-command | unquoted-command ;
command? : Any -> Boolean
Produces true if input is a command. In practice, this is equivalent
to quoted?
.
quoted? : Any -> Boolean
Produces true if input is a quoted command.
defined?: Command -> Boolean
Produces true if given command is defined.
local? : Any -> Boolean
Produces true if define bound to this command has a context. Command
must exist - fails with a RuntimeError
if command does not exist.
unquote : Command -> Command
Turns a quoted command into a command, which, by the evaluation
rules, is immediately evaluated. No command exists that quotes a command, since unquoted commands can't
exist on the stack.
command-to-string : Command -> String
Produces the string-form representation of the command.
Includes the inital grave symbol, `.
string-to-command : String -> Command
Parses a command, as if it were read in from the
interpreter. Fails with a RuntimeError
if string cannot be parsed. If resulting command
is not quoted, result is immediately evaluated.
string-to-command* : String -> Command
Parses a command, as if it were read in from the
interpreter. Fails with a RuntimeError
if string cannot be parsed. Resulting command is
coerced into quoted form automatically.
For all of these commands, the given command must exist, and these commands will fail with a RuntimeError
if
the command does not exist.
arity : Command -> Number
Produces the arity of the given command.
body : Command -> Substack
Produces the body of this command. Fails with a RuntimmeError
if
given command is not defined.
context : Command -> Command
Produces the context of this command. Fails with a RuntimeError
if
none exists.
signature : Command -> Substack(Types)
Produces the signature of this command (the list
of types it expects, in order).
gensym : -> Command
lambda : Substack Substack(Type) -> Command
Defines a function in the global context with
a name created by gensym
, and produces the name.