A lot of changes have been made in LPC4 compared to earlear versions
I will try to describe what I have done, and why here.
Floats
Obviously floats can be very nice, so I added them as a new type.
Lists
A list is really a somewhat ill-named type. It is _not_ a type for
linked list. It is instead a type of array in which the order of the
members is not important. Like a mapping without data. It has been
made so that lookups, and logical operations such as anding and oring
is quite fast.
Functionpointers
Functionpointers is now used for _all_ LPC function calls (not for
efuns though) The name of a defined function is a 'constant
functionpointer and parentheses are used to call it. Other ways of
writing functionpointers include: file::fun, ::fun, obj->fun and
lambdafunctions. A funcitonpointer consists of an objectpointer
and an index that tells which function is pointed to in that object.
Lambdafunctions
Is essentially a nice way of defining functions inside another
function for instance:
foo()
{
return lambda() { return 2; }
}
Will return a functionpointer to a function that will return 2 when
called.
No 'master' objects, only clones
I never liked the need for a 'master' for the clones so I removed
the cloning of a masterobject and made the functions load() and
update() to handle programs. I also invented a way to 'label' clones
so that it would still be possible to address objects not yet loaded.
Object labels:
When a string is casted to an objectpointer, this will happen:
If a # is present in the string, the part before it will be called
file and the part after a label. If there is no # in the string or
the label is an empty string, then only the file will be considered.
It the program residing in the file file isn't already loaded, it
will be loaded and a clone will be made. This clone will be labeled
with the original string (without the # if the label was empty) and
the label will be sent to create() as an argument. The object may then
selfdestruct if it didn't like it's label, otherwise that object will
be returned and hashed with that label. Next time that string is
casted to an object, this clone will simply be digged out of the
hashtable.
There is a similar function in clone_object(), with the only
difference that it doesn't actually label the object, it just sends
the label to create()
A lot of new efuns have been added (of course)
read about them in doc/efun
The compiler has been rewritten
It now uses parse-trees and optimizes the code somewhat.
Casting
Casting has been changed, casting to most types now actually _does_
something. A list of actions during casting follows:
string to int: atoi()
string to fload: atod()
string to object: loads an object as described above
string to function: is equal to this_object()->string
No casting
Previously some implicit casting were done from strings to objects
at runtime, now the compiler tries to detect where such casting is
needed and insers castings there. However, if the types doesn't match
exactly (ie. if one of them is 'mixed') no casting implicit casting
will be done automatically.
Communication
The old communication code that used interactive objects has been
replaced by general socket efuns. THe removal of the interactive
structure also led to the removal of this_interactive(), find_player()
ed(), query_idle(), snoop(), trace(), traceprefix() and some other gunk
in the driver.
Shadows
has been removed, they only complicated things.
Binary strings
Some functions can now handle binary strings, that is strings that
contains zeros.
Communication
The old communication code has been ripped out and replaced by general
socket-handling functions.