Telerin Piki Language Reference

2007 Edition

The following is two years or so out of date, as of this writing. It lacks several of the late features added to Telerin, including event triggering (with @on) (and therefore error handling) and job locking. It reflects the state of the language that most software was written in.

The job locking feature is a rather important omission, however, so let me explain it: it allowed programs to tell the system when they had nothing to do, when previously they had to enter very CPU-intensive idle loops. In fact, the CPU originally was incapable of entering sleep mode, and `lock was added as a result. It allowed jobs to go to sleep when not working, and increased speeds of the system drastically; no longer did two MUE users connected at once mean half the normal CPU response time, because such user-input-oriented programs spend most of their time waiting for input anyway. (This feature was called MicroNap when it was introduced in Telerin 2.2.)

_context

Allows the prefix of commonly-used data for nested variable names when they are
referenced.

        _context = "spam"
        .magic = "happiness"

is equivalent to

        spam.magic = "happiness"

This can be useful for large batch operations, such as public segs that need to
keep their storage away from the main program. _context can be manipulated like
any other variable, and is stored directly on the program's memory plate.


_false

Returns 0.


_jobnum

Returns the operating index of the currently running job. This number
(although not necessarily this mechanism for accessing it) is important in
all job-related functions.


_keydown

Returns chr(0) & chr(80).


_keyleft

Returns chr(0) & chr(75).


_keyright

Returns chr(0) & chr(77).


_keyup

Returns chr(0) & chr(72).


_lock

_lock is used to halt the execution of a program pending some condition. A program's
execution is halted as long as the line of code specified in _lock evaluates to a
null string or "0". The _lock variable is deleted once its condition is met. An empty
_lock string tells the task scheduler to ignore the job. (This is not recommended.)

        echo "Please input some text: " &
        _lock = "`lastdata"
        echo "You inputted: " & `lastdata & chr(13)

_lock may contain more complex instructions, but be aware that it will affect system
performance to have an extremely complex _lock.

        _lock = "if int(_rnd * 20) = 30 then `lastdata"

