PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Aurora/AuroraDotNetEngine/CompilerTools/LSL2CSCodeTransformer.cs

https://bitbucket.org/VirtualReality/aurora-sim
C# | 620 lines | 457 code | 23 blank | 140 comment | 94 complexity | 94015ffeafd85fdf15df9da041ad810c MD5 | raw file
  1. /*
  2. * Copyright (c) Contributors, http://aurora-sim.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the Aurora-Sim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System.Collections.Generic;
  28. using Tools;
  29. using Aurora.ScriptEngineParser;
  30. namespace Aurora.ScriptEngine.AuroraDotNetEngine.CompilerTools
  31. {
  32. public class LSL2CSCodeTransformer
  33. {
  34. private static Dictionary<string, string> m_datatypeLSL2OpenSim;
  35. private readonly SYMBOL m_astRoot;
  36. private readonly Dictionary<string, string> m_globalVariableValues = new Dictionary<string, string>();
  37. private readonly Dictionary<string, SYMBOL> m_duplicatedGlobalVariableValues = new Dictionary<string, SYMBOL>();
  38. private Dictionary<string, Dictionary<string, SYMBOL>> m_localVariableValues = new Dictionary<string, Dictionary<string, SYMBOL>>();
  39. private Dictionary<string, Dictionary<string, string>> m_localVariableValuesStr = new Dictionary<string, Dictionary<string, string>>();
  40. private Dictionary<string, Dictionary<string, int>> m_localVariableScope = new Dictionary<string, Dictionary<string, int>>();
  41. private readonly Dictionary<string, Dictionary<string, SYMBOL>> m_duplicatedLocalVariableValues = new Dictionary<string, Dictionary<string, SYMBOL>>();
  42. private string m_currentEvent = "";
  43. private string m_currentState = "";
  44. public Dictionary<string, SYMBOL> DuplicatedGlobalVars
  45. {
  46. get { return m_duplicatedGlobalVariableValues; }
  47. }
  48. public Dictionary<string, string> GlobalVars
  49. {
  50. get { return m_globalVariableValues; }
  51. }
  52. public Dictionary<string, Dictionary<string, SYMBOL>> DuplicatedLocalVars
  53. {
  54. get { return m_duplicatedLocalVariableValues; }
  55. }
  56. public Dictionary<string, Dictionary<string, SYMBOL>> LocalVars
  57. {
  58. get { return m_localVariableValues; }
  59. }
  60. /// <summary>
  61. /// Pass the new CodeTranformer an abstract syntax tree.
  62. /// </summary>
  63. /// <param name = "astRoot">The root node of the AST.</param>
  64. public LSL2CSCodeTransformer(SYMBOL astRoot)
  65. {
  66. m_astRoot = astRoot;
  67. // let's populate the dictionary
  68. if (null == m_datatypeLSL2OpenSim)
  69. {
  70. m_datatypeLSL2OpenSim = new Dictionary<string, string>
  71. {
  72. {"integer", "LSL_Types.LSLInteger"},
  73. {"float", "LSL_Types.LSLFloat"},
  74. {"key", "LSL_Types.LSLString"},
  75. {"string", "LSL_Types.LSLString"},
  76. {"vector", "LSL_Types.Vector3"},
  77. {"rotation", "LSL_Types.Quaternion"},
  78. {"list", "LSL_Types.list"}
  79. };
  80. }
  81. }
  82. /// <summary>
  83. /// Transform the code in the AST we have.
  84. /// </summary>
  85. /// <returns>The root node of the transformed AST</returns>
  86. public SYMBOL Transform()
  87. {
  88. return Transform(null, null);
  89. }
  90. public SYMBOL Transform(Dictionary<string, string> GlobalMethods,
  91. Dictionary<string, ObjectList> MethodArguements)
  92. {
  93. foreach (SYMBOL s in m_astRoot.kids)
  94. TransformNode(s, GlobalMethods, MethodArguements);
  95. return m_astRoot;
  96. }
  97. /// <summary>
  98. /// Recursively called to transform each type of node. Will transform this
  99. /// node, then all it's children.
  100. /// </summary>
  101. /// <param name = "s">The current node to transform.</param>
  102. /// <param name="GlobalMethods"> </param>
  103. /// <param name="MethodArguements"> </param>
  104. private void TransformNode(SYMBOL s, Dictionary<string, string> GlobalMethods,
  105. Dictionary<string, ObjectList> MethodArguements)
  106. {
  107. TransformNode(s, GlobalMethods, MethodArguements, new List<int>(), 0);
  108. }
  109. /// <summary>
  110. /// Recursively called to transform each type of node. Will transform this
  111. /// node, then all it's children.
  112. /// </summary>
  113. /// <param name = "s">The current node to transform.</param>
  114. /// <param name="GlobalMethods"> </param>
  115. /// <param name="MethodArguements"> </param>
  116. /// <param name="scopesParent"> </param>
  117. /// <param name="scopeCurrent"> </param>
  118. private void TransformNode(SYMBOL s, Dictionary<string, string> GlobalMethods,
  119. Dictionary<string, ObjectList> MethodArguements, List<int> scopesParent, int scopeCurrent)
  120. {
  121. // make sure to put type lower in the inheritance hierarchy first
  122. // ie: since IdentConstant and StringConstant inherit from Constant,
  123. // put IdentConstant and StringConstant before Constant
  124. if (s is Declaration)
  125. {
  126. Declaration dec = (Declaration)s;
  127. dec.Datatype = m_datatypeLSL2OpenSim[dec.Datatype];
  128. }
  129. else if (s is Constant)
  130. ((Constant)s).Type = m_datatypeLSL2OpenSim[((Constant)s).Type];
  131. else if (s is TypecastExpression)
  132. ((TypecastExpression)s).TypecastType = m_datatypeLSL2OpenSim[((TypecastExpression)s).TypecastType];
  133. else if (s is GlobalFunctionDefinition)
  134. {
  135. GlobalFunctionDefinition fun = (GlobalFunctionDefinition)s;
  136. if ("void" == fun.ReturnType) // we don't need to translate "void"
  137. {
  138. if (GlobalMethods != null && !GlobalMethods.ContainsKey(fun.Name))
  139. GlobalMethods.Add(fun.Name, "void");
  140. }
  141. else
  142. {
  143. fun.ReturnType =
  144. m_datatypeLSL2OpenSim[fun.ReturnType];
  145. if (GlobalMethods != null && !GlobalMethods.ContainsKey(fun.Name))
  146. {
  147. GlobalMethods.Add(fun.Name, fun.ReturnType);
  148. MethodArguements.Add(fun.Name, (s).kids);
  149. }
  150. }
  151. //Reset the variables, we changed events
  152. m_currentEvent = fun.Name;
  153. m_localVariableValues.Add("global_function_" + fun.Name, new Dictionary<string, SYMBOL>());
  154. m_localVariableValuesStr.Add("global_function_" + fun.Name, new Dictionary<string, string>());
  155. m_duplicatedLocalVariableValues.Add("global_function_" + fun.Name, new Dictionary<string, SYMBOL>());
  156. m_localVariableScope.Add("global_function_" + fun.Name, new Dictionary<string, int>());
  157. // this is a new function, lets clear the parent scopes and set the current scope to this
  158. scopesParent.Clear();
  159. scopeCurrent = s.pos;
  160. scopesParent.Add(scopeCurrent);
  161. }
  162. else if (s is State)
  163. {
  164. //Reset the variables, we changed events
  165. State evt = (State)s;
  166. m_currentState = evt.Name;
  167. }
  168. else if (s is StateEvent)
  169. {
  170. //Reset the variables, we changed events
  171. StateEvent evt = (StateEvent)s;
  172. m_currentEvent = evt.Name;
  173. m_localVariableValues.Add(m_currentState + "_" + evt.Name, new Dictionary<string, SYMBOL>());
  174. m_localVariableValuesStr.Add(m_currentState + "_" + evt.Name, new Dictionary<string, string>());
  175. m_duplicatedLocalVariableValues.Add(m_currentState + "_" + evt.Name, new Dictionary<string, SYMBOL>());
  176. m_localVariableScope.Add(m_currentState + "_" + evt.Name, new Dictionary<string, int>());
  177. // this is a new state event, lets clear the parent scopes and set the current scope to this
  178. scopesParent.Clear();
  179. scopeCurrent = s.pos;
  180. scopesParent.Add(scopeCurrent);
  181. }
  182. else if (s is GlobalVariableDeclaration)
  183. {
  184. GlobalVariableDeclaration gvd = (GlobalVariableDeclaration)s;
  185. foreach (SYMBOL child in gvd.kids)
  186. {
  187. if (child is Assignment)
  188. {
  189. bool isDeclaration = false;
  190. string decID = "";
  191. foreach (SYMBOL assignmentChild in child.kids)
  192. {
  193. if (assignmentChild is Declaration)
  194. {
  195. Declaration d = (Declaration)assignmentChild;
  196. decID = d.Id;
  197. isDeclaration = true;
  198. }
  199. else if (assignmentChild is IdentExpression)
  200. {
  201. IdentExpression identEx = (IdentExpression)assignmentChild;
  202. if (isDeclaration)
  203. {
  204. if (m_globalVariableValues.ContainsKey(decID))
  205. m_duplicatedGlobalVariableValues[decID] = identEx;
  206. m_globalVariableValues[decID] = identEx.Name;
  207. }
  208. }
  209. else if (assignmentChild is ListConstant)
  210. {
  211. ListConstant listConst = (ListConstant)assignmentChild;
  212. foreach (SYMBOL listChild in listConst.kids)
  213. {
  214. if (listChild is ArgumentList)
  215. {
  216. ArgumentList argList = (ArgumentList)listChild;
  217. int i = 0;
  218. bool changed = false;
  219. object[] p = new object[argList.kids.Count];
  220. foreach (SYMBOL objChild in argList.kids)
  221. {
  222. p[i] = objChild;
  223. if (objChild is IdentExpression)
  224. {
  225. IdentExpression identEx = (IdentExpression)objChild;
  226. if (m_globalVariableValues.ContainsKey(identEx.Name))
  227. {
  228. changed = true;
  229. p[i] = new IdentExpression(identEx.yyps,
  230. m_globalVariableValues[identEx.Name])
  231. {
  232. pos = objChild.pos,
  233. m_dollar = objChild.m_dollar
  234. };
  235. }
  236. }
  237. i++;
  238. }
  239. if (changed)
  240. {
  241. argList.kids = new ObjectList();
  242. foreach (object o in p)
  243. argList.kids.Add(o);
  244. }
  245. if (isDeclaration)
  246. {
  247. if (m_globalVariableValues.ContainsKey(decID))
  248. m_duplicatedGlobalVariableValues[decID] = listConst;
  249. m_globalVariableValues[decID] = listConst.Value;
  250. }
  251. }
  252. }
  253. }
  254. else if (assignmentChild is VectorConstant || assignmentChild is RotationConstant)
  255. {
  256. Constant listConst = (Constant)assignmentChild;
  257. int i = 0;
  258. bool changed = false;
  259. object[] p = new object[listConst.kids.Count];
  260. foreach (SYMBOL objChild in listConst.kids)
  261. {
  262. p[i] = objChild;
  263. if (objChild is IdentExpression)
  264. {
  265. IdentExpression identEx = (IdentExpression)objChild;
  266. if (m_globalVariableValues.ContainsKey(identEx.Name))
  267. {
  268. changed = true;
  269. p[i] = new IdentExpression(identEx.yyps,
  270. m_globalVariableValues[identEx.Name])
  271. {
  272. pos = objChild.pos,
  273. m_dollar = objChild.m_dollar
  274. };
  275. }
  276. }
  277. i++;
  278. }
  279. if (changed)
  280. {
  281. listConst.kids = new ObjectList();
  282. foreach (object o in p)
  283. listConst.kids.Add(o);
  284. }
  285. if (isDeclaration)
  286. {
  287. if (m_globalVariableValues.ContainsKey(decID))
  288. m_duplicatedGlobalVariableValues[decID] = listConst;
  289. m_globalVariableValues[decID] = listConst.Value;
  290. }
  291. }
  292. else if (assignmentChild is Constant)
  293. {
  294. Constant identEx = (Constant)assignmentChild;
  295. if (isDeclaration)
  296. {
  297. if (m_globalVariableValues.ContainsKey(decID))
  298. m_duplicatedGlobalVariableValues[decID] = identEx;
  299. m_globalVariableValues[decID] = identEx.Value;
  300. }
  301. }
  302. }
  303. }
  304. }
  305. }
  306. else if (s is Assignment && m_currentEvent != "")
  307. {
  308. Assignment ass = (Assignment)s;
  309. bool isDeclaration = false;
  310. string decID = "";
  311. foreach (SYMBOL assignmentChild in ass.kids)
  312. {
  313. if (assignmentChild is Declaration)
  314. {
  315. Declaration d = (Declaration)assignmentChild;
  316. decID = d.Id;
  317. isDeclaration = true;
  318. }
  319. else if (assignmentChild is IdentExpression)
  320. {
  321. IdentExpression identEx = (IdentExpression)assignmentChild;
  322. if (isDeclaration)
  323. {
  324. if (m_localVariableValues[GetLocalVariableDictionaryKey()].ContainsKey(decID) &&
  325. !m_duplicatedLocalVariableValues[GetLocalVariableDictionaryKey()].ContainsKey(decID) &&
  326. scopesParent.Contains(m_localVariableScope[GetLocalVariableDictionaryKey()][decID]))
  327. m_duplicatedLocalVariableValues[GetLocalVariableDictionaryKey()][decID] = m_localVariableValues[GetLocalVariableDictionaryKey()][decID];
  328. m_localVariableValues[GetLocalVariableDictionaryKey()][decID] = identEx;
  329. m_localVariableValuesStr[GetLocalVariableDictionaryKey()][decID] = identEx.Name;
  330. m_localVariableScope[GetLocalVariableDictionaryKey()][decID] = scopeCurrent;
  331. }
  332. }
  333. else if (assignmentChild is ListConstant)
  334. {
  335. ListConstant listConst = (ListConstant)assignmentChild;
  336. foreach (SYMBOL listChild in listConst.kids)
  337. {
  338. if (listChild is ArgumentList)
  339. {
  340. ArgumentList argList = (ArgumentList)listChild;
  341. int i = 0;
  342. bool changed = false;
  343. object[] p = new object[argList.kids.Count];
  344. foreach (SYMBOL objChild in argList.kids)
  345. {
  346. p[i] = objChild;
  347. if (objChild is IdentExpression)
  348. {
  349. IdentExpression identEx = (IdentExpression)objChild;
  350. if (m_localVariableValues[GetLocalVariableDictionaryKey()].ContainsKey(identEx.Name))
  351. {
  352. changed = true;
  353. p[i] = new IdentExpression(identEx.yyps,
  354. m_localVariableValuesStr[GetLocalVariableDictionaryKey()][identEx.Name])
  355. {
  356. pos = objChild.pos,
  357. m_dollar = objChild.m_dollar
  358. };
  359. }
  360. }
  361. i++;
  362. }
  363. if (changed)
  364. {
  365. argList.kids = new ObjectList();
  366. foreach (object o in p)
  367. argList.kids.Add(o);
  368. }
  369. if (isDeclaration)
  370. {
  371. if (m_localVariableValues[GetLocalVariableDictionaryKey()].ContainsKey(decID) &&
  372. !m_duplicatedLocalVariableValues[GetLocalVariableDictionaryKey()].ContainsKey(decID) &&
  373. scopesParent.Contains(m_localVariableScope[GetLocalVariableDictionaryKey()][decID]))
  374. m_duplicatedLocalVariableValues[GetLocalVariableDictionaryKey()][decID] = m_localVariableValues[GetLocalVariableDictionaryKey()][decID];
  375. m_localVariableValues[GetLocalVariableDictionaryKey()][decID] = listConst;
  376. m_localVariableValuesStr[GetLocalVariableDictionaryKey()][decID] = listConst.Value;
  377. m_localVariableScope[GetLocalVariableDictionaryKey()][decID] = scopeCurrent;
  378. }
  379. }
  380. }
  381. }
  382. else if (assignmentChild is VectorConstant || assignmentChild is RotationConstant)
  383. {
  384. Constant listConst = (Constant)assignmentChild;
  385. int i = 0;
  386. bool changed = false;
  387. object[] p = new object[listConst.kids.Count];
  388. foreach (SYMBOL objChild in listConst.kids)
  389. {
  390. p[i] = objChild;
  391. if (objChild is IdentExpression)
  392. {
  393. IdentExpression identEx = (IdentExpression)objChild;
  394. if (m_localVariableValues[GetLocalVariableDictionaryKey()].ContainsKey(identEx.Name))
  395. {
  396. changed = true;
  397. p[i] = new IdentExpression(identEx.yyps,
  398. m_localVariableValuesStr[GetLocalVariableDictionaryKey()][identEx.Name])
  399. {
  400. pos = objChild.pos,
  401. m_dollar = objChild.m_dollar
  402. };
  403. }
  404. }
  405. i++;
  406. }
  407. if (changed)
  408. {
  409. listConst.kids = new ObjectList();
  410. foreach (object o in p)
  411. listConst.kids.Add(o);
  412. }
  413. if (isDeclaration)
  414. {
  415. if (m_localVariableValues[GetLocalVariableDictionaryKey()].ContainsKey(decID) &&
  416. !m_duplicatedLocalVariableValues[GetLocalVariableDictionaryKey()].ContainsKey(decID) &&
  417. scopesParent.Contains(m_localVariableScope[GetLocalVariableDictionaryKey()][decID]))
  418. m_duplicatedLocalVariableValues[GetLocalVariableDictionaryKey()][decID] = m_localVariableValues[GetLocalVariableDictionaryKey()][decID];
  419. m_localVariableValues[GetLocalVariableDictionaryKey()][decID] = listConst;
  420. m_localVariableValuesStr[GetLocalVariableDictionaryKey()][decID] = listConst.Value;
  421. m_localVariableScope[GetLocalVariableDictionaryKey()][decID] = scopeCurrent;
  422. }
  423. }
  424. else if (assignmentChild is Constant)
  425. {
  426. Constant identEx = (Constant)assignmentChild;
  427. if (isDeclaration)
  428. {
  429. if (m_localVariableValues[GetLocalVariableDictionaryKey()].ContainsKey(decID) &&
  430. !m_duplicatedLocalVariableValues[GetLocalVariableDictionaryKey()].ContainsKey(decID) &&
  431. scopesParent.Contains(m_localVariableScope[GetLocalVariableDictionaryKey()][decID]))
  432. m_duplicatedLocalVariableValues[GetLocalVariableDictionaryKey()][decID] = m_localVariableValues[GetLocalVariableDictionaryKey()][decID];
  433. m_localVariableValues[GetLocalVariableDictionaryKey()][decID] = identEx;
  434. m_localVariableValuesStr[GetLocalVariableDictionaryKey()][decID] = identEx.Value;
  435. m_localVariableScope[GetLocalVariableDictionaryKey()][decID] = scopeCurrent;
  436. }
  437. }
  438. }
  439. }
  440. /*if(s is Statement)
  441. {
  442. if(s.kids.Count == 1 && s.kids[0] is Assignment)
  443. {
  444. Assignment assignment = (Assignment)s.kids[0];
  445. object[] p = new object[assignment.kids.Count];
  446. int i = 0;
  447. int toRemove = -1;
  448. foreach(SYMBOL assignmentChild in assignment.kids)
  449. {
  450. p[i] = assignmentChild;
  451. if(assignmentChild is Declaration)
  452. {
  453. Declaration d = (Declaration)assignmentChild;
  454. if(m_allVariableValues.Contains(d.Id))
  455. toRemove = i;
  456. else
  457. m_allVariableValues.Add(d.Id);
  458. }
  459. i++;
  460. }
  461. if(toRemove != -1)
  462. {
  463. List<object> ps = new List<object>();
  464. foreach(object obj in p)
  465. ps.Add(obj);
  466. ps[toRemove] = new IDENT(null)
  467. {
  468. kids = new ObjectList(),
  469. pos = ((SYMBOL)ps[toRemove]).pos,
  470. m_dollar = ((SYMBOL)ps[toRemove]).m_dollar,
  471. yylval = ((SYMBOL)ps[toRemove]).yylval,
  472. yylx = ((SYMBOL)ps[toRemove]).yylx,
  473. yyps = ((SYMBOL)ps[toRemove]).yyps,
  474. yytext = ps[toRemove] is Declaration ?
  475. ((Declaration)ps[toRemove]).Id
  476. : ((SYMBOL)ps[toRemove]).yyname,
  477. };
  478. ((SYMBOL)s.kids[0]).kids = new ObjectList();
  479. foreach(object obj in ps)
  480. if(obj != null)
  481. ((SYMBOL)s.kids[0]).kids.Add(obj);
  482. }
  483. }
  484. }*/
  485. for (int i = 0; i < s.kids.Count; i++)
  486. {
  487. // It's possible that a child is null, for instance when the
  488. // assignment part in a for-loop is left out, ie:
  489. //
  490. // for (; i < 10; i++)
  491. // {
  492. // ...
  493. // }
  494. //
  495. // We need to check for that here.
  496. if (null == s.kids[i]) continue;
  497. bool scopeAdded = false;
  498. // we need to keep track of the scope for dulicate variables
  499. if ((s is IfStatement) || (s is WhileStatement) || (s is ForLoopStatement) || (s is DoWhileStatement))
  500. {
  501. scopeCurrent = ((SYMBOL)s.kids[i]).pos;
  502. scopesParent.Add(scopeCurrent);
  503. scopeAdded = true;
  504. }
  505. if (!(s is Assignment || s is ArgumentDeclarationList) && s.kids[i] is Declaration)
  506. AddImplicitInitialization(s, i);
  507. TransformNode((SYMBOL)s.kids[i], null, null, scopesParent, scopeCurrent);
  508. // we need to remove the current scope from the parent since we are no longer in that scope
  509. if (scopeAdded)
  510. scopesParent.Remove(scopeCurrent);
  511. }
  512. }
  513. private string GetLocalVariableDictionaryKey()
  514. {
  515. if (m_currentState == "")
  516. return "global_function_" + m_currentEvent;
  517. return m_currentState + "_" + m_currentEvent;
  518. }
  519. /// <summary>
  520. /// Replaces an instance of the node at s.kids[didx] with an assignment
  521. /// node. The assignment node has the Declaration node on the left hand
  522. /// side and a default initializer on the right hand side.
  523. /// </summary>
  524. /// <param name = "s">
  525. /// The node containing the Declaration node that needs replacing.
  526. /// </param>
  527. /// <param name = "didx">Index of the Declaration node to replace.</param>
  528. private void AddImplicitInitialization(SYMBOL s, int didx)
  529. {
  530. // We take the kids for a while to play with them.
  531. int sKidSize = s.kids.Count;
  532. object[] sKids = new object[sKidSize];
  533. for (int i = 0; i < sKidSize; i++)
  534. sKids[i] = s.kids.Pop();
  535. // The child to be changed.
  536. Declaration currentDeclaration = (Declaration)sKids[didx];
  537. // We need an assignment node.
  538. Assignment newAssignment = new Assignment(currentDeclaration.yyps,
  539. currentDeclaration,
  540. GetZeroConstant(currentDeclaration.yyps,
  541. currentDeclaration.Datatype),
  542. "=");
  543. sKids[didx] = newAssignment;
  544. // Put the kids back where they belong.
  545. for (int i = 0; i < sKidSize; i++)
  546. s.kids.Add(sKids[i]);
  547. }
  548. /// <summary>
  549. /// Generates the node structure required to generate a default
  550. /// initialization.
  551. /// </summary>
  552. /// <param name = "p">
  553. /// Tools.Parser instance to use when instantiating nodes.
  554. /// </param>
  555. /// <param name = "constantType">String describing the datatype.</param>
  556. /// <returns>
  557. /// A SYMBOL node conaining the appropriate structure for intializing a
  558. /// constantType.
  559. /// </returns>
  560. private SYMBOL GetZeroConstant(Parser p, string constantType)
  561. {
  562. switch (constantType)
  563. {
  564. case "integer":
  565. return new Constant(p, constantType, "0");
  566. case "float":
  567. return new Constant(p, constantType, "0.0");
  568. case "string":
  569. case "key":
  570. return new Constant(p, constantType, "");
  571. case "list":
  572. ArgumentList al = new ArgumentList(p);
  573. return new ListConstant(p, al);
  574. case "vector":
  575. Constant vca = new Constant(p, "float", "0.0");
  576. Constant vcb = new Constant(p, "float", "0.0");
  577. Constant vcc = new Constant(p, "float", "0.0");
  578. ConstantExpression vcea = new ConstantExpression(p, vca);
  579. ConstantExpression vceb = new ConstantExpression(p, vcb);
  580. ConstantExpression vcec = new ConstantExpression(p, vcc);
  581. return new VectorConstant(p, vcea, vceb, vcec);
  582. case "rotation":
  583. Constant rca = new Constant(p, "float", "0.0");
  584. Constant rcb = new Constant(p, "float", "0.0");
  585. Constant rcc = new Constant(p, "float", "0.0");
  586. Constant rcd = new Constant(p, "float", "0.0");
  587. ConstantExpression rcea = new ConstantExpression(p, rca);
  588. ConstantExpression rceb = new ConstantExpression(p, rcb);
  589. ConstantExpression rcec = new ConstantExpression(p, rcc);
  590. ConstantExpression rced = new ConstantExpression(p, rcd);
  591. return new RotationConstant(p, rcea, rceb, rcec, rced);
  592. default:
  593. return null; // this will probably break stuff
  594. }
  595. }
  596. }
  597. }