Copyright by Denys Duchier, Jan 1995
Simon Fraser University

All the new primitives and sort added WILD Life belong to module
"sys".  Unless otherwise specified, all functions residuate as
appropriate.

----------------------------------------------------------------------
			     BIT VECTORS
----------------------------------------------------------------------
make_bitvector(Size:int)
	a function returning a bitvector value that can contain at
	least Size bits.

bitvector_and(B1:bitvector,B2:bitvector)
	a function returning a new bitvector that is the logical and
	of its arguments.  If B1 and B2 are of different size, the
	result is of size the maximum of the 2, and the smaller
	argument behaves as if it was padded with zeros at the upper
	end.

bitvector_or(B1:bitvector,B2:bitvector)
	same as above but for logical or.

bitvector_xor(B1:bitvector,B2:bitvector)
	same as above but for logical xor (exclusive or).

bitvector_not(B:bitvector)
	returns a bitvector where the bits have been flipped.

bitvector_count(B:bitvector)
	returns an integer which is the number of 1 bits in B.

bitvector_get(B:bitvector,I:int)
	returns 1 or 0 depending on whether bit I is set in bitvector
	B.

bitvector_set(B:bitvector,I:int)
	set bit I to 1 in B.

bitvector_clear(B:bitvector,I:int)
	set bit I to 0 in B.

----------------------------------------------------------------------
			 REGULAR EXPRESSIONS
----------------------------------------------------------------------

The regular expression facility makes use of Henry Spencer's free
implementation of V8 egrep-style regular expressions library.

regexp_compile(S:string)
	takes a string representing a regular expression and returns a
	value of sort regexp which is a compiled of version of that
	regular expression.

regexp_execute can function either as a predicate or as a function
depending on whether you supply a mask (3rd arg) or not.

regexp_execute(R:regexp,S:string [,offset=>I:int])
	function that attempts to match R with S.  The optional offset
	indicates where to start the match in S (by default at the
	first character).  Returns a term where numeric feature n has
	value (i,j) if group n in R matched the substring of S
	starting at character i and ending before character j.  Keep
	in mind that for some stupid reason strings in WILD Life use
	1-based indexing.

regexp_execute(R:regexp,S:string,Mask [,offset=>I:int])
	this works as a predicate.  The Mask indicates for what groups
	information is desired.  If numeric feature n is present in
	Mask, this unifies (i,j) with its value (with same
	interpretation for i and j as above).

module("regexp")?

re_compile(X:{string;regexp})
	function returning a regexp given a string representing a
	regular expression or a compiled regular expression (in which
	case it simply returns its argument).

re_match(R:{string;regexp},S:string)
	behaves like the functional version of regexp_execute, but
	also accepts a non-compiled regular expression as its 1st
	argument.

re_match(R:{string;regexp},S:string,Mask)
	behaves like the predicate version of regexp_execute...

re_split(R:{string;regexp},S:string,Mask)
	a predicate which fills the numeric features of Mask with the
	corresponding substrings of S rather than the bounds of the
	corresponding group.

re_matching(R:{string;regexp})
	function returning a non-instantiated string that is
	constrained to match the regular expression R.

----------------------------------------------------------------------
			     FILE STREAMS
----------------------------------------------------------------------

file_stream <| stream.

stdin, stdout, stderr are global vars bound the appropriate file_streams

int2stream(FD:int,Mode:string)
	function returning a stream (which you should then specialize
	appropriately).  FD is an integer denoting a file descriptor,
	and Mode is "r" or "w" etc...

fopen(Path:string,Mode:string)
	function returning a file_stream.  Mode is like for the C
	call, i.e. "r", or "w", etc...

fclose(S:stream)
	predicate to close a stream.

fwrite(S:stream,Text:string)
	predicate that writes the Text to the stream.

fflush(S:stream)
	predicate causing all buffered text written to S to be
	effectively sent to S.  This is very useful for client/server
	communication through sockets.

get_buffer(S:stream,Size:int)
	function that reads Size bytes from S and returns them as a
	string.  The string can be shorter than Size if fewer than
	Size bytes are available from S (i.e. EOF).

get_record(S:stream,Terminator:string)
	function that reads from S up to and including the given
	Terminator.  If no more bytes are available from S but we
	haven't found the terminator yet, what has been read up to now
	is returned as a string.  If the Terminator is empty, we read
	everything until we run out.

get_code(S:stream)
	function that returns the next character from S, as an integer.
	or fails if EOF has been reached.

ftell(S:file_stream)
	returns the current position in the file as an integer.

fseek(S:file_stream,I:int [,Whence:int])
	sets the current position in S to offset I.  Whence has the
	same signification as for the C call and should 0 (default)
	for counting from the beginning, 1 for counting from the
	current position, or 2 for counting from the end of the file
	onward.

stream2sys_stream(S)
	turns an old style stream into a new style stream.

