It is syntactic sugar for if (!(foo)), but is useful for avoiding
inconsistencies between such things as if (string) and if (!string), even
though qcc can't parse if not (string). It also makes for easier to read
code when the logic in the condition is complex.
The keywords table was rather awkward to edit (and sometimes confusing).
Worse, because the hash table used to look up the keywords was initialized
only once, changing modes in the same execution of qfcc would not work
properly as keywords would not be added or removed as appropriate.
Now there are four categories of keywords:
o "core" Always available. They form the core of QuakeC except for two
extensions.
o "@" In extended and advanced modes, the preceeding @ is optional,
but tranditional mode requires the keywords to be preceeded by
an @. They are the C keywords that QuakeC did not use, but can
be implemented in v6 progs under certain circumstances.
o "QF" These keywords require the QuakeForge VM to be usable.
o "Obj" These keywords form Ruamoko/Objective-QuakeC and require both
advanced mode and the QuakeForge VM.
This is needed to allow compile-time protocol conformance checks, though
nothing along those lines has been implemented yet.
id has been changed from TYPE to OBJECT, required to allow id <proto> to be
parsed. OBJECT uses symbol, allowing id to be redefined once suitable work
has been done on the parser.
qfcc now does local common subexpression elimination. It seems to work, but
is optional (default off): use -O to enable. Also, uninitialized variable
detection is finally back :)
The progs engine now has very basic valgrind-like functionality for
checking pointer accesses. Enable with pr_boundscheck 2
The evil comment is not just "pragmas are bad, ok?", but switching between
advanced, extended and tradtitional modes when compiling truly is evil and
not guaranteed to work. However, I needed it to make building test cases
easier (it's mostly ok to go from advanced to extended or tradtional, but
going the other way will probably cause all sorts of fun).
In the process, opcode_init now copies the opcode table data rather than
modifying it.
After running across a question about lists of animation frames and states,
I decided giving qfcc the ability to generate such lists might be a nice
distraction from the optimizer :) Works for both progs.src and separate
compilation. No frame file is generated if no macros have been created.
All internal structs now have "proper" names, and fit the naming convention
(eg, obj_module (like objective-c's types, but obj instead of objc). Some
redundant types got removed (holdovers from before proper struct tag
handling).
Also, it has proven to be unnecessary to build internal classes, so
make_class and make_class_struct are gone, too.
Since gnu bison and flex are required anyway, no harm in using their api
prefix options. Now, qfcc can compile both QC/Ruamoko and Pascal files
(Pascal is (currently?) NOT supported in progs.src mode), selecting the
language based on the extension: .r, .qc and .c select QC/Ruamoko, .pas and
.p select Pascal, while anything else is treated as an object file (as
before).
That which isn't rewritten is horribly broken. However, this does include a
nice mechanism for building QC structs for emitting data.
emit.c has been gutted in the spirit of "throw one away".
There is much work to be done to get even variables emitted, let alone
code. Things should be a little more fun from here on.
Use "@reference ClassName;" or "@reference ClassName(CategoryName);" to
create a refence to the class or category, forcing the defining object file
to be linked into the program when the object file is part of a library.