%% – % character
RETURNS: | the rest of val that cannot be parsed or if the format line is ended
|
span(arg delims)
skips a prefix of arg which contains solely of characters from delims
reverse(arg)
pad(arg length [pad-char])
pads an arg to a specific length using pad-char as a filler (space by default). No truncation occurs if arg already exceeds length
If lenggth is positive, arg is right-justified, otherwise – left-justified.
substit(arg substr repl [flags])
Substitutes repl for occurences of substr in arg. Flags may be used to control the behaviour:
-
nocase case is ignored when looking for a substring
-
first only the first occurence of substr is replaced
-
pattern uses a simple pattern technique when looking for and substituting, namely \a in substr means 'any character', \a in repl – 'the character found at the corresponding position'; \v – the whole found substring.
NOTE: | Pattern metacharacters should not be escaped twice – they are really BEL and VT characters. No escaping mechanism is present, since literal usage of those characters should be rare enough.
|
RETURNS: | arg with substitutions made
|
expand(arg [storage [delims]])
expands variables in arg. The syntax here is slightly different from the standard: namely, '$$' means literal $; computed variable names aren't allowed; tag references aren't allowed too. If
storage is present and not empty, not the real variables are used for expansion, but items from
storage
call(proc-name [arg ...])
calls a procedure proc-name with args in the current execution environment. proc-name may be either a user-defined procedure or a builtin
RETURNS: | the result of calling proc-name; null if proc-name doesn't normally return a value
|
.(proc [arg...])
like call but the result replaces the contents of the current execution buffer
defstream(name extname type [writeable])
defines a stream with name of type and links it to an external entity extname (what depends on the type of the stream). If name is null or '*', a stream is assigned a unique name. If writeable is present and true, the stream can be written to.
NOTE: | Whether it is possible to read from a writeable stream depends on the kind of stream
|
RETURNS: | the name of the stream
|
rmstream(stream)
This function is not completely equivalent to release stream, since it checks whether the stream is the current input or output stream, and if so, clears it, so that there were not invalid pointers
instream([stream])
if stream is present, sets the current input stream to stream; if null, sets the current input stream to none
RETURNS: | the name of the current input stream, or null if none
|
outstream([stream])
if stream is present, sets the current output stream to stream if null, sets the current input stream to none
RETURNS: | the name of the current output stream, or null if none
|
defproc(name body)
defines a procedure in the current environment with name and body. Note there is no way to specify named parameter aliases here (see SYNTAX OVERVIEW below)
defprocin(subint name body)
like defproc but operates on the environment subint no matter whether it has defproc allowed
isproc(name)
RETURNS: | true if a procedure name is defined in the current environment
|
iscallback(subint name)
RETURNS: | true if a procedure name within subint is a callback
|
NOTE: | this function is provided primarily for security reasons – to ensure that a called function wouldn't hurt the caller. It seems to be no use to check the environment's own procedures.
|
getenv(name)
RETURNS: | the value of an environment variable name or null if it is not defined
|
setenv(name value)
sets an environment variable name to value, probably overwriting the existing one
ERROR: | setenv 'name' to 'value' failed
|
sql(subcommand [arg])
An interface to SQL. Refer to sl_sql(1) for more details
feature(name)
RETURNS: | true if a feature name is supported by the interpreter. There are following special features currently defined:
|
-
::locking – is file locking supported by the OS
-
::fileno – may fileno be obtained (in general)
-
::isatty – does the OS support `isatty' function
-
::modules – are loadable modules supported
-
::refs – are variable references enabled
-
::pipes – are pipe flows available
-
::module::<modulename> – is modulename installed, i. e. is it in the module map
Other featutes will be added in future, all started with `::'
Any other value not listed above is treated as a name of a builtin function, then
feature tests for its presence
version([module])
RETURNS: | the version of the interpreter or of the module A special value [libutils] is used to obtain the version of the underlying libutils library.
|
builddate([module])
RETURNS: | the build date of the interpreter or of the module in the format of "MMM DD YYYY" like __DATE__ macro in C
|
NOTE: | This function is of little real use. Its value, for obvious reasons, cannot be used to check features, bugs etc. Use
srcdate instead.
|
srcdate([module])
RETURNS: | the date of the latest modification of the source in the form YYYY/MM/DD. The argument has the same meaning as for version
|
pid()
RETURNS: | a PID of the interpreter process
|
id([subint])
RETURNS: | a unique id of the environment subint or of the current environment if subint is omitted
|
caller([type])
RETURNS: | an identification of the environment that called the current procedure. If type is omitted or is 'subint', the internal name of the caller in the current environment is returned (or null if the caller is not subordinate to the current environment); if
type is 'id', the unique id of the called is returned; if type is 'extname', the exported name of the caller is returned, or null if it is not exported.
|
sysvar(name [value]
gets or sets an internal interpreter variable
The following variables are defined:
-
mem:squee_interval
-
mem:squee_long
-
mem:maxreserved
-
mem:maxkeep
-
env:location. This variable contains a path to where all Tensile files reside and is read-only
-
sys:maxint, sys:minint – maximal and minimal integer values (r/o)
NOTE: | those variables are global so you'd better restrict sysvar for unsecure environments
|
SYNTAX OVERVIEW
Source file
A source file consists of a series of procedure definitions and directives. A directive starts with '.' if it occurs outside any procedure definition, and with '..' elsewhere
NOTE: | this is ugly. I am thinking on changing '.' to '!'
|
Procedure
Procedures may be of three kinds: plain procedures, tag handlers and character filter. The latter two are used when processing input stream and cannot be called directly. The definition of a plain proc starts with its header, followed by its body. The header consists of an optional qualifier, the procedure name and an optional parameter declaration.
An optional qualifier may be either :void: to indicate that a function returns no meaningful value and can therefore be used only at the top level; or
:pure: indicating that a function produces no side effects and that it may and will be executed at parse-time if all its arguments are constant.
The procedure name may end in * indicating a callback function. A callback function is executed within the execution environment of a caller, not in its native environment.
The parameter declaration has the following syntax:
argname1 argname2 ... optargnamei=value ... // [][...][]])
The declaration may be empty as well, meaning no arguments allowed. If the declaration is present, during parse-time
argnames are translated into 'def argnamei = argi)', so that reading access might be available by name, not by index. The number of arguments is also checked when entering the procedure. Arguments followed by
are optional – if they are not present, the default value is assigned. No required arguments may follow optional ones. A ... means unlimited maximal number of arguments (all unnamed actual parameters are accessible thru their indices only)
NOTE: | parameter names behave exactly like local variable, i. e. they cannot be overriden by following
defs; when setting the parameter, the actual parameter accessible thru arg does not change, only its named alias. If a parameter is optional and is not present, its default value is assigned to the alias only, not to the parameter itself
A ; may also be present in the argument list. It marks the argument which is considered the last one if a second form of the procedure call is used (see below)
The definitions of tag handlers/filters start with 'tag' or 'char' resp. followed by a glob-like pattern followed by the body
The body is a sequence of procedure calls surrounded by {}
|
Top-level procedure call
Procedure calls at top-level may look either as normal procedure calls (see below) or as following:
procedure-name arg1 ... argn ;
NOTE: | ';' may be missing; then the default number of arguments for a given procedure is assumed. For some procedures such number is unlimited, so you'd better always end such calls with ';'.
|
NOTE: | a newline is not a terminator!
If a procedure-name starts with ::, the rest of it is interpreted as a user-defined procedure even if a builtin with the same name exists. This holds true for inner procedure calls and for indirect calls via
call as well.
|
Arguments & chunks
Each argument is a series of chunks ended with a space. The value of an argument is concatenation of values of all its chunks. Chunks may be of ... kinds (yielded values are in parentheses):
-
single character (the character itself). A character may be an escape sequence too.
-
single-quoted string (the same). Escape sequences are allowed.
-
text (the same). It has the following syntax: <delim-id spaces text delim-id>>. Spaces in the beginning of the text are eaten. Escape sequences are not recognized.
-
parameter It starts with '$' following by a digit or '#'. When '#' is given, the value is the number of parameters of the current procedure. If '0' is given, the value is the contents of the working buffer. Elsewhere, the value is the
nth parameter of the current procedure.
-
variable It starts with '$' followed by variable name. If the name is not an identifier or may produce an identifier with the following text, parentheses are used to delimit the name. If the variable is not defined, an error occurs.
$(expr)) is equivalent to var(expr).
-
tag Its syntax is $[tagname] where tagname is the same as an argument for tag. If the current chunk is not defined or has no such parameter, an error occurs.
$[expr)] is equivalent to tag(expr)
-
double-quoted string. It is considered as a sequence of chunks ended with a closing quote.
-
bracketed string. It is a sequence of chunks ended with a closing bracket. It is much like a dq-string, but since opening and closing characters differ, bracketed strings can be nested.
-
bracketed quoted string. It is a single-quoted string enclosed in brackets. It is equivalent to expand(single-quoted-str)
-
backquoted string. `string` is equivalent to eval('string')
-
block is in all respects similar to a procedure body. In fact, blocks may be regarded as unnamed procedures. Though local variables of an outer block/procedure are accessible within an inner one.
PREPROCESSING DIRECTIVES
NOTE: | Only .if.../.else/.endif and .env directives are allowed within procedure body
|
.include <name> or .include "name"
switches to processing file name; after the end, the current file continues. The maximal depth of nesting is not limited.
If angle brackets are used, the script is searched for in SCRIPT_PATH, otherwise in the current directory
.if expr ... .else ... .endif
evaluates a NSL expression expr and if it is null skips until matching .else/.endif. expr is limited by the end-of-line
.ifdef proc-name
is equivalent to .if isproc(proc-name)
.ifndef proc-name
is equivalent to .if not(isproc(proc-name))
.ifhas feature-name
is equivalent to .if feature(feature-name)
.ifhasnt feature-name
is equivalent to .if not(feature(feature-name))
.pool name or .pool "name"
creates a shared variable pool name. If it exists already, nothing happens. Sets the current pool for the following procedure definitions to it (or sets no pool if
name is null or 'none')
.error error-msg
generates an error error-msg
.env name = value
is equivalent to setenv(name value) at parse-time
name and value may be either identifiers or strings limited by "
.do { some-code }
executes some-code at parse time
.module <module-name
loads the module module-name and attaches it to the current environment. If module support is off, do nothing. If 'module' builtin is turned off, generates an
ERROR: | loading modules is prohibited
|
.pragma module-name pragma
.declare name declspec
declares a procedure name according to declspec. Declspec has the following form: minarg[-maxarg][/defarg][v|p]
If maxarg is missing, it is considered equal to minarg. If defarg is missing, the parethesesless notation for name is not allowed. maxarg as well as defarg may be $. that indicates infinity.
v means `void' showing that a function does not return a value; p means `pure', i. e. a function can be computed at parse-time provided its arguments are constant
.override name declspace
the same as .declare but overrides any existing declaration for name
.line lno
sets the current logical line number to lno
NOTE: | This affects error messages only, not the processing (like #line in C)
|
.automaton name
creates an automaton name All the following text up to .end directive is treated as the automaton body
PREDEFINED STORAGES
Each environment predefines a set of storages:
LOCALS, GLOBALS, SHAREDS
Those storage provide access to lists of resp. local, global and shared (of the current pool) variables. Access to items of the storages is fully equivalent to accessing the variables itself.
NOTE: | There is no builtin to remove global and shared variables; this can be done via
remove GLOBALS ... or remove SHAREDS ... resp.
|
ARGV
This storage gives access to command-line options. This storage is read-only and silent in the sense that accessing to a missing argument yields null, not an error (though
check will return true only for arguments actually present)
Other types of storages will be added
BUGS
Presumably, lots of them. But the major one is incomplete documentation...
Please, use Savannah facilities at http://savannah.gnu.org/projects/nsl to report bugs, request for support etc or mail me directly to artem@AA577.spb.edu
Prev Top