mung/langdoc.txt
cecilkorik a70737f90f implementing database and VM error handling
added crypt and pbkdf2 libraries for password hashing

--HG--
branch : mung
2015-10-27 14:50:59 -06:00

312 lines
15 KiB
Text
Executable file

DIFFERENCES FROM LAMBDAMOO
~~~~~~~~~~~~~~~~~~~~~~~~~~
The idea is that most things should be marginally similar, but there is no guarantee of backwards
compatibility. In fact, it is intended that some of MOO's most adorable anachronisms will be
updated to more modern techniques and terminology. This will by neccessity break compatibility in
many situations.
It is likely that the only way to port code or objects from LambdaMOO will involve an intermediate
translation step, which is beyond the scope of this project right now. The best I can offer is that
said translation step SHOULD BE possible, and hopefully allows nearly 100% of code to be portable,
at least in theory...
Key differences from LambdaMOO include:
* The list of built-in functions has changed; some renamed, some new, some removed.
* "Verbs" will be referred to as "functions", or "func" when an abbreviated form is required.
(yes, I know this is sad. I have fond memories of "programming verbs" too)
* "Permissions" in the sense of +r or "rxd" have been renamed to "flags", as their
meaning and usage has expanded significantly.
* The "+w" world-writable flag has been removed, because it is absolutely stupid and should
never be used anyway. In exchange, there is now a "+e" flag supporting extended permissions
which allows permissions to be extended to larger groups.
* Pre-emptive multitasking is now a plausible, albeit unimplemented, option.
* Various functionality that was provided through patches and extensions to the LambdaMOO
server will now have functional equivalents made available through built-ins.
* Files are now a built-in, first-class feature that works similarly to properties, however
they allow data to be stored on disk, rather than in memory.
* Binary data (raw bytes) will be a separate and distinct datatype from regular strings.
* Strings will be assumed to be UTF-8 at all times. To index or manage them as raw byte
strings, they will need to be converted to the bytes datatype.
* UTF-8 strings will be permitted for pretty much everything, including property and function
names, output to users, and it will be expected as user input as well.
* notify, tell, and announce will quite possibly be given more contemporary names.
* Memory usage will be monitored on a task, user, and property basis and reasonable limits
will be enforced, in the same way that object quotas are limited for users, and in the same
way that seconds/tick usage are limited for tasks. However avoiding the task memory limit
will not be as simple as calling suspend(0) :)
* The meaning of +r has been reversed. It now means "restricted". Globally readable is the
default state for all objects, properties, files and functions.
* Built-in properties like "wizard" are gone, replaced by various built-in functions.
* The characters " : and ; are no longer hardcoded to say, emote, and eval respectively.
OBJECT FLAGS
~~~~~~~~~~~~
f = fertile
Fertile objects can have children created by anyone. Normally, only the owner (or a wizard)
can use this object as a parent for another object. +f extends this ability to everyone.
If desired, more granular control can be achieved through the +e extended permissions.
e = extended permissions
Normally, an object has 1 owner, no more. The owner (and any wizards) are able to modify
the object and all its attributes. This is adequate in most cases, however, an extended
permissions system can be enabled through this flag that allows a more complicated but
robust way of assigning more granular permissions across multiple users. The owner (and any
wizards) will still maintain full access however.
This is not enabled by default because it's generally unnecessary and can be confusing.
r = restricted
This restricts the visibility of several of the object's attributes to be limited to the
owner and wizards. The meaning of restriction in this case is actually quite limited.
Other users are only prevented from viewing the lists of locally-defined properties,
functions, and files, or any of the attributes of those properties, functions, and files.
It ONLY applies to the lists, flags and attributes however. Notably, it does NOT prevent
access to the CONTENT. The value of a property, the contents of a file, or the source code
of a function are all fully accessible on a restricted object, provided the property, file
or function are themselves not restricted. Additionally, some flags and attributes can be
inferred by various methods of probing, especially if the object has children which are not
+r. Functions defined on this object can also still be called simply by guessing their
names, unless the function is flagged +y. One countermeasure provided to prevent users from
simply brute-force fishing for valid names is that any attempt to access an unknown name
on a +r object will result in E_PERM instead of E_PROPNF, E_FUNCNF, etc. This makes it
impossible for a fisher to know whether the name is actually valid and restricted by its
own +r flag, or whether the name is simply invalid.
PROPERTY FLAGS
~~~~~~~~~~~~~~
c = copy value to children
Normally a child object has a "cleared" property, which means the value is inherited from
the parent. If the value on the parent changes, so do all the "cleared" properties on the
children. However, with the +c flag, the value will be copied to the child object at the
time of creation. Further changes to the parent's value will have no effect on the child.
It is possible to "clear" a +c property, however all this will do is re-copy the parent's
value at that moment. Even once "cleared", further changes on the parent will still not
propagate to the child's properties. +c properties are essentially "copy-on-create"
instead of the default "copy-on-write".
Mutually exclusive with +s and completely irrelevant with +h
d = direct access / dynamic
This property is excluded from the the usual behavior of getter/setter functions.
Normally, if an appropriate getter/setter function is available, a call to that function
will be transparently substituted instead of a direct assignment. The +d flag overriddes
that behavior.
h = hidden / private
This property ONLY exists on the object itself, children will not contain this property.
The same property can be added to the children as if it doesn't exist, because it doesn't.
Setting this flag makes +c and +s meaningless, as no such child property exists.
s = shared / static
With this flag, the property inherited by children will all share the same value with the
parent. Setting the value on the parent will also cause the value to change on all the
children. Less obviously, setting the value on one of the children will also change the
value on all other children and on the parent as well. The same value is shared among all.
Note that in combination with the +o flag, this can allow the property to be freely
modified by users other than the owner, which may or may not be the expected behavior and
should be approached with caution. Also note that the +s and +o flags, in combination with
any object or child that has the +f flag is essentially allowing a world-writable property.
This should be approached with even more extreme caution, and is a great reason to avoid
ever setting +s in combination with +o in the first place.
o = transfer ownership
Normally, the property inherited by an object's children will still be owned by the same
user that owns the property on the parent. If the +o flag is set, the inherited property
will instead be owned by the same user that owns the child object.
e = extended permissions
Normally, a function has 1 owner, no more. The owner (and any wizards) are able to modify
the property and all its attributes. This is adequate in most cases, however, an extended
permissions system can be enabled through this flag that allows a more complicated but
robust way of assigning more granular permissions across multiple users. The owner (and any
wizards) will still maintain full access however.
This is not enabled by default because it's generally unnecessary and can be confusing.
FUNCTION FLAGS
~~~~~~~~~~
a = access restricted
Functions with this flag cannot be overridden on child objects, even by the owner of the
child object. This is checked and enforced on creation, as well as on chparent. Notable
exceptions are:
* The function can be overridden if the creator can also edit the code on the
a-flagged parent function
* Wizards are obviously exempt for the above reason
* Once created, the function can be chowned freely, even if the new owner does not have
the neccessary privileges to create such a function.
* Additionally, if the overriding function does not ALSO have an +a flag, then children
of THAT object can also freely override the function without restriction.
r = public readable
Functions with this flag have public source code that is visible to everyone
x = function-callable execution allowed
If this function is called from another function, the interpreter will ensure this flag
is set. If not, an E_FUNCNF exception will be raised.
c = command-line execution allowed
The command-line processor will include this function in its search as it attempts to match
the input with an appropriate command-line function.
e = extended permissions
Normally, a function has 1 owner, no more. The owner (and any wizards) are able to modify
the function and all its attributes. This is adequate in most cases, however, an extended
permissions system can be enabled through this flag that allows a more complicated but
robust way of assigning more granular permissions across multiple users. The owner (and any
wizards) will still maintain full access however.
This is not enabled by default because it's generally unnecessary and can be confusing.
m = legacy command-line argument matching (dobj/prepstr/iobj, etc)
This uses the LambdaMOO-style argument matching.
y = owner-only
This function can only be called by the owner (or a wizard) or by someone entitled to do so
through +e. Attempts to call the function by other players will fail with E_PERM.
p = pre-emptive multitasking
This is a placeholder for future plans to allow pre-emptive multitasking on an opt-in
basis. This will allow the virtual machine to decide (based on resource availability) when
the function can be paused, instead of relying on a specific tick limit and expecting the
process to cooperatively decide to suspend itself before that limit is reached.
s = set permissions (WIZARD ONLY)
Normally, a function executes with the permissions of the person who wrote the code. This
flag specifies that the code should instead execute with the permissions of the player
who initiated the command. This is an alternative to using set_task_perms boilerplate.
u = unlimited execution time (WIZARD ONLY)
This flag allows a function (and all functions it calls) to run continuously, without any
risk of the function being pre-empted by other processes or any need to suspend, no matter
how long it takes to run. This flag should be enabled with EXTREME caution, as a badly-
behaved process running +u can completely monopolize the server, preventing all input or
new connections from being processed.
The main purpose of this flag is to allow "absolutely critical" functions to run without
interruption. Such functions should be few and far between, and very specific and limited
in what they actually do. It is imperative that the +u function takes abundant care with
the inputs it accepts and the functions it calls, as abuse can be very easy. For example by
repeatedly calling the function in a loop and passing an enormous list as an argument.
f = fail silently
Exceptions are suppressed and supplied as the return value (if callable.)
Command-line functions will simply exit silently if an exception is encountered.
FILE FLAGS
~~~~~~~~~~
Files are a first-class data storage feature that can be used similarly to properties in many
respects. However they do not use inheritance, and they may be very slightly slower. Their main
advantage is mostly that they are not stored in memory, making them suitable for storing very
large data. They also support additional features for partial, incremental loading and random
access that properties do not.
At their simplest and most straightforward, files can be accessed with an exclamation mark "!"
using the syntax #789!filename
More specific methods of accessing file data are documented in the built-in functions.
b = binary mode
A file in binary mode may only contain the bytes datatype, and will always provide a bytes
datatype when read. The actual file stored on disk will match the exact bytes written to
or read from the file, which can be useful when the file either comes from or is intended
to be used by another program.
A file must be flagged for binary mode in order to enable several types of file operations,
such as random access.
Note that setting a file +b will delete all existing content, UNLESS the content is already
of type "bytes". If the existing content was already bytes, then it is populated into the
file as-is. All other datatypes (even strings or lists containing only bytes) will be
deleted and the new +b file will be empty. When setting a file +b, the data it contains
should be converted to bytes explicitly first if you wish to keep it.
Conversely, -b will cause the contents of the file on disk to change, as the bytes data is
converted into the internal storage format, but doing so will always preserve the content.
And because the stored data retains the "bytes" datatype, it can be converted directly back
to +b without data loss. Although you should avoid frequent switching of this flag, as the
entire file needs to be completely re-written to disk whenever the flag is changed.
r = readable
Files flagged +r will be readable by any user, otherwise they will be private and readable
only by the owner.
d = direct access / dynamic
Similar to properties, this flag exempts the file from being transparently intercepted by
getter/setter functions. However, it's important to note that getter/setters on files can
already be easily bypassed simply by using the raw file access functions provided as
built-ins. This flag only applies when files are accessed by the "!" syntax.
l = large file
Files flagged with this are considered to be too large to access all at once using the "!"
syntax or by any functions that read the whole file into memory at once. Attempts to do so
will cause the error E_IDUNNO to be raised.
TASK ATTRIBUTES
~~~~~~~~~~~~~~~
A task has a number of important attributes, mostly read-only, which can be accessed through
built-in functions. These persist throughout the entire task,
CHICKENSCRATCH
~~~~~~~~~~~~~~
simple program:
while (1)
arg = "message";
send(#7407, arg);
suspend(1.0);
endwhile
bytecode:
startblock 1
stack_literal_int 1 1
exit_true 1 0
stack_literal_str "message" 1
set_var arg 1
discard_stack 1 0
get_var arg 1
stack_literal_obj #7407 2
call_builtin send 1
discard_stack 1 0
stack_literal_float 1.0 1
call_builtin suspend 1
discard_stack 1 0
endblock 1
other stuff:
var = 1 == 0 + 1
list = [1, 2, @[3, 4], 5]
literal 1
literal 2
literal 3
literal 4
literal 2
makelist
flatten
literal 5
literal 4 <-- the length
makelist 4