This example makes it look like the system is under heavier load than it is. (See the
entry for if for more information on this line's syntax.)

To insert a quotation mark into a lock, use chr(34).


_mycode

The code, in running condition, of the current process. See pxss_jc and
set_code for more information.


_nil

Returns a blank string.


_pi

Returns pi to 63 decimal places. Not that you can use that much of it in
math functions, however.


_plate

The table which variables are currently being written to, read from, and
modified on. This is modified with every pass to be equal to _jobnum.


_rnd

Returns a random number between 0 and 1. This can be controlled through the
following mechanism:

        int(_rnd * range) + offset

With offset = 1 and range = 5, this mechanism returns a random number
between 1 and 5.


_space

The variable table on which all memory space interactions are currently
occuring.


_t

Returns 1.


_termnum

Returns the number of the terminal that the job has been bound to through
the use of bind_job or the built-in job executor.


_timer

Returns the number of seconds that have elapsed since midnight.


_timestamp

Returns a dense string containing the current time.

YYYYMMDDHHNNSS
  | | | | | |
  | | | | | `- Second of Minute
  | | | | |
  | | | | `--- Minute of Hour
  | | | |
  | | | `----- Hour of Day
  | | |
  | | `------- Day of Month
  | |
  | `--------- Month of Year
  |
  `----------- Year

For a more precise measurement, see _timer.


_todegs

Returns the numeric constant required to convert a number specified in
radians to degrees.

        radians * 57.2957795130824 = degrees


_torads

Returns the numeric constant required to convert a number specified in
degrees to radians.

        degrees * 0.0174532925199433 = radians


_true

Returns 1.


`lastclick

Returns the following information about the last mouse click on the ECVD
display:

button[shift]@x,y

Where shift is a binary nibble specifying what bucky bits were suppressed
at the time:

        BIT        VALUE        MEANING
        1        1        shift
        2        2        control
        3        4        alt

Buttons:

        BIT        VALUE        MEANING
        1        1        left
        2        2        right
        3        4        middle
        (etc for extended mice)


`lastdata

A global variable that contains the text last received from any terminal.
The number of this terminal is stored in `lastnum. If the current job is bound
to a terminal, `lastdata returns the text last received from that terminal.
The terminal also sets a private `lastnum variable to its number when a message
is received.


`lastnum

The number of the last terminal to send a message to the system. This is
not read-only, and it is standard practice to set it to -1 if no other
terminal has said anything.

If the current job is bound to a terminal, `lastdata returns the text last
received from that terminal. The terminal also sets a private `lastnum variable
to its number when a message is received.

        if `lastnum = _termnum then if `lastdata = data_we_got then `lastnum = -1


`pxss_cs

The speed of program execution achieved on the last run of PXSS's main
loop, specified in cycles (one line for every process) per second.


`pxss_gc

The number of processes that Telerin has created since it was started. This
number is used to determine a process's _pid.


`pxss_jc

The number of simultaneous processes that Telerin can support. Usually
a power of 2 - 1. PXSS 816/11 can support a maximum of 32767, theoretically
65535, jobs.


`pxss_jr

The quantity of processes currently running.


`skynet_opts

Returns a string listing the active and inactive terminal connections as 1s
and 0s, respectively.

        len(`skynet_opts)

is equal to skynet_peak.


`skynet_rev_opts

Returns a string listing the active and inactive reverse skynet connections
as 1s and 0s, respectively.

        len(`skynet_rev_opts)

is equal to skynet_rev_peak.


`system_keyb

In the emulator, the filename of the system keyboard map. In real hardware,
the system keyboard map itself. See the hardware documentation for the
system keyboard map format. This pertains primarily to 605/11s, not Skynet
640/11s.


`system_root

In the emulator, the path prefix from which the current 'real' directory
is derrived. In real hardware, the raw name of the root device.


{private}

Any variable name that begins with the string {private} is hidden to
other processes that attempt to peek at or modify it, even through dcb.
The children of a {private} variable are hidden as well.


asc(x)

Returns the ASCII value of the first character in x.

        asc("A") = 65

Characters below 32 (space) are reserved for control codes. (Important ones
are chr(10), linefeed; chr(13), linebreak; chr(9), tab; chr(8), backspace
and chr(7), bell. chr(1), chr(2) and chr(25) have reserved functions in
Cordicom Telerin.)

Note that, beyond 127, the character set varies widely. Windows and IBM PCs
have different character sets from each other, as do Telerin built-in
terminals. Most remote terminals conform to the stripped-down version of
what Windows implements, which has since become the start of Unicode.



backspace term, chars

Backspaces chars times on terminal term. Does NOT presently work over
Skynet.


bind_job job, terminal

Binds job job to terminal terminal. This determines what terminal job will
output to, and can be later read by that job with the variable _termnum. If
a terminal becomes jobless, it (sometimes) only presents the job execute
prompt if no processes are bound to it. A job's terminal can be read with the function pxss_jt(). The inverse of this function is bind_term.


bind_term terminal, job

Binds terminal terminal to job job. A terminal that is not bound to any jobs
presents its user with an execute prompt. The reciprocal of this function
is pxss_tp() and the inverse is bind_job.


blanks(x)

Returns a string consisting of x spaces. Couple with replace() to produce
a tasty string of many interesting attributes:

        pattern = "_,.-'`'-.,"
        length = 35
        magicstring = replace(blanks(length), " ", pattern)
        magicstring = left(magicstring, length)
        echo magicstring

And thus:

        _,.-'`'-.,_,.-'`'-.,_,.-'`'-.,_,.-'

A very pretty line indeed.


broadcast data

Sends the string data to all terminals connected. See echo for more
information.

case x: statement

If the universal value specified by the last readvar is equal to x, then
execute statement. The practical uses of this are generally considered to
be very low. Once a case statement is executed, no other case statements
may catch the condition.

case else: statement

Evaluates to true if no other case statement has been evaluated to true
since readvar was last set.


cchars(field, data)

Returns the quantity of times that the string data occurs within the string
field. This includes overlapping matches:

        cchars("isisi", "isi") = 2


chr(x)

Returns the character with the ASCII value x. Most common use: the
linebreak. See notes at asc() for an extensive chart of ASCII codes and
beyond.


cos(x)

Returns the cosine of x, in radians.


cujo(x)

Creates a job from the file x with no parameters and returns the job number.
Used only when parameters are definitely not required and is only very
slightly faster than pxss_go(), the recommended call for accessing Exec.
Note that cujo is older, so you may occasionally see programs that use the
format

        set "foo", cujo(":lalala.pk"), _jobnum
        set "_params", "these are your parameters", foo

This is generally considered stupid, because of the chance that the
job number of the newly-created job might change between these two lines.

Both this and pxss_go predate _pid, getpid() and findpid().


curdir(x)

Returns the current directory of terminal x. All file-reading functions,
including job execution (although not file-writing or cfg-handling) and
excluding writefile will look in the current directory of the job they're
bound to if they are given a path that does not begin with a colon (see note
at readfile).


dbg x

Echos x to the debugging console, with [@]
added onto the end.


dbl_eval(x)

eval()s x twice. This allows for the storage of math in x. Take the example
from eval() and consider:

        dbl_eval("sin(1)") = .841470984807897


dcb(x)

Returns the variable table of job x. Variable names beginning with {private}
and all of their children are hidden from dcb() unless x = _jobnum.

Variables are stored in memory in the following format:

        chr(13) & "[" & varname & "]=" & data & chr(4) & varname & chr(4)

Variables can contain child variables, to create a basic tree, simply by
writing them inside. A child or 'nested' variable's name, when in
use with GetVar, PutVar and kill, can be broken into elements, which are
separated by periods, with the oldest parent on the outside. PutVar is
written in such a way that any number of levels can be created on access.

        ($ represents chr(13) and # represents chr(4) in the following)

        _space = _jobnum;megastash "";// Clear the current job's var table
        parent.child = "data"
        echo dcb(_jobnum)

        $[parent]=$[child]=data#child##parent#

        echo parent

        $[child]=data#child#

The statement dcb can be used to immediately dump a variable table to a
the calling job's current terminal.


dcb x

See dcb(). Echos the contents of job x's variable plate, with {priate} data
removed, to the terminal that this process is currently bound to.


dcl x

Creates the variable specified by the string x with default content of ""

dcl num x

Creates the variable specified by the string x with default content of ""

        dcl num "my_number"
        dcl "my_string"


dclcfg col, var, val

Creates the variable var inside of CFG collection col with the initial
value val. Attempting to declare a variable more than once will append the
new declaration to the end of the collection and is a BAD IDEA unless you're
really stuffed for a logging format. A common structure is:

        if getcfg(col, var) = "deadbeef++" then dclcfgcol col
        if getcfg(col, var) = "deadbeef" then dclcfg col, var, val
        setcfg col, var, val

(Although not necessarily an efficient one.)


dclcfgcol x

Creates the CFG collection x. See getcfg() for more information on CFG
collections.

        dclcfgcol x

Is equivalent to

        writefile ":cfg\" & x, ""


delcfg col, var

Deletes the variable var from CFG collection col. See getcfg() for more
information on CFG collections. If there is more than one occurance of var
in col (not that there ever should be), only the first will be deleted.


delcfgcol x

Deletes the CFG collection x. See getcfg() for more information on the CFG
collection system.

        delcfgcol x

Is equivalent to

        fsmu_rm ":cfg\" & x


dropseg

Unloads a segment of code that was loaded with loadseg and returns
execution to the line after the point of entry.


echo data

Echos a string or variable to the terminal the job is currently bound to,
like C printf(). Note that this does not include free linebreaks, thus you
may want to get in the habit of

        echo "hello!" & chr(13)


echocast mask, data

Echos the text data to all terminals according to the variable mask. A 1 in
the first byte means that the message will be sent to the first terminal
(which is terminal 0, the console.) A 2 in this position means that the
message will be sent to the terminal that the first job (job 0) is bound
to. As a general rule, mask values effect job/terminal (offset - 1).


ecvd_cl

Clears the Elachrome video display and replaces the whole thing with pure
black (0, 0, 0).


ecvd_db xa, ya, xb, yb, r, g, b

Draws a hollow rectangle on the Elachrome video display, with corners (xa,
ya) and (xb, yb), using colour rgb.


ecvd_dc xa, ya, rad, dia, r, g, b

Draws a circle on the Elachrome video display, with centre (xa, ya), a
radius of rad and using colour rgb. "dia" is discarded.


ecvd_dl xa, ya, xb, yb, r, g, b

Draws a line on the Elachrome video display, from point (xa, ya) to point
(xb, yb), using colour rgb.


ecvd_ds xa, ya, xb, yb, r, g, b

Draws a filled rectangle on the Elachrome video display, with corners (xa,
ya) and (xb, yb), using colour rgb.


ecvd_ps xa, ya, r, g, b

Sets the pixel at (xa, ya) to colour rgb on the Elachrome video display.


ecvd_pt xa, ya, family, size, opts, r, g, b, message

Prints the text message at (xa, ya) in the font family at size size points in the colour rgb.

opts is a binary nibble consisting of the following:

Adding 1 to opts toggles bold, adding 2 to it toggles italics, adding 4
toggles underline and 8 toggles strikeout. Thus, opts = 3 would give the
printed text a "bold italic" effect, because opts would be equal to 1 + 2

        BIT        VALUE        EFFECT

        1        1        Bold
        2        2        Italic
        3        4        Underline
        4        8        Strikeout


else targname

Skip execution to the equivalent endif targname. (see endif) Also used as a
destination by if-endpoint (see if). This is part of the "multi-line if
statement" structure.


endif targname

Execution jumps here from an else targname (see else). Indicates the end of a
"multi-line if statement" (see if).


eraw x

Prints x to the debugger without any source identification. Contrast with
dbg.


eval(x)

Evaluates the contents of x. What purpose this serves is little-known, but
the construction

        eval(eval(x))

allows the storage of math in a variable:

        theta = 1
        math = "sin(theta)"
        echo eval(eval(math))

Returns

        .841470984807897

This has been, for the sake of
convenience, implemented as dbl_eval() as well.


eval x

See eval().


exec string

Instantly and immediately executes the file specified by string. This is
considered a BAD idea because it holds up the rest of the system. exec is
curdir()-aware.


f_exist(x)

Returns the first filename matching the provided search pattern. The search
pattern may contain a path name and a file name, with asterisk wildcards to
indicate a string of variable length, or question marks to indicate a
single character. These wildcards may only occur in the filename itself. If
no file is found, f_exist() returns an empty string. f_exist() is sensitive
to curdir().


fern_tn(x)

Returns the soft name of terminal x. In the emulator, this is configured by
Machine\termnames.cfg. Otherwise, this is configured in the 605/11 terminal
controller's hardware.


fetch(var, plate)

Fetches the contents of variable var from job plate. var should be in
quotes:

        fetch("user", 0) = "cordica"


findpid(x)

Returns the job number of the process with the unique identifier x. If this
is invalidly low, findpid() will return -2. If it not running, findpid()
will return -1. See _pid for more information on unique identifiers.


for counter = initval

Sets the variable counter to initval. This is also used as a target (in the
partial form "for counter") by the next statement. for and next are part of the
"countered loop" structure. The same counter name cannot be used more than
once in a program.

        for x = 5
            echo "X = " & x & chr(13)
        next x (i x) until x = 10

Although the syntax is presented here as counter = initval, the assignment
in the = sign is processed by the normal language facilities. Thus, statements
can be substituted for counter because of next's flexibility (see next):

        m = readfile(":tmp\value_m")
        for i m
            echo "m = " & m & chr(13)
        next i (i m) until m = 10

The usefulness of this is sketchy, but it is extant. Again, remember that
the counter name must be unique.


fsmu_cp source, destination

Copies from one file to another. Does not accept wildcards. Is aware of
curdir().


fsmu_dl(x)

Returns a list of subdirectories in directory x. Sensitive to curdir(). Each
entry in the list is followed by chr(13). This list may sometimes be out of
date if fsmu_fx(), fsmu_fl(), fsmu_dl() or fsmu_fl() have not been used on
another directory since it was last called. (No, no one knows why, and
attempting to make it list the contents of a throwaway directory first
doesn't seem to work. This is considered an FSMU bug.)


fsmu_dx(x)

Returns 1 if directory x exists, 0 if not. Sensitive to curdir().


fsmu_fl(x)

Returns a list of files in directory x. Sensitive to curdir(). Each
entry in the list is followed by chr(13). This list may sometimes be out of
date if fsmu_fx(), fsmu_fl(), fsmu_dl() or fsmu_fl() have not been used on
another directory since it was last called. (No, no one knows why, and
attempting to make it list the contents of a throwaway directory first
doesn't seem to work. This is considered an FSMU bug.)


fsmu_fx(x)

Returns 1 if file x exists, 0 if not. Sensitive to curdir().


fsmu_md x

Creates the directory x. Is curdir() aware.


fsmu_rd x

Removes the directory x, which probably has to be emptied of files and
directories first. Does not accept wildcards. Is curdir() aware.


fsmu_rm x

Deletes files matching the pattern x. Is wildcard-aware. Cannot remove
directories (use fsmu_rd for that). Is curdir() aware.


getcfg(collection, keyword)

getcfg() returns the contents of the variable keyword stored in the non-
volitile space collection. Non-volitile spaces are stored in the
directory :cfg, and must be created with dclcfgcol or writefile before they
can be used. Individual entries must be declared with dclcfg() before they
can be used. Attempting to fetch a non-existent entry will return the
message "deadbeef". Attempting to fetch an entry from a non-existent file
will return the message "deadbeef++".

CFG entries are in the template:

        [variablename]=contentschr(4)

That is, a left square bracket, the name of the variable, a right square
bracket, an equals sign, the value of the variable, and chr(4), the ASCII
control character for end of transmission.


getpid(x)

Returns the process unique ID number for job x. See _pid for more
information.


gfx x, y, v

Prints the character v at position x, y on the job's current terminal. This
only appears on the 605/11 special overlay mode. The top-left corner is
point 1, 1. Attempting to address a position with x = 0 will clear the
screen. Only outputting one character at a time is recommended to save on
massive headaches.


glue x, y

Appends y to x and stores the result in x. x is a string containing the
variable name to store in:

        happy = "this is"
        glue "happy", " my string"


goto x

Sets the current process's line offset counter to that of the first
instance of the string ";@" & x & ";" in the program's code. If no such
line exists, an error message is printed, and the process jumps to the
start of its code.


grab(offset, length)

Returns length bytes at position offset from the currently selected memory
space. This is considered slightly faster, because memory space access
bypasses GetVar and PutVar. However, it can be flimsy at times, because
memory space selection is global between all processes running on the
system, and memory spaces share the same storage as programs' variable
plates. Thus, if a process moves, _space must be changed, in which case the
program loses normal functionality of variables, or an extremely high value
must be chosen for _space that is not likely to be used by anything else
(such as `pxss_jc).

Memory space functions: grab(), stash, megastash, init


i x

Adds 1 to the variable x. i contains a special debug trap that prints an
error message into the debug log if _plate isn't the same as _jobnum,
although this can technically occur in normal operation.


if val1 operator val2 then statement

If the expression (val1 operator val2) evaluates to true, then statement
will be executed. Currently, operator and val2 are required. Possible
values for operator:

Char        Example on 'string'        Example on 'number'        Relationship

=        "spam" = "spam"                4 = 4                        Equal

>        "spam" > "SPAM"                6 > 4                        Greater than

<        "SPAM" < "spam"                6 < 4                        Less than

<>      "SPAM" <> "spam"        4 <> 6                        Not equal; greater
                                                        or less than

If the text specified by statement returns a value, then the line will too:

        m = int(_rnd * 4) + 1
        echo "I have " & m & " jellybean" & (if m > 1 then "s") & "." & chr(13)


if val1 operator val2 endpoint targname

If the expression (val1 operator val2) evaluates to true, then execution will
continue at the next line. If it evaluates to false, then execution will jump
to the line after "else " targname. If it evaluates to true, once the line
"else " targname is reached, execution will jump to the line after "endif "
targname. targname *is* in quotes. This serves as Telerin Piki's multi-line
if statement.

        if x = 1 endpoint "magic"
            echo "x = 1!" & chr(13)
        else magic
            echo "x isn't one." & chr(13)
        endif magic


init x

Replaces variable table x with 8191 spaces. Used for initialising byte-
access memory space storage. All other memory space functions require the
variable _space to be set. See grab() for information on memory space
storage.

Memory space functions: grab(), stash, megastash, init


instr(field, data)

Returns the offset of the first occurance of the string data within the
string field. If data does not occur in field, returns 0.

        instr("spammy", "m") = 4

        instr("this is my happy song", "is") = 3


instrrev(field, data)

Returns the offset of the last occurance of the string data within the
string field. This is counted from the left, as with instr(), and not the
right. If data does not occur in field, returns 0.

        instrrev("spammy", "m") = 5

        instrrev("this is my happy song", "is") = 6


int(x)

Returns the integer value of x.


jmp x

Jumps to line x + 1 in the current process. When a process is created, two
lines are added onto its front and all totally blank lines are removed.

A program with a negative line number or a line number higher than its line
count is considered a dead one. Because jmp acts before the line counter is
incremented, jmp -1 actually jumps to the start of a program, and thus the
standard method of job suicide is jmp -2.


kill x

Deletes the variable x from the current program's variable table.

        kill happy

kill :x

Deletes the variable that x points to from the current program's variable table.

        happy = "lemons!"
        sad = "happy"
        kill :sad
        echo len(sad) & chr(13)
        echo len(happy) & chr(13)

Returns:
        5
        0


lcase(x)

Returns the lower-case version of a string. This affects all low ASCII
values (65 to 90) and some values in the extended Windows range. (See
table at asc().)


left(data, x)

Returns the first x bytes of the string data. left() and lop() are the
fundamental functions of many string-handling algorithms.


len(x)

Returns the length of x, in characters.


loadseg file, label

Appends the contents of file onto the end of the running program, and then
begins execution from label. loadseg is fully capable of supporting
recursive calls, although may mess up if non-unique labels are used in
different files. Use dropseg to exit a loaded segment cleanly. loadseg is
curdir()-aware.

loadseg var

As the other definition of loadseg, except extracting the segment to jump
into from the variable var, and beginning execution from the label var.


lop(field, offset)

Returns the contents of field starting from character offset. This is
identical to a two-argument mid() function in BASIC.

        lop("maximum speed", 5) = "mum speed"

lop() and left() are the fundamental functions of many string-parsing
algorithms.


max(x, y)

Returns the larger value.


megastash x

Overwrites the variable space specified by the universal variable _space
with x. This is designed as a memory space function, but has seen use in
reloading a process's state from a dcb() that has been written to disk. See
grab() for a discussion on memory space storage.

Memory space functions: grab(), stash, megastash, init


mid(field, offset, length)

mid() returns a sub-string from field, starting at offset and running for
length bytes. Unlike BASIC, Piki requires all three arguments. In the case
of simply extracting a string that runs to the end of field, as one would
attain with a BASIC two-argument mid(), use lop().

        mid("this is my string", 6, 5) = "is my"


min(x, y)

Returns the lower value.


ncmu_fn(x)

Returns information about the remote console. Possible values for x are:

        "remote_ip"
                The IP address of the last person to connect to the remote
                console.
        "remote"
                The host name of the last person to connect to the remote
                console (rarely known).
        "remote_port"
                The port the remote console connected from.

        "local_ip"
                The local IP address of the server.
        "local"
                The host name of the server (rarely known).
        "local_port"
                The port that the remote console is listening on/connected
                to at.

        "term_num"
                The terminal that NCMU accesses. We recommend 0. (For the
                console itself, which is the only terminal not linked up
                to by Skynet.)

        "state"
                The state of the NCMU connection. A complete list of
                network connection status numbers is available in the
                system documentation.


next lblname (operation) until condition

Executes operation. Unless condition is valid after operation is executed,
resume execution at the line after for lblname (see for). The parentheses
around operation are optional.

        for a = 0
           echo "a = " & a & chr(13)
        next a (i a) until a = 4

This will print the following:

        a = 0
        a = 1
        a = 2
        a = 3
        a = 4

See if for the list of conditional operators valid in condition. next can also
trigger on condition being a variable that is non-zero and non-null:

        for a = 0
           echo "a = " & a & chr(13)
        next a (a = a + .1) until int(a)


nthoffset(field, data, instance)

Returns the offset of the instance-th occurance of data within the string
field. instr() returns the offset of the first occurance, and instrrev()
returns the offset of the last occurance.

        field = "this is my text string"
        data = "i"
        instr(field, data) = nthoffset(field, data, 1)
        instrrev(field, data) = nthoffset(field, data, cchars(field, data))


pad(string, padding, length)

Returns string prefixed with padding until it as at least length characters
long. padding should probably only be one character. If string is already
as long or longer than length, string is returned unmodified.

        pad("happy", " ", 7) = "  happy"
       pad("happy", " ", 3) = "happy"


pxss_gj x

Kills job x. The variable space and bindings of the job with the former
highest running index (`pxss_jr) will remain until a new job is created,
although they will not interact with system functions in any way unless a
program is written to explicitly do so. If this job is not the job being
killed, the job being killed will be replaced by the job with the former
highest running index.

Immediately after killer.pk executes pxss_gj 0:

        #        LINE NUMBER        CODE
        0        -1                victim.pk
        1        10                killer.pk
        2        767                bystander.pk

The next pass:

        #        LINE NUMBER        CODE
        0        768                bystander.pk
        1        11                killer.pk

A program with a negative line number or a line number higher than its line
count is considered a dead one. Because jmp acts before the line counter is
incremented, jmp -1 actually jumps to the start of a program, and thus the
standard method of job suicide is jmp -2.


pxss_go(x, y)

Runs program x and sets the _params variable in the newly-created job to y.
See historic note at cujo().


pxss_jc(x)

Returns the code job x is currently running off of, in its executory state.
All linebreaks have been removed and lines are separated by semicolons.
Blank lines have been removed. The program is prefixed with a comment
containing pxss_jn.


pxss_jl(x)

The line of code job x is currently executing. If job x is dead, this will
be -1. Otherwise, this number is one higher than it should be, as can be
revealed through the use of jmp:

        jmp -1 + pxss_jl(_jobnum)

This line of code causes the program to not execute the previous line, but
the same line again (and thus is the most basic "idle" loop in Telerin.)


pxss_jn(x)

Returns the name of the code file job x was started from. This is usually
without path, though if the filename was provided as ":.pk", then
the colon will be included. (This is usually only the case with KBT
services.)


pxss_jt(x)

Returns the terminal job x is bound to. See bind_job for info on binding
jobs to terminals. This value determines what terminal a job will echo
and report crash information to.


pxss_tp(x)

The job (process) a terminal is currently bound to. If this is -1, then the
terminal will use a built-in input handler that accesses Exec directly.
Terminals can be bound to jobs through the bind_term statement.


readfile(x)

Returns the contents of the file x. Telerin uses paths in the format

        :\\

In the emulator, : is translated into a path set by the bootup script.
Otherwise, : corresponds to the current active master disk. Both are
determined by the variable `system_root. See note at curdir() for what
happens when a path does not begin with a colon. If no file exist, the
readfile() function returns "deadbeef++".


readvar x

Puts the value x under scrutiny for case statements. This is universal, and
thus is probably not a good idea to use in general code, but may have merit
as a global message-sending system. See case and stopvar as well.


replace(field, old, new)

Returns the string field with new substituted for all occurances of old.
This function can handle old being a substring of new. Thus,

        replace("this is my string", " is", " isn't")

returns

        "this isn't my string"

instead of

        "this isn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn't
n'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn't
n'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn'tn't
stack overflow


right(data, x)

Returns the last x bytes of the string data.


rinstr(field, data)

Causes your program to crash. Use instrrev() instead.


set var, val, plate

Sets the variable specified by the string var to val, on job plate.

        set "magic", "hat", _jobnum

Means that

        magic = "hat"


set_code job, prograw

Set the code for process job to the text prograw. All lines must be
separated by semicolons, and all leading tab characters must be removed.
(Spaces are OK, but discouraged.) The reciprocal of this function is
pxss_jc(). A program may manipulate its own code more familiarly through
the variable _mycode.


set_volvox terminal, message

Sets the volvox line on a 605/11 terminal to message. See volvox() for more
information.


setcfg col, var, val

Stores val in the keyword var in the CFG collection col. col must be first
created with dclcfgcol and var must first be created with dclcfg. See
getcfg() for more information on the CFG collection system.


sin(x)

Returns the sine of x, in radians.


skynet_clients

Returns the number of clients currently connected.

skynet_host(x)

Returns the host name that Skynet terminal x is currently connecting from.
Almost always blank, since Skynet doesn't actively perform reverse DNS
lookups.


skynet_ip(x)

The IP address of the client that skynet terminal x is connecting from. If
no terminal is connected, then the last IP address on that terminal.


skynet_kill x

Forcibly disconnects terminal x from the Skynet network interface.


skynet_peak

Returns the most clients that were ever connected at one point, and thus
the number of connections Telerin has available before it must make more.

skynet_port(x)

Returns the remote port that Skynet terminal x is connected to. This is
generally useless information.


skynet_rev_create(ip, port)

Attempts to open a TCP connection to the IP address ip on port port.
Returns the Reverse Skynet connection number. This is the first step of a
connection attempt--afterwards, monitor your progress with
skynet_rev_state() and wait for it to reach 7 before attempting to
skynet_rev_read() or skynet_rev_send.


skynet_rev_host(x)

Returns the hostname that Reverse Skynet interface x last connected to.
This is non-blank if skynet_rev_create() was used with a host name instead
of an IP address.


skynet_rev_hosts

The number of Reverse Skynet ports that are currently in use.


skynet_rev_ip(x)

Returns the IP address that reverse skynet connection x is connected to or
was last connected to. If the connection hasn't been created yet, this
function returns "0.0.0.0".


skynet_rev_kill x

Forcibly disconnects line x from the reverse skynet interface. This may be
incoming or outgoing. The skynet_rev_read() buffer remains in-tact.


skynet_rev_listen(x)

Opens a Reverse Skynet listening connection on port x. The listener will automatically accept connection attempts. See the hardware documentation's
network states list for information on how to tell when this occurs.


skynet_rev_local_port(x)

Returns the local port that reverse skynet interface x is connecting from.


skynet_rev_peak

Returns the most reverse clients that were ever running at one point, and
thus the number of reverse connections Telerin has available before it must
make more.

skynet_rev_port(x)

Returns the remote port that reverse skynet interface x is connected to.


skynet_rev_read(x)

Gets the contents of the read buffer from skynet reverse connection x. The
buffer is also cleared. It is not cleared on disconnect. Consider the
following device:

        m = skynet_rev_read(x)
        if skynet_rev_state(x) <> 7 then goto "connection_lost"
        if m = "" then jmp -3 + pxss_jl(_jobnum)

(See the hardware documentation for information on network states.)


skynet_rev_send connection, message

Sends the string message through reverse skynet socket connection.


skynet_rev_sending(x)

Returns 1 if Reverse Skynet connection x is currently sending text.
Returns 0 if Reverse Skynet connection x is doing anything else.
Returns -1 if Reverse Skynet connection x hasn't been created yet.
Returns -2 if x < 1.


skynet_rev_state(x)

The connection state of Reverse Skynet socket x. See the hardware
documentation for a list of connection states and their meanings.


skynet_state(x)

Returns the current state of skynet terminal connection x. A complete list
of state values and their meanings can be found with the hardware
documentation.

sqr(x)

Returns the square root of x.


stash offset, string

Stores string string at offset offset in the memory space specified by
_space. See grab() for information on memory space storage.

Memory space functions: grab(), stash, megastash, init


stopvar

Clears the universal value set by readvar. See readvar and case for more
information.


swd term, directory

Sets the working directory on terminal term to directory. This is not
inherently curdir() aware--paths must be absolute. This function determines
what curdir() returns, however. All filesystem functions except writefile
are curdir()-sensitive.


system(x)

The system function executes or accesses a low-level feature that interacts
with special stuff. Possibilities for x include:

        "emulator->volvox_show #"
                Displays terminal # on the emulator.
        "emulator->shell x"
                Executes the program x on the emulator's host system.
        "emulator->bgshell x"
                Executes the program x on the emulator's host system but
                does not steal focus.
        "emulator->model"
                Returns the emulator model number. Format is:                                        Name/PlatformPlatformMajorVersion
                EmulatorMajorVersion.EmulatorMinorVersion.EmulatorRevision
        "emulator->halt"
                Halts the virtual CPU.
        "emulator->quit"
                Quits the emulator.

        "cpu->model"
                Returns the CPU model number. Format is:
                MachineNameCPUName PartNumber/PlatformNumber
        "cpu->halt"
                Halts the CPU.

        "skynet->getvar x"
                Return variable x from the network device's configuration
                PROM.

Any other message will result in an error sent to the debug console.


tan(x)

Returns the tangent of x, in radians.


trim(x)

Removes all leading and trailing spaces from x. Whether or not it removes
tabs or nullifies strings consisting solely of whitespace is a mystery.


ucase(x)

Returns the upper-case version of a string. This affects all low ASCII
values (97 to 122) and some values in the extended Windows range. (See
table at asc().)


val(x)

Returns the numeric value of x, trimming off any preceding whitespace and
any characters after the number. This is built into most other math
functions. Note that val() (and other functions that use it) interpret the
prefix of "&H" on the front of a string to mean that the number is in
hexadecimal and ought to be converted. Also, sticking an "e" in a number
will be interpreted as scientific notation "x10^", thus

        val("2e5")

Is

        20000

Furthermore: if Princess (a component of the interpreter) comes across a
number, it will val() it anyway. The val() function in code is rarely
necessary, except when you want to force a string to mean zero in math...

        val(getcfg("my_magic_cfg", "variable_that_is_deadbeef") = 0

Because if you attempt to add one or more values that are not the same
going into val() as they are coming out (including hex and scientific
notation) Piki will resort to interpretting the + sign as a & sign and
append:

        "deadbeef" + &H443 = "deadbeef&H443"

So be careful out there.


var(x)

Returns the contents of variable x. You might think this is an obvious one at first, but won't when you see it in action:

        option_0 = "happy"
        option_1 = "sad"
        emotion = var("option_" & int(_rnd * 2))

Because, see, x comes in quotes.


volvox(x)

Returns the contents of the scroller line on terminal x. The contents of
this line are displayed on Skynet's display panel, but are invisible to a
Skynet user. (Unlike a 605/11 user.)


wait x

Pause the system for x milliseconds. Not recommended.


writefile filename, text

Writes the string text to the file filename. writefile does not observe
curdir(), because it can be one of the most damaging functions if used
improperly. See readfile() for information on path formats.
Copyright © 2009 Samantha Wright.
All those rights are, like, totally reserved. This mumbling is legally binding.