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