- implemented complete resolving of constants - both global and class-local.
This uses a different algorithm as the old implementation - instead of recursively resolving unknown symbols it will first collect all constants from all scopes and then process them in one operation, doing multiple passes over the list until no more constants can be resolved anymore.
This commit is contained in:
parent
5bb6bb31ca
commit
08f313d011
9 changed files with 238 additions and 122 deletions
|
|
@ -3,6 +3,7 @@
|
|||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright -2016 Randy Heit
|
||||
** Copyright 2016 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -41,6 +42,7 @@
|
|||
#include "zcc_parser.h"
|
||||
#include "zcc_compile.h"
|
||||
#include "v_text.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "gdtoa.h"
|
||||
|
||||
#define DEFINING_CONST ((PSymbolConst *)(void *)1)
|
||||
|
|
@ -155,7 +157,7 @@ ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols,
|
|||
case AST_Class:
|
||||
case AST_Struct:
|
||||
case AST_ConstantDef:
|
||||
if ((tnode = AddNamedNode(static_cast<ZCC_NamedNode *>(node))))
|
||||
if ((tnode = AddNamedNode(static_cast<ZCC_NamedNode *>(node), Symbols)))
|
||||
{
|
||||
switch (node->NodeType)
|
||||
{
|
||||
|
|
@ -204,6 +206,9 @@ PSymbolTreeNode *ZCCCompiler::AddNamedNode(ZCC_NamedNode *node, PSymbolTable *pa
|
|||
{
|
||||
auto sy = new PSymbolTreeNode(name, node);
|
||||
sy->Symbols.SetParentTable(parentsym);
|
||||
FString name;
|
||||
name << "nodes - " << FName(node->NodeName);
|
||||
sy->Symbols.SetName(name);
|
||||
Symbols->AddSymbol(sy);
|
||||
return sy;
|
||||
}
|
||||
|
|
@ -275,7 +280,7 @@ int ZCCCompiler::Compile()
|
|||
{
|
||||
CreateClassTypes();
|
||||
CreateStructTypes();
|
||||
CompileConstants(Constants);
|
||||
CompileAllConstants();
|
||||
return ErrorCount;
|
||||
}
|
||||
|
||||
|
|
@ -292,6 +297,9 @@ void ZCCCompiler::CreateStructTypes()
|
|||
for(auto s : Structs)
|
||||
{
|
||||
s->Type = NewStruct(s->NodeName, nullptr);
|
||||
s->Symbol = new PSymbolType(s->NodeName, s->Type);
|
||||
s->Type->Symbols.SetName(FName(s->NodeName));
|
||||
GlobalSymbols.AddSymbol(s->Symbol);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -366,6 +374,9 @@ void ZCCCompiler::CreateClassTypes()
|
|||
// We will never get here if the name is a duplicate, so we can just do the assignment.
|
||||
c->Type = parent->FindClassTentative(c->NodeName);
|
||||
}
|
||||
c->Symbol = new PSymbolType(c->NodeName, c->Type);
|
||||
GlobalSymbols.AddSymbol(c->Symbol);
|
||||
c->Type->Symbols.SetName(FName(c->NodeName).GetChars());
|
||||
Classes.Push(c);
|
||||
OrigClasses.Delete(i);
|
||||
i--;
|
||||
|
|
@ -389,6 +400,9 @@ void ZCCCompiler::CreateClassTypes()
|
|||
Error(c, "Class %s has unknown base class %s", FName(c->NodeName).GetChars(), FName(c->ParentName->Id).GetChars());
|
||||
// create a placeholder so that the compiler can continue looking for errors.
|
||||
c->Type = RUNTIME_CLASS(DObject)->FindClassTentative(c->NodeName);
|
||||
c->Symbol = new PSymbolType(c->NodeName, c->Type);
|
||||
GlobalSymbols.AddSymbol(c->Symbol);
|
||||
c->Type->Symbols.SetName(FName(c->NodeName).GetChars());
|
||||
Classes.Push(c);
|
||||
OrigClasses.Delete(i);
|
||||
donesomething = true;
|
||||
|
|
@ -403,28 +417,132 @@ void ZCCCompiler::CreateClassTypes()
|
|||
{
|
||||
Error(c, "Class %s has circular inheritance", FName(c->NodeName).GetChars());
|
||||
c->Type = RUNTIME_CLASS(DObject)->FindClassTentative(c->NodeName);
|
||||
c->Symbol = new PSymbolType(c->NodeName, c->Type);
|
||||
c->Type->Symbols.SetName(FName(c->NodeName).GetChars());
|
||||
GlobalSymbols.AddSymbol(c->Symbol);
|
||||
Classes.Push(c);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: CompileConstants
|
||||
// ZCCCompiler :: AddConstants
|
||||
//
|
||||
// Make symbols from every constant defined at this level.
|
||||
// Helper for CompileAllConstants
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZCCCompiler::CompileConstants(const TArray<ZCC_ConstantDef *> &defs)
|
||||
void ZCCCompiler::AddConstants(TArray<ZCC_ConstantWork> &dest, TArray<ZCC_ConstantDef*> &Constants, PSymbolTable *nt, PSymbolTable *ot)
|
||||
{
|
||||
for (unsigned i = 0; i < defs.Size(); ++i)
|
||||
for (auto c : Constants)
|
||||
{
|
||||
ZCC_ConstantDef *def = defs[i];
|
||||
if (def->Symbol == NULL)
|
||||
dest.Push({ c, nt, ot });
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: CompileAllConstants
|
||||
//
|
||||
// Make symbols from every constant defined at all levels.
|
||||
// Since constants may only depend on other constants this can be done
|
||||
// without any more involved processing of the AST as a first step.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZCCCompiler::CompileAllConstants()
|
||||
{
|
||||
// put all constants in one list to make resolving this easier.
|
||||
TArray<ZCC_ConstantWork> constantwork;
|
||||
|
||||
AddConstants(constantwork, Constants, Symbols, OutputSymbols);
|
||||
for (auto &c : Classes)
|
||||
{
|
||||
AddConstants(constantwork, c.Constants, &c.node->Symbols, &c->Type->Symbols);
|
||||
for (auto &s : c.Structs)
|
||||
{
|
||||
PSymbolConst *sym = CompileConstant(def);
|
||||
AddConstants(constantwork, s.Constants, &s.node->Symbols, &s->Type->Symbols);
|
||||
}
|
||||
}
|
||||
for (auto &s : Structs)
|
||||
{
|
||||
AddConstants(constantwork, s.Constants, &s.node->Symbols, &s->Type->Symbols);
|
||||
}
|
||||
|
||||
// Before starting to resolve the list, let's create symbols for all already resolved ones first (i.e. all literal constants), to reduce work.
|
||||
for (unsigned i = 0; i<constantwork.Size(); i++)
|
||||
{
|
||||
if (constantwork[i].node->Value->NodeType == AST_ExprConstant)
|
||||
{
|
||||
AddConstant(constantwork[i]);
|
||||
// Remove the constant from the list
|
||||
constantwork.Delete(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
bool donesomething = true;
|
||||
// Now go through this list until no more constants can be resolved. The remaining ones will be non-constant values.
|
||||
while (donesomething && constantwork.Size() > 0)
|
||||
{
|
||||
donesomething = false;
|
||||
for (unsigned i = 0; i < constantwork.Size(); i++)
|
||||
{
|
||||
if (CompileConstant(constantwork[i].node, constantwork[i].outputtable))
|
||||
{
|
||||
AddConstant(constantwork[i]);
|
||||
// Remove the constant from the list
|
||||
constantwork.Delete(i);
|
||||
i--;
|
||||
donesomething = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < constantwork.Size(); i++)
|
||||
{
|
||||
Error(constantwork[i].node, "%s is not a constant", FName(constantwork[i].node->NodeName).GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: AddConstant
|
||||
//
|
||||
// Adds a constant to its assigned symbol table
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant)
|
||||
{
|
||||
auto def = constant.node;
|
||||
auto val = def->Value;
|
||||
if (val->NodeType == AST_ExprConstant)
|
||||
{
|
||||
ZCC_ExprConstant *cval = static_cast<ZCC_ExprConstant *>(val);
|
||||
if (cval->Type == TypeString)
|
||||
{
|
||||
def->Symbol = new PSymbolConstString(def->NodeName, *(cval->StringVal));
|
||||
}
|
||||
else if (cval->Type->IsA(RUNTIME_CLASS(PInt)))
|
||||
{
|
||||
def->Symbol = new PSymbolConstNumeric(def->NodeName, cval->Type, cval->IntVal);
|
||||
}
|
||||
else if (cval->Type->IsA(RUNTIME_CLASS(PFloat)))
|
||||
{
|
||||
def->Symbol = new PSymbolConstNumeric(def->NodeName, cval->Type, cval->DoubleVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(def->Value, "Bad type for constant definiton");
|
||||
def->Symbol = nullptr;
|
||||
}
|
||||
|
||||
if (def->Symbol == nullptr)
|
||||
{
|
||||
// Create a dummy constant so we don't make any undefined value warnings.
|
||||
def->Symbol = new PSymbolConstNumeric(def->NodeName, TypeError, 0);
|
||||
}
|
||||
constant.outputtable->ReplaceSymbol(def->Symbol);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -432,51 +550,19 @@ void ZCCCompiler::CompileConstants(const TArray<ZCC_ConstantDef *> &defs)
|
|||
// ZCCCompiler :: CompileConstant
|
||||
//
|
||||
// For every constant definition, evaluate its value (which should result
|
||||
// in a constant), and create a symbol for it. Simplify() uses recursion
|
||||
// to resolve constants used before their declarations.
|
||||
// in a constant), and create a symbol for it.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PSymbolConst *ZCCCompiler::CompileConstant(ZCC_ConstantDef *def)
|
||||
bool ZCCCompiler::CompileConstant(ZCC_ConstantDef *def, PSymbolTable *sym)
|
||||
{
|
||||
assert(def->Symbol == NULL);
|
||||
assert(def->Symbol == nullptr);
|
||||
|
||||
def->Symbol = DEFINING_CONST; // avoid recursion
|
||||
ZCC_Expression *val = Simplify(def->Value);
|
||||
ZCC_Expression *val = Simplify(def->Value, sym);
|
||||
def->Value = val;
|
||||
PSymbolConst *sym = NULL;
|
||||
if (val->NodeType == AST_ExprConstant)
|
||||
{
|
||||
ZCC_ExprConstant *cval = static_cast<ZCC_ExprConstant *>(val);
|
||||
if (cval->Type == TypeString)
|
||||
{
|
||||
sym = new PSymbolConstString(def->NodeName, *(cval->StringVal));
|
||||
}
|
||||
else if (cval->Type->IsA(RUNTIME_CLASS(PInt)))
|
||||
{
|
||||
sym = new PSymbolConstNumeric(def->NodeName, cval->Type, cval->IntVal);
|
||||
}
|
||||
else if (cval->Type->IsA(RUNTIME_CLASS(PFloat)))
|
||||
{
|
||||
sym = new PSymbolConstNumeric(def->NodeName, cval->Type, cval->DoubleVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(def->Value, "Bad type for constant definiton");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(def->Value, "Constant definition requires a constant value");
|
||||
}
|
||||
if (sym == NULL)
|
||||
{
|
||||
// Create a dummy constant so we don't make any undefined value warnings.
|
||||
sym = new PSymbolConstNumeric(def->NodeName, TypeError, 0);
|
||||
}
|
||||
def->Symbol = sym;
|
||||
OutputSymbols->ReplaceSymbol(sym);
|
||||
return sym;
|
||||
if (def->Symbol == DEFINING_CONST) def->Symbol = nullptr;
|
||||
return (val->NodeType == AST_ExprConstant);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -493,27 +579,27 @@ PSymbolConst *ZCCCompiler::CompileConstant(ZCC_ConstantDef *def)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
ZCC_Expression *ZCCCompiler::Simplify(ZCC_Expression *root)
|
||||
ZCC_Expression *ZCCCompiler::Simplify(ZCC_Expression *root, PSymbolTable *sym)
|
||||
{
|
||||
if (root->NodeType == AST_ExprUnary)
|
||||
{
|
||||
return SimplifyUnary(static_cast<ZCC_ExprUnary *>(root));
|
||||
return SimplifyUnary(static_cast<ZCC_ExprUnary *>(root), sym);
|
||||
}
|
||||
else if (root->NodeType == AST_ExprBinary)
|
||||
{
|
||||
return SimplifyBinary(static_cast<ZCC_ExprBinary *>(root));
|
||||
return SimplifyBinary(static_cast<ZCC_ExprBinary *>(root), sym);
|
||||
}
|
||||
else if (root->Operation == PEX_ID)
|
||||
{
|
||||
return IdentifyIdentifier(static_cast<ZCC_ExprID *>(root));
|
||||
return IdentifyIdentifier(static_cast<ZCC_ExprID *>(root), sym);
|
||||
}
|
||||
else if (root->Operation == PEX_MemberAccess)
|
||||
{
|
||||
return SimplifyMemberAccess(static_cast<ZCC_ExprMemberAccess *>(root));
|
||||
return SimplifyMemberAccess(static_cast<ZCC_ExprMemberAccess *>(root), sym);
|
||||
}
|
||||
else if (root->Operation == PEX_FuncCall)
|
||||
{
|
||||
return SimplifyFunctionCall(static_cast<ZCC_ExprFuncCall *>(root));
|
||||
return SimplifyFunctionCall(static_cast<ZCC_ExprFuncCall *>(root), sym);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
|
@ -524,9 +610,13 @@ ZCC_Expression *ZCCCompiler::Simplify(ZCC_Expression *root)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
ZCC_Expression *ZCCCompiler::SimplifyUnary(ZCC_ExprUnary *unary)
|
||||
ZCC_Expression *ZCCCompiler::SimplifyUnary(ZCC_ExprUnary *unary, PSymbolTable *sym)
|
||||
{
|
||||
unary->Operand = Simplify(unary->Operand);
|
||||
unary->Operand = Simplify(unary->Operand, sym);
|
||||
if (unary->Operand->Type == nullptr)
|
||||
{
|
||||
return unary;
|
||||
}
|
||||
ZCC_OpProto *op = PromoteUnary(unary->Operation, unary->Operand);
|
||||
if (op == NULL)
|
||||
{ // Oh, poo!
|
||||
|
|
@ -545,10 +635,15 @@ ZCC_Expression *ZCCCompiler::SimplifyUnary(ZCC_ExprUnary *unary)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
ZCC_Expression *ZCCCompiler::SimplifyBinary(ZCC_ExprBinary *binary)
|
||||
ZCC_Expression *ZCCCompiler::SimplifyBinary(ZCC_ExprBinary *binary, PSymbolTable *sym)
|
||||
{
|
||||
binary->Left = Simplify(binary->Left);
|
||||
binary->Right = Simplify(binary->Right);
|
||||
binary->Left = Simplify(binary->Left, sym);
|
||||
binary->Right = Simplify(binary->Right, sym);
|
||||
if (binary->Left->Type == nullptr || binary->Right->Type == nullptr)
|
||||
{
|
||||
// We do not know yet what this is so we cannot promote it (yet.)
|
||||
return binary;
|
||||
}
|
||||
ZCC_OpProto *op = PromoteBinary(binary->Operation, binary->Left, binary->Right);
|
||||
if (op == NULL)
|
||||
{
|
||||
|
|
@ -569,32 +664,41 @@ ZCC_Expression *ZCCCompiler::SimplifyBinary(ZCC_ExprBinary *binary)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
ZCC_Expression *ZCCCompiler::SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop)
|
||||
ZCC_Expression *ZCCCompiler::SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop, PSymbolTable *symt)
|
||||
{
|
||||
dotop->Left = Simplify(dotop->Left);
|
||||
PSymbolTable *symtable;
|
||||
|
||||
dotop->Left = Simplify(dotop->Left, symt);
|
||||
|
||||
if (dotop->Left->Operation == PEX_TypeRef)
|
||||
{ // Type refs can be evaluated now.
|
||||
PType *ref = static_cast<ZCC_ExprTypeRef *>(dotop->Left)->RefType;
|
||||
PSymbolTable *symtable;
|
||||
PSymbol *sym = ref->Symbols.FindSymbolInTable(dotop->Right, symtable);
|
||||
if (sym == NULL)
|
||||
{
|
||||
Error(dotop, "'%s' is not a valid member", FName(dotop->Right).GetChars());
|
||||
}
|
||||
else
|
||||
if (sym != nullptr)
|
||||
{
|
||||
ZCC_Expression *expr = NodeFromSymbol(sym, dotop, symtable);
|
||||
if (expr == NULL)
|
||||
{
|
||||
Error(dotop, "Unhandled symbol type encountered");
|
||||
}
|
||||
else
|
||||
if (expr != nullptr)
|
||||
{
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dotop->Left->Operation == PEX_Super)
|
||||
{
|
||||
symt = symt->GetParentTable();
|
||||
if (symt != nullptr)
|
||||
{
|
||||
PSymbol *sym = symt->FindSymbolInTable(dotop->Right, symtable);
|
||||
if (sym != nullptr)
|
||||
{
|
||||
ZCC_Expression *expr = NodeFromSymbol(sym, dotop, symtable);
|
||||
if (expr != nullptr)
|
||||
{
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dotop;
|
||||
}
|
||||
|
||||
|
|
@ -607,12 +711,12 @@ ZCC_Expression *ZCCCompiler::SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
ZCC_Expression *ZCCCompiler::SimplifyFunctionCall(ZCC_ExprFuncCall *callop)
|
||||
ZCC_Expression *ZCCCompiler::SimplifyFunctionCall(ZCC_ExprFuncCall *callop, PSymbolTable *sym)
|
||||
{
|
||||
ZCC_FuncParm *parm;
|
||||
int parmcount = 0;
|
||||
|
||||
callop->Function = Simplify(callop->Function);
|
||||
callop->Function = Simplify(callop->Function, sym);
|
||||
parm = callop->Parameters;
|
||||
if (parm != NULL)
|
||||
{
|
||||
|
|
@ -620,7 +724,7 @@ ZCC_Expression *ZCCCompiler::SimplifyFunctionCall(ZCC_ExprFuncCall *callop)
|
|||
{
|
||||
parmcount++;
|
||||
assert(parm->NodeType == AST_FuncParm);
|
||||
parm->Value = Simplify(parm->Value);
|
||||
parm->Value = Simplify(parm->Value, sym);
|
||||
parm = static_cast<ZCC_FuncParm *>(parm->SiblingNext);
|
||||
}
|
||||
while (parm != callop->Parameters);
|
||||
|
|
@ -751,12 +855,14 @@ ZCC_Expression *ZCCCompiler::AddCastNode(PType *type, ZCC_Expression *expr)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
ZCC_Expression *ZCCCompiler::IdentifyIdentifier(ZCC_ExprID *idnode)
|
||||
ZCC_Expression *ZCCCompiler::IdentifyIdentifier(ZCC_ExprID *idnode, PSymbolTable *symt)
|
||||
{
|
||||
// Check the symbol table for the identifier.
|
||||
PSymbolTable *table;
|
||||
PSymbol *sym = Symbols->FindSymbolInTable(idnode->Identifier, table);
|
||||
if (sym != NULL)
|
||||
PSymbol *sym = symt->FindSymbolInTable(idnode->Identifier, table);
|
||||
// GlobalSymbols cannot be the parent of a class's symbol table so we have to look for global symbols explicitly.
|
||||
if (sym == nullptr && symt != &GlobalSymbols) sym = GlobalSymbols.FindSymbolInTable(idnode->Identifier, table);
|
||||
if (sym != nullptr)
|
||||
{
|
||||
ZCC_Expression *node = NodeFromSymbol(sym, idnode, table);
|
||||
if (node != NULL)
|
||||
|
|
@ -766,46 +872,26 @@ ZCC_Expression *ZCCCompiler::IdentifyIdentifier(ZCC_ExprID *idnode)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Also handle line specials.
|
||||
// To call this like a function this needs to be done differently, but for resolving constants this is ok.
|
||||
int spec = P_FindLineSpecial(FName(idnode->Identifier).GetChars());
|
||||
if (spec != 0)
|
||||
{
|
||||
ZCC_ExprConstant *val = static_cast<ZCC_ExprConstant *>(AST.InitNode(sizeof(*val), AST_ExprConstant, idnode));
|
||||
val->Operation = PEX_ConstValue;
|
||||
val->Type = TypeSInt32;
|
||||
val->IntVal = spec;
|
||||
return val;
|
||||
}
|
||||
symt->DumpSymbolTable();
|
||||
GlobalSymbols.DumpSymbolTable();
|
||||
|
||||
Error(idnode, "Unknown identifier '%s'", FName(idnode->Identifier).GetChars());
|
||||
idnode->ToErrorNode();
|
||||
}
|
||||
// Identifier didn't refer to anything good, so type error it.
|
||||
idnode->ToErrorNode();
|
||||
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
|
||||
|
|
@ -814,18 +900,8 @@ PSymbol *ZCCCompiler::CompileNode(ZCC_NamedNode *node)
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
assert(sym != nullptr);
|
||||
|
||||
if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst)))
|
||||
{
|
||||
return NodeFromSymbolConst(static_cast<PSymbolConst *>(sym), source);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue