예제 #1
0
파일: DACGenerator.cpp 프로젝트: Djon/COM
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));
}