PageRenderTime 38ms CodeModel.GetById 19ms app.highlight 15ms RepoModel.GetById 0ms app.codeStats 0ms

/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
 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}