/Aurora/AuroraDotNetEngine/CompilerTools/LSL2CSCodeTransformer.cs

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