- create struct types.

- fixed class creation. There was an infinite loop and some missing checks for native classes.
- do not write the compiler's symbols to the same symbol table as the output. The output must go to GlobalSymbols but the internal symbols must go to a namespace specific table that can be discarded after compilation.
This commit is contained in:
Christoph Oelckers 2016-10-08 13:34:37 +02:00
parent b71e8d09ed
commit 82ac2081b6
6 changed files with 41 additions and 24 deletions

View file

@ -3197,7 +3197,7 @@ void PClass::BuildFlatPointers ()
// //
// PClass :: NativeClass // PClass :: NativeClass
// //
// Finds the underlying native type underlying this class. // Finds the native type underlying this class.
// //
//========================================================================== //==========================================================================

View file

@ -248,6 +248,7 @@ struct_def(X) ::= STRUCT(T) IDENTIFIER(A) LBRACE opt_struct_body(B) RBRACE opt_s
NEW_AST_NODE(Struct,def,T); NEW_AST_NODE(Struct,def,T);
def->NodeName = A.Name(); def->NodeName = A.Name();
def->Body = B; def->Body = B;
def->Type = nullptr;
X = def; X = def;
} }

View file

@ -51,8 +51,8 @@
// //
//========================================================================== //==========================================================================
ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols) ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols, PSymbolTable &_outsymbols)
: Outer(_outer), Symbols(&_symbols), AST(ast), ErrorCount(0), WarnCount(0) : Outer(_outer), Symbols(&_symbols), OutputSymbols(&_outsymbols), AST(ast), ErrorCount(0), WarnCount(0)
{ {
// Group top-level nodes by type // Group top-level nodes by type
if (ast.TopNode != NULL) if (ast.TopNode != NULL)
@ -181,11 +181,28 @@ void ZCCCompiler::MessageV(ZCC_TreeNode *node, const char *txtcolor, const char
int ZCCCompiler::Compile() int ZCCCompiler::Compile()
{ {
CreateClasses(); CreateClassTypes();
CreateStructTypes();
CompileConstants(Constants); CompileConstants(Constants);
return ErrorCount; return ErrorCount;
} }
//==========================================================================
//
// ZCCCompiler :: CreateStructTypes
//
// Creates a PStruct for every struct.
//
//==========================================================================
void ZCCCompiler::CreateStructTypes()
{
for(auto s : Structs)
{
s->Type = NewStruct(s->NodeName, nullptr);
}
}
//========================================================================== //==========================================================================
// //
// ZCCCompiler :: CreateClassTypes // ZCCCompiler :: CreateClassTypes
@ -197,16 +214,16 @@ int ZCCCompiler::Compile()
// //
//========================================================================== //==========================================================================
void ZCCCompiler::CreateClasses() void ZCCCompiler::CreateClassTypes()
{ {
auto OrigClasses = std::move(Classes); auto OrigClasses = std::move(Classes);
Classes.Clear(); Classes.Clear();
bool donesomething = true; bool donesomething = true;
while (donesomething) while (donesomething)
{
for (unsigned i=0;i<OrigClasses.Size();i++)
{ {
donesomething = false; donesomething = false;
for (unsigned i = 0; i<OrigClasses.Size(); i++)
{
auto c = OrigClasses[i]; auto c = OrigClasses[i];
// Check if we got the parent already defined. // Check if we got the parent already defined.
PClass *parent; PClass *parent;
@ -235,13 +252,17 @@ void ZCCCompiler::CreateClasses()
// The parent exists, we may create a type for this class // The parent exists, we may create a type for this class
if (c->Flags & ZCC_Native) if (c->Flags & ZCC_Native)
{ {
// If this is a native class, its own type must also already exist. // If this is a native class, its own type must also already exist and not be a runtime class.
auto me = PClass::FindClass(c->NodeName); auto me = PClass::FindClass(c->NodeName);
if (me == nullptr) if (me == nullptr)
{ {
Error(c, "Unknown native class %s", FName(c->NodeName).GetChars()); Error(c, "Unknown native class %s", FName(c->NodeName).GetChars());
me = parent->FindClassTentative(c->NodeName); me = parent->FindClassTentative(c->NodeName);
} }
else if (me->bRuntimeClass)
{
Error(c, "%s is not a native class", FName(c->NodeName).GetChars());
}
else else
{ {
DPrintf(DMSG_SPAMMY, "Registered %s as native with parent %s\n", me->TypeName.GetChars(), parent->TypeName.GetChars()); DPrintf(DMSG_SPAMMY, "Registered %s as native with parent %s\n", me->TypeName.GetChars(), parent->TypeName.GetChars());
@ -250,17 +271,8 @@ void ZCCCompiler::CreateClasses()
} }
else else
{ {
auto me = PClass::FindClass(c->NodeName); // We will never get here if the name is a duplicate, so we can just do the assignment.
if (me != nullptr) c->Type = parent->FindClassTentative(c->NodeName);
{
Error(c, "Redefining class %s", FName(c->NodeName).GetChars());
}
else
{
me = parent->FindClassTentative(c->NodeName);
DPrintf(DMSG_SPAMMY, "Created %s with parent %s\n", me->TypeName.GetChars(), parent->TypeName.GetChars());
}
c->Type = me;
} }
Classes.Push(c); Classes.Push(c);
OrigClasses.Delete(i); OrigClasses.Delete(i);
@ -371,7 +383,7 @@ PSymbolConst *ZCCCompiler::CompileConstant(ZCC_ConstantDef *def)
sym = new PSymbolConstNumeric(def->NodeName, TypeError, 0); sym = new PSymbolConstNumeric(def->NodeName, TypeError, 0);
} }
def->Symbol = sym; def->Symbol = sym;
Symbols->ReplaceSymbol(sym); OutputSymbols->ReplaceSymbol(sym);
return sym; return sym;
} }

View file

@ -4,11 +4,12 @@
class ZCCCompiler class ZCCCompiler
{ {
public: public:
ZCCCompiler(ZCC_AST &tree, DObject *outer, PSymbolTable &symbols); ZCCCompiler(ZCC_AST &tree, DObject *outer, PSymbolTable &symbols, PSymbolTable &outsymbols);
int Compile(); int Compile();
private: private:
void CreateClasses(); void CreateStructTypes();
void CreateClassTypes();
void CompileConstants(const TArray<ZCC_ConstantDef *> &defs); void CompileConstants(const TArray<ZCC_ConstantDef *> &defs);
PSymbolConst *CompileConstant(ZCC_ConstantDef *def); PSymbolConst *CompileConstant(ZCC_ConstantDef *def);
@ -47,6 +48,7 @@ private:
DObject *Outer; DObject *Outer;
PSymbolTable *Symbols; PSymbolTable *Symbols;
PSymbolTable *OutputSymbols;
ZCC_AST &AST; ZCC_AST &AST;
int ErrorCount; int ErrorCount;
int WarnCount; int WarnCount;

View file

@ -338,7 +338,8 @@ static void DoParse(int lumpnum)
#endif #endif
} }
ZCCCompiler cc(state, NULL, GlobalSymbols); PSymbolTable symtable(&GlobalSymbols);
ZCCCompiler cc(state, NULL, symtable, GlobalSymbols);
cc.Compile(); cc.Compile();
// ... and another one afterward so we can see what the compiler does with the data. // ... and another one afterward so we can see what the compiler does with the data.
#ifdef _DEBUG #ifdef _DEBUG

View file

@ -192,6 +192,7 @@ struct ZCC_Class : ZCC_NamedNode
struct ZCC_Struct : ZCC_NamedNode struct ZCC_Struct : ZCC_NamedNode
{ {
ZCC_TreeNode *Body; ZCC_TreeNode *Body;
PStruct *Type;
}; };
struct ZCC_Enum : ZCC_NamedNode struct ZCC_Enum : ZCC_NamedNode