Updates von /doc/LPC aus Driversourcen
Change-Id: I60960bf74c3914a6fb6b0bd6628b39c1a4d8ba2d
diff --git a/doc/LPC/async b/doc/LPC/async
new file mode 100644
index 0000000..addc14d
--- /dev/null
+++ b/doc/LPC/async
@@ -0,0 +1,32 @@
+NAME
+ async
+
+SYNTAX
+ /* function */
+ async <modifiers> <type> name ( <arguments> )
+ {
+ statements...
+ }
+
+ /* inline closure */
+ async function <type> ( ) : <context>
+ {
+ statements...
+ }
+
+DESCRIPTION
+ The async modifer turns a function or inline closure into a coroutine.
+
+ If the function is called it will immediately return a coroutine
+ object that will represent the remainder of the function's execution.
+
+ The inline closure notation will not result in a closure, but a
+ coroutine object.
+
+HISTORY
+ Coroutines were introduced in LDMud 3.6.5.
+
+SEE ALSO
+ coroutines(LPC), await(LPC), yield(LPC), foreach(LPC),
+ call_coroutine(E), this_coroutine(E)
+
diff --git a/doc/LPC/await b/doc/LPC/await
new file mode 100644
index 0000000..95a7c25
--- /dev/null
+++ b/doc/LPC/await
@@ -0,0 +1,35 @@
+NAME
+ await
+
+SYNTAX
+ await(<coroutine>)
+ await(<coroutine>, <value>)
+
+DESCRIPTION
+ The instruction is only allowed in a coroutine and suspends its
+ execution.
+
+ The target coroutine must also be in a suspended state. Its
+ execution will then continue.
+
+ The current coroutine will wait for the execution of the target
+ coroutine to finish with a return statement or end of statement
+ block. It cannot continue its execution until then. Only one
+ coroutine may wait for another. If there is already a coroutine
+ waiting for the target coroutine the instruction will fail.
+
+ Any calls during the waiting period to continue the current
+ coroutine will result in execution of the target coroutine.
+ So the await() call can be seen as a sub-coroutine call.
+
+ The value will be passed into the target coroutine as the result
+ of its yield() instruction that suspended its execution before.
+ If the coroutine had just started, the value will be discarded.
+ If no value was given, 0 will be passed instead.
+
+HISTORY
+ Coroutines were introduced in LDMud 3.6.5.
+
+SEE ALSO
+ coroutines(LPC), async(LPC), yield(LPC), foreach(LPC),
+ call_coroutine(E), this_coroutine(E)
diff --git a/doc/LPC/closure_guide b/doc/LPC/closure_guide
index 1f23acb..b1155cf 100644
--- a/doc/LPC/closure_guide
+++ b/doc/LPC/closure_guide
@@ -516,8 +516,8 @@
#'catch executes the closure given as argument, but catches any
runtime error (see catch(E)). Optionally the symbols 'nolog,
- 'publish and 'reserve may be given as additional arguments to
- modify the behaviour of the catch.
+ 'publish, 'reserve and 'limit may be given as additional
+ arguments to modify the behaviour of the catch.
#'= and the #'<op>= variants are also special because the first
argument has to be an lvalue.
diff --git a/doc/LPC/closures-abstract b/doc/LPC/closures-abstract
index 6b1d932..0731151 100644
--- a/doc/LPC/closures-abstract
+++ b/doc/LPC/closures-abstract
@@ -36,7 +36,8 @@
Evaluate expression, then evaluate the result form labeled with
the value equal to the value evaluated from expression.
If no matching label exists, the value of #'switch is 0.
- ({#'catch, <body> [, 'nolog ] [, 'publish ], [, 'reserve, <expr> })
+ ({#'catch, <body> [, 'nolog ] [, 'publish ] [, 'reserve, <expr> ]
+ [, 'limit, <expr> ] })
Evaluates the <body> and catches any runtime error. If the symbol
'nolog is also given, a caught error is not logged. If the
symbol 'publish is also given, master::runtime_error() is
diff --git a/doc/LPC/coroutines b/doc/LPC/coroutines
new file mode 100644
index 0000000..7284561
--- /dev/null
+++ b/doc/LPC/coroutines
@@ -0,0 +1,130 @@
+CONCEPT
+ coroutines
+
+INTRODUCTION
+ Regular LPC functions have a short life span. They must finish,
+ before a new event like a player command can be processed.
+ Coroutines are a special type of functions, whose execution can
+ be suspended and continued at a later time. At each suspension
+ point values can be exchanged with another coroutine or the caller.
+
+ Coroutines are passed by reference. When a coroutine finishes
+ it decays to the number zero.
+
+
+DEFINITION
+ Coroutines can be created by calling a function that was declared
+ with the async modifier:
+
+ async void fun()
+ {
+ ...
+ }
+
+ coroutine cr = fun();
+
+ Alternatively inline coroutines are created with the inline closure
+ syntax:
+
+ coroutine cr = async function void() { ... };
+
+ Normal coroutines can get parameters, inline coroutines cannot.
+ (They however can use context variables.)
+
+
+OPERATIONS
+ These operations can be used from within a coroutine:
+
+ await(coroutine[, value])
+
+ Call another coroutine, pass on the given value and wait for
+ this coroutine to finish with a return statement.
+ Until then the current coroutine is suspended. Any operation
+ on this coroutine will be passed to the called coroutine.
+ The result of the await() call is the return value from the
+ called coroutine.
+
+ yield([value])
+
+ Suspend execution of the current coroutine and pass the given
+ value to the caller. The result of the yield() call is the
+ value that will be passed in when the coroutine will be
+ continued.
+
+ yield(value, coroutine)
+
+ Suspend execution of the current coroutine and continue the
+ given coroutine, thereby passing the value in. The result of
+ the yield() call is the value that will be passed in when the
+ coroutine will be continued.
+
+ return [value]
+
+ Destroy the current coroutine. If any coroutine is waiting,
+ continue its execution. Otherwise return to the caller.
+
+
+EFUNS
+ call_coroutine(coroutine[, value])
+
+ Call the given coroutine, pass on the given value.
+
+ In contrast to await() and yield() the current execution will
+ only be suspended for the call (just like any other function
+ call) and be continued when the coroutine suspends execution
+ with yield() or finishes execution with return.
+
+ Therefore this efun can also be used from regular functions.
+
+ The result of the efun call is the value of the yield() or
+ return call that suspended the execution of the called coroutine.
+
+ this_coroutine()
+
+ Returns the current coroutine. If it's not called from a
+ coroutine, the innermost coroutine in the caller stack will
+ be returned. Returns 0 if there is no coroutine in the caller
+ stack.
+
+
+EXAMPLE
+ /* Coroutine that sleeps a given amount of time. */
+ async void sleep(int sec)
+ {
+ /* Start a call_out that will wake this coroutine. */
+ call_out(#'call_coroutine, sec, this_coroutine());
+
+ /* Suspend and wait. */
+ yield();
+ }
+
+ /* Use of the sleep() function. */
+ async void fun()
+ {
+ write("Starting...\n");
+ await(sleep(10));
+ write("Finishing after 10s.\n");
+ }
+
+
+MISCELLANEOUS
+ Support for coroutines is signaled by the macro __LPC_COROUTINES__.
+
+ Only declarative casts to coroutine are possible, there is no
+ conversion of any other type to coroutine available (therefore
+ there is no to_coroutine() efun).
+
+ Coroutines can not be copied or serialized with save_value().
+ Coroutines are bound to their object. If the object is destroyed,
+ the coroutines will be as well (and any awaiting coroutines).
+
+ foreach() can be used to call coroutines repeatedly.
+
+
+HISTORY
+ Coroutines were introduced in LDMud 3.6.5.
+
+
+SEE ALSO
+ async(LPC), await(LPC), yield(LPC), foreach(LPC),
+ call_coroutine(E), this_coroutine(E)
diff --git a/doc/LPC/decltype b/doc/LPC/decltype
new file mode 100644
index 0000000..8c74039
--- /dev/null
+++ b/doc/LPC/decltype
@@ -0,0 +1,31 @@
+NAME
+ decltype
+
+SYNTAX
+ decltype(<expr>)
+
+DESCRIPTION
+ The expression will compiled just to determine the resulting type.
+ The expression itself will not be executed. The result of this
+ operator is the lpctype value representing the expression result.
+
+NOTE
+ The result of this operator depends on a lot of factors, for example
+ if any type information is preserved for any inherited programs that
+ are referenced in the expression. But it also depends on the type
+ inference capabilities of the LPC compiler. So future versions of
+ LDMud might have different results on the same expression.
+
+
+EXAMPLES
+ int var;
+ decltype(var) /* result: [int] */
+
+ string fun();
+ decltype(fun()) /* result: [string], fun() will not be called. */
+
+HISTORY
+ Introduced in LDMud 3.6.7.
+
+SEE ALSO
+ lpctypes(LPC)
diff --git a/doc/LPC/foreach b/doc/LPC/foreach
index 9e4df32..5740f37 100644
--- a/doc/LPC/foreach
+++ b/doc/LPC/foreach
@@ -52,9 +52,14 @@
the variables. This allows the loop body to change the contents
of the original data.
- If <expr> evalutes to an integer, the loop will count up <var>
+ If <expr> evaluates to an integer, the loop will count up <var>
from 0 to <expr>-1, basically implementing a count loop.
+ If <expr> evaluates to a coroutine, the loop will call the
+ coroutine until the coroutine finishes execution. All values
+ from the coroutine's yield() calls will be assigned to <var>,
+ essentially using the coroutine as a generator function.
+
If there are more variables than necessary, the unneeded ones
are not changed.
@@ -126,7 +131,8 @@
LDMud 3.3.44 introduced the use of references, the loop over
an integer expression, and the loop over an integer range.
LDMud 3.3.266 added support for structs.
+ LPMud 3.6.5 added support for coroutines.
SEE ALSO
- for(LPC)
+ for(LPC), yield(LPC)
diff --git a/doc/LPC/lpctypes b/doc/LPC/lpctypes
new file mode 100644
index 0000000..2e2d7e9
--- /dev/null
+++ b/doc/LPC/lpctypes
@@ -0,0 +1,48 @@
+CONCEPT
+ lpctypes
+
+INTRODUCTION
+ An lpctype variable stores an LPC type like int or string*.
+ They are mainly used in the check_types() efun, but also for
+ introspection with functionlist() and variable_list().
+
+DEFINITION
+ An lpctype literal can be created either by writing the type
+ in brackets or using the decltype(LPC) operator:
+
+ lpctype t1 = [int];
+ lpctype t2 = decltype(t1); /* t2 will be [lpctype] */
+
+ The type in brackets can be any type declaration, similar to
+ the type declarations of variable or function result.
+
+OPERATIONS
+ lpctypes support the following operations:
+
+ t1 | t2
+
+ Create a union type of both types.
+
+ t1 & t2
+
+ Create the intersection of both types. If the intersection
+ is empty [void] will be returned.
+
+ t1 in t2
+
+ Yields 1 if t1 is a subset of t2.
+
+EXAMPLE
+ void process(mixed value)
+ {
+ if (check_type(value, [int|float]))
+ process_number(value);
+ else
+ process_anything(value);
+ }
+
+HISTORY
+ The type was introduced in LDMud 3.6.7.
+
+SEE ALSO
+ check_type(E), decltype(LPC)
diff --git a/doc/LPC/lwobjects b/doc/LPC/lwobjects
index f9559c8..81fc57c 100644
--- a/doc/LPC/lwobjects
+++ b/doc/LPC/lwobjects
@@ -4,7 +4,7 @@
INTRODUCTION
Lightweight objects are a cross between regular objects and structs.
Like regular objects they are build from programs (.c files) and
- encapsulate data und functions. Like structs they are automatically
+ encapsulate data and functions. Like structs they are automatically
destructed, they can be copied and saved.
As with regular objects its variables are hidden from outside
@@ -62,6 +62,10 @@
any outside program can inspect its variables. To really hide
variable contents they must be nosave.
+ Prior to restoring or copying a lightweight object all variables
+ of the new lightweight object will be initialized regularly first
+ when pragma init_variables is in effect.
+
HISTORY
Lightweight objects were introduced in LDMud 3.6.5.
diff --git a/doc/LPC/mappings b/doc/LPC/mappings
index 381e3c8..2f64b88 100644
--- a/doc/LPC/mappings
+++ b/doc/LPC/mappings
@@ -139,6 +139,11 @@
If there is no <key> (and <n> is equal to 0 or not specified at all) a
new one will be added automatically.
+ Multiple values for a single key can be modified with range access:
+
+ map[key, n1..n2] = ({ valuen1, ..., valuen2 });
+ map[key, 0..<1] = ({ value0, ..., valuen });
+
Deletion of a key is done with the -= operator or the efun
m_delete(). A mapping can only be substracted by one without any values:
@@ -170,6 +175,12 @@
all (which is the same) a 0 will be returned or if <n> is greater than 0
an "Illegal index" error will be reported.
+ Multiple values for a single key can be accessed by:
+
+ arr = map[key, n1..n2];
+
+ The values are returned in an array.
+
6. How can I test for the existance of a key?
diff --git a/doc/LPC/modifiers b/doc/LPC/modifiers
index 7639741..163ed1c 100644
--- a/doc/LPC/modifiers
+++ b/doc/LPC/modifiers
@@ -107,15 +107,16 @@
Inheritance:
~~~~~~~~~~~~
- It is also possible to redeclare all variables and/or functions
- of an inherited object for the own object at the inheriting
+ It is also possible to redeclare all variables, functions and/or
+ structs of an inherited object for the own object at the inheriting
statement:
private functions nosave variables inherit "complex/room";
public variables inherit "complex/room";
private functions inherit "complex/room";
+ private structs inherit "complex/room";
- To redeclare a function or a variable declared public in the
+ To redeclare a function, variable or struct declared public in the
inherited object to be private or protected is not possible.
The following table shows the result of the combination of
@@ -157,22 +158,23 @@
To simplify the adoption of existing code, LPC allows to specify
- a default visibility for functions and variables, using a syntax
- similar to the inherit syntax:
+ a default visibility for functions, variables and structs, using
+ a syntax similar to the inherit syntax:
default private;
- All variables and functions are by default private.
+ All variables, functions and structs are by default private.
- default private variables public functions;
+ default private variables public functions public structs;
- All variables are by default private, but functions are public.
+ All variables are by default private, but functions and
+ structs are public.
Only the modifiers 'private', 'protected', 'visible' and 'public'
(and 'static' for functions only) are allowed here.
- The default visibility thus set affects only variables/functions with
- no explicit visibility:
+ The default visibility thus set affects only functions/variables/
+ structs with no explicit visibility:
default private;
@@ -203,5 +205,7 @@
LDMud 3.5 introduced 'visible' as a name for the default
visibility.
+ LDMud 3.6.6 introduced inheritance and default modifiers for structs.
+
SEE ALSO
closures(LPC), inheritance(LPC), functions(LPC), types(LPC)
diff --git a/doc/LPC/pragma b/doc/LPC/pragma
index d005ce3..a30ff63 100644
--- a/doc/LPC/pragma
+++ b/doc/LPC/pragma
@@ -23,6 +23,11 @@
share_variables: Clone variables are initialized from the
blueprint.
+ no_simul_efuns: Disable the use of simul-efuns. This pragma
+ raises a privilege_violation("no_simul_efuns").
+ simul_efuns: Enables the use of simul-efuns (this is the
+ default for all objects except the master).
+
weak_types: no type checking (this is the default).
strict_types: all functions must be declared with argument
prototypes, and the return values of call_other() must
@@ -107,16 +112,27 @@
(the default).
warn_unused_variables: Warn about variables that are not used.
- If will warn about variables never written to, variables
+ It will warn about variables never written to, variables
never read from or variables never used at all.
This applies to local variables and private global variables.
no_warn_unused_variables: Turn off warn_unused_variables
(the default).
+ warn_unused_values: Warn about values that are not used.
+ It will warn about values that are created without
+ side-effects (eg. a literal value or created by some
+ operation) and are not used afterwards.
+ no_warn_unused_values: Turn off warn_unused_values (the default).
+
warn_lightweight: Warn about efuns that are not suitable for
lightweight objects.
no_warn_lightweight: Turn off warn_lightweight.
+ save_local_names: When activated the name of local variables
+ are saved for debugging purposes. This increases the
+ size of the program.
+ no_save_local_names: Turn off save_local_names (the default).
+
When an object is compiled with type testing (#pragma
strict_types), all types are saved of the arguments for that
function during compilation. If the #pragma save_types is
diff --git a/doc/LPC/references b/doc/LPC/references
index c1d60f0..1f4f25b 100644
--- a/doc/LPC/references
+++ b/doc/LPC/references
@@ -33,7 +33,7 @@
assign(&(a[<0..<1]), ({1,2,3,"sink","x","y","x"}));
assign(&(a[5][0]), 'w');
assign(&(a[5][<1]), 'g');
- printf("%O", a));
+ printf("%O", a);
}
({ /* sizeof() == 9 */
diff --git a/doc/LPC/structs b/doc/LPC/structs
index a53029a..e45f464 100644
--- a/doc/LPC/structs
+++ b/doc/LPC/structs
@@ -50,8 +50,9 @@
with the difference that all structs live in the same flat namespace.
This means: a struct defined in a program is visible in _all_
inherited programs, regardless of how deep the inheritance is
- nested. This also means that in one program there must not be
- two structs, inherited or not, with the same name.
+ nested. This also means that in one program there must not be
+ two structs, inherited or not, with the same name. This does not
+ apply to structs declared as private.
To declare a struct without defining it, write:
@@ -78,13 +79,16 @@
LPC it constructs a new struct type whereever it is included).
- A variable to hold a struct is defined like this:
+ A variable to hold a specific or arbitrary struct is defined like
+ this:
struct Foo var;
+ struct mixed var;
and similar for function arguments:
void fun (struct Foo arg)
+ void fun (struct mixed arg)
Just writing 'struct Foo var' however does not _create_ a struct,
diff --git a/doc/LPC/types b/doc/LPC/types
index 15f98a6..ca17619 100644
--- a/doc/LPC/types
+++ b/doc/LPC/types
@@ -129,6 +129,8 @@
functions, efuns and to functions compiled at
run-time ("lambda closures").
+ o coroutine Holds the execution state of an asynchronous function.
+
o symbol Identifier names, which in essence are quoted strings.
They are used to compute lambda closures, e.g. instead
of ({..., 'ident, ... }) you can write declare a
@@ -146,6 +148,8 @@
o struct A collection of values. See structs(LPC).
+ o lpctype A type itself. See lpctypes(LPC).
+
o union A range of types, either of which the variable
can contain at runtime. See unions(LPC).
@@ -160,7 +164,12 @@
A pointer to a destructed object will always have the value 0.
+HISTORY
+ The types lwobject and coroutine were introduced in LDMud 3.6.5.
+
+
SEE ALSO
- alists(LPC), arrays(LPC), mappings(LPC), closures(LPC), structs(LPC),
- unions(LPC), typeof(E), get_type_info(E), inheritance(LPC),
- pragma(LPC), modifiers(LPC), escape(LPC)
+ alists(LPC), arrays(LPC), mappings(LPC), closures(LPC), coroutines(LPC),
+ objects(LPC), structs(LPC), unions(LPC), lpctypes(E), typeof(E),
+ get_type_info(E), inheritance(LPC), pragma(LPC), modifiers(LPC),
+ escape(LPC)
diff --git a/doc/LPC/yield b/doc/LPC/yield
new file mode 100644
index 0000000..43f35e2
--- /dev/null
+++ b/doc/LPC/yield
@@ -0,0 +1,29 @@
+NAME
+ yield
+
+SYNTAX
+ yield()
+ yield(<value>)
+ yield(<value>, <coroutine>)
+
+DESCRIPTION
+ The instruction is only allowed in a coroutine and suspends its
+ execution.
+
+ The first two forms return to the caller (i.e. the function that
+ continued the execution of the coroutine with call_coroutine()),
+ the third form resumes execution of the given coroutine, which
+ must currently be in a suspended state.
+
+ The value will be passed to the caller as the result of the
+ call_coroutine() call resp. to the target coroutine as the result
+ of its yield() instruction that suspended its execution before.
+ If the coroutine had just started, the value will be discarded.
+ In the first form, 0 will be passed to the caller.
+
+HISTORY
+ Coroutines were introduced in LDMud 3.6.5.
+
+SEE ALSO
+ coroutines(LPC), async(LPC), await(LPC), foreach(LPC),
+ call_coroutine(E), this_coroutine(E)