Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/doc/LPC/closures b/doc/LPC/closures
new file mode 100644
index 0000000..ba5d804
--- /dev/null
+++ b/doc/LPC/closures
@@ -0,0 +1,331 @@
+CONCEPT
+ closures
+
+NOTE
+ This is the official man page concerning closures. If you find
+ it hard to read maybe the Closure Guide is an easier introduction
+ for you: See closure_guide(LPC) and closures-example(LPC).
+
+DESCRIPTION
+ Closures provide a means of creating code dynamically and
+ passing pieces of code as parameters, storing them in
+ variables. One might think of them as a very advanced form of
+ process_string(). However, this falls short of what you can
+ actually do with them.
+
+ The simplest kind of closures are efuns, lfuns or operators.
+ For example, #'this_player is an example of a closure. You can
+ assign it to a variable as in
+
+ closure f;
+ object p;
+ f = #'this_player;
+
+ and later use either the funcall() or apply() efun to evaluate
+ it. Like
+
+ p = funcall(f);
+
+ or
+
+ p = apply(f);
+
+ In both cases there p will afterwards hold the value of
+ this_player(). Of course, this is only a rather simple
+ application.
+
+ Inline closures are a variant of lfun closures, the difference
+ being that the function text is written right where the
+ closure is used. Since they are pretty powerful by
+ themselves, inline closures have their own manpage.
+
+ More useful instances of closures can be created
+ using the lambda() efun. It is much like the lambda function
+ in LISP. For example, you can do the following:
+
+ f = lambda( ({ 'x }), ({ #'environment, 'x }) );
+
+ This will create a lambda closure and assign it to f. The
+ first argument to lambda is an array describing the arguments
+ (symbols) passed to the closure upon evaluation by funcall()
+ or apply(). You can now evaluate f, for example by means of
+ funcall(f,this_object()). This will result in the following
+ steps:
+
+ 1. The value of this_object() will be bound to symbol x.
+ 2. environment(x) evaluates to environment(this_object())
+ and is returned as the result of the funcall().
+
+ One might wonder why there are two functions, funcall() and
+ apply(), to perform the seemingly same job, namely evaluating
+ a closure. Of course there is a subtle difference. If the last
+ argument to apply() is an array, then each of its elements
+ gets expanded to an additional paramater. The obvious use
+ would be #'call_other as in:
+
+ mixed eval(object ob,string func,mixed *args) {
+ return apply(#'call_other,ob,func,args);
+ }
+
+ This will result in calling
+ ob->func(args[0],args[1],...,args[sizeof(args)-1]). Using
+ funcall() instead of apply() would have given us
+ ob->func(args).
+
+ Of course, besides efuns there are closures for operators,
+ like #'+, '-, #'<, #'&&, etc.
+
+ Well, so far closures have been pretty much limited despite
+ their obvious flexibility. This changes now with the
+ introduction of conditional and loop operators. For example,
+ try:
+
+ closure max;
+ max = lambda( ({ 'x, 'y }),
+ ({ #'? ,({ #'>, 'x, 'y }), 'x, 'y }) );
+ return funcall(max,7,3);
+
+ The above example will return 7. What happened? Of course #'?
+ is the conditional operator and its 'syntax' is as follows:
+
+ ({ #'?, cond1, val1, cond2, val2, ..., condn, valn,
+ valdefault });
+
+ It evaluates cond1, cond2, ..., condn successively until it
+ gets a nonzero result and then returns the corresponding
+ value. If there is no condition evaluating to a nonzero
+ result, valdefault gets returned. If valdefault is omitted, 0
+ gets returned. #'?! works just like #'?, except that the !
+ operator is applied to conditions before testing. Therefore,
+ while #'? is somewhat like an if statement, #'?! resembles an
+ if_not statement if there were one.
+
+ There are also loops:
+
+ ({ #'do, loopbody1, ..., loopbodyN, loopcond, loopresult })
+
+ will evaluate the loopbodies until loopcond evaluates to 0 and
+ then return the value of loopresult. Symbols may be used as
+ variables, of course.
+
+ ({ #'while, loopcond, loopresult, loopbody1, ..., loopbodyN })
+
+ works similar but evaluates loopcond before the loopbodies.
+
+ The foreach() loop also exists:
+
+ ({ #'foreach, 'var, expr, loopbody1, ..., loopbodyN })
+ ({ #'foreach, ({ 'var1, ..., 'varN}) , expr
+ , loopbody1, ..., loopbodyN })
+
+
+ Now on to a couple of tricky things:
+
+ a) How do I write down an array within a lambda closure to
+ avoid interpretation as a subclosure?
+
+ ({ #'member, ({ "abc", "xyz" }), 'x }) will obviously
+ result in an error as soon as lambda() tries to interpret
+ "abc" as a closure operator. The solution is to quote the
+ array, as in: ({ #'member, '({ "abc", "xyz" }), 'x }).
+ Applying lambda() to this will not result in an error.
+ Instead, the quote will be stripped from the array and the
+ result regarded as a normal array literal. The same can be
+ achieved by using the efun quote(), e.g.:
+
+ ({ #'member, quote( ({ "abc", "xyz" }), 'x ) })
+
+ b) Isn't it a security risk to pass, say, a closure to the
+ master object which then evaluates it with all the
+ permissions it got?
+
+ Luckily, no. Each closure gets upon compilation bound to
+ the object defining it. That means that executing it first
+ sets this_object() to the object that defined it and then
+ evaluates the closure. This also allows us to call lfuns
+ which might otherwise be undefined in the calling object.
+
+ There is however, a variant of lambda(), called
+ unbound_lambda(), which works similar but does not allow
+ the use of lfuns and does not bind the closure to the
+ defining object. The drawback is that trying to evaluate it
+ by apply() or funcall() will result in an error. The
+ closure first needs to be bound by calling bind_lambda().
+ bind_lambda() normally takes one argument and transforms an
+ unbound closure into a closure bound to the object
+ executing the bind_lambda().
+
+ Privileged objects, like the master and the simul_efun
+ object (or those authorized by the privilege_violation()
+ function in the master) may also give an object as the
+ second argument to bind_lambda(). This will bind the
+ closure to that object. A sample application is:
+
+ dump_object(ob)
+ // will dump the variables of ob to /dump.o
+ {
+ closure save;
+ save = unbound_lambda( ({ }),
+ ({ #'save_object, "/open/dump" }) );
+ bind_lambda(save,ob);
+ funcall(save);
+ }
+
+ bind_lambda() can also be used with efun closures.
+
+ c) It might be an interesting application to create closures
+ dynamically as an alternative to writing LPC code to a file
+ and then loading it. However, how do I avoid doing exactly
+ that if I need symbols like 'x or 'y?
+
+ To do that one uses the quote() efun. It takes a string as
+ its argument and transforms it into a symbol. For example,
+ writing quote("x") is exactly the same as writing 'x.
+
+ d) How do I test if a variable holds a closure?
+
+ Use the closurep() efun which works like all the other type
+ testing efuns. For symbols there is also symbolp()
+ available.
+
+ e) That means, I can do:
+ if (closurep(f)) return funcall(f); else return f; ?
+
+ Yes, but in the case of funcall() it is unnecessary. If
+ funcall() gets only one argument and it is not a closure it
+ will be returned unchanged. So return funcall(f); would
+ suffice.
+
+ f) I want to use a function in some object as a closure. How do I do
+ that?
+
+ There are several ways. If the function resides in
+ this_object(), just use #'func_name. If not, or if you want
+ to create the function dnynamically, use the efun
+ symbol_function(). It takes a string as it first and an
+ object as its second argument and returns a closure which
+ upon evaluation calls the given function in the given
+ object (and faster than call_other(), too, if done from
+ inside a loop, since function search will be done only when
+ calling symbol_function().
+
+ g) Can I create efun closures dynamically, too?
+
+ Yes, just use symbol_function() with a single argument.
+ Most useful for marker objects and the like. But
+ theoretically a security risk if not used properly and from
+ inside a security relevant object. Take care, however,
+ that, if there is a simul_efun with the same name, it will
+ be preferred as in the case of #'function. Use the efun::
+ modifier to get the efun if you need it.
+
+ h) Are there other uses of closures except using them to store
+ code?
+
+ Lots. For example, you can use them within almost all of
+ the efuns where you give a function as an argument, like
+ filter(), sort_array() or walk_mapping().
+ sort_array(array,#'>) does indeed what is expected. Another
+ application is set_prompt(), where a closure can output
+ your own prompt based on the current time and other stuff
+ which changes all the time.
+
+ Finally, there are some special efun/operator closures:
+
+ #'[ : indexes an array.
+ #'[< : does the same, but starting at the end.
+ #'[..] : gets an array and two numbers
+ and returns a sub-array.
+ #'[..<] : same as above but the second index is
+ interpreted as counted from the left end.
+ #'[<..] and
+ #'[<..<] : should be clear now.
+ #'[.. : takes only one index and returns the sub-
+ array from this index to the end.
+ #'[<.. : same as above but the index is interpreted
+ as counted from the left end.
+ #'({ : puts all arguments into an array.
+ #'([ : gets an unquoted (!) array which must include
+ at least one element as argument and returns a mapping of
+ the width of the given array's size with one entry that
+ contains the first element as key and the other elements
+ as values to the key.
+
+ #'negate is for unary minus.
+ #', may be followed by any number of closures,
+ e.g.: ({ (#',),
+ ({#'= 'h, 'a, }), ({#'=, 'a, 'b }), ({#'=, 'b, 'h }) })
+ will swap 'a and 'b when compiled and executed.
+
+
+ Procedural elements:
+ ====================
+
+ definition of terms:
+ <block> : zero or more values to be evaluated.
+ <test> : one value to be evaluated as branch or loop condition.
+ <result> : one value to be evaluated at the end of the
+ execution of the form; the value is returned.
+ <lvalue> : local variable/parameter, global variable, or an
+ indexed lvalue.
+ useded EBNF operators:
+ { } iteration
+ [ ] option
+
+ forms:
+ ({#', <body> <result>})
+ ({#'? { <test> <result> } [ <result> ] })
+ ({#'?! { <test> <result> } [ <result> ] })
+ ({#'&& { test } })
+ ({#'|| { test } })
+ ({#'while <test> <result> <body>}) loop while test
+ evaluates non-zero.
+ ({#'do <body> <test> <result>}) loop till test
+ evaluates zero.
+ ({#'= { <lvalue> <value> } }) assignment
+ other assignment
+ operators work, too.
+
+ lisp similars:
+ #', progn
+ #'? cond
+ #'&& and
+ #'|| or
+ #'while do /* but lisp has more syntactic candy here */
+ #'= setq
+
+ A parameter / local variable 'foo' is referenced as 'foo , a
+ global variable as ({#'foo}) . In lvalue positions
+ (assignment), you need not enclose global variable closures in
+ arrays.
+
+ Call by reference parameters are given with ({#'&, <lvalue>})
+
+ Some special efuns:
+ #'[ indexing
+ #'[< indexing from the end
+ #'negate unary -
+
+ Unbound lambda closures
+ =======================
+
+ These closures are not bound to any object. They are created
+ with the efun unbound_lambda() . They cannot contain
+ references to global variables, and all lfun closures are
+ inserted as is, since there is no native object for this
+ closure. You can bind and rebind unbound lambda closures to
+ an object with efun bind_lambda() You need to bind it before
+ it can be called. Ordinary objects can obly bind to
+ themselves, binding to other objects causes a privilege
+ violation(). The point is that previous_object for calls done
+ from inside the closure will reflect the object doing
+ bind_lambda(), and all object / uid based security will also
+ refer to this object.
+
+
+AUTHOR
+ MacBeth, Amylaar, Hyp
+
+SEE ALSO
+ closures-abstract(LPC), closures-example(LPC), closure_guide(LPC)
+ inline-closures(LPC)