Symbol * DACGenerator::AddSymbol(Symbol * pSymbol) { if (pSymbol == 0) { Error("AddSymbol: invalid symbol"); return 0; } // check if symbol already exists Symbol* result = mSymbolTable.Find(pSymbol->GetName()); if (result != 0) { if (result->GetSymbolType() != eConst) { std::wstring wname = std::wstring(result->GetName()); std::string name = std::string(wname.begin(), wname.end()); Error("Symbol " + name + " already defined"); } delete pSymbol; pSymbol = result; } else { result = mSymbolTable.Add(pSymbol); } return result; }
// -------------------------------------------------------------------------------- // Writes the data out for a given symbol. // -------------------------------------------------------------------------------- void CodeGenerator::WriteMetaData(Symbol* symbol) { if (symbol->GeneratedSymbolData == false) { symbol->GeneratedSymbolData = true; // Write out the header. WriteLine(symbol->UniqueASMName + "_meta:"); // General information. switch (symbol->GetSymbolType()) { case ST_VARIABLE: WriteLine("\tdd " + StringHelper::IntToString(META_TYPE_VARIABLE)); break; case ST_FUNCTION: WriteLine("\tdd " + StringHelper::IntToString(META_TYPE_FUNCTION)); break; case ST_CLASS: WriteLine("\tdd " + StringHelper::IntToString(META_TYPE_CLASS)); break; case ST_NAMESPACE: WriteLine("\tdd " + StringHelper::IntToString(META_TYPE_NAMESPACE)); break; } // Source code declaration. WriteLine("\tdd " + FindStringLiteralLabel(symbol->DefinitionToken.Path, true)); WriteLine("\tdd " + StringHelper::IntToString(symbol->DefinitionToken.Line)); WriteLine("\tdd " + StringHelper::IntToString(symbol->DefinitionToken.Column)); // General properties. WriteLine("\tdd " + FindStringLiteralLabel(symbol->Identifier, true)); // Child properties. WriteLine("\tdd " + symbol->UniqueASMName + "_meta_children"); // Write in specific symbol information. switch (symbol->GetSymbolType()) { // Emit a namespace! case ST_NAMESPACE: { NamespaceSymbol* func = (NamespaceSymbol*)symbol; break; } // Emit metadata for a function. case ST_FUNCTION: { FunctionSymbol* func = (FunctionSymbol*)symbol; WriteLine("\tdd " + std::string(func->IsExtern == false ? func->UniqueASMName : "0")); WriteLine("\tdd " + StringHelper::IntToString((int)func->ReturnDataType->GetPrimitive())); WriteLine("\tdd " + StringHelper::IntToString(func->ReturnDataType->GetPrimitive() == PDT_CLASS ? ((ClassDataType*)func->ReturnDataType)->Class->ClassDefinitionIndex : 0)); WriteLine("\tdd " + StringHelper::IntToString(func->ParameterCount)); WriteLine("\tdd " + StringHelper::IntToString(func->ParameterSize)); WriteLine("\tdd " + StringHelper::IntToString(func->LocalCount)); WriteLine("\tdd " + StringHelper::IntToString(func->LocalSize)); WriteLine("\tdd " + StringHelper::IntToString((int)func->IsExtern)); WriteLine("\tdd " + StringHelper::IntToString((int)func->IsMethod)); WriteLine("\tdd " + StringHelper::IntToString((int)func->IsGenerator)); WriteLine("\tdd " + StringHelper::IntToString((int)func->IsVirtual)); WriteLine("\tdd " + StringHelper::IntToString((int)func->IsBase)); WriteLine("\tdd " + StringHelper::IntToString((int)func->VirtualFunctionTableOffset)); WriteLine("\tdd " + StringHelper::IntToString((int)func->AccessModifier)); break; } // Emit metadata for a variable. case ST_VARIABLE: { VariableSymbol* var = (VariableSymbol*)symbol; WriteLine("\tdd " + std::string(var->Scope == _globalScope ? var->UniqueASMName : "0")); WriteLine("\tdd " + StringHelper::IntToString((int)var->VariableType)); WriteLine("\tdd " + StringHelper::IntToString((int)var->DataType->GetPrimitive())); WriteLine("\tdd " + StringHelper::IntToString(var->DataType->GetPrimitive() == PDT_CLASS ? ((ClassDataType*)var->DataType)->Class->ClassDefinitionIndex : 0)); WriteLine("\tdd " + StringHelper::IntToString(var->StackOffset)); WriteLine("\tdd " + StringHelper::IntToString(var->ParamStackOffset)); WriteLine("\tdd " + StringHelper::IntToString(var->ClassOffset)); WriteLine("\tdd " + StringHelper::IntToString((int)var->IsConst)); WriteLine("\tdd " + StringHelper::IntToString((int)var->IsBase)); WriteLine("\tdd " + StringHelper::IntToString((int)var->AccessModifier)); break; } // Emit metadata for a class. case ST_CLASS: { ClassSymbol* classSymbol = (ClassSymbol*)symbol; WriteLine("\tdd " + classSymbol->UniqueASMName + "_vftable"); WriteLine("\tdd " + StringHelper::IntToString(classSymbol->VirtualFunctionTableSize)); WriteLine("\tdd " + StringHelper::IntToString(classSymbol->MemoryDataSize)); if (classSymbol->SuperClass != NULL) WriteLine("\tdd " + StringHelper::IntToString(classSymbol->SuperClass->ClassDefinitionIndex)); else WriteLine("\tdd -1"); WriteLine("\tdd " + StringHelper::IntToString(classSymbol->ClassDefinitionIndex)); WriteLine("\tdd " + (classSymbol->InternalConstructMethod == NULL ? "0" : classSymbol->InternalConstructMethod->UniqueASMName)); WriteLine("\tdd " + (classSymbol->InternalDisposeMethod == NULL ? "0" : classSymbol->InternalDisposeMethod->UniqueASMName)); // Write out the virtual-table. WriteLine(classSymbol->UniqueASMName + "_vftable:"); for (int i = 0; i < classSymbol->VirtualFunctionTableSize; i++) { // Emit dat virtual functions in order. for (int j = 0; j < classSymbol->Children.size(); j++) { FunctionSymbol* func = dynamic_cast<FunctionSymbol*>(classSymbol->Children.at(j)); if (func != NULL && func->VirtualFunctionTableOffset == i) { //printf("%i = %s\n", i, func->Identifier.c_str()); WriteLine("\tdd " + func->UniqueASMName); } } } break; } } WriteLine(""); // Define the list of children. WriteLine(symbol->UniqueASMName + "_meta_children:"); for (int i = 0; i < (int)symbol->Children.size(); i++) { Symbol* child = symbol->Children.at(i); if (child->GetSymbolType() == ST_CLASS || child->GetSymbolType() == ST_VARIABLE || child->GetSymbolType() == ST_FUNCTION || child->GetSymbolType() == ST_NAMESPACE) WriteLine("\tdd " + child->UniqueASMName + "_meta"); } WriteLine("\tdd 0"); WriteLine(""); // Emit the children! for (int i = 0; i < (int)symbol->Children.size(); i++) { Symbol* child = symbol->Children.at(i); if (child->GetSymbolType() == ST_CLASS || child->GetSymbolType() == ST_VARIABLE || child->GetSymbolType() == ST_FUNCTION || child->GetSymbolType() == ST_NAMESPACE) WriteMetaData(child); } } // Emit all sub symbols. // for (int i = 0; i < (int)symbol->Children.size(); i++) // WriteMetaData(symbol->Children.at(i)); }