diff --git a/Hydra b/Hydra new file mode 100644 index 0000000..1ace228 --- /dev/null +++ b/Hydra @@ -0,0 +1,265 @@ + Hydra is a server that uses the same overall design as the LP server +made by Lars Pensj�. However, there are several important differences: +Hydra uses less memory because it is disk-based; it can dump state and later +restart from a snapshot; it uses LPC as an internal interpreted language, +but also offers the option of precompiling LPC objects to C, making them part +of the program itself. + Hydra has two special objects which determine the interface with the +server for all other objects: the auto object and the driver object. + The auto object (short for automatically inherited object) is +inherited by all other objects, except for the driver object. It can +redeclare the predefined functions (called kfuns, kernel functions) +that Hydra provides, and it can also define standard properties that +every object should have. Hydra is made in such a way that some kfuns + to be redeclared in an environment with several users +programming together; for instance, by default there is no file security. +The auto object has some other special properties; static functions +declared in the auto object cannot be called using this_object()->func() +(i.e. they behave like kfuns). + The driver object defines several functions which are called by the +driver, mostly to translate pathnames. + The following functions will be called by the driver: + - in the driver object: + + void initialize() + + Called when the system starts up after a reboot. + + void restored() + + Called after the system has restarted from a snapshot. + + string path_read(string path) + + Used to translate a path for an editor read command. If nil is + returned, the file cannot be read. + + string path_write(string path) + + Used to translate a path for an editor write command. If nil is + returned, the file cannot be written to. + + object call_object(string objname) + + Get the object named by objname as the first argument of a call_other(). + compile_object() may be called from here. + + int touch(object obj, string function) + + Called just before a function is called in an object which has been + marked by call_touch(). A non-zero return value indicates that the + object's "untouched" status should be preserved through the following + call. + + object inherit_program(string file, string program, int priv) + + Get the object named by program as an object to inherit. The third + argument is 1 for private inheritance, 0 otherwise. + compile_object() may be called from here. + + mixed include_file(string file, string path) + + Used to translate include path when included from the file + . The return value can be either string for the translated path, + in which case an attempt is made to read the included file from that + location, or an array of strings, the concatenation of which represents + the included file itself. If any other value is returned, the file + cannot be included. + + void recompile(object obj) + + If an object A is loaded, A inherits B, B inherits C, and the + version of C inherited by B is out of date, recompile(B) will be + called in the driver object. If B should actually be recompiled + (inheriting the new version of C from B), the driver object must + destruct B; if this is done, A will inherit the most recent + versions of B and C. + + object telnet_connect(int port) + + Return an object for a new connection on the given telnet port. + + object binary_connect(int port) + + Return an object for a new connection on the given binary port. + + void interrupt() + + Called if the driver receives a kill signal. The function should + shut down the system, and possibly dump state. + + void compile_error(string file, int line, string err) + + Handle a compile-time error; there can be several for the same + LPC file before a runtime error results (calling runtime_error). + + void runtime_error(string error, int caught, int ticks) + + Called when a runtime error occurs. is 0 if the error + is not caught, or 1 + an index in the return value of call_trace(), + indicating the frame in which the error is caught. runtime_error() + is called with rlimits (-1; -1) so it will not run out of stack or + ticks. specifies the amount of ticks left at the moment + the error occurred. + + void atomic_error(string error, int atom, int ticks) + + Called when a runtime error occurs in atomic code. is an + an index in the return value of call_trace(), indicating the frame in + which the atomically executed code starts. atomic_error() is called + with rlimits (-1; -1) so it will not run out of stack or ticks. + specifies the amount of ticks left at the moment the error + occurred. + + string object_type(string file, string type) + + Called when is compiled, to translate the object path + used in a type declaration, cast or <- operator. + + int compile_rlimits(string objname) + + An object uses the rlimits (stackdepth; ticks) { /* code */ } + construct, which can be used to assign arbitrary limits to function + call stack depth and ticks; running out of ticks during execution + causes an error. -1 signifies an infinite amount of stack space or + ticks. + During compilation, driver->compile_rlimits(objname) is called. If + non-zero is returned, the object will be able to use rlimits at + runtime with no restrictions. If 0 is returned, + driver->runtime_rlimits() will be called at runtime to further + verify if an object is allowed to change its rlimits (resource + limits). + + int runtime_rlimits(object obj, int stack, int ticks) + + Called at runtime for rlimits constructs not already cleared by + compile_rlimits(). If 0 is returned, the rlimits usage is illegal + and is aborted with an error. + Values for stack and ticks: < 0: infinite, 0: no change, + > 0: set to specified amount. + + void remove_program(string objname, int timestamp, int index) + + Called whenever the program of a master object is removed (because + the object has been destructed, and all clones and inheriting objects + have also been destructed). This function is called with + rlimits (-1; -1). + The "index" is a unique number for each master object, also + available with status(obj), which can help distinguishing between + different issues of the same object. + + - in every object: + + void create() + + Called in an object which has just been cloned, or if it is not a + clone, just before a function is called in it for the first time. + The actual name of this function is configurable. + + - in the user object (returned by driver->telnet_connect() or + driver->binary_connect()): + + int open() + + A connection has just been opened for this object. + For a binary connection, if the return value of this function is + non-zero, a UDP channel will be opened for the same object. UDP + datagrams can be received from the same host and port as the TCP + connection is on, and after at least one datagram has been + received, send_datagram() can be used to send datagrams to that + destination. + For a telnet connection, the return value will be ignored. + + void close(int flag) + + The connection for this object has just been closed. close() is + called when the user goes linkdead, or when the user object is + destructed. The flag argument is 1 if the object is destructed, + 0 otherwise. + + void receive_message(string message) + + This function is called with the text the user typed. For telnet + connections, this is always an entire line, with the newline at + the end filtered out. For binary connections, this is whatever + the other side of the connection saw fit to send, without any + filtering or processing. + + void message_done() + + This function is called when a string sent by send_message was + fully transmitted. + + void open_datagram() + + This function is called when a response to the datagram challenge + has been received, opening a datagram channel on the current + connection. + + void receive_datagram(string packet) + + This function is called when a packet is received on the datagram + channel of the connection. + + + On startup, the system is configured with a configuration file, which +must specify the following configuration parameters: + +param type meaning +-------------------------------------------------------------------------- +telnet_port mapping A mapping containing host:port pairs, where the host + or string is a name, an IP number or "*", and the port + number number is a port on which to accept telnet connections. + Alternatively, a telnet port number. +binary_port mapping A mapping containing host:port pairs, where the host + or string is a name, an IP number or "*", and the port + number number is a port on which to accept raw TCP/IP + connections. Alternatively, a binary port number. +directory string The base directory for the system. +users number The maximum number of active telnet and binary + connections. +editors number The maximum number of simultaneously active + editor instances. +ed_tmpfile string The proto editor temporary file (actual files + will have a number appended). +swap_file string The name of the swap file. +swap_size number The total number of sectors in the swap file. +cache_size number The number of sectors in the swap cache in memory. +sector_size number The size of a swap sector in bytes. +swap_fragment number The fragment of all objects to swap out at the end of + each task (e.g. with a swap_fragment of 32, 1/32th + of all objects will be swapped out). +static_chunk number The size in bytes of a static or dynamic chunk +dynamic_chunk number of memory. Memory is divided into static memory + and dynamic memory; static memory is never freed. + Both are allocated in chunks of the specified size. + Setting the size of the static chunk to 0 will + cause the system never to swap out everything to + make more room for static memory, but will also + increase fragmentation. +dump_file string The name of the snapshot file. +dump_interval number The expected interval between snapshots, in seconds. + Effectively, the time during which the swapfile will be + fully recreated. +typechecking number If zero, only functions with a declared type are + typechecked. + If one, all LPC functions are typechecked. + If two, additionally, nil (the value of an uninitialized + string, object, array or mapping variable) is a value + distinct from integer 0. +include_file string The standard include file, which is always + included automatically for each compiled object + (relative to the base directory). +include_dirs string* The standard system include directories (relative + to the base directory). In the first of those, + the include files which are automatically + generated on startup will be placed. +auto_object string The file name of the auto object (relative to the + base directory). +driver_object string The file name of the driver object (relative to + the base directory). +create string The name of the create function. +array_size int The maximum array and mapping size. +objects int The maximum number of objects. +call_outs int The maximum number of simultaneously active + callouts. diff --git a/editor b/editor new file mode 100644 index 0000000..40ab278 --- /dev/null +++ b/editor @@ -0,0 +1,358 @@ + editor reference guide + + + The editor is line oriented. It has two different modes, Command Mode and +Insert Mode. In Command Mode, commands may be given that affect a range of +lines in the main buffer. In Insert Mode, new lines may be added to the main +buffer. Apart from the main buffer, lines may be copied to and from 26 +secondary buffers. + The editor remembers the current line and at most 26 marked lines in the +main buffer, and has some status-affecting variables which can be changed by the +user. + + + 1. Insert Mode + + In Insert Mode, each line typed by the user is inserted into the main buffer. +Insert Mode is indicated by the prompt '*'. Insert Mode is entered with the +commands 'append', 'change' and 'insert' from Command Mode, and is left by +typing a line consisting of a single '.'. + + + 2. Command Mode + + In Command Mode, the user may issue commands that affect the current line, +all lines or a specified range of lines. Command Mode is indicated by the +prompt ':'. After a command has been executed, the new current line will +usually be displayed. The most general format of commands is as follows: + + address1 , address2 command ! parameters count flags + + and specify the first and last line of a range of lines +that are to be affected by the command. If no second line address is given, +the range is assumed to be . If no line range is specified +at all, a default range is assumed, usually just the current line. + is a string of letters or non-digits. + may be given with some commands to specify a different, but similar +operation. + Some commands require . + A may be given with many commands to specify the number of lines +that is to be affected by the command, as an alternative to specifying the +first and last line. A will always override , if given. + Finally, may be given to affect the way in which the new current +line is displayed after the command has been executed. + + All parts are optional, even the command itself may be omitted. A range of +lines without a following command will print the lines specified. A single +
will set the current line to
, and the 'empty command' will +set the current line to the next line. + + + 2.1 Line addressing + + An
specifies a line in the main buffer. It may be a number, '.' +or '$', a regular expression, a marked line, or an expression containing one of +the previous and an offset. The most general format is: + + [number | . | $ | /pattern/ | ?pattern? | 'm] [+ | -] [number] + + Lines in the main buffer are numbered starting with 1. A number may be +given to specify a line. '.' denotes the current line, and '$' the last line +in the main buffer. + A regular expression must be enclosed within '/' or '?' pairs. '/pattern/' +will search forward, starting with the line after the current line, and +'?pattern?' will search backward. If no pattern is specified, '//' or '??' will +respectively search forward and backward, using the previous regular expression. +If the regular expression forms the whole command, the closing '/' or '?' may be +omitted. + A marked line is specified by a single quote "'", followed by a lowercase +letter. The mark must have been set by the 'mark' command. + + Offsets may be given to a given
using '+' and '-', followed by +a number. If the '+' or '-' sign is not preceded by an
, the current +line is assumed. If the '+' or '-' sign is not followed by a number, the number +1 is assumed. Offsets may be repeated, with a cumulative effect. + + A range of lines is indicated by . Either of the +addresses may be omitted: + + means + <, address> means <., address> + <,> means <., .> + + Alternatively, ',' can be replaced with ';'. This has the effect of setting +the current line to , just before is evaluated. + '%' is an alias for '1,$'. + + + 2.1.1 Regular expressions + + In a regular expression, characters may form a string that is searched for in +the main buffer. Only strings on a single line can be searched for. Some +characters and character sequences have a special meaning in regular +expressions: + + ^ matches the beginning of the line. + $ matches the end of the line. + . matches any single character. + \< matches the beginning of a word (LPC identifier). + \> matches the end of a word (LPC identifier). + [string] matches any single character in the string between the square + brackets. a-z specifies a range of characters, and if the + first character following the opening '[' is '^', any character + NOT in the string is matched. + * matches 0, 1 or more occurances of the preceding (single + character matching) pattern. + \( and \) does not match a pattern, but indicate the beginning and end of + a subpattern that can be used in the 'substitute' command. + + If any of the symbols '^', '$', '.', '[', '*' or '\' itself is desired in +regular expressions, it should be prefixed by '\'. + Depending on the value of the 'ignorecase' variable, which can be changed +with the 'set' command, lowercase letters may match either just the lowercase +letter or both uppercase and lowercase. By default, only lowercase letters are +matched. + + + 2.1.2 Marked lines + + Lines in the main buffer can be given a mark, consisting of a lowercase +letter, which afterwards can be used in line addresses to refer to the marked +line. This is done with the 'mark' command. + + + 2.2 Secondary buffers + + Apart from the main buffer, the editor maintains 26 secondary buffers which +are addressed by letters. A range of lines from the main buffer may be copied +into a secondary buffer, and the contents of a secondary buffer may be copied +into the main buffer. When copying lines to a secondary buffer, a lowercase +letter indicates that the previous contents of the secondary buffer (if any) is +to be replaced, and an uppercase letter indicates that the lines are to be +appended to the secondary buffer. When copying back lines from a secondary +buffer, case of the letter specifying the buffer is not significant. + + + 2.2.1 Default buffer + + Each command that has the option of copying lines into a secondary buffer, +always stores the lines in a default buffer also. If no secondary buffer is +specified when lines are copied back to the main buffer, lines are copied from +the default buffer. + + + 2.3 Flags + + Many commands may followed by one of the characters 'p', 'l', '#', '+' and +'-', which affect the way in which the current line is displayed after the +command is executed or, if the command itself prints lines, in which way these +lines are printed. The characters have the following meaning: + + p print the current line after the command has finished. This usually + happens automatically. + l print the current line after the command has finished, in 'list' format. + # print the current line after the command has finished, in 'number' + format. + + increase the current line number by 1 before printing it. + - decrease the current line number by 1 before printing it. + + Flags may be repeated, with a cumulative effect. + + + 2.4 Multiple commands inside a global command + + More than one command may be given inside a global command, by separating +the individual commands with '|'. + + + 2.5 Command summary + + In the following list of commands, the default line range is shown in +parenthesis, and an optional parameter is marked with '[' ']'. After each +command, the current line is set at the last line changed or displayed. + + +RANGE COMMAND ABBREV + +(.) append a + Enter Insert Mode and append lines after the specified line. + A line address of 0 may be given to indicate that lines are to + be inserted before the first line in the main buffer. + +(.,.) change [count] c + Enter Insert Mode and replace the specified lines. + +(.,.) copy address [count] [flags] co + Place a copy of the specified lines after the given address. + The address may be 0, in which case the copied lines are + inserted before the first line in the main buffer. + +(.,.) delete [buffer] [count] [flags] d + Delete the specified lines. The deleted lines are saved in the + default buffer, and in the secondary buffer if one is specified. + + edit [file] e + Start editing a new file. The current main buffer and all + secondary buffers will be discarded. The current line will be + placed at the last line of the main buffer. + + edit! [file] e! + Start editing a new file, even if the current main buffer was + modified. + + file [file] f + Show statistics on the current file edited. If an argument is + given, the current file name is changed into the one specified. + +(1,$) global /pattern/ [command] g + Execute the command on all lines matching the given pattern. + By default, the matching lines are just printed. + +(1,$) global! /pattern/ [command] g! + Execute the command on all lines not matching the given pattern. + By default, the lines that don't match are just printed. + +(.) insert i + Enter Insert Mode and insert lines before the specified one. + +(.,.+1) join [count] [flags] j + Join the specified lines together in a single line. White + space at the beginning of a next line will be discarded. + Unless the next line starts with ')', a space is inserted + between two joined lines, or two spaces if the first line ends + in '.'. + +(.,.+1) join! [count] [flags] j! + Join the specified lined together in a single line without + white space processing. + +(.,.) list [count] [flags] l + Show the specified lines, displaying tabs as '^I' and marking + the end of the line with '$'. + +(.) mark x k + Mark the specified line with x, a single lowercase letter. If + the abbreviation 'k' is used, there need not be any spaces + between the command and the argument. + +(.,.) move address [flags] m + Reposition the specified lines after the given address. + +(.,.) number [count] [flags] # + Display the specified lines, preceded by their line number. + +(.,.) print [count] [flags] p + Display the specified lines. + +(.) put [buffer] pu + Copy lines from the secondary buffer, or from the default + buffer if none is given, after the specified line. + + quit q + Quit this editing session. + + quit! q! + Quit this editing session, even if the main buffer has been + modified. + +(.) read [file] r + Place a copy of the text in [file] after the specified line. + + set [parameter] se + Set without argument shows the current values of the editor + variables. Variables are numeric or toggles. Toggles can be + turned on with 'set option' and turned off with 'set nooption'. + Numeric variables can be given a value with 'set numeric=value'. + The following variables exist: + + NAME ABBREV DEFAULT MEANING + + ignorecase ic noic ignore case in searches. + shiftwidth sw 4 affects the '<', '>' and 'I' + commands. + window wi 20 specifies the number of lines + displayed with the z command. + + +(.,.) substitute /pattern/replacement/ [g] [count] [flags] s + Replace by in the specified lines. If + the 'g' option is specified, repeat the substitution in each + line until all occurrances of have been replaced. + In , \x, where x is a digit in range 1-9, specifies + the xth subexpression in , which is enclosed by \( \) + pairs in . Furthermore, '&' in specifies + the text that matched , and '\n' in + specifies a newline, splitting the line in two. If the symbols + '&' and '\' themselves are desired in , they should + be prefixed by '\'. All parameters are optional. 'substitute' + by itself will repeat the previous substitution. + +(.,.) t address [flags] + An alias for the 'copy' command. + + undo u + Undo the effects of the previous command on the main buffer. + 'edit' and 'yank' commands can not be undone, and 'global' + commands are undone as a whole. + +(1,$) v /pattern/ [command] + An alias for the 'global!' command. + +(1,$) write [file] w + Write the specified lines to [file], or to the current file if + no argument is specified. + +(1,$) write! [file] w! + Write the specified lines to [file], even if some error + occurred that prevented the main buffer from containing an exact + image of the file that is being edited. + +(1,$) write >> [file] w>> + This variant of write appends to a file, instead of overwriting + it. + +(1,$) wq [file] + Write the main buffer to the current file, and quit this + editing session. + +(1,$) wq! [file] + Write the main buffer to the current file and quit this editing + session, even if some error occurred that prevented the main + buffer from containing an exact image of the file that is being + edited. + + xit [file] x + Write the main buffer to the current file if it was modified, + and quit this editing session. + +(.,.) yank [buffer] [count] [flags] y + Copy the specified lines to the secondary buffer given in the + argument, or just to the default buffer if no argument is given. + +(.+1) z [mode] [flags] + Show a page of lines, starting with the specified line. The + number of lines displayed is determined by the value of the + 'window' variable, which can be changed by the 'set' command. + [mode] can be one of the following: + + + show specified line at top of page (default) + . show specified line in middle of page + - show specified line at bottom of page + + +(.,.) < [count] [flags] + Leftshift the specified lines the number of spaces given by the + 'shiftwidth' variable, which can be changed by the 'set' command. + +(.,.) > [count] [flags] + Rightshift the specified lines the number of spaces given by the + 'shiftwidth' variable, which can be changed by the 'set' command. + +($) = + Show the specified line number. + +(1,$) I [flags] + Indent the specified lines, under the assumption that they are + LPC code. The number of spaces used for indentation is given by + the 'shiftwidth' variable, which can be changed by the 'set' + command. diff --git a/kfun/acos b/kfun/acos new file mode 100644 index 0000000..75a35c4 --- /dev/null +++ b/kfun/acos @@ -0,0 +1,15 @@ +NAME + acos - compute arc cosine + +SYNOPSIS + float acos(float x) + + +DESCRIPTION + Return the arc cosine of the argument. + +ERRORS + If the argument is less than -1 or larger than 1, an error will result. + +SEE ALSO + kfun/asin, kfun/atan diff --git a/kfun/allocate b/kfun/allocate new file mode 100644 index 0000000..f7a5574 --- /dev/null +++ b/kfun/allocate @@ -0,0 +1,18 @@ +NAME + allocate - allocate an array + +SYNOPSIS + mixed *allocate(int size) + + +DESCRIPTION + Allocate an array with size elements. All elements are initialized + to nil. The new array is returned. + +ERRORS + If the specified array size is smaller than zero or larger than + status()[ST_ARRAYSIZE], with ST_ARRAYSIZE defined in the include file + , an error will result. + +SEE ALSO + kfun/allocate_int, kfun/allocate_float, kfun/sizeof diff --git a/kfun/allocate_float b/kfun/allocate_float new file mode 100644 index 0000000..3ecc08e --- /dev/null +++ b/kfun/allocate_float @@ -0,0 +1,18 @@ +NAME + allocate_float - allocate an array of floats + +SYNOPSIS + float *allocate_float(int size) + + +DESCRIPTION + Allocate an array with size elements. All elements are initialized + to 0.0. The new array is returned. + +ERRORS + If the specified array size is smaller than zero or larger than + status()[ST_ARRAYSIZE], with ST_ARRAYSIZE defined in the include file + , an error will result. + +SEE ALSO + kfun/allocate, kfun/allocate_int, kfun/sizeof diff --git a/kfun/allocate_int b/kfun/allocate_int new file mode 100644 index 0000000..249aa0e --- /dev/null +++ b/kfun/allocate_int @@ -0,0 +1,18 @@ +NAME + allocate_int - allocate an array of integers + +SYNOPSIS + int *allocate_int(int size) + + +DESCRIPTION + Allocate an array with size elements. All elements are initialized + to 0. The new array is returned. + +ERRORS + If the specified array size is smaller than zero or larger than + status()[ST_ARRAYSIZE], with ST_ARRAYSIZE defined in the include file + , an error will result. + +SEE ALSO + kfun/allocate, kfun/allocate_float, kfun/sizeof diff --git a/kfun/asin b/kfun/asin new file mode 100644 index 0000000..50dd288 --- /dev/null +++ b/kfun/asin @@ -0,0 +1,15 @@ +NAME + asin - compute arc sine + +SYNOPSIS + float asin(float x) + + +DESCRIPTION + Return the arc sine of the argument. + +ERRORS + If the argument is less than -1 or larger than 1, an error will result. + +SEE ALSO + kfun/acos, kfun/atan diff --git a/kfun/asn_add b/kfun/asn_add new file mode 100644 index 0000000..c92ae6f --- /dev/null +++ b/kfun/asn_add @@ -0,0 +1,19 @@ +NAME + asn_add - add two arbitrary size numbers + +SYNOPSIS + string asn_add(string a, string b, string m) + + +DESCRIPTION + Compute the sum of a and b modulo m. The modulus must be larger than + zero. + Arbitrary size numbers are encoded as strings, most significant byte + first. The most significant bit in the first byte, when set, indicates + that the number is negative and encoded in two's complement. + +ERRORS + An error will result if the modulus is less than or equal to zero. + +SEE ALSO + kfun/asn_div, kfun/asn_mod, kfun/asn_mult, kfun/asn_pow, kfun/asn_sub diff --git a/kfun/asn_and b/kfun/asn_and new file mode 100644 index 0000000..1d80336 --- /dev/null +++ b/kfun/asn_and @@ -0,0 +1,13 @@ +NAME + asn_and - logical and of two arbitrary size numbers + +SYNOPSIS + string asn_and(string a, string b) + + +DESCRIPTION + Compute the bit-wise logical and of a and b (sign extended). The + result will be as long as the longest argument. + +SEE ALSO + kfun/asn_lshift, kfun/asn_or, kfun/asn_rshift, kfun/asn_xor diff --git a/kfun/asn_cmp b/kfun/asn_cmp new file mode 100644 index 0000000..5201866 --- /dev/null +++ b/kfun/asn_cmp @@ -0,0 +1,13 @@ +NAME + asn_cmp - compare two arbitrary size numbers + +SYNOPSIS + int asn_cmp(string a, string b) + + +DESCRIPTION + Compare a and b, returning -1 if a is smaller than b, 1 if a is larger + than b, or 0 if a is equal to b. + Arbitrary size numbers are encoded as strings, most significant byte + first. The most significant bit in the first byte, when set, indicates + that the number is negative and encoded in two's complement. diff --git a/kfun/asn_div b/kfun/asn_div new file mode 100644 index 0000000..be68e94 --- /dev/null +++ b/kfun/asn_div @@ -0,0 +1,19 @@ +NAME + asn_div - divide one arbitrary size number by another + +SYNOPSIS + string asn_div(string a, string b, string m) + + +DESCRIPTION + Compute a divided by b modulo m. The modulus must be larger than zero. + Arbitrary size numbers are encoded as strings, most significant byte + first. The most significant bit in the first byte, when set, indicates + that the number is negative and encoded in two's complement. + +ERRORS + An error will result if the modulus is less than or equal to zero, or + if b is equal to zero. + +SEE ALSO + kfun/asn_add, kfun/asn_mod, kfun/asn_mult, kfun/asn_pow, kfun/asn_sub diff --git a/kfun/asn_lshift b/kfun/asn_lshift new file mode 100644 index 0000000..56645ed --- /dev/null +++ b/kfun/asn_lshift @@ -0,0 +1,19 @@ +NAME + asn_lshift - left shift an arbitrary size number + +SYNOPSIS + string asn_lshift(string a, int shift, string m) + + +DESCRIPTION + Left shift a by the given amount, and return the result modulo m. + Arbitrary size numbers are encoded as strings, most significant byte + first. The most significant bit in the first byte, when set, indicates + that the number is negative and encoded in two's complement. + +ERRORS + An error will result if shift is less than zero, or if the modulus is + less than or equal to zero. + +SEE ALSO + kfun/asn_and, kfun/asn_or, kfun/asn_rshift, kfun/asn_xor diff --git a/kfun/asn_mod b/kfun/asn_mod new file mode 100644 index 0000000..e9fa954 --- /dev/null +++ b/kfun/asn_mod @@ -0,0 +1,18 @@ +NAME + asn_mod - one arbitrary size number modulo another + +SYNOPSIS + string asn_mod(string a, string m) + + +DESCRIPTION + Compute a modulo m. The modulus must be larger than zero. + Arbitrary size numbers are encoded as strings, most significant byte + first. The most significant bit in the first byte, when set, indicates + that the number is negative and encoded in two's complement. + +ERRORS + An error will result if the modulus is less than or equal to zero. + +SEE ALSO + kfun/asn_add, kfun/asn_div, kfun/asn_mult, kfun/asn_pow, kfun/asn_sub diff --git a/kfun/asn_mult b/kfun/asn_mult new file mode 100644 index 0000000..a43f971 --- /dev/null +++ b/kfun/asn_mult @@ -0,0 +1,19 @@ +NAME + asn_mult - multiply two arbitrary size numbers + +SYNOPSIS + string asn_mult(string a, string b, string m) + + +DESCRIPTION + Compute a multiplied by b modulo m. The modulus must be larger than + zero. + Arbitrary size numbers are encoded as strings, most significant byte + first. The most significant bit in the first byte, when set, indicates + that the number is negative and encoded in two's complement. + +ERRORS + An error will result if the modulus is less than or equal to zero. + +SEE ALSO + kfun/asn_add, kfun/asn_div, kfun/asn_mod, kfun/asn_pow, kfun/asn_sub diff --git a/kfun/asn_or b/kfun/asn_or new file mode 100644 index 0000000..f489730 --- /dev/null +++ b/kfun/asn_or @@ -0,0 +1,13 @@ +NAME + asn_or - logical or of two arbitrary size numbers + +SYNOPSIS + string asn_or(string a, string b) + + +DESCRIPTION + Compute the bit-wise logical or of a and b (sign extended). The + result will be as long as the longest argument. + +SEE ALSO + kfun/asn_and, kfun/asn_lshift, kfun/asn_rshift, kfun/asn_xor diff --git a/kfun/asn_pow b/kfun/asn_pow new file mode 100644 index 0000000..6eefa47 --- /dev/null +++ b/kfun/asn_pow @@ -0,0 +1,21 @@ +NAME + asn_pow - raise one arbitrary size number to the power of another + +SYNOPSIS + string asn_pow(string a, string b, string m) + + +DESCRIPTION + Compute a raised to the power b modulo m. The modulus must be larger + than zero. Negative powers can only be used if an inverse modulo m + exists. + Arbitrary size numbers are encoded as strings, most significant byte + first. The most significant bit in the first byte, when set, indicates + that the number is negative and encoded in two's complement. + +ERRORS + An error will result if the modulus is less than or equal to zero, or + if b is negative and no inverse modulo m exists. + +SEE ALSO + kfun/asn_add, kfun/asn_div, kfun/asn_mod, kfun/asn_mult, kfun/asn_sub diff --git a/kfun/asn_rshift b/kfun/asn_rshift new file mode 100644 index 0000000..075f194 --- /dev/null +++ b/kfun/asn_rshift @@ -0,0 +1,15 @@ +NAME + asn_rshift - right shift an arbitrary size number + +SYNOPSIS + string asn_rshift(string a, int shift) + + +DESCRIPTION + Right shift a by the given amount. + +ERRORS + An error will result if shift is less than zero. + +SEE ALSO + kfun/asn_and, kfun/asn_lshift, kfun/asn_or, kfun/asn_xor diff --git a/kfun/asn_sub b/kfun/asn_sub new file mode 100644 index 0000000..dfa0edb --- /dev/null +++ b/kfun/asn_sub @@ -0,0 +1,18 @@ +NAME + asn_sub - subtract one arbitrary size number from another + +SYNOPSIS + string asn_sub(string a, string b, string m) + + +DESCRIPTION + Compute a minus b modulo m. The modulus must be larger than zero. + Arbitrary size numbers are encoded as strings, most significant byte + first. The most significant bit in the first byte, when set, indicates + that the number is negative and encoded in two's complement. + +ERRORS + An error will result if the modulus is less than or equal to zero. + +SEE ALSO + kfun/asn_add, kfun/asn_div, kfun/asn_mod, kfun/asn_mult, kfun/asn_pow diff --git a/kfun/asn_xor b/kfun/asn_xor new file mode 100644 index 0000000..d374c07 --- /dev/null +++ b/kfun/asn_xor @@ -0,0 +1,13 @@ +NAME + asn_xor - logical xor of two arbitrary size numbers + +SYNOPSIS + string asn_xor(string a, string b) + + +DESCRIPTION + Compute the bit-wise logical xor of a and b (sign extended). The + result will be as long as the longest argument. + +SEE ALSO + kfun/asn_and, kfun/asn_lshift, kfun/asn_or, kfun/asn_rshift diff --git a/kfun/atan b/kfun/atan new file mode 100644 index 0000000..9ed63f6 --- /dev/null +++ b/kfun/atan @@ -0,0 +1,12 @@ +NAME + atan - compute arc tangent + +SYNOPSIS + float atan(float x) + + +DESCRIPTION + Return the arc tangent of the argument. + +SEE ALSO + kfun/acos, kfun/asin, kfun/atan2 diff --git a/kfun/atan2 b/kfun/atan2 new file mode 100644 index 0000000..48e3935 --- /dev/null +++ b/kfun/atan2 @@ -0,0 +1,13 @@ +NAME + atan2 - compute arc tangent of two variables + +SYNOPSIS + float atan2(float y, float x) + + +DESCRIPTION + Return the arc tangent of y/x, using the signs of the arguments to + determine the quadrant of the result. + +SEE ALSO + kfun/atan diff --git a/kfun/block_input b/kfun/block_input new file mode 100644 index 0000000..ba82d6f --- /dev/null +++ b/kfun/block_input @@ -0,0 +1,11 @@ +NAME + block_input - block input on a connection + +SYNOPSIS + void block_input(int flag) + + +DESCRIPTION + Block or unblock input from the user associated with the current + object, depending on whether the argument is non-zero or zero, + respectively. diff --git a/kfun/call_other b/kfun/call_other new file mode 100644 index 0000000..9a2f827 --- /dev/null +++ b/kfun/call_other @@ -0,0 +1,30 @@ +NAME + call_other - call a function in an object + +SYNOPSIS + mixed call_other(mixed obj, string function, mixed args...) + + +DESCRIPTION + Call a function in an object. The first argument must be either an + object or a string. If it is a string, call_object() will be called + in the driver object to get the corresponding object. + Only non-private functions can be called with call_other(). If the + function is static, the object in which the function is called must + be the same as the object from which the function is called, or the + call will fail. + Any additional arguments to call_other() will be passed on to the + called function. + In LPC, obj->func(arg1, arg2, argn) can be used as a shorthand for + call_other(obj, "func", arg1, arg2, argn). + +ERRORS + An error will result if the first argument is not an object and not a + string, or if the first argument is a string, but the specified object + is uncompiled. + Calling a function that does not exist, or a function that cannot be + called with call_other() because it is private or static, does not + result in an error but returns the value nil. + +SEE ALSO + kfun/call_touch, kfun/function_object diff --git a/kfun/call_out b/kfun/call_out new file mode 100644 index 0000000..675b4ff --- /dev/null +++ b/kfun/call_out @@ -0,0 +1,29 @@ +NAME + call_out - call function with delay + +SYNOPSIS + int call_out(string function, mixed delay, mixed args...) + + +DESCRIPTION + Call a function in the current object with a delay. The function to + be called must not be private. The delay is specified in seconds. + The minimum delay is 0 seconds, for a function that is to be called + as soon as possible after termination of the current task. + If the delay is an integer, the function will be called after + approximately the specified number of seconds. Otherwise, the delay + must be a floating point number, and the function will be called with a + millisecond resolution. + The returned value is the callout handle, an integer > 0 which must be + used if the callout is to be removed. + +ERRORS + If the number of active delayed calls in the system is equal to the + value of the ST_COTABSIZE field of the array returned by status(), + where ST_COTABSIZE is defined in the include file , + attempting to add another one will result in an error. + If the maximum number of callouts is set to 0, no delayed call will + be added, and no error will be caused. + +SEE ALSO + kfun/remove_call_out diff --git a/kfun/call_touch b/kfun/call_touch new file mode 100644 index 0000000..acf9502 --- /dev/null +++ b/kfun/call_touch @@ -0,0 +1,18 @@ +NAME + call_touch - prepare to report when the object is next touched + +SYNOPSIS + void call_touch(object obj) + + +DESCRIPTION + Just before the next call to the object, call the function "touch" in + the driver object, with the object and the function to be called as + arguments. + +ERRORS + An error will result if the object did not yet have its creator + function called. + +SEE ALSO + kfun/call_other diff --git a/kfun/call_trace b/kfun/call_trace new file mode 100644 index 0000000..f018ce9 --- /dev/null +++ b/kfun/call_trace @@ -0,0 +1,22 @@ +NAME + call_trace - return the function call trace + +SYNOPSIS + mixed **call_trace() + + +DESCRIPTION + Return the function call trace as an array. The elements are of + the following format: + + ({ objname, progname, function, line, extern, arg1, ..., argn }) + + The line number is 0 if the function is in a compiled object. + Extern is 1 if the function was called with call_other(), and 0 + otherwise. + The offsets in the array are named in the include file . + The last element of the returned array is the trace of the + current function. + +SEE ALSO + kfun/previous_object, kfun/previous_program diff --git a/kfun/ceil b/kfun/ceil new file mode 100644 index 0000000..85264cf --- /dev/null +++ b/kfun/ceil @@ -0,0 +1,12 @@ +NAME + ceil - round a float towards infinity + +SYNOPSIS + float ceil(float x) + + +DESCRIPTION + Round the argument towards positive infinity. + +SEE ALSO + kfun/floor, kfun/fmod diff --git a/kfun/clone_object b/kfun/clone_object new file mode 100644 index 0000000..d2146e1 --- /dev/null +++ b/kfun/clone_object @@ -0,0 +1,15 @@ +NAME + clone_object - clone an object + +SYNOPSIS + object clone_object(object master) + + +DESCRIPTION + Create a clone of the specified object with an unique name of the form + "object_name#1234". The cloned object must not itself be a clone. The + new object is returned. The creator function will be called in the + cloned object immediately. + +SEE ALSO + kfun/compile_object, kfun/destruct_object, kfun/new_object diff --git a/kfun/compile_object b/kfun/compile_object new file mode 100644 index 0000000..3ec0ad1 --- /dev/null +++ b/kfun/compile_object @@ -0,0 +1,26 @@ +NAME + compile_object - compile an object + +SYNOPSIS + object compile_object(string file, string source...) + + +DESCRIPTION + Compile an object from a LPC file, specified by the first argument with + ".c" appended. If the optional source argument are supplied, the object + is compiled from the concatenaton of those strings, instead. The + returned object will have the file string as name. + If the object to be compiled already exists and is not inherited by + any other object, it and all of its clones will be upgraded to the + new version. Variables will be preserved only if they also exist in + the new version and have the same type; new variables will be + initialized to 0 or nil. The actual upgrading is done immediately upon + completion of the current task. + +ERRORS + Compilation errors will be reported to the driver object. Furthermore, + a failure to compile will result in a runtime error, as well. + +SEE ALSO + kfun/clone_object, kfun/destruct_object, kfun/new_object, + kfun/object_name diff --git a/kfun/cos b/kfun/cos new file mode 100644 index 0000000..813cd5a --- /dev/null +++ b/kfun/cos @@ -0,0 +1,16 @@ +NAME + cos - compute cosine + +SYNOPSIS + float cos(float x) + + +DESCRIPTION + Return the cosine of the argument. + +ERRORS + An error will result if the argument is too large to accurately + compute the cosine (around 1e9). + +SEE ALSO + kfun/sin, kfun/tan diff --git a/kfun/cosh b/kfun/cosh new file mode 100644 index 0000000..b3622a1 --- /dev/null +++ b/kfun/cosh @@ -0,0 +1,15 @@ +NAME + cosh - compute hyperbolic cosine + +SYNOPSIS + float cosh(float x) + + +DESCRIPTION + Return the hyperbolic cosine of the argument. + +ERRORS + If the computed hyperbolic cosine is too large, an error will result. + +SEE ALSO + kfun/sinh, kfun/tanh diff --git a/kfun/crypt b/kfun/crypt new file mode 100644 index 0000000..d9a4390 --- /dev/null +++ b/kfun/crypt @@ -0,0 +1,14 @@ +NAME + crypt - hash a password string + +SYNOPSIS + string crypt(string passwd, varargs string salt) + + +DESCRIPTION + The same as hash_string("crypt", passwd, salt) + + This kfun is retained for backward compatibility. + +SEE ALSO + kfun/hash_string diff --git a/kfun/ctime b/kfun/ctime new file mode 100644 index 0000000..86cf8bf --- /dev/null +++ b/kfun/ctime @@ -0,0 +1,14 @@ +NAME + ctime - convert a time integer into a string + +SYNOPSIS + string ctime(int time) + + +DESCRIPTION + Convert the specified time, which is an integer such as is returned + by the kfun time(), into a string of the form + "Tue Aug 3 14:40:18 1993". + +SEE ALSO + kfun/millitime, kfun/time diff --git a/kfun/datagram_challenge b/kfun/datagram_challenge new file mode 100644 index 0000000..b6deea1 --- /dev/null +++ b/kfun/datagram_challenge @@ -0,0 +1,20 @@ +NAME + datagram_challenge - set the datagram challenge + +SYNOPSIS + void datagram_challenge(string challenge) + + +DESCRIPTION + Set the datagram challenge for the current binary user object. The + client must send this challenge in order to open the datagram channel, + after which open_datagram() will be called in the object. All + outstanding challenges must be unique. + +ERRORS + An error will result if a challenge has already been set for the + current object. + +SEE ALSO + kfun/query_ip_name, kfun/query_ip_number, kfun/send_datagram, + kfun/this_user, kfun/users diff --git a/kfun/decrypt b/kfun/decrypt new file mode 100644 index 0000000..4fac51f --- /dev/null +++ b/kfun/decrypt @@ -0,0 +1,15 @@ +NAME + decrypt - decrypt a string + +SYNOPSIS + mixed decrypt(string cipher, string key, varargs string mesg) + + +DESCRIPTION + For any given cipher, decrypt("CIPHER key", key) returns a key prepared + for decryption, and decrypt("CIPHER", prepared_key, str) decrypts a + string. + The only currently defined cipher is DES. + +SEE ALSO + kfun/encrypt diff --git a/kfun/destruct_object b/kfun/destruct_object new file mode 100644 index 0000000..244972a --- /dev/null +++ b/kfun/destruct_object @@ -0,0 +1,22 @@ +NAME + destruct_object - destruct an object + +SYNOPSIS + void destruct_object(object obj) + + +DESCRIPTION + Destruct the object given as the argument. Any value holding the object + will immediately change into nil, and the object will cease to exist. + If an object destructs itself, it will cease to exist as soon as + execution leaves it. If the last reference to a master object is + removed (including cloned objects and inheriting objects), the + function remove_program(objname) will be called in the driver object. + +ERRORS + Objects destructing themselves may not do certain things between the + time of destruction and the time the object will cease to exist. Most + notably, call_other() may not be used from destructed objects. + +SEE ALSO + kfun/clone_object, kfun/compile_object diff --git a/kfun/dump_state b/kfun/dump_state new file mode 100644 index 0000000..c1cdd9f --- /dev/null +++ b/kfun/dump_state @@ -0,0 +1,14 @@ +NAME + dump_state - create a snapshot + +SYNOPSIS + void dump_state(vararg int incremental) + + +DESCRIPTION + Create a snapshot of the current state of the system. The actual + snapshot is not created until after the current task has finished. + If the argument is non-zero, the snapshot will be incremental. + +SEE ALSO + kfun/swapout diff --git a/kfun/editor b/kfun/editor new file mode 100644 index 0000000..1508be0 --- /dev/null +++ b/kfun/editor @@ -0,0 +1,26 @@ +NAME + editor - handle an editor command + +SYNOPSIS + string editor(varargs string command) + + +DESCRIPTION + Execute an editor command for the current object. If the editor + command is the first for this object, an editor instance will be + created for it. The editor instance will remain active until an + editor command is specified that terminates it, or until the object + is destructed. Editor output will be returned as a string. The + editor status of an object can be queried with the kfun query_editor(). + File paths for reading and writing will be translated by path_read() + and path_write(), respectively, in the driver object. + +ERRORS + If the number of active editor instances is equal to the value of the + ST_ETABSIZE field of the array returned by status(), where ST_ETABSIZE + is defined in the include file , attempting to add another + one will result in an error. + It is not possible to start an editor instance for a user object. + +SEE ALSO + kfun/read_file, kfun/write_file diff --git a/kfun/encrypt b/kfun/encrypt new file mode 100644 index 0000000..0990408 --- /dev/null +++ b/kfun/encrypt @@ -0,0 +1,15 @@ +NAME + encrypt - encrypt a string + +SYNOPSIS + mixed encrypt(string cipher, string key, varargs string mesg) + + +DESCRIPTION + For any given cipher, encrypt("CIPHER key", key) returns a key prepared + for encryption, and encrypt("CIPHER", prepared_key, str) encrypts a + string. + The only currently defined cipher is DES. + +SEE ALSO + kfun/decrypt diff --git a/kfun/error b/kfun/error new file mode 100644 index 0000000..4d2accf --- /dev/null +++ b/kfun/error @@ -0,0 +1,10 @@ +NAME + error - cause an error + +SYNOPSIS + void error(string errormessage) + + +DESCRIPTION + Cause an error, which will stop execution. If the error is caught, + execution will continue after the catch. diff --git a/kfun/exp b/kfun/exp new file mode 100644 index 0000000..97575a8 --- /dev/null +++ b/kfun/exp @@ -0,0 +1,15 @@ +NAME + exp - compute exponential + +SYNOPSIS + float exp(float x) + + +DESCRIPTION + Return the exponential value of the given argument. + +ERRORS + If the computed exponential is too large, an error will result. + +SEE ALSO + kfun/log, kfun/log10, kfun/pow diff --git a/kfun/explode b/kfun/explode new file mode 100644 index 0000000..eb1b7ed --- /dev/null +++ b/kfun/explode @@ -0,0 +1,19 @@ +NAME + explode - explode a string + +SYNOPSIS + string *explode(string str, string separator) + + +DESCRIPTION + Return an array of substrings of str, divided by the given separator. + The separators that str starts and ends with, if any, are not taken + into account. + +ERRORS + If the resulting array size is larger than status()[ST_ARRAYSIZE], with + ST_ARRAYSIZE defined in the include file , an error will + result. + +SEE ALSO + kfun/implode, kfun/parse_string, kfun/sscanf diff --git a/kfun/fabs b/kfun/fabs new file mode 100644 index 0000000..7b67c4e --- /dev/null +++ b/kfun/fabs @@ -0,0 +1,9 @@ +NAME + fabs - return the absolute value of a float + +SYNOPSIS + float fabs(float x) + + +DESCRIPTION + Return the absolute value of the argument. diff --git a/kfun/find_object b/kfun/find_object new file mode 100644 index 0000000..96903e2 --- /dev/null +++ b/kfun/find_object @@ -0,0 +1,14 @@ +NAME + find_object - find an object + +SYNOPSIS + object find_object(string obj) + + +DESCRIPTION + The string argument is resolved as a file path, and the object with + the resulting name is searched for. Either the object, if found, or + nil is returned. + +SEE ALSO + kfun/object_name diff --git a/kfun/floor b/kfun/floor new file mode 100644 index 0000000..1c26f6f --- /dev/null +++ b/kfun/floor @@ -0,0 +1,12 @@ +NAME + floor - round float towards minus infinity + +SYNOPSIS + float floor(float x) + + +DESCRIPTION + Round the argument towards negative infinity. + +SEE ALSO + kfun/ceil, kfun/fmod diff --git a/kfun/fmod b/kfun/fmod new file mode 100644 index 0000000..5dbd6a1 --- /dev/null +++ b/kfun/fmod @@ -0,0 +1,17 @@ +NAME + fmod - floating point modulus + +SYNOPSIS + float fmod(float x, float y) + + +DESCRIPTION + Return the value f, for which there exists an integer k such that + k * y + f == x, f has the same sign of x, and the absolute value of + f is less than the absolute value of y. + +ERRORS + A domain error will result if y == 0.0. + +SEE ALSO + kfun/ceil, kfun/floor diff --git a/kfun/frexp b/kfun/frexp new file mode 100644 index 0000000..a59a146 --- /dev/null +++ b/kfun/frexp @@ -0,0 +1,14 @@ +NAME + frexp - split float into fraction and exponent + +SYNOPSIS + mixed *frexp(float x) + + +DESCRIPTION + The argument is split into a fraction f and an integer exponent n, + such that either f == 0.0, or 0.5 <= | f | < 1.0, and f * 2 ** n == x. + ({ f, n }) is returned. If x == 0.0, both f and n will be zero. + +SEE ALSO + kfun/ldexp, kfun/modf diff --git a/kfun/function_object b/kfun/function_object new file mode 100644 index 0000000..2c8d599 --- /dev/null +++ b/kfun/function_object @@ -0,0 +1,14 @@ +NAME + function_object - find a function in an object + +SYNOPSIS + string function_object(string function, object obj) + + +DESCRIPTION + Find the named function, which must be callable with call_other(), + in an object. If the function is found, the name of the inherited + object that defines it is returned; otherwise, nil is returned. + +SEE ALSO + kfun/call_other diff --git a/kfun/get_dir b/kfun/get_dir new file mode 100644 index 0000000..0c146ac --- /dev/null +++ b/kfun/get_dir @@ -0,0 +1,34 @@ +NAME + get_dir - get information about files in a directory + +SYNOPSIS + mixed **get_dir(string file) + + +DESCRIPTION + Get information about a file or files in a directory. The return + value is of the form + + ({ ({ file names }), ({ file sizes }), ({ file mod times }) }) + + If a file is a directory, the file size will be given as -2. + If the last path component of the specified file can be interpreted + as a regular expression, all files which match this regular expression + are collected. Otherwise, only the file itself is taken. If no files + match, or if the file is not present, the return value of get_dir() + will be ({ ({ }), ({ }), ({ }) }). + The following characters have a special meaning in a regular expression: + + ? any single character + * any (possibly empty) string + [a-z] any character in the range a-z + [^a-z] any character not in range a-z + \c the character c, not interpreted as having a special + meaning + + The files will be sorted by file name. + Only as many files as specified by status()[ST_ARRAYSIZE], with + ST_ARRAYSIZE defined in the include file , will be collected. + +SEE ALSO + kfun/make_dir, kfun/remove_dir diff --git a/kfun/hash_crc16 b/kfun/hash_crc16 new file mode 100644 index 0000000..683629b --- /dev/null +++ b/kfun/hash_crc16 @@ -0,0 +1,18 @@ +NAME + hash_crc16 - 16 bit cyclic redundancy code + +SYNOPSIS + int hash_crc16(string str, string extra...) + + +DESCRIPTION + Compute the 16 bit Cyclic Redundancy Code of the concatenation of all + string arguments, with polynomial: + + X^16 + X^12 + X^5 + 1 + + CRC-16 is considered suitable for strings of up to a total of 4096 + characters. + +SEE ALSO + kfun/hash_crc32, kfun/hash_string diff --git a/kfun/hash_crc32 b/kfun/hash_crc32 new file mode 100644 index 0000000..7bbffe9 --- /dev/null +++ b/kfun/hash_crc32 @@ -0,0 +1,16 @@ +NAME + hash_crc32 - 32 bit cyclic redundancy code + +SYNOPSIS + int hash_crc32(string str, string extra...) + + +DESCRIPTION + Compute the 32 bit Cyclic Redundancy Code of the concatenation of all + string arguments, with polynomial: + + x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + + x^7 + x^5 + x^4 + x^2 + x + 1 + +SEE ALSO + kfun/hash_crc16, kfun/hash_string diff --git a/kfun/hash_string b/kfun/hash_string new file mode 100644 index 0000000..3bb7bbf --- /dev/null +++ b/kfun/hash_string @@ -0,0 +1,24 @@ +NAME + hash_string - hash a string with a given algorithm + +SYNOPSIS + string hash_string(string algo, string str, string extra...) + + +DESCRIPTION + Hash a string, possibly after concatenation of optional extra + arguments, with the given algorithm. The following hash algorithms are + defined: + + "crypt" Unix password crypt. Unless the salt is specified in an + extra argument, it is randomly chosen. The result is a + string of 13 characters. + "MD5" The MD5 message digest (128 bits). Extra arguments are + concatenated before the hash is calculated. The result is + a string of 16 characters. + "SHA1" The SHA-1 message digest (160 bits). Extra arguments are + concatenated before the hash is calculated. The result is + a string of 20 characters. + +SEE ALSO + kfun/hash_crc16, kfun/hash_crc32 diff --git a/kfun/implode b/kfun/implode new file mode 100644 index 0000000..75bf587 --- /dev/null +++ b/kfun/implode @@ -0,0 +1,17 @@ +NAME + implode - implode a string + +SYNOPSIS + string implode(string *arr, string separator) + + +DESCRIPTION + Return a string, consisting of all string elements of the array arr + concatenated, separated by the string separator. + +ERRORS + If the resulting string would be too long, an error will result. + The argument array may contain only string values. + +SEE ALSO + kfun/explode, kfun/parse_string, kfun/sscanf diff --git a/kfun/ldexp b/kfun/ldexp new file mode 100644 index 0000000..ccfe3c3 --- /dev/null +++ b/kfun/ldexp @@ -0,0 +1,15 @@ +NAME + ldexp - add an integer to the exponent of a float + +SYNOPSIS + float ldexp(float x, int n) + + +DESCRIPTION + Return the value x * 2 ** n. + +ERRORS + An error will occur if the result is out of range. + +SEE ALSO + kfun/frexp, kfun/modf diff --git a/kfun/log b/kfun/log new file mode 100644 index 0000000..81c3b55 --- /dev/null +++ b/kfun/log @@ -0,0 +1,15 @@ +NAME + log - compute natural logarithm + +SYNOPSIS + float log(float x) + + +DESCRIPTION + Return the natural logarithm of the argument. + +ERRORS + An error will result if the argument is less than or equal to 0. + +SEE ALSO + kfun/exp, kfun/log10, kfun/pow diff --git a/kfun/log10 b/kfun/log10 new file mode 100644 index 0000000..75a4359 --- /dev/null +++ b/kfun/log10 @@ -0,0 +1,15 @@ +NAME + log10 - base 10 logarithm + +SYNOPSIS + float log10(float x) + + +DESCRIPTION + Return the logarithm of the argument to base 10. + +ERRORS + An error will result if the argument is less than or equal to 0. + +SEE ALSO + kfun/exp, kfun/log, kfun/pow diff --git a/kfun/make_dir b/kfun/make_dir new file mode 100644 index 0000000..9ae7b39 --- /dev/null +++ b/kfun/make_dir @@ -0,0 +1,13 @@ +NAME + make_dir - create a directory + +SYNOPSIS + int make_dir(string dir) + + +DESCRIPTION + Create a new directory. 1 is returned if the directory could be + created, 0 otherwise. + +SEE ALSO + kfun/get_dir, kfun/remove_dir diff --git a/kfun/map_indices b/kfun/map_indices new file mode 100644 index 0000000..b236d4f --- /dev/null +++ b/kfun/map_indices @@ -0,0 +1,12 @@ +NAME + map_indices - get the indices of a mapping + +SYNOPSIS + mixed *map_indices(mapping map) + + +DESCRIPTION + Return an array containing the indices of mapping map. + +SEE ALSO + kfun/map_values diff --git a/kfun/map_sizeof b/kfun/map_sizeof new file mode 100644 index 0000000..b9dffdc --- /dev/null +++ b/kfun/map_sizeof @@ -0,0 +1,12 @@ +NAME + map_sizeof - get size of a mapping + +SYNOPSIS + int map_sizeof(mapping map) + + +DESCRIPTION + Return the number of index-value pairs in mapping map. + +SEE ALSO + kfun/sizeof, kfun/strlen diff --git a/kfun/map_values b/kfun/map_values new file mode 100644 index 0000000..eac38ac --- /dev/null +++ b/kfun/map_values @@ -0,0 +1,13 @@ +NAME + map_values - get the values of a mapping + +SYNOPSIS + mixed *map_values(mapping map) + + +DESCRIPTION + Return an array containing the values of mapping map, sorted in the + order of the corresponding indices. + +SEE ALSO + kfun/map_indices diff --git a/kfun/millitime b/kfun/millitime new file mode 100644 index 0000000..6520e82 --- /dev/null +++ b/kfun/millitime @@ -0,0 +1,15 @@ +NAME + millitime - return the current time in milliseconds + +SYNOPSIS + mixed *millitime() + + +DESCRIPTION + Return the current time as an array ({ time, fraction }), where time + is an integer denoting the current time in seconds, and fraction is + a float in range [0.0 .. 1.0>, denoting the fraction of the current + second that has passed, with a resolution of 0.001. + +SEE ALSO + kfun/time, kfun/ctime diff --git a/kfun/modf b/kfun/modf new file mode 100644 index 0000000..d67198f --- /dev/null +++ b/kfun/modf @@ -0,0 +1,14 @@ +NAME + modf - compute floating point remainder + +SYNOPSIS + float *modf(float x) + + +DESCRIPTION + Split the argument into a fraction f and an integer part n, such that + | f | < 1.0, and f + n == x. ({ f, n }) is returned. Note that + n is returned as a float, and may not be representable in type int. + +SEE ALSO + kfun/frexp, kfun/ldexp diff --git a/kfun/new_object b/kfun/new_object new file mode 100644 index 0000000..2a8dcb7 --- /dev/null +++ b/kfun/new_object @@ -0,0 +1,18 @@ +NAME + new_object - create a new light-weight object + +SYNOPSIS + object new_object(object master) + + +DESCRIPTION + Create a new light-weight instance of the specified object with a name + of the form "object_name#-1". If the master object is itself a light- + weight object, it will be copied. Light-weight objects cannot be + destructed and are automatically deallocated once the last reference + to them is removed. + The new object is returned. The creator function will be called in the + new object immediately. + +SEE ALSO + kfun/clone_object diff --git a/kfun/object_name b/kfun/object_name new file mode 100644 index 0000000..02363cc --- /dev/null +++ b/kfun/object_name @@ -0,0 +1,12 @@ +NAME + object_name - return the name of an object + +SYNOPSIS + string object_name(object obj) + + +DESCRIPTION + Return the name of object obj. + +SEE ALSO + kfun/find_object diff --git a/kfun/parse_string b/kfun/parse_string new file mode 100644 index 0000000..2874269 --- /dev/null +++ b/kfun/parse_string @@ -0,0 +1,20 @@ +NAME + parse_string - parse a string + +SYNOPSIS + mixed *parse_string(string grammar, string str, + varargs int alternatives) + + +DESCRIPTION + Parse a string as described by the grammar. If parsing is successful, + the parse tree is returned as an array. The optional third argument + specifies the number of alternative parse trees to integrate in the + result, if the grammar is ambiguous. + parse_string() uses internal object storage to cache generated + automatons between calls, which is not removed until the object is + destructed. + This function cannot be used from a special object. + +SEE ALSO + kfun/explode, kfun/implode, kfun/sscanf diff --git a/kfun/pow b/kfun/pow new file mode 100644 index 0000000..d29b085 --- /dev/null +++ b/kfun/pow @@ -0,0 +1,16 @@ +NAME + pow - compute power + +SYNOPSIS + float pow(float x, float y) + + +DESCRIPTION + Return x to the power y. + +ERRORS + An error will result if 0.0 is taken to a negative power, if a negative + number is taken to a non-integer power, or if the result is too large. + +SEE ALSO + kfun/exp, kfun/log, kfun/log10 diff --git a/kfun/previous_object b/kfun/previous_object new file mode 100644 index 0000000..1dbf388 --- /dev/null +++ b/kfun/previous_object @@ -0,0 +1,15 @@ +NAME + previous_object - return the previous object + +SYNOPSIS + object previous_object(varargs int n) + + +DESCRIPTION + Return the object n+1 (default: 1) steps back in the call_other chain. + If the object is destructed, or the number of steps is larger than + the number of call_others involved, nil is returned. + +SEE ALSO + kfun/call_other, kfun/previous_program, kfun/this_object, + kfun/call_trace diff --git a/kfun/previous_program b/kfun/previous_program new file mode 100644 index 0000000..04789f4 --- /dev/null +++ b/kfun/previous_program @@ -0,0 +1,14 @@ +NAME + previous_program - return the previous program + +SYNOPSIS + string previous_program(varargs int n) + + +DESCRIPTION + Return the name of the object with the function n+1 (default: 1) steps + back in the function call chain. If the number of steps is larger than + the number of function calls involved, nil is returned. + +SEE ALSO + kfun/previous_object, kfun/call_trace diff --git a/kfun/query_editor b/kfun/query_editor new file mode 100644 index 0000000..cdd4c7f --- /dev/null +++ b/kfun/query_editor @@ -0,0 +1,15 @@ +NAME + query_editor - query editor status + +SYNOPSIS + string query_editor(object obj) + + +DESCRIPTION + Return the editor status of an object. This is either "command", if + the editor instance is in command mode, "insert", if the editor instance + is in input mode, or nil, if there is no editor instance for the given + object. + +SEE ALSO + kfun/editor diff --git a/kfun/query_ip_name b/kfun/query_ip_name new file mode 100644 index 0000000..eedb6f8 --- /dev/null +++ b/kfun/query_ip_name @@ -0,0 +1,15 @@ +NAME + query_ip_name - get the ip name of a user + +SYNOPSIS + string query_ip_name(object user) + + +DESCRIPTION + Return the IP name of a user, as a string, or nil if the given object + is not a user object. If the IP name could not be resolved, the + IP number is returned, instead. + +SEE ALSO + kfun/datagram_challenge, kfun/query_ip_number, kfun/send_datagram, + kfun/send_message, kfun/this_user, kfun/users diff --git a/kfun/query_ip_number b/kfun/query_ip_number new file mode 100644 index 0000000..d1be186 --- /dev/null +++ b/kfun/query_ip_number @@ -0,0 +1,14 @@ +NAME + query_ip_number - get the ip number of a user + +SYNOPSIS + string query_ip_number(object user) + + +DESCRIPTION + Return the ip number of a user, as a string, or nil if the given object + is not a user object. + +SEE ALSO + kfun/datagram_challenge, kfun/query_ip_name, kfun/send_datagram, + kfun/send_message, kfun/this_user, kfun/users diff --git a/kfun/random b/kfun/random new file mode 100644 index 0000000..c8d5cfa --- /dev/null +++ b/kfun/random @@ -0,0 +1,10 @@ +NAME + random - return random number + +SYNOPSIS + int random(int mod) + + +DESCRIPTION + Return a positive random number in the range 0 .. mod-1. If mod + is less than 1, 0 is returned. diff --git a/kfun/read_file b/kfun/read_file new file mode 100644 index 0000000..6f6a615 --- /dev/null +++ b/kfun/read_file @@ -0,0 +1,20 @@ +NAME + read_file - read a file + +SYNOPSIS + string read_file(string file, varargs int offset, int size) + + +DESCRIPTION + Read a file. The optional second and third arguments specify an + offset in the file and the maximum length of the string to be read, + and default to the whole file from the beginning. The offset may + be specified as negative, to read from the end of a file. Nil is + returned if the file does not exist. + +ERRORS + If the offset is out of range or the returned string would be too + large, an error will result. + +SEE ALSO + kfun/editor, kfun/write_file diff --git a/kfun/remove_call_out b/kfun/remove_call_out new file mode 100644 index 0000000..124d9d1 --- /dev/null +++ b/kfun/remove_call_out @@ -0,0 +1,16 @@ +NAME + remove_call_out - remove a delayed call to a function + +SYNOPSIS + mixed remove_call_out(int handle) + + +DESCRIPTION + Remove the callout associated with handle. The delay after which the + function would have been called is returned. The delay is an integer + or a floating point number, depending on how the callout was started. + If there is no scheduled call associated with the handle in the current + object, return -1. + +SEE ALSO + kfun/call_out diff --git a/kfun/remove_dir b/kfun/remove_dir new file mode 100644 index 0000000..373993f --- /dev/null +++ b/kfun/remove_dir @@ -0,0 +1,13 @@ +NAME + remove_dir - remove a directory + +SYNOPSIS + int remove_dir(string dir) + + +DESCRIPTION + Remove a directory, which must be empty. 1 is returned if the + directory could be removed, 0 otherwise. + +SEE ALSO + kfun/get_dir, kfun/make_dir diff --git a/kfun/remove_file b/kfun/remove_file new file mode 100644 index 0000000..97d8f83 --- /dev/null +++ b/kfun/remove_file @@ -0,0 +1,13 @@ +NAME + remove_file - remove a file + +SYNOPSIS + int remove_file(string file) + + +DESCRIPTION + Remove a file. 1 is returned if the file could be removed, 0 + otherwise. + +SEE ALSO + kfun/rename_file diff --git a/kfun/rename_file b/kfun/rename_file new file mode 100644 index 0000000..390fe2a --- /dev/null +++ b/kfun/rename_file @@ -0,0 +1,18 @@ +NAME + rename_file - rename a file + +SYNOPSIS + int rename_file(string from, string to) + + +DESCRIPTION + Rename a file. The destination file must not yet exist. 1 is + returned if the file could be renamed, 0 otherwise. + +ERRORS + Moving a directory may not be possible if the host operating system + does not support this as a system call. Moving a file across file + systems will probably fail. + +SEE ALSO + kfun/remove_file diff --git a/kfun/restore_object b/kfun/restore_object new file mode 100644 index 0000000..7b8b88f --- /dev/null +++ b/kfun/restore_object @@ -0,0 +1,19 @@ +NAME + restore_object - restore variables of an object + +SYNOPSIS + int restore_object(string file) + + +DESCRIPTION + Restore all global variables in an object that are not private or + static from a file. All variables which qualify, but were not + restored and do not contain object values, will be set to 0 or nil. + 1 is returned if the variables could be restored, 0 otherwise. + +ERRORS + An error will result if the restore file does not have the proper + format. + +SEE ALSO + kfun/save_object diff --git a/kfun/save_object b/kfun/save_object new file mode 100644 index 0000000..be0f204 --- /dev/null +++ b/kfun/save_object @@ -0,0 +1,16 @@ +NAME + save_object - save variables of an object + +SYNOPSIS + void save_object(string file) + + +DESCRIPTION + Save all global variables in an object that are not private or static + to a file. Only non-zero and non-object values are actually saved. + +ERRORS + An error will result if the save file could not be created. + +SEE ALSO + kfun/restore_object diff --git a/kfun/send_datagram b/kfun/send_datagram new file mode 100644 index 0000000..ea95755 --- /dev/null +++ b/kfun/send_datagram @@ -0,0 +1,20 @@ +NAME + send_datagram - send a message on the datagram channel + +SYNOPSIS + int send_datagram(string message) + + +DESCRIPTION + Send a message on the datagram channel of a binary user object. At + least one message must have been received on the same channel before + this function can be used. The return value is the length of the + message if it could be sent, or 0 otherwise. + No more than one datagram can be sent per user object during each task. + +ERRORS + An error will result if the current object has no datagram channel. + +SEE ALSO + kfun/datagram_challenge, kfun/query_ip_name, kfun/query_ip_number, + kfun/send_message, kfun/this_user, kfun/users diff --git a/kfun/send_message b/kfun/send_message new file mode 100644 index 0000000..f833804 --- /dev/null +++ b/kfun/send_message @@ -0,0 +1,24 @@ +NAME + send_message - send a message to a user + +SYNOPSIS + int send_message(string message) + int send_message(int echo) + + +DESCRIPTION + In the first form, send a message to the user associated with the + current object, returning the number of bytes that could be sent. + When used by the driver object, the string will be written to stderr. + In the second form, user input echoing will be turned off or on, + depending on the value of the argument being zero or non-zero, + respectively; the return value is 1 if input echoing could be set, or 0 + otherwise. + When the output buffer has emptied, message_done() will be called in + the user object. If send_message() is called again before the output + buffer has fully drained, message_done() will not be called before the + output buffer has emptied completely. + +SEE ALSO + kfun/datagram_challenge, kfun/query_ip_name, kfun/query_ip_number, + kfun/send_datagram, kfun/this_user, kfun/users diff --git a/kfun/shutdown b/kfun/shutdown new file mode 100644 index 0000000..cf261a3 --- /dev/null +++ b/kfun/shutdown @@ -0,0 +1,9 @@ +NAME + shutdown - shutdown the system + +SYNOPSIS + void shutdown() + + +DESCRIPTION + Shut down the system after the current user typed command has finished. diff --git a/kfun/sin b/kfun/sin new file mode 100644 index 0000000..6919aef --- /dev/null +++ b/kfun/sin @@ -0,0 +1,16 @@ +NAME + sin - comput sine + +SYNOPSIS + float sin(float x) + + +DESCRIPTION + Return the sine of the argument. + +ERRORS + An error will result if the argument is too large to accurately + compute the sine (around 1e9). + +SEE ALSO + kfun/cos, kfun/tan diff --git a/kfun/sinh b/kfun/sinh new file mode 100644 index 0000000..67512be --- /dev/null +++ b/kfun/sinh @@ -0,0 +1,15 @@ +NAME + sinh - compute hyperbolic sine + +SYNOPSIS + float sinh(float x) + + +DESCRIPTION + Return the hyperbolic sine of the argument. + +ERRORS + If the computed hyperbolic sine is too large, an error will result. + +SEE ALSO + kfun/cosh, kfun/tanh diff --git a/kfun/sizeof b/kfun/sizeof new file mode 100644 index 0000000..f29f4fb --- /dev/null +++ b/kfun/sizeof @@ -0,0 +1,12 @@ +NAME + sizeof - get size of an array + +SYNOPSIS + int sizeof(mixed *arr) + + +DESCRIPTION + Return the number of elements in array arr. + +SEE ALSO + kfun/map_sizeof, kfun/strlen diff --git a/kfun/sqrt b/kfun/sqrt new file mode 100644 index 0000000..b121377 --- /dev/null +++ b/kfun/sqrt @@ -0,0 +1,12 @@ +NAME + sqrt - compute square root + +SYNOPSIS + float sqrt(float x) + + +DESCRIPTION + Return the square root of the argument. + +ERRORS + An error will result if the argument is negative. diff --git a/kfun/sscanf b/kfun/sscanf new file mode 100644 index 0000000..946d318 --- /dev/null +++ b/kfun/sscanf @@ -0,0 +1,29 @@ +NAME + sscanf - simple string parser + +SYNOPSIS + int sscanf(string str, string fmt, ...) + + +DESCRIPTION + Parse the string str, using the format string fmt. The following + character sequences have a special meaning in the format string: + + %s match a substring + %d match a number + %f match a floating-point number + %c match a character + %% match single % + + Other characters must be matched exactly. %*s, %*d, %*f and %*c + can be used to match without assignment. Matched substrings and + numbers are assigned to the successive lvalue arguments following the + format string. The number of matched substrings and numbers is + returned. + +ERRORS + An error is caused if the format string is malformed, or if too few + lvalue arguments were given. + +SEE ALSO + kfun/explode, kfun/implode, kfun/parse_string diff --git a/kfun/status b/kfun/status new file mode 100644 index 0000000..5b1def8 --- /dev/null +++ b/kfun/status @@ -0,0 +1,12 @@ +NAME + status - get information about resource usage + +SYNOPSIS + mixed *status(varargs object obj) + + +DESCRIPTION + Called without an argument, this kfun returns information about + resources used by the system. With an object as argument, resource + usage by that object is given. The returned value is an array, the + fields of which are described in the include file . diff --git a/kfun/strlen b/kfun/strlen new file mode 100644 index 0000000..05d7efa --- /dev/null +++ b/kfun/strlen @@ -0,0 +1,12 @@ +NAME + strlen - get length of a string + +SYNOPSIS + int strlen(string str) + + +DESCRIPTION + Return the length of string str. + +SEE ALSO + kfun/map_sizeof, kfun/sizeof diff --git a/kfun/swapout b/kfun/swapout new file mode 100644 index 0000000..1ebcd34 --- /dev/null +++ b/kfun/swapout @@ -0,0 +1,13 @@ +NAME + swapout - swap out all objects + +SYNOPSIS + void swapout() + + +DESCRIPTION + Swap out all objects. This function can be called periodically to + clean up memory. + +SEE ALSO + kfun/dump_state diff --git a/kfun/tan b/kfun/tan new file mode 100644 index 0000000..f379a85 --- /dev/null +++ b/kfun/tan @@ -0,0 +1,19 @@ +NAME + tan - compute tangent + +SYNOPSIS + float tan(float x) + + +DESCRIPTION + Return the tangent of the argument. + +ERRORS + An error will result if the argument is too large to accurately + compute the tangent (around 1e9). + +SEE ALSO + kfun/cos, kfun/sin + +NOTE + For values close to a multiple of PI/2, the result may be inaccurate. diff --git a/kfun/tanh b/kfun/tanh new file mode 100644 index 0000000..7f1e243 --- /dev/null +++ b/kfun/tanh @@ -0,0 +1,12 @@ +NAME + tanh - compute hyperbolic tangent + +SYNOPSIS + float tanh(float x) + + +DESCRIPTION + Return the hyperbolic tangent of the argument. + +SEE ALSO + kfun/cosh, kfun/sinh diff --git a/kfun/this_object b/kfun/this_object new file mode 100644 index 0000000..4a6fad2 --- /dev/null +++ b/kfun/this_object @@ -0,0 +1,12 @@ +NAME + this_object - return current object + +SYNOPSIS + object this_object() + + +DESCRIPTION + Return the current object, or nil if the current object is destructed. + +SEE ALSO + kfun/previous_object diff --git a/kfun/this_user b/kfun/this_user new file mode 100644 index 0000000..eb5bdfe --- /dev/null +++ b/kfun/this_user @@ -0,0 +1,14 @@ +NAME + this_user - return the current user + +SYNOPSIS + object this_user() + + +DESCRIPTION + Return the user for which the current task started. If the current + task started from a delayed function call, nil is returned. + +SEE ALSO + kfun/datagram_challenge, kfun/query_ip_name, kfun/query_ip_number, + kfun/send_datagram, kfun/send_message, kfun/users diff --git a/kfun/time b/kfun/time new file mode 100644 index 0000000..1d0913b --- /dev/null +++ b/kfun/time @@ -0,0 +1,13 @@ +NAME + time - return the current time + +SYNOPSIS + int time() + + +DESCRIPTION + Return the current time as an integer. The time can be converted + into a string with the kfun ctime(). + +SEE ALSO + kfun/ctime, kfun/millitime diff --git a/kfun/typeof b/kfun/typeof new file mode 100644 index 0000000..29e87e8 --- /dev/null +++ b/kfun/typeof @@ -0,0 +1,10 @@ +NAME + typeof - return the type of a value + +SYNOPSIS + int typeof(mixed value) + + +DESCRIPTION + Return the type of a value. The return values are declared in + the include file . diff --git a/kfun/users b/kfun/users new file mode 100644 index 0000000..026d799 --- /dev/null +++ b/kfun/users @@ -0,0 +1,14 @@ +NAME + users - return array with users + +SYNOPSIS + object *users() + + +DESCRIPTION + Return an array containing the objects associated with the current + users. + +SEE ALSO + kfun/datagram_challenge, kfun/query_ip_name, kfun/query_ip_number, + kfun/send_datagram, kfun/send_message, kfun/this_user diff --git a/kfun/write_file b/kfun/write_file new file mode 100644 index 0000000..9357468 --- /dev/null +++ b/kfun/write_file @@ -0,0 +1,21 @@ +NAME + write_file - write to a file + +SYNOPSIS + int write_file(string file, string str, varargs int offset) + + +DESCRIPTION + Write a string to a file. If the optional third argument is + specified and non-zero, write the string at the given offset in + the file; otherwise, append to the file. The offset may be + negative to offset backwards from the end of the file. + To write a string to the beginning of a file, let the offset be + equal to minus the length of the file. + The return value is 1 for success, 0 for failure. + +ERRORS + If the offset is out of range, an error will result. + +SEE ALSO + kfun/editor, kfun/read_file diff --git a/parser b/parser new file mode 100644 index 0000000..32f3210 --- /dev/null +++ b/parser @@ -0,0 +1,184 @@ + Parser reference manual + +1. Introduction + +The parse_string() utility parses strings as follows: first, the string is +broken up into two types of smaller strings, called "tokens" and "whitespace". +Next, the resulting array of tokens (whitespace is ignored) is parsed as a +sentence in the language defined by a formal grammar. For any valid parsings, +LPC functions are called as appropriate, which may transform the array of +tokens, or indicate that a particular parsing of the string is yet to be +considered invalid. Finally, the resultant array of tokens, if any, is +returned by the function. + +Regular expressions are used to define tokens and whitespace, and the language +of those tokens is defined by a context-free grammar, which can be enhanced +with LPC function calls. Token/whitespace definitions and language definition +together are called "the grammar". + +Internally, two partial automatons are generated for each grammar, one to +match tokens and one to parse a sentence of tokens. Only those parts of the +automatons are generated that are required to parse the sentences seen so far; +this effect is cumulative for successive calls in each object, ensuring that +the automatons are not needlessly generated more than once. Each object can +handle only one grammar at a time. If a grammar differs from the previous +one used by the same object, any existing generated automatons are wiped out +and constructed anew. + + +2. Grammar + +A grammar consists of token rules and production rules, which may be given in +any order. Each grammar must contain at least one token rule and one +production rule. + + +2.1 Token rules + +A normal token rule has the following format: + + token = /regexp/ + +where "token" is an identifier name as in LPC, and "regexp" a regular +expression, with the following syntax: + + c a single character except `.', `[', `\', `*', `+', `(', `)', `/' + . any single character + \c a single character c, including `.', `[', `\', `*', `+', `(', `)', + `/' + [set] a single character in the given set, which is constructed of + single characters such as `a' and/or character ranges such as + `a-z'. `\' may be used to escape the characters `]', `^', `-', `\' + [^set] a single character not in the given set + +and, with regular expressions "a" and "b": + + a* zero or more occurrences of a (highest precedence) + a? zero or one occurrences of a + a+ one or more occurrences of a + ab the concatenation of a and b + a|b a or b + (a) a (lowest precedence) + +For any regular expression, the longest possible token will be matched. The +name "whitespace" is reserved for defining a special token, which is simply +skipped. More than one rule may be specified for each token, including +whitespace. + +If a string matches more than token, the token for which the rule appears first +in the grammar is selected. If a string does not match any token, it is +rejected and parsing fails. + +A special token rule may be defined which matches anything not matched by +other rules: + + token = nomatch + +where "nomatch" is literal text. Nomatch rules can be very inefficient, and +their use should be avoided if possible. + + +2.2 Production rules + +A production rule has the following format: + + symbol : rule + +where "symbol" is an identifier name as in LPC for the production rule, and +"rule" consists of zero or more token symbols, production rule symbols, or +string constants delimited by single quotes. + +A string constant in a production rule matches the given sequence of characters +directly, without reference to a token rule. Since a token rule is implicitly +generated for such string constants, the string constant is also said to be a +token. String constants take precedence over regular expressions, and any +token that matches both a string constant and a regular expression will always +match the string constant, only. `\' may be used in a string constant to +escape the single quote. + +More than one production rule may be given for the same symbol. All +production rules taken together form a context-free grammar, for which the +start symbol is defined in the first rule. Production rules that are +unreachable from the start symbol are ignored. Any symbol used in a +production rule reachable from the start symbol must itself define a token +rule or a production rule. + +Optionally, a rule can be followed by an LPC function name: + + symbol : rule ? function + +where "function" is the name of an LPC function to be called in the current +object if the specified rule has been matched. + + +3. Parsing + +Normally, parse_string() returns a flat array of token strings (if the input +string could be parsed as a sentence in the language defined by the grammar) +or nil (if the input string could not be parsed). However, the return value +can be modified to an array containing arbitrary other values, including +sub-arrays, by specifying LPC functions in the grammar that will be called +while parsing. Moreover, if the grammar is ambiguous, sub-arrays for the +alternative may be automatically included in the result. + + +3.1 LPC functions + +An LPC function called for a production rule will have a single argument, +an array with the parse tree that matches the production rule. LPC functions +are called in bottom-up order, so any function calls for sub-parse trees in +the current parse tree will already have been made. + +The LPC function can return its argument unchanged, or modify its argument +before returning it, or return a completely different value. Whatever the +return value is, it is taken to be an array matching the current rule; if +it is not an array at all, the current parse tree (and all parse trees that +depend on it) is discarded altogether. + +LPC functions are typically used to replace tokens in the parse tree by +their semantic value, or to add structure to a parse tree, which otherwise +would be represented as a flat array. + + +3.2 Ambiguous grammars + +A grammar that allows more than one parse tree for the same input string is +said to be "ambiguous". The string parser will sort alternative parse trees +by the order of the topmost different rule in the grammar, and by default +ignore all of them but the first one. + +An optional third argument to parse_string() can be used to retain an +additional number of alternative parse trees, which will be merged with the +first one; the argument specifies the number of extra alternatives to keep at +each point where sub-parse trees are handled by different rules in the grammar. +Instead of incorporating the first alternative immediately in the array +returned, a sub-array containing all of the alternatives as separate elements +is included, sorted by the order of their topmost rule in the grammar. + +LPC functions called for rules can be used to invalidate alternative parse +trees. Invalidated alternatives will be removed from the overall result. + + +3.3 Writing grammars + +Grammars can be parsed most efficiently if they are not ambiguous. Generally, +ambiguous grammars can be rewritten to be non-ambiguous. For example, +consider the following (partial) grammar, which is ambiguous: + + Expr: number + Expr: Expr '+' Expr + +It can be rewritten to be either left-recursive, + + Expr: number + Expr: Expr '+' number + +or right-recursive: + + Expr: number + Expr: number '+' Expr + +Neither rewritten grammar is ambiguous, and both explicitly specify the order +in which expressions are to be evaluated: from left to right, or from right to +left, respectively. If the order doesn't matter, left recursion should be +preferred, as this is parsed more efficiently.