sys_stream2stream(S)
	turns a new style stream into an old style stream.

----------------------------------------------------------------------
			SOCKETS AND NETWORKING
----------------------------------------------------------------------

socket_stream <| stream.

socket(Family:{"AF_INET";"AF_UNIX"},
       Type:{"SOCK_STREAM";"SOCK_DGRAM";"SOCK_RAW"})
	both arguments are optional Family defaults to "AF_INET" and
	Type to "SOCK_STREAM".  function returns a socket_stream.

bind(S:socket_stream [,host=>H:string] , port=>P:int)
	predicate binds the socket to a port on host (which is
	optional and naturally defaults to the current host :-)
	actually INADDR_ANY).  the socket should be in family AF_INET.
	H can be a hostname or an IP address.

bind(S:socket_stream,path=>P:string)
	binds the socket to path P in the file system.  the socket
	should be in family AF_UNIX.

connect(S:socket_stream[,host=>H:string],port=>P:int)
connect(S:socket_stream,path=>P:string)
	connects (to a server).  same interface as bind (see above).

listen(S:socket_stream,N:int)
	accept at most N simultaneous connections.  Of course, since
	we don't have threads this isn't too terribly useful at the
	moment.

accept(S:socket_stream)
	function blocks until a client attempts to connect, at which
	point it returns a new socket_stream to communicate with the
	client.

module("client-server")?

connect_to_server(Host:string,Port:int)
	function returns a socket connected to the server running on
	machine Host at port Port.

http_query(URL)
	function returns a term @(headers=>H,body=>B) where B is the
	document proper, and H is the collection of MIME headers
	transmitted by the server; each header field is stored on the
	feature by that name.

	this function won't stay in this module, but will eventually
	migrate to an http module or something.

start_server(port=>P:int,handler=>H)
	predicate that turns the current WILD Life process into a
	server that accepts connections on port P on the local
	machine.  H should be a boolean function that takes a
	socket_stream as its argument; it handles communication with
	one client on the given socket.

Example:

	import("client-server")?
	client_fun(S)->true|sys#fwrite(S,"Hello World\n").
	start_server(port=>5000,handler=>client_fun)?

The above implements a simple server that says "Hello World" to
anybody who connects to this machine on port 5000.  E.g.:

	% telnet roquefort 5000
	Trying 199.60.4.216...
	Connected to roquefort.cs.sfu.ca.
	Escape character is '^]'.
	Hello World
	Connection closed by foreign host.

	start_server is written so that it calls fflush and fclose on
	the client socket no matter what happens.

----------------------------------------------------------------------
			    SYSTEM ERRORS
----------------------------------------------------------------------

errno
	function returns the current C Lib errno as an integer.

errmsg([I:int])
	returns error message string for error number I.  I defaults
	to the current errno.

----------------------------------------------------------------------
			       MODULES
----------------------------------------------------------------------

import_symbol(Symbol [,as=>Name])
	predicate. creates in the current module a new name for the
	definition currently associated with Symbol.  If as=>Name is
	given then Name must be a symbol and is used as the name.  If
	omitted, use the same as that of Symbol.

----------------------------------------------------------------------
			      PROCESSES
----------------------------------------------------------------------

fork	function returning an integer.  Spawns off as a child process
	a copy of the current WILD Life process.  returns 0 to the
	child and the child's process id to the parent.

wait	function returning one of:
		process_no_children
		process_exited(PID:int,EXITSTATUS:int)
		process_signaled(PID:int,SIGNAL:int)
		process_stopped(PID:int,STOPSTATUS:int)
		process_continued(PID:int)

waitpid(Pid:int [,Options:int])
	function returning same as above, but waiting only on child
	process Pid.

kill(Pid:int,Signal:int)
	predicate sending a signal to another process.

----------------------------------------------------------------------
		   ANSI ESCAPE SEQUENCES IN STRINGS
----------------------------------------------------------------------

ansi escape sequences are now allowed in strings.

----------------------------------------------------------------------
			    MISCELLANEOUS
----------------------------------------------------------------------

cuserid -> string
	returns the username associated with the current process.

gethostname -> string
	returns the current host's domain name as a string.

lazy_project(X,Feature)
	function that residuates until the feature becomes available
	on X. (cf "bullshit" comment in sys.c).

wait_on_feature(X,Feature,Goal)
	suspends until X acquires Feature, then executes Goal.  To
	denote the value associated with the feature in Goal, just
	use X.Feature.  In order to install a value on X's Feature,
	use X=@(Feature=>Value), because X.Feature = Value will
	first create Feature, then release Goal, and finally unify
	Feature's value with Value.

apply1(Fun,Feature,Value)
	residuates on Fun.  Applies curried function Fun to one more
	argument as specified by Feature and Value.

getpid	returns the process's id as an integer.

psi2string(X)
	returns a writeq'ed representation of X as a string.
