123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 |
- #include "pch.h"
- class NameSpaceInfo : public INameSpaceInfo {
- private:
- INameSpace* m_pns;
- ZString m_str;
- public:
- NameSpaceInfo(INameSpace* pns, const ZString& str) :
- m_pns(pns),
- m_str(str)
- {
- }
- INameSpace* GetNameSpace()
- {
- return m_pns;
- }
- const ZString& GetName()
- {
- return m_str;
- }
- };
- TRef<INameSpaceInfo> CreateNameSpaceInfo(INameSpace* pns, const ZString& str)
- {
- return new NameSpaceInfo(pns, str);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // NameSpace
- //
- //////////////////////////////////////////////////////////////////////////////
- class NameSpaceImpl : public INameSpace {
- private:
- //////////////////////////////////////////////////////////////////////////////
- //
- // types
- //
- //////////////////////////////////////////////////////////////////////////////
- class SymbolData {
- public:
- ZString m_strName;
- TRef<IObject> m_pobject;
- SymbolData(){}
- SymbolData(const ZString& strName, TRef<IObject> pobject) :
- m_strName(strName),
- m_pobject(pobject)
- {
- }
- SymbolData(const SymbolData& data) :
- m_strName(data.m_strName),
- m_pobject(data.m_pobject)
- {
- }
- };
- typedef TList<SymbolData, DefaultNoEquals> SymbolList;
- class TypeData {
- public:
- ZString m_strName;
- TRef<MDLType> m_ptype;
- };
-
- typedef TList<TypeData, DefaultNoEquals> TypeList;
- //////////////////////////////////////////////////////////////////////////////
- //
- // data members
- //
- //////////////////////////////////////////////////////////////////////////////
- ZString m_strName;
- INameSpaceList m_listParents;
- SymbolList m_listSymbols;
- TypeList m_listTypes;
- //////////////////////////////////////////////////////////////////////////////
- //
- // methods
- //
- //////////////////////////////////////////////////////////////////////////////
- public:
- NameSpaceImpl(const ZString& strName) :
- m_strName(strName)
- {
- }
- NameSpaceImpl(const ZString& strName, INameSpace* pnsParent) :
- m_strName(strName)
- {
- m_listParents.PushFront(pnsParent);
- }
- NameSpaceImpl(const ZString& strName, INameSpaceList& parents) :
- m_strName(strName),
- m_listParents(parents)
- {
- // !!! should make an ordered list of parents so we don't search
- // any parent more than once.
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // INameSpace methods
- //
- //////////////////////////////////////////////////////////////////////////////
- const ZString& GetName()
- {
- return m_strName;
- }
- void AddMember(const ZString& strName, IObject* pobject)
- {
- ZAssert(FindMemberLocal(strName) == NULL);
- m_listSymbols.PushEnd(SymbolData(strName, pobject));
- //
- // !!! this is a total hack, only do this on Debug builds since it
- // requires dynamic casting. MDLC is always built debug so it's
- // ok.
- //
- #if defined(_DEBUG) && !defined(DREAMCAST)
- Value* pvalue = dynamic_cast<Value*>(pobject);
- if (pvalue != NULL) {
- pvalue->SetNameSpaceInfo(CreateNameSpaceInfo(this, strName));
- }
- #endif
- }
- IObject* FindMemberLocal(const ZString& str)
- {
- SymbolList::Iterator iter(m_listSymbols);
- while (!iter.End()) {
- const SymbolData& data = iter.Value();
- if (data.m_strName == str) {
- return data.m_pobject;
- }
- iter.Next();
- }
- return NULL;
- }
- IObject* FindMemberAndNameSpace(const ZString& str, INameSpace*& pns)
- {
- IObject* pobject = FindMemberLocal(str);
- if (pobject != NULL) {
- pns = this;
- return pobject;
- }
- INameSpaceList::Iterator iter(m_listParents);
- while (!iter.End()) {
- pobject = iter.Value()->FindMemberAndNameSpace(str, pns);
- if (pobject != NULL) {
- return pobject;
- }
- iter.Next();
- }
- return NULL;
- }
- IObject* FindMember(const ZString& str)
- {
- INameSpace* pns;
- return FindMemberAndNameSpace(str, pns);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Types
- //
- //////////////////////////////////////////////////////////////////////////////
- void AddType(const ZString& strName, MDLType* ptype)
- {
- ZAssert(FindTypeLocal(strName) == NULL);
- m_listTypes.PushEnd();
- m_listTypes.GetEnd().m_strName = strName;
- m_listTypes.GetEnd().m_ptype = ptype;
- }
- MDLType* FindTypeLocal(const ZString& strName)
- {
- TypeList::Iterator iter(m_listTypes);
- while (!iter.End()) {
- const TypeData& data = iter.Value();
- if (data.m_strName == strName) {
- return data.m_ptype;
- }
- iter.Next();
- }
- return NULL;
- }
- MDLType* FindTypeAndNameSpace(const ZString& str, NameSpaceImpl*& pns)
- {
- MDLType* ptype = FindTypeLocal(str);
- if (ptype != NULL) {
- pns = this;
- return ptype;
- }
- INameSpaceList::Iterator iter(m_listParents);
- while (!iter.End()) {
- NameSpaceImpl* pnsImpl; CastTo(pnsImpl, iter.Value());
- ptype = pnsImpl->FindTypeAndNameSpace(str, pns);
- if (ptype != NULL) {
- return ptype;
- }
- iter.Next();
- }
- return NULL;
- }
- MDLType* FindType(const ZString& strName)
- {
- NameSpaceImpl* pns;
- return FindTypeAndNameSpace(strName, pns);
- }
- void WriteTypeHeader(ZFile* pfile)
- {
- TypeList::Iterator iter(m_listTypes);
- while (!iter.End()) {
- const TypeData& data = iter.Value();
- iter.Next();
- if (data.m_ptype->IsStruct()) {
- pfile->Write(GetStructHeader(data.m_ptype, data.m_strName));
- if (!iter.End()) {
- pfile->Write(ZString("\n"));
- }
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Binary File Writer
- //
- //////////////////////////////////////////////////////////////////////////////
- class MDLBinaryFile : public IMDLBinaryFile {
- private:
- class ImportData {
- public:
- DWORD m_indexNameSpaceTable;
- ZString m_str;
- };
- TVector<TRef<INameSpace> > m_pnss;
- TVector<ImportData> m_importDatas;
- TRef<NameSpaceImpl> m_pns;
- TRef<ZFile> m_pfile;
- public:
- MDLBinaryFile(NameSpaceImpl* pns, ZFile* pfile) :
- m_pns(pns),
- m_pfile(pfile)
- {
- }
- int FindImport(const ZString& str)
- {
- int count = m_importDatas.GetCount();
- for (int index = 0; index < count; index++) {
- if (m_importDatas[index].m_str == str) {
- return index;
- }
- }
- return -1;
- }
- void AddImport(const ZString& str, INameSpace* pns)
- {
- int count = m_pnss.GetCount();
- for (int index = 0; index < count; index++) {
- if (m_pnss[index] == pns) {
- break;
- }
- }
- //
- // Do we need to add a new namespace to the namespace import list?
- //
- if (index == count) {
- m_pnss.PushEnd(pns);
- }
- //
- // Add the new import symbol
- //
- m_importDatas.PushEnd();
- ImportData& data = m_importDatas.GetEnd();
- data.m_indexNameSpaceTable = index;
- data.m_str = str;
- }
- void AddImport(const ZString& str)
- {
- int index = FindImport(str);
- if (index == -1) {
- INameSpace* pns;
- IObject* pobject = m_pns->FindMemberAndNameSpace(str, pns);
- ZAssert(pobject != NULL);
- if (pns == m_pns) {
- return;
- }
- AddImport(str, pns);
- }
- }
- //
- // return true if this is really an import
- // or false if it's in our own namespace.
- //
- bool AddImport(INameSpaceInfo* pnsInfo)
- {
- ZString str = pnsInfo->GetName();
- int index = FindImport(pnsInfo->GetName());
- if (index == -1) {
- //
- // Didn't find it search local
- //
- IObject* pobject = m_pns->FindMemberLocal(pnsInfo->GetName());
- if (pobject == NULL) {
- AddImport(str, pnsInfo->GetNameSpace());
- return true;
- }
- return false;
- }
- return true;
- }
- void WriteString(const ZString& str)
- {
- m_pfile->Write(ObjectString);
- m_pfile->WriteAlignedString(str);
- }
- void WriteReference(const ZString& str)
- {
- int index = FindImport(str);
- if (index == -1) {
- index = 0;
- SymbolList::Iterator iter(m_pns->m_listSymbols);
- while (!iter.End()) {
- if (str == iter.Value().m_strName) {
- m_pfile->Write(ObjectReference);
- m_pfile->Write(index);
- return;
- }
- index++;
- iter.Next();
- }
- ZError("WriteReference: can't find " + str);
- } else {
- m_pfile->Write(ObjectImport);
- m_pfile->Write(index);
- }
- }
- void WriteApply()
- {
- m_pfile->Write(ObjectApply);
- }
- ZFile* WriteBinary()
- {
- m_pfile->Write(ObjectBinary);
- return m_pfile;
- }
- void WriteList(DWORD count)
- {
- m_pfile->Write(ObjectList);
- m_pfile->Write(count);
- }
- void WriteNumber(float value)
- {
- m_pfile->Write(ObjectFloat);
- m_pfile->Write(value);
- }
- void WriteBoolean(bool value)
- {
- if (value) {
- m_pfile->Write(ObjectTrue);
- } else {
- m_pfile->Write(ObjectFalse);
- }
- }
- void WritePair()
- {
- m_pfile->Write(ObjectPair);
- }
- void WriteEnd()
- {
- m_pfile->Write(ObjectEnd);
- }
- void CreateImportTable()
- {
- m_importDatas.SetCount(0);
- SymbolList::Iterator iter(m_pns->m_listSymbols);
- DWORD index = 0;
- while (!iter.End()) {
- Value* pvalue; CastTo(pvalue, iter.Value().m_pobject);
- pvalue->FillImportTable(this);
- iter.Next();
- }
- }
- void Write()
- {
- CreateImportTable();
- //
- // write out the header
- //
- m_pfile->Write(MDLMagic );
- m_pfile->Write(MDLVersion );
- m_pfile->Write(m_pnss.GetCount() ); // imported libraries
- m_pfile->Write(m_importDatas.GetCount() ); // imported symbols
- m_pfile->Write(m_pns->m_listSymbols.GetCount()); // exported symbols
- m_pfile->Write(0 ); // other defined objects
- //
- // write out used libraries
- //
- {
- int count = m_pnss.GetCount();
- for (int index = 0; index < count; index++) {
- const ZString& str = m_pnss[index]->GetName();
- m_pfile->WriteAlignedString(str);
- }
- }
- //
- // write out imported symbols
- //
- {
- int count = m_importDatas.GetCount();
- for (int index = 0; index < count; index++) {
- const ImportData& data = m_importDatas[index];
- m_pfile->Write(data.m_indexNameSpaceTable);
- m_pfile->WriteAlignedString(data.m_str);
- }
- }
- //
- // write out exported symbols
- //
- {
- SymbolList::Iterator iter(m_pns->m_listSymbols);
- while (!iter.End()) {
- const ZString& str = iter.Value().m_strName;
- m_pfile->WriteAlignedString(str);
- iter.Next();
- }
- }
- //
- // write out definitions
- //
- {
- SymbolList::Iterator iter(m_pns->m_listSymbols);
- DWORD index = 0;
- while (!iter.End()) {
- Value* pvalue; CastTo(pvalue, iter.Value().m_pobject);
- m_pfile->Write(index);
- pvalue->Write(this);
- m_pfile->Write(ObjectEnd);
- index++;
- iter.Next();
- }
- }
- }
- };
- friend class MDLBinaryFile;
- void WriteToBinaryFile(ZFile* pfile)
- {
- TRef<MDLBinaryFile> pmdlFile = new MDLBinaryFile(this, pfile);
- pmdlFile->Write();
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Functions for writing to a text file
- //
- //////////////////////////////////////////////////////////////////////////////
- void WriteToTextFile(int indent, ZFile* pfile)
- {
- //
- // write out used libraries
- //
- {
- INameSpaceList::Iterator iter(m_listParents);
- while (!iter.End()) {
- INameSpace* pns = iter.Value();
- pfile->Write(
- Value::Indent(indent ) + "use \"" + pns->GetName() + "\";\n"
- );
- iter.Next();
- }
- if (!m_listParents.IsEmpty()) {
- pfile->Write("\n");
- }
- }
- //
- // write out definitions
- //
- {
- SymbolList::Iterator iter(m_listSymbols);
- while (!iter.End()) {
- const SymbolData& data = iter.Value();
- Value* pvalue; CastTo(pvalue, (IObject*)data.m_pobject);
- pfile->Write(
- Value::Indent(indent ) + data.m_strName + " = \n"
- + Value::Indent(indent + 1) + pvalue->GetString(indent + 1) + ";\n\n"
- );
- iter.Next();
- }
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Constructors
- //
- //////////////////////////////////////////////////////////////////////////////
- TRef<INameSpace> CreateNameSpace(const ZString& strName)
- {
- return new NameSpaceImpl(strName);
- }
- TRef<INameSpace> CreateNameSpace(const ZString& strName, INameSpace* pnsParent)
- {
- return new NameSpaceImpl(strName, pnsParent);
- }
- TRef<INameSpace> CreateNameSpace(const ZString& strName, INameSpaceList& parents)
- {
- return new NameSpaceImpl(strName, parents);
- }
|