Store known but uncompiled nodes in the symbol table

- Don't bother keeping track of uncompiled nodes in a special table. Use
  the regular symbol table instead. This should in the future make
  compiling nodes referenced deeper than (and before) their definitions
  fairly straightforward.
- Also, break up the compiler's Message() function into Warn() and Error()
  and get rid of zcc_errors.h. I can't really see having a set of error
  numbers being useful.
This commit is contained in:
Randy Heit 2016-03-12 21:22:29 -06:00
parent 9b134a78e3
commit aaae9f2e05
8 changed files with 212 additions and 131 deletions

View file

@ -2711,6 +2711,7 @@ END_POINTERS
IMPLEMENT_POINTY_CLASS(PSymbolVMFunction) IMPLEMENT_POINTY_CLASS(PSymbolVMFunction)
DECLARE_POINTER(Function) DECLARE_POINTER(Function)
END_POINTERS END_POINTERS
IMPLEMENT_CLASS(PSymbolTreeNode)
//========================================================================== //==========================================================================
// //
@ -2773,6 +2774,22 @@ PSymbol *PSymbolTable::FindSymbol (FName symname, bool searchparents) const
return value != NULL ? *value : NULL; return value != NULL ? *value : NULL;
} }
PSymbol *PSymbolTable::FindSymbolInTable(FName symname, PSymbolTable *&symtable)
{
PSymbol * const *value = Symbols.CheckKey(symname);
if (value == NULL)
{
if (ParentSymbolTable != NULL)
{
return ParentSymbolTable->FindSymbolInTable(symname, symtable);
}
symtable = NULL;
return NULL;
}
symtable = this;
return *value;
}
PSymbol *PSymbolTable::AddSymbol (PSymbol *sym) PSymbol *PSymbolTable::AddSymbol (PSymbol *sym)
{ {
// Symbols that already exist are not inserted. // Symbols that already exist are not inserted.
@ -2783,3 +2800,19 @@ PSymbol *PSymbolTable::AddSymbol (PSymbol *sym)
Symbols.Insert(sym->SymbolName, sym); Symbols.Insert(sym->SymbolName, sym);
return sym; return sym;
} }
PSymbol *PSymbolTable::ReplaceSymbol(PSymbol *newsym)
{
// If a symbol with a matching name exists, take its place and return it.
PSymbol **symslot = Symbols.CheckKey(newsym->SymbolName);
if (symslot != NULL)
{
PSymbol *oldsym = *symslot;
*symslot = newsym;
return oldsym;
}
// Else, just insert normally and return NULL since there was no
// symbol to replace.
Symbols.Insert(newsym->SymbolName, newsym);
return NULL;
}

View file

@ -67,6 +67,18 @@ public:
PSymbolType() : PSymbol(NAME_None) {} PSymbolType() : PSymbol(NAME_None) {}
}; };
// A symbol for a compiler tree node ----------------------------------------
class PSymbolTreeNode : public PSymbol
{
DECLARE_CLASS(PSymbolTreeNode, PSymbol);
public:
struct ZCC_NamedNode *Node;
PSymbolTreeNode(FName name, struct ZCC_NamedNode *node) : PSymbol(name), Node(node) {}
PSymbolTreeNode() : PSymbol(NAME_None) {}
};
// A symbol table ----------------------------------------------------------- // A symbol table -----------------------------------------------------------
struct PSymbolTable struct PSymbolTable
@ -85,11 +97,19 @@ struct PSymbolTable
// as well. // as well.
PSymbol *FindSymbol (FName symname, bool searchparents) const; PSymbol *FindSymbol (FName symname, bool searchparents) const;
// Like FindSymbol with searchparents set true, but also returns the
// specific symbol table the symbol was found in.
PSymbol *FindSymbolInTable(FName symname, PSymbolTable *&symtable);
// Places the symbol in the table and returns a pointer to it or NULL if // Places the symbol in the table and returns a pointer to it or NULL if
// a symbol with the same name is already in the table. This symbol is // a symbol with the same name is already in the table. This symbol is
// not copied and will be freed when the symbol table is destroyed. // not copied and will be freed when the symbol table is destroyed.
PSymbol *AddSymbol (PSymbol *sym); PSymbol *AddSymbol (PSymbol *sym);
// Similar to AddSymbol but always succeeds. Returns the symbol that used
// to be in the table with this name, if any.
PSymbol *ReplaceSymbol(PSymbol *sym);
// Frees all symbols from this table. // Frees all symbols from this table.
void ReleaseSymbols(); void ReleaseSymbols();

