While expression symbols worked for what they are, they weren't so good
for ivar access because every ivar of a class (and its super classes)
would be accessed at method scope creation, generating spurious access
errors if any were private. That is, when the access checks worked at
all.
The end goal was to fix erroneous non-constant initializer errors for
the following (ie, nested initializer blocks):
typedef struct { int x; int y; } Point;
typedef struct { int width; int height; } Extent;
typedef struct Rect_s { Point offset; Extent extent; } Rect;
Rect makeRect (int xpos, int ypos, int xlen, int ylen)
{
Rect rect = {{xpos, ypos}, {xlen, ylen}};
return rect;
}
However, it turned out that nested initializer blocks for local
variables did not work at all in that the relocations were lost because
fake defs were being created for the generated instructions.
Thus, instead of creating fake defs, simply record the offset relative
to the base def, the type, and the basic type initializer expression,
then generate instructions that all refer to the correct def but with a
relative offset.
Other than using the new element system, static initializers are largely
unaffected.
Doesn't have timestamps at this stage, but otherwise it reflects the
event system I had in my old text UI which was heavily based on
TurboVision. TV is pretty good (after looking at things a bit closer I
found it wasn't as deep as I thought), and better yet, Borland released
it to the public domain 23 years ago! (wish I'd known that).
Anyway, this commit gets something happening on the screen, even though
the current hierarchy is still a mess.
As well as $prefix/include, of course. This fixes the problem with
external ruamoko builds failing due to keys.h and qfcc's "lockdown" on
system headers.
This is horrible, doesn't work, isn't really the direction I want to go
(that became apparent while implementing Screen's handleEvent) and
crashes anyway (Array and not-id...)
*sigh*
Still, this does have some good stuff in it, and it pushed qfcc along
some more.
This is for adding methods to classes and protocols via their interface,
not for adding methods by adding protocols (they still get copied).
Slightly more memory efficient.
Copying methods is done when adding protocols to classes (the current
use for adding regular methods is an incorrect solution to a different
problem). However, when a method is added to a class, the type of its
self parameter is set to be a pointer to the class. Thus, not only does
the method need to be copied, the self parameter does too, otherwise
the self parameter of methods added via protocols will have their type
set to be a pointer to the last class seen adding the protocol.
That is, if, while compiling the implementation for class A, but the
interface for class B is comes after the interface for class A, and both
A and B add protocol P, then all methods in protocol P will have self
pointing to B rather than A.
@protocol P
-method;
@end
@interface A <P>
@end
@interface B <P>
@end
@implementation A
-method {} // self is B, not A!
@end