namespace.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. #include "pch.h"
  2. class NameSpaceInfo : public INameSpaceInfo {
  3. private:
  4. INameSpace* m_pns;
  5. ZString m_str;
  6. public:
  7. NameSpaceInfo(INameSpace* pns, const ZString& str) :
  8. m_pns(pns),
  9. m_str(str)
  10. {
  11. }
  12. INameSpace* GetNameSpace()
  13. {
  14. return m_pns;
  15. }
  16. const ZString& GetName()
  17. {
  18. return m_str;
  19. }
  20. };
  21. TRef<INameSpaceInfo> CreateNameSpaceInfo(INameSpace* pns, const ZString& str)
  22. {
  23. return new NameSpaceInfo(pns, str);
  24. }
  25. //////////////////////////////////////////////////////////////////////////////
  26. //
  27. // NameSpace
  28. //
  29. //////////////////////////////////////////////////////////////////////////////
  30. class NameSpaceImpl : public INameSpace {
  31. private:
  32. //////////////////////////////////////////////////////////////////////////////
  33. //
  34. // types
  35. //
  36. //////////////////////////////////////////////////////////////////////////////
  37. class SymbolData {
  38. public:
  39. ZString m_strName;
  40. TRef<IObject> m_pobject;
  41. SymbolData(){}
  42. SymbolData(const ZString& strName, TRef<IObject> pobject) :
  43. m_strName(strName),
  44. m_pobject(pobject)
  45. {
  46. }
  47. SymbolData(const SymbolData& data) :
  48. m_strName(data.m_strName),
  49. m_pobject(data.m_pobject)
  50. {
  51. }
  52. };
  53. typedef TList<SymbolData, DefaultNoEquals> SymbolList;
  54. class TypeData {
  55. public:
  56. ZString m_strName;
  57. TRef<MDLType> m_ptype;
  58. };
  59. typedef TList<TypeData, DefaultNoEquals> TypeList;
  60. //////////////////////////////////////////////////////////////////////////////
  61. //
  62. // data members
  63. //
  64. //////////////////////////////////////////////////////////////////////////////
  65. ZString m_strName;
  66. INameSpaceList m_listParents;
  67. SymbolList m_listSymbols;
  68. TypeList m_listTypes;
  69. //////////////////////////////////////////////////////////////////////////////
  70. //
  71. // methods
  72. //
  73. //////////////////////////////////////////////////////////////////////////////
  74. public:
  75. NameSpaceImpl(const ZString& strName) :
  76. m_strName(strName)
  77. {
  78. }
  79. NameSpaceImpl(const ZString& strName, INameSpace* pnsParent) :
  80. m_strName(strName)
  81. {
  82. m_listParents.PushFront(pnsParent);
  83. }
  84. NameSpaceImpl(const ZString& strName, INameSpaceList& parents) :
  85. m_strName(strName),
  86. m_listParents(parents)
  87. {
  88. // !!! should make an ordered list of parents so we don't search
  89. // any parent more than once.
  90. }
  91. //////////////////////////////////////////////////////////////////////////////
  92. //
  93. // INameSpace methods
  94. //
  95. //////////////////////////////////////////////////////////////////////////////
  96. const ZString& GetName()
  97. {
  98. return m_strName;
  99. }
  100. void AddMember(const ZString& strName, IObject* pobject)
  101. {
  102. ZAssert(FindMemberLocal(strName) == NULL);
  103. m_listSymbols.PushEnd(SymbolData(strName, pobject));
  104. //
  105. // !!! this is a total hack, only do this on Debug builds since it
  106. // requires dynamic casting. MDLC is always built debug so it's
  107. // ok.
  108. //
  109. #if defined(_DEBUG) && !defined(DREAMCAST)
  110. Value* pvalue = dynamic_cast<Value*>(pobject);
  111. if (pvalue != NULL) {
  112. pvalue->SetNameSpaceInfo(CreateNameSpaceInfo(this, strName));
  113. }
  114. #endif
  115. }
  116. IObject* FindMemberLocal(const ZString& str)
  117. {
  118. SymbolList::Iterator iter(m_listSymbols);
  119. while (!iter.End()) {
  120. const SymbolData& data = iter.Value();
  121. if (data.m_strName == str) {
  122. return data.m_pobject;
  123. }
  124. iter.Next();
  125. }
  126. return NULL;
  127. }
  128. IObject* FindMemberAndNameSpace(const ZString& str, INameSpace*& pns)
  129. {
  130. IObject* pobject = FindMemberLocal(str);
  131. if (pobject != NULL) {
  132. pns = this;
  133. return pobject;
  134. }
  135. INameSpaceList::Iterator iter(m_listParents);
  136. while (!iter.End()) {
  137. pobject = iter.Value()->FindMemberAndNameSpace(str, pns);
  138. if (pobject != NULL) {
  139. return pobject;
  140. }
  141. iter.Next();
  142. }
  143. return NULL;
  144. }
  145. IObject* FindMember(const ZString& str)
  146. {
  147. INameSpace* pns;
  148. return FindMemberAndNameSpace(str, pns);
  149. }
  150. //////////////////////////////////////////////////////////////////////////////
  151. //
  152. // Types
  153. //
  154. //////////////////////////////////////////////////////////////////////////////
  155. void AddType(const ZString& strName, MDLType* ptype)
  156. {
  157. ZAssert(FindTypeLocal(strName) == NULL);
  158. m_listTypes.PushEnd();
  159. m_listTypes.GetEnd().m_strName = strName;
  160. m_listTypes.GetEnd().m_ptype = ptype;
  161. }
  162. MDLType* FindTypeLocal(const ZString& strName)
  163. {
  164. TypeList::Iterator iter(m_listTypes);
  165. while (!iter.End()) {
  166. const TypeData& data = iter.Value();
  167. if (data.m_strName == strName) {
  168. return data.m_ptype;
  169. }
  170. iter.Next();
  171. }
  172. return NULL;
  173. }
  174. MDLType* FindTypeAndNameSpace(const ZString& str, NameSpaceImpl*& pns)
  175. {
  176. MDLType* ptype = FindTypeLocal(str);
  177. if (ptype != NULL) {
  178. pns = this;
  179. return ptype;
  180. }
  181. INameSpaceList::Iterator iter(m_listParents);
  182. while (!iter.End()) {
  183. NameSpaceImpl* pnsImpl; CastTo(pnsImpl, iter.Value());
  184. ptype = pnsImpl->FindTypeAndNameSpace(str, pns);
  185. if (ptype != NULL) {
  186. return ptype;
  187. }
  188. iter.Next();
  189. }
  190. return NULL;
  191. }
  192. MDLType* FindType(const ZString& strName)
  193. {
  194. NameSpaceImpl* pns;
  195. return FindTypeAndNameSpace(strName, pns);
  196. }
  197. void WriteTypeHeader(ZFile* pfile)
  198. {
  199. TypeList::Iterator iter(m_listTypes);
  200. while (!iter.End()) {
  201. const TypeData& data = iter.Value();
  202. iter.Next();
  203. if (data.m_ptype->IsStruct()) {
  204. pfile->Write(GetStructHeader(data.m_ptype, data.m_strName));
  205. if (!iter.End()) {
  206. pfile->Write(ZString("\n"));
  207. }
  208. }
  209. }
  210. }
  211. //////////////////////////////////////////////////////////////////////////////
  212. //
  213. // Binary File Writer
  214. //
  215. //////////////////////////////////////////////////////////////////////////////
  216. class MDLBinaryFile : public IMDLBinaryFile {
  217. private:
  218. class ImportData {
  219. public:
  220. DWORD m_indexNameSpaceTable;
  221. ZString m_str;
  222. };
  223. TVector<TRef<INameSpace> > m_pnss;
  224. TVector<ImportData> m_importDatas;
  225. TRef<NameSpaceImpl> m_pns;
  226. TRef<ZFile> m_pfile;
  227. public:
  228. MDLBinaryFile(NameSpaceImpl* pns, ZFile* pfile) :
  229. m_pns(pns),
  230. m_pfile(pfile)
  231. {
  232. }
  233. int FindImport(const ZString& str)
  234. {
  235. int count = m_importDatas.GetCount();
  236. for (int index = 0; index < count; index++) {
  237. if (m_importDatas[index].m_str == str) {
  238. return index;
  239. }
  240. }
  241. return -1;
  242. }
  243. void AddImport(const ZString& str, INameSpace* pns)
  244. {
  245. int count = m_pnss.GetCount();
  246. for (int index = 0; index < count; index++) {
  247. if (m_pnss[index] == pns) {
  248. break;
  249. }
  250. }
  251. //
  252. // Do we need to add a new namespace to the namespace import list?
  253. //
  254. if (index == count) {
  255. m_pnss.PushEnd(pns);
  256. }
  257. //
  258. // Add the new import symbol
  259. //
  260. m_importDatas.PushEnd();
  261. ImportData& data = m_importDatas.GetEnd();
  262. data.m_indexNameSpaceTable = index;
  263. data.m_str = str;
  264. }
  265. void AddImport(const ZString& str)
  266. {
  267. int index = FindImport(str);
  268. if (index == -1) {
  269. INameSpace* pns;
  270. IObject* pobject = m_pns->FindMemberAndNameSpace(str, pns);
  271. ZAssert(pobject != NULL);
  272. if (pns == m_pns) {
  273. return;
  274. }
  275. AddImport(str, pns);
  276. }
  277. }
  278. //
  279. // return true if this is really an import
  280. // or false if it's in our own namespace.
  281. //
  282. bool AddImport(INameSpaceInfo* pnsInfo)
  283. {
  284. ZString str = pnsInfo->GetName();
  285. int index = FindImport(pnsInfo->GetName());
  286. if (index == -1) {
  287. //
  288. // Didn't find it search local
  289. //
  290. IObject* pobject = m_pns->FindMemberLocal(pnsInfo->GetName());
  291. if (pobject == NULL) {
  292. AddImport(str, pnsInfo->GetNameSpace());
  293. return true;
  294. }
  295. return false;
  296. }
  297. return true;
  298. }
  299. void WriteString(const ZString& str)
  300. {
  301. m_pfile->Write(ObjectString);
  302. m_pfile->WriteAlignedString(str);
  303. }
  304. void WriteReference(const ZString& str)
  305. {
  306. int index = FindImport(str);
  307. if (index == -1) {
  308. index = 0;
  309. SymbolList::Iterator iter(m_pns->m_listSymbols);
  310. while (!iter.End()) {
  311. if (str == iter.Value().m_strName) {
  312. m_pfile->Write(ObjectReference);
  313. m_pfile->Write(index);
  314. return;
  315. }
  316. index++;
  317. iter.Next();
  318. }
  319. ZError("WriteReference: can't find " + str);
  320. } else {
  321. m_pfile->Write(ObjectImport);
  322. m_pfile->Write(index);
  323. }
  324. }
  325. void WriteApply()
  326. {
  327. m_pfile->Write(ObjectApply);
  328. }
  329. ZFile* WriteBinary()
  330. {
  331. m_pfile->Write(ObjectBinary);
  332. return m_pfile;
  333. }
  334. void WriteList(DWORD count)
  335. {
  336. m_pfile->Write(ObjectList);
  337. m_pfile->Write(count);
  338. }
  339. void WriteNumber(float value)
  340. {
  341. m_pfile->Write(ObjectFloat);
  342. m_pfile->Write(value);
  343. }
  344. void WriteBoolean(bool value)
  345. {
  346. if (value) {
  347. m_pfile->Write(ObjectTrue);
  348. } else {
  349. m_pfile->Write(ObjectFalse);
  350. }
  351. }
  352. void WritePair()
  353. {
  354. m_pfile->Write(ObjectPair);
  355. }
  356. void WriteEnd()
  357. {
  358. m_pfile->Write(ObjectEnd);
  359. }
  360. void CreateImportTable()
  361. {
  362. m_importDatas.SetCount(0);
  363. SymbolList::Iterator iter(m_pns->m_listSymbols);
  364. DWORD index = 0;
  365. while (!iter.End()) {
  366. Value* pvalue; CastTo(pvalue, iter.Value().m_pobject);
  367. pvalue->FillImportTable(this);
  368. iter.Next();
  369. }
  370. }
  371. void Write()
  372. {
  373. CreateImportTable();
  374. //
  375. // write out the header
  376. //
  377. m_pfile->Write(MDLMagic );
  378. m_pfile->Write(MDLVersion );
  379. m_pfile->Write(m_pnss.GetCount() ); // imported libraries
  380. m_pfile->Write(m_importDatas.GetCount() ); // imported symbols
  381. m_pfile->Write(m_pns->m_listSymbols.GetCount()); // exported symbols
  382. m_pfile->Write(0 ); // other defined objects
  383. //
  384. // write out used libraries
  385. //
  386. {
  387. int count = m_pnss.GetCount();
  388. for (int index = 0; index < count; index++) {
  389. const ZString& str = m_pnss[index]->GetName();
  390. m_pfile->WriteAlignedString(str);
  391. }
  392. }
  393. //
  394. // write out imported symbols
  395. //
  396. {
  397. int count = m_importDatas.GetCount();
  398. for (int index = 0; index < count; index++) {
  399. const ImportData& data = m_importDatas[index];
  400. m_pfile->Write(data.m_indexNameSpaceTable);
  401. m_pfile->WriteAlignedString(data.m_str);
  402. }
  403. }
  404. //
  405. // write out exported symbols
  406. //
  407. {
  408. SymbolList::Iterator iter(m_pns->m_listSymbols);
  409. while (!iter.End()) {
  410. const ZString& str = iter.Value().m_strName;
  411. m_pfile->WriteAlignedString(str);
  412. iter.Next();
  413. }
  414. }
  415. //
  416. // write out definitions
  417. //
  418. {
  419. SymbolList::Iterator iter(m_pns->m_listSymbols);
  420. DWORD index = 0;
  421. while (!iter.End()) {
  422. Value* pvalue; CastTo(pvalue, iter.Value().m_pobject);
  423. m_pfile->Write(index);
  424. pvalue->Write(this);
  425. m_pfile->Write(ObjectEnd);
  426. index++;
  427. iter.Next();
  428. }
  429. }
  430. }
  431. };
  432. friend class MDLBinaryFile;
  433. void WriteToBinaryFile(ZFile* pfile)
  434. {
  435. TRef<MDLBinaryFile> pmdlFile = new MDLBinaryFile(this, pfile);
  436. pmdlFile->Write();
  437. }
  438. //////////////////////////////////////////////////////////////////////////////
  439. //
  440. // Functions for writing to a text file
  441. //
  442. //////////////////////////////////////////////////////////////////////////////
  443. void WriteToTextFile(int indent, ZFile* pfile)
  444. {
  445. //
  446. // write out used libraries
  447. //
  448. {
  449. INameSpaceList::Iterator iter(m_listParents);
  450. while (!iter.End()) {
  451. INameSpace* pns = iter.Value();
  452. pfile->Write(
  453. Value::Indent(indent ) + "use \"" + pns->GetName() + "\";\n"
  454. );
  455. iter.Next();
  456. }
  457. if (!m_listParents.IsEmpty()) {
  458. pfile->Write("\n");
  459. }
  460. }
  461. //
  462. // write out definitions
  463. //
  464. {
  465. SymbolList::Iterator iter(m_listSymbols);
  466. while (!iter.End()) {
  467. const SymbolData& data = iter.Value();
  468. Value* pvalue; CastTo(pvalue, (IObject*)data.m_pobject);
  469. pfile->Write(
  470. Value::Indent(indent ) + data.m_strName + " = \n"
  471. + Value::Indent(indent + 1) + pvalue->GetString(indent + 1) + ";\n\n"
  472. );
  473. iter.Next();
  474. }
  475. }
  476. }
  477. };
  478. //////////////////////////////////////////////////////////////////////////////
  479. //
  480. // Constructors
  481. //
  482. //////////////////////////////////////////////////////////////////////////////
  483. TRef<INameSpace> CreateNameSpace(const ZString& strName)
  484. {
  485. return new NameSpaceImpl(strName);
  486. }
  487. TRef<INameSpace> CreateNameSpace(const ZString& strName, INameSpace* pnsParent)
  488. {
  489. return new NameSpaceImpl(strName, pnsParent);
  490. }
  491. TRef<INameSpace> CreateNameSpace(const ZString& strName, INameSpaceList& parents)
  492. {
  493. return new NameSpaceImpl(strName, parents);
  494. }