View file

@ -281,7 +281,7 @@ static void PrintClass(FLispString &out, ZCC_TreeNode *node)
ZCC_Class *cnode = (ZCC_Class *)node; ZCC_Class *cnode = (ZCC_Class *)node;
out.Break(); out.Break();
out.Open("class"); out.Open("class");
out.AddName(cnode->ClassName); out.AddName(cnode->NodeName);
PrintNodes(out, cnode->ParentName); PrintNodes(out, cnode->ParentName);
PrintNodes(out, cnode->Replaces); PrintNodes(out, cnode->Replaces);
out.AddHex(cnode->Flags); out.AddHex(cnode->Flags);
@ -294,7 +294,7 @@ static void PrintStruct(FLispString &out, ZCC_TreeNode *node)
ZCC_Struct *snode = (ZCC_Struct *)node; ZCC_Struct *snode = (ZCC_Struct *)node;
out.Break(); out.Break();
out.Open("struct"); out.Open("struct");
out.AddName(snode->StructName); out.AddName(snode->NodeName);
PrintNodes(out, snode->Body, false, true); PrintNodes(out, snode->Body, false, true);
out.Close(); out.Close();
} }
@ -304,7 +304,7 @@ static void PrintEnum(FLispString &out, ZCC_TreeNode *node)
ZCC_Enum *enode = (ZCC_Enum *)node; ZCC_Enum *enode = (ZCC_Enum *)node;
out.Break(); out.Break();
out.Open("enum"); out.Open("enum");
out.AddName(enode->EnumName); out.AddName(enode->NodeName);
PrintBuiltInType(out, enode->EnumType); PrintBuiltInType(out, enode->EnumType);
out.Add(enode->Elements == NULL ? "nil" : "...", 3); out.Add(enode->Elements == NULL ? "nil" : "...", 3);
out.Close(); out.Close();
@ -733,7 +733,7 @@ static void PrintConstantDef(FLispString &out, ZCC_TreeNode *node)
ZCC_ConstantDef *dnode = (ZCC_ConstantDef *)node; ZCC_ConstantDef *dnode = (ZCC_ConstantDef *)node;
out.Break(); out.Break();
out.Open("constant-def"); out.Open("constant-def");
out.AddName(dnode->Name); out.AddName(dnode->NodeName);
PrintNodes(out, dnode->Value, false); PrintNodes(out, dnode->Value, false);
out.Close(); out.Close();
} }

View file

