Factor the common if (TokenType != t) UnexpectedToken() into a function.
Write the end-of-list-or-comma as one if and one Match instead of a long
switch-case-statement.
As discussed in http://forum.openclonk.org/topic_show.pl?tid=2917, I
have merged all copyright notices into a single file and referenced that
merged file from each source file.
For the updated source files, the timeline has been split into three
parts:
1. Pre-RWD code (before 2001)
2. RWD code (2001 through 2009)
3. OpenClonk code (2009 and later)
All pre-RWD copyright notices have been left intact, as have RWD-era
copyright notices where the file did not have a RedWolf design copyright
notice but only individual author ones. All copyright notices of the
OpenClonk era have been replaced by a single notice ranging from the
first recorded year to the current year (2013). Mape code did not get a
OpenClonk Team copyright notice because it is somewhat separate from the
main OpenClonk codebase and has only been touched by Armin Burgmeier.
When reloading a function, C4AulParse didn't reset the parameter count.
This resulted in the function's ParCount to eventually increase above
C4AUL_MAX_Par, at which point parameter type checking would access
invalid memory.
The parser does not know whether the constant proplist it is about to fill
is missing because it was overwritten by a later local/constant, or because
the preparser was interrupted by a script error and didn't store its
proplist. Thus, the parser cannot simply give up at that point, and in
order to keep things simple it creates a throwaway proplist. This proplist
was thrown away too soon, though.
Thanks to Zapper for the testcase.
C4AulParse::Host is now only used for local variables and named functions.
Global directexec functions have neither, so they won't need a scripthost
at all anymore.
The missing break meant that the freshly created copy of the proplist would
get overwritten by the original, which was thankfully caught and announced
with "internal error: constant proplist has the wrong parent".
Thanks to Zapper for the testcase.
This makes functions independent of their "Code Owner"s, which removes the
necessity to maintain that connection and carefully reset functions when
their scripthost is cleared.
"Anon" referred to the fact that these proplists have neither a number,
like simple proplists, objects and effects, nor an ID like Definitions.
However, they now store the names of the global constant or property they
are in, so "Anon" is no longer appropriate.
There are now three classes of proplists:
- ordinary proplists (C4PropListScript) have a number only in the savegame
- objects and effects (C4PropListNumbered) always have a number
- proplists created during initialization (C4PropListStatic) have a path
So the function could be called NewNamed, but the source of the proplist
has been far more stable than the method used for serialization, and Static
somewhat describes the source.
C4Aul's Warn uses the format attribute to check for format string correctness.
Passing a dynamic string buffer from FormatString to it will break the build
with -Werror=format-string. Given that Warn already does the formatting itself,
just drop the use of FormatString
Previously, only the outer proplist would be copied, but the parser expects
the inner proplists to also be present. Copy proplists deeply instead, as
is already done for functions, and in the linking step.
Because the interpreter throws for every function that is called with a
this parameter that has been removed, this() isn't a function anymore.
The function could stay around so that Call("this") or foo->this()
would still work, but I doubt any script ever did that.
These operators have a stricter definition of equality than the == and !=
operators. Those are already stricter than in some other languages, so the
new ones are probably not needed very often. But if the need does arise,
there's no workaround short of modifying the data structures and checking
whether they are still the same.
The map is currently only used in the parser for some warning heuristics.
Since it uses a hash table with separate chaining and the amount of
functions is fairly predictable, the hash table doesn't have to be
resizable.
The parser now copies the contents of the proplists in the order of their
source scripts into the final proplist. This way, local variable contents
get properly included, and the list of functions has one user less.
Constant expressions for global constants and for Definition properties are
now treated the same way. The preparser creates the structure that
the parser will fill in. Since the structure will not move, the parser can
refer to it before it is filled in, just like functions can call siblings
defined further down in the script. This will also allow proplists (and later
functions) to refer to each other.
For example, the proplist in Clonk.ActMap.Walk is saved as DClonk.ActMap.Walk.
Should the script defining the proplist change while the savegame is stored,
the proplist will have the new contents instead of the old ones after savegame
load.
Also, save functions as DFlint.Hit instead of fDFlint.Hit. Loading uses the same
code as static proplist loading.
Curiously, this makes g++ 4.4 use the C4RefCntPointer move constructor,
which was broken until now. Fix it to take a mutable rvalue reference.
This short-circuiting operator will evaluate to its first operand if the operand
is not nil, or to its second operand otherwise. Its intended use is to simplify
defaulting expressions that may evaluate to nil to a valid value.
So the only thing #appendtos may contain are lokal functions and variables,
which are only reachable via the Definition the script is appended to, and
global constants and variables, which only need to be parsed once. Thus,
#appendto scripts can skip being parsed without a definition, and the
errors that sometimes produces are gone.
For functions that are not appended/included, this is done by reusing them.
Functions that are not in the new script version are left with their code
raising and error. Appended/included functions are handled by a reference count.
The parser doesn't need it to find the functions it has to parse anymore.
And the global proplist can be cleared before removing the functions,
instead of having engine functions deregister themselves and script
functions being deregistered when their linked function is removed.
Instead of carefully inserting functions at the start or end of the list,
build the list just before the parser runs, at the same time as filling
the proplist where the functions are looked up.
This way, the overloaded function is simply the one that was previously in
the proplist, is not needed outside of the overloading function, and can thus
be replaced in the proplist.