@ -174,7 +174,7 @@ class_definition(X) ::= class_head(A) class_body(B).
class_head(X) ::= CLASS(T) IDENTIFIER(A) class_ancestry(B) class_flags(C). class_head(X) ::= CLASS(T) IDENTIFIER(A) class_ancestry(B) class_flags(C).
{ {
NEW_AST_NODE(Class,head,T); NEW_AST_NODE(Class,head,T);
head->ClassName = A.Name(); head->NodeName = A.Name();
head->ParentName = B; head->ParentName = B;
head->Flags = C.Flags; head->Flags = C.Flags;
head->Replaces = C.Replaces; head->Replaces = C.Replaces;
@ -248,7 +248,7 @@ class_member(X) ::= const_def(A). { X = A; }
struct_def(X) ::= STRUCT(T) IDENTIFIER(A) LBRACE opt_struct_body(B) RBRACE opt_semicolon. struct_def(X) ::= STRUCT(T) IDENTIFIER(A) LBRACE opt_struct_body(B) RBRACE opt_semicolon.
{ {
NEW_AST_NODE(Struct,def,T); NEW_AST_NODE(Struct,def,T);
def->StructName = A.Name(); def->NodeName = A.Name();
def->Body = B; def->Body = B;
X = def; X = def;
} }
@ -269,7 +269,7 @@ struct_member(X) ::= const_def(A). { X = A; }
const_def(X) ::= CONST(T) IDENTIFIER(A) EQ expr(B) SEMICOLON. const_def(X) ::= CONST(T) IDENTIFIER(A) EQ expr(B) SEMICOLON.
{ {
NEW_AST_NODE(ConstantDef,def,T); NEW_AST_NODE(ConstantDef,def,T);
def->Name = A.Name(); def->NodeName = A.Name();
def->Value = B; def->Value = B;
def->Symbol = NULL; def->Symbol = NULL;
X = def; X = def;
@ -286,7 +286,7 @@ const_def(X) ::= CONST(T) IDENTIFIER(A) EQ expr(B) SEMICOLON.
enum_def(X) ::= ENUM(T) IDENTIFIER(A) enum_type(B) LBRACE opt_enum_list(C) RBRACE(U) opt_semicolon. enum_def(X) ::= ENUM(T) IDENTIFIER(A) enum_type(B) LBRACE opt_enum_list(C) RBRACE(U) opt_semicolon.
{ {
NEW_AST_NODE(Enum,def,T); NEW_AST_NODE(Enum,def,T);
def->EnumName = A.Name(); def->NodeName = A.Name();
def->EnumType = (EZCCBuiltinType)B.Int; def->EnumType = (EZCCBuiltinType)B.Int;
def->Elements = C; def->Elements = C;
@ -324,7 +324,7 @@ enum_def(X) ::= ENUM(T) IDENTIFIER(A) enum_type(B) LBRACE opt_enum_list(C) RBRAC
NEW_INTCONST_NODE(one, TypeSInt32, 1, T); NEW_INTCONST_NODE(one, TypeSInt32, 1, T);
NEW_AST_NODE(ExprID, label, node); NEW_AST_NODE(ExprID, label, node);
label->Operation = PEX_ID; label->Operation = PEX_ID;
label->Identifier = prev->Name; label->Identifier = prev->NodeName;
label->Type = NULL; label->Type = NULL;
BINARY_EXPR(label, one, PEX_Add); BINARY_EXPR(label, one, PEX_Add);
@ -355,7 +355,7 @@ opt_enum_list(X) ::= enum_list(A) opt_comma. { X = A; }
enumerator(X) ::= IDENTIFIER(A). enumerator(X) ::= IDENTIFIER(A).
{ {
NEW_AST_NODE(ConstantDef,node,A); NEW_AST_NODE(ConstantDef,node,A);
node->Name = A.Name(); node->NodeName = A.Name();
node->Value = NULL; node->Value = NULL;
node->Symbol = NULL; node->Symbol = NULL;
X = node; X = node;
@ -363,7 +363,7 @@ enumerator(X) ::= IDENTIFIER(A).
enumerator(X) ::= IDENTIFIER(A) EQ expr(B). /* Expression must be constant. */ enumerator(X) ::= IDENTIFIER(A) EQ expr(B). /* Expression must be constant. */
{ {
NEW_AST_NODE(ConstantDef,node,A); NEW_AST_NODE(ConstantDef,node,A);
node->Name = A.Name(); node->NodeName = A.Name();
node->Value = B; node->Value = B;
node->Symbol = NULL; node->Symbol = NULL;
X = node; X = node;

View file

@ -19,7 +19,7 @@
//========================================================================== //==========================================================================
ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols) ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols)
: Outer(_outer), Symbols(_symbols), AST(ast), ErrorCount(0), WarnCount(0) : Outer(_outer), Symbols(&_symbols), 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)
@ -30,29 +30,22 @@ ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols)
switch (node->NodeType) switch (node->NodeType)
{ {
case AST_Class: case AST_Class:
if (AddNamedNode(static_cast<ZCC_Class *>(node)->ClassName, node))
{
Classes.Push(static_cast<ZCC_Class *>(node));
}
break;
case AST_Struct: case AST_Struct:
if (AddNamedNode(static_cast<ZCC_Struct *>(node)->StructName, node)) case AST_ConstantDef:
if (AddNamedNode(static_cast<ZCC_NamedNode *>(node)))
{ {
Structs.Push(static_cast<ZCC_Struct *>(node)); switch (node->NodeType)
{
case AST_Class: Classes.Push(static_cast<ZCC_Class *>(node)); break;
case AST_Struct: Structs.Push(static_cast<ZCC_Struct *>(node)); break;
case AST_ConstantDef: Constants.Push(static_cast<ZCC_ConstantDef *>(node)); break;
}
} }
break; break;
case AST_Enum: break; case AST_Enum: break;
case AST_EnumTerminator:break; case AST_EnumTerminator:break;
case AST_ConstantDef:
if (AddNamedNode(static_cast<ZCC_ConstantDef *>(node)->Name, node))
{
Constants.Push(static_cast<ZCC_ConstantDef *>(node));
}
break;
default: default:
assert(0 && "Unhandled AST node type"); assert(0 && "Unhandled AST node type");
break; break;
@ -72,55 +65,76 @@ ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols)
// //
//========================================================================== //==========================================================================
bool ZCCCompiler::AddNamedNode(FName name, ZCC_TreeNode *node) bool ZCCCompiler::AddNamedNode(ZCC_NamedNode *node)
{ {
ZCC_TreeNode **check = NamedNodes.CheckKey(name); FName name = node->NodeName;
if (check != NULL && *check != NULL) PSymbol *check = Symbols->FindSymbol(name, false);
if (check != NULL)
{ {
Message(node, ERR_symbol_redefinition, "Attempt to redefine '%s'", name.GetChars()); assert(check->IsA(RUNTIME_CLASS(PSymbolTreeNode)));
Message(*check, ERR_original_definition, " Original definition is here"); Error(node, "Attempt to redefine '%s'", name.GetChars());
Error(static_cast<PSymbolTreeNode *>(check)->Node, " Original definition is here");
return false; return false;
} }
else else
{ {
NamedNodes.Insert(name, node); Symbols->AddSymbol(new PSymbolTreeNode(name, node));
return true; return true;
} }
} }
//========================================================================== //==========================================================================
// //
// ZCCCompiler :: Message // ZCCCompiler :: Warn
// //
// Prints a warning or error message, and increments the appropriate // Prints a warning message, and increments WarnCount.
// counter.
// //
//========================================================================== //==========================================================================
void ZCCCompiler::Message(ZCC_TreeNode *node, EZCCError errnum, const char *msg, ...) void ZCCCompiler::Warn(ZCC_TreeNode *node, const char *msg, ...)
{
va_list argptr;
va_start(argptr, msg);
MessageV(node, TEXTCOLOR_ORANGE, msg, argptr);
va_end(argptr);
WarnCount++;
}
//==========================================================================
//
// ZCCCompiler :: Error
//
// Prints an error message, and increments ErrorCount.
//
//==========================================================================
void ZCCCompiler::Error(ZCC_TreeNode *node, const char *msg, ...)
{
va_list argptr;
va_start(argptr, msg);
MessageV(node, TEXTCOLOR_RED, msg, argptr);
va_end(argptr);
ErrorCount++;
}
//==========================================================================
//
// ZCCCompiler :: MessageV
//
// Prints a message, annotated with the source location for the tree node.
//
//==========================================================================
void ZCCCompiler::MessageV(ZCC_TreeNode *node, const char *txtcolor, const char *msg, va_list argptr)
{ {
FString composed; FString composed;
composed.Format("%s%s, line %d: ", composed.Format("%s%s, line %d: ", txtcolor, node->SourceName->GetChars(), node->SourceLoc);
errnum & ZCCERR_ERROR ? TEXTCOLOR_RED : TEXTCOLOR_ORANGE,
node->SourceName->GetChars(), node->SourceLoc);
va_list argptr;
va_start(argptr, msg);
composed.VAppendFormat(msg, argptr); composed.VAppendFormat(msg, argptr);
va_end(argptr);
composed += '\n'; composed += '\n';
PrintString(PRINT_HIGH, composed); PrintString(PRINT_HIGH, composed);
if (errnum & ZCCERR_ERROR)
{
ErrorCount++;
}
else
{
WarnCount++;
}
} }
//========================================================================== //==========================================================================
@ -133,7 +147,7 @@ void ZCCCompiler::Message(ZCC_TreeNode *node, EZCCError errnum, const char *msg,
int ZCCCompiler::Compile() int ZCCCompiler::Compile()
{ {
CompileConstants(); CompileConstants(Constants);
return ErrorCount; return ErrorCount;
} }
@ -145,14 +159,14 @@ int ZCCCompiler::Compile()
// //
//========================================================================== //==========================================================================
void ZCCCompiler::CompileConstants() void ZCCCompiler::CompileConstants(const TArray<ZCC_ConstantDef *> &defs)
{ {
for (unsigned i = 0; i < Constants.Size(); ++i) for (unsigned i = 0; i < defs.Size(); ++i)
{ {
ZCC_ConstantDef *def = Constants[i]; ZCC_ConstantDef *def = defs[i];
if (def->Symbol == NULL) if (def->Symbol == NULL)
{ {
CompileConstant(def); PSymbolConst *sym = CompileConstant(def);
} }
} }
} }
@ -180,33 +194,32 @@ PSymbolConst *ZCCCompiler::CompileConstant(ZCC_ConstantDef *def)
ZCC_ExprConstant *cval = static_cast<ZCC_ExprConstant *>(val); ZCC_ExprConstant *cval = static_cast<ZCC_ExprConstant *>(val);
if (cval->Type == TypeString) if (cval->Type == TypeString)
{ {
sym = new PSymbolConstString(def->Name, *(cval->StringVal)); sym = new PSymbolConstString(def->NodeName, *(cval->StringVal));
} }
else if (cval->Type->IsA(RUNTIME_CLASS(PInt))) else if (cval->Type->IsA(RUNTIME_CLASS(PInt)))
{ {
sym = new PSymbolConstNumeric(def->Name, cval->Type, cval->IntVal); sym = new PSymbolConstNumeric(def->NodeName, cval->Type, cval->IntVal);
} }
else if (cval->Type->IsA(RUNTIME_CLASS(PFloat))) else if (cval->Type->IsA(RUNTIME_CLASS(PFloat)))
{ {
sym = new PSymbolConstNumeric(def->Name, cval->Type, cval->DoubleVal); sym = new PSymbolConstNumeric(def->NodeName, cval->Type, cval->DoubleVal);
} }
else else
{ {
Message(def->Value, ERR_bad_const_def_type, "Bad type for constant definiton"); Error(def->Value, "Bad type for constant definiton");
} }
} }
else else
{ {
Message(def->Value, ERR_const_def_not_constant, "Constant definition requires a constant value"); Error(def->Value, "Constant definition requires a constant value");
} }
if (sym == NULL) if (sym == NULL)
{ {
// Create a dummy constant so we don't make any undefined value warnings. // Create a dummy constant so we don't make any undefined value warnings.
sym = new PSymbolConstNumeric(def->Name, TypeError, 0); sym = new PSymbolConstNumeric(def->NodeName, TypeError, 0);
} }
def->Symbol = sym; def->Symbol = sym;
PSymbol *addsym = Symbols.AddSymbol(sym); Symbols->ReplaceSymbol(sym);
assert(NULL != addsym && "Symbol was redefined (but we shouldn't have even had the chance to do so)");
return sym; return sym;
} }
@ -307,17 +320,18 @@ ZCC_Expression *ZCCCompiler::SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop)
if (dotop->Left->Operation == PEX_TypeRef) if (dotop->Left->Operation == PEX_TypeRef)
{ // Type refs can be evaluated now. { // Type refs can be evaluated now.
PType *ref = static_cast<ZCC_ExprTypeRef *>(dotop->Left)->RefType; PType *ref = static_cast<ZCC_ExprTypeRef *>(dotop->Left)->RefType;
PSymbol *sym = ref->Symbols.FindSymbol(dotop->Right, true); PSymbolTable *symtable;
PSymbol *sym = ref->Symbols.FindSymbolInTable(dotop->Right, symtable);
if (sym == NULL) if (sym == NULL)
{ {
Message(dotop, ERR_not_a_member, "'%s' is not a valid member", FName(dotop->Right).GetChars()); Error(dotop, "'%s' is not a valid member", FName(dotop->Right).GetChars());
} }
else else
{ {
ZCC_Expression *expr = NodeFromSymbol(sym, dotop); ZCC_Expression *expr = NodeFromSymbol(sym, dotop, symtable);
if (expr == NULL) if (expr == NULL)
{ {
Message(dotop, ERR_bad_symbol, "Unhandled symbol type encountered"); Error(dotop, "Unhandled symbol type encountered");
} }
else else
{ {
@ -361,7 +375,7 @@ ZCC_Expression *ZCCCompiler::SimplifyFunctionCall(ZCC_ExprFuncCall *callop)
{ {
if (parmcount != 1) if (parmcount != 1)
{ {
Message(callop, ERR_cast_needs_1_parm, "Type cast requires one parameter"); Error(callop, "Type cast requires one parameter");
callop->ToErrorNode(); callop->ToErrorNode();
} }
else else
@ -371,8 +385,8 @@ ZCC_Expression *ZCCCompiler::SimplifyFunctionCall(ZCC_ExprFuncCall *callop)
int routelen = parm->Value->Type->FindConversion(dest, route, countof(route)); int routelen = parm->Value->Type->FindConversion(dest, route, countof(route));
if (routelen < 0) if (routelen < 0)
{ {
// FIXME: Need real type names ///FIXME: Need real type names
Message(callop, ERR_cast_not_possible, "Cannot convert type 1 to type 2"); Error(callop, "Cannot convert type 1 to type 2");
callop->ToErrorNode(); callop->ToErrorNode();
} }
else else
@ -483,53 +497,79 @@ ZCC_Expression *ZCCCompiler::AddCastNode(PType *type, ZCC_Expression *expr)
ZCC_Expression *ZCCCompiler::IdentifyIdentifier(ZCC_ExprID *idnode) ZCC_Expression *ZCCCompiler::IdentifyIdentifier(ZCC_ExprID *idnode)
{ {
// First things first: Check the symbol table. // Check the symbol table for the identifier.
PSymbol *sym; PSymbolTable *table;
if (NULL != (sym = Symbols.FindSymbol(idnode->Identifier, true))) PSymbol *sym = Symbols->FindSymbolInTable(idnode->Identifier, table);
if (sym != NULL)
{ {
ZCC_Expression *node = NodeFromSymbol(sym, idnode); ZCC_Expression *node = NodeFromSymbol(sym, idnode, table);
if (node != NULL) if (node != NULL)
{ {
return node; return node;
} }
} }
else else
{ // Check nodes that haven't had symbols created for them yet.
ZCC_TreeNode **node = NamedNodes.CheckKey(idnode->Identifier);
if (node != NULL && *node != NULL)
{ {
if ((*node)->NodeType == AST_ConstantDef) Error(idnode, "Unknown identifier '%s'", FName(idnode->Identifier).GetChars());
{
ZCC_ConstantDef *def = static_cast<ZCC_ConstantDef *>(*node);
PSymbolConst *sym = def->Symbol;
if (sym == DEFINING_CONST)
{
Message(idnode, ERR_recursive_definition, "Definition of '%s' is infinitely recursive", FName(idnode->Identifier).GetChars());
sym = NULL;
}
else
{
assert(sym == NULL);
sym = CompileConstant(def);
}
return NodeFromSymbolConst(sym, idnode);
}
}
} }
// Identifier didn't refer to anything good, so type error it. // Identifier didn't refer to anything good, so type error it.
idnode->ToErrorNode(); idnode->ToErrorNode();
return idnode; return idnode;
} }
//==========================================================================
//
// ZCCCompiler :: CompileNode
//
//==========================================================================
PSymbol *ZCCCompiler::CompileNode(ZCC_NamedNode *node)
{
assert(node != NULL);
if (node->NodeType == AST_ConstantDef)
{
ZCC_ConstantDef *def = static_cast<ZCC_ConstantDef *>(node);
PSymbolConst *sym = def->Symbol;
if (sym == DEFINING_CONST)
{
Error(node, "Definition of '%s' is infinitely recursive", FName(node->NodeName).GetChars());
sym = NULL;
}
else
{
assert(sym == NULL);
sym = CompileConstant(def);
}
return sym;
}
else if (node->NodeType == AST_Struct)
{
}
return NULL;
}
//========================================================================== //==========================================================================
// //
// ZCCCompiler :: NodeFromSymbol // ZCCCompiler :: NodeFromSymbol
// //
//========================================================================== //==========================================================================
ZCC_Expression *ZCCCompiler::NodeFromSymbol(PSymbol *sym, ZCC_Expression *source) ZCC_Expression *ZCCCompiler::NodeFromSymbol(PSymbol *sym, ZCC_Expression *source, PSymbolTable *table)
{ {
assert(sym != NULL);
if (sym->IsA(RUNTIME_CLASS(PSymbolTreeNode)))
{
PSymbolTable *prevtable = Symbols;
Symbols = table;
sym = CompileNode(static_cast<PSymbolTreeNode *>(sym)->Node);
Symbols = prevtable;
if (sym == NULL)
{
return NULL;
}
}
if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst))) if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst)))
{ {
return NodeFromSymbolConst(static_cast<PSymbolConst *>(sym), source); return NodeFromSymbolConst(static_cast<PSymbolConst *>(sym), source);

View file

@ -1,8 +1,6 @@
#ifndef ZCC_COMPILE_H #ifndef ZCC_COMPILE_H
#define ZCC_COMPILE_H #define ZCC_COMPILE_H
#include "zcc_errors.h"
class ZCCCompiler class ZCCCompiler
{ {
public: public:
@ -10,15 +8,14 @@ public:
int Compile(); int Compile();
private: private:
void CompileConstants(); void CompileConstants(const TArray<ZCC_ConstantDef *> &defs);
PSymbolConst *CompileConstant(ZCC_ConstantDef *def); PSymbolConst *CompileConstant(ZCC_ConstantDef *def);
TArray<ZCC_ConstantDef *> Constants; TArray<ZCC_ConstantDef *> Constants;
TArray<ZCC_Struct *> Structs; TArray<ZCC_Struct *> Structs;
TArray<ZCC_Class *> Classes; TArray<ZCC_Class *> Classes;
TMap<FName, ZCC_TreeNode *> NamedNodes;
bool AddNamedNode(FName name, ZCC_TreeNode *node); bool AddNamedNode(ZCC_NamedNode *node);
ZCC_Expression *Simplify(ZCC_Expression *root); ZCC_Expression *Simplify(ZCC_Expression *root);
ZCC_Expression *SimplifyUnary(ZCC_ExprUnary *unary); ZCC_Expression *SimplifyUnary(ZCC_ExprUnary *unary);
@ -37,14 +34,18 @@ private:
ZCC_Expression *AddCastNode(PType *type, ZCC_Expression *expr); ZCC_Expression *AddCastNode(PType *type, ZCC_Expression *expr);
ZCC_Expression *IdentifyIdentifier(ZCC_ExprID *idnode); ZCC_Expression *IdentifyIdentifier(ZCC_ExprID *idnode);
ZCC_Expression *NodeFromSymbol(PSymbol *sym, ZCC_Expression *source); ZCC_Expression *NodeFromSymbol(PSymbol *sym, ZCC_Expression *source, PSymbolTable *table);
ZCC_ExprConstant *NodeFromSymbolConst(PSymbolConst *sym, ZCC_Expression *idnode); ZCC_ExprConstant *NodeFromSymbolConst(PSymbolConst *sym, ZCC_Expression *idnode);
ZCC_ExprTypeRef *NodeFromSymbolType(PSymbolType *sym, ZCC_Expression *idnode); ZCC_ExprTypeRef *NodeFromSymbolType(PSymbolType *sym, ZCC_Expression *idnode);
PSymbol *ZCCCompiler::CompileNode(ZCC_NamedNode *node);
void Message(ZCC_TreeNode *node, EZCCError errnum, const char *msg, ...);
void Warn(ZCC_TreeNode *node, const char *msg, ...);
void Error(ZCC_TreeNode *node, const char *msg, ...);
void MessageV(ZCC_TreeNode *node, const char *txtcolor, const char *msg, va_list argptr);
DObject *Outer; DObject *Outer;
PSymbolTable &Symbols; PSymbolTable *Symbols;
ZCC_AST &AST; ZCC_AST &AST;
int ErrorCount; int ErrorCount;
int WarnCount; int WarnCount;

View file

@ -1,14 +0,0 @@
#define ZCCERR_ERROR 0x40000000
enum EZCCError
{
ERR_const_def_not_constant = 20000 | ZCCERR_ERROR,
ERR_bad_const_def_type = 20001 | ZCCERR_ERROR,
ERR_symbol_redefinition = 20002 | ZCCERR_ERROR,
ERR_original_definition = 20003 | ZCCERR_ERROR,
ERR_recursive_definition = 20004 | ZCCERR_ERROR,
ERR_not_a_member = 20005 | ZCCERR_ERROR,
ERR_bad_symbol = 20006 | ZCCERR_ERROR,
ERR_cast_needs_1_parm = 20007 | ZCCERR_ERROR,
ERR_cast_not_possible = 20008 | ZCCERR_ERROR,
};

View file

@ -174,24 +174,26 @@ struct ZCC_Identifier : ZCC_TreeNode
ENamedName Id; ENamedName Id;
}; };
struct ZCC_Class : ZCC_TreeNode struct ZCC_NamedNode : ZCC_TreeNode
{
ENamedName NodeName;
};
struct ZCC_Class : ZCC_NamedNode
{ {
ENamedName ClassName;
ZCC_Identifier *ParentName; ZCC_Identifier *ParentName;
ZCC_Identifier *Replaces; ZCC_Identifier *Replaces;
VM_UWORD Flags; VM_UWORD Flags;
ZCC_TreeNode *Body; ZCC_TreeNode *Body;
}; };
struct ZCC_Struct : ZCC_TreeNode struct ZCC_Struct : ZCC_NamedNode
{ {
ENamedName StructName;
ZCC_TreeNode *Body; ZCC_TreeNode *Body;
}; };
struct ZCC_Enum : ZCC_TreeNode struct ZCC_Enum : ZCC_NamedNode
{ {
ENamedName EnumName;
EZCCBuiltinType EnumType; EZCCBuiltinType EnumType;
struct ZCC_ConstantDef *Elements; struct ZCC_ConstantDef *Elements;
}; };
@ -432,9 +434,8 @@ struct ZCC_FuncParamDecl : ZCC_TreeNode
int Flags; int Flags;
}; };
struct ZCC_ConstantDef : ZCC_TreeNode struct ZCC_ConstantDef : ZCC_NamedNode
{ {
ENamedName Name;
ZCC_Expression *Value; ZCC_Expression *Value;
PSymbolConst *Symbol; PSymbolConst *Symbol;
}; };