From a73e3b4e3fdb6b563dddaa7f67d5fe69e65ca752 Mon Sep 17 00:00:00 2001
From: Johan Berntsson
Date: Tue, 8 Jul 2008 03:02:11 +0000
Subject: another patch from Mike: the llscript compiler is now available in
XEngine as well. Thanks Mike
---
.../Shared/CodeTools/CSCodeGenerator.cs | 803 +++++++++++++++++++++
1 file changed, 803 insertions(+)
create mode 100644 OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
(limited to 'OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs')
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
new file mode 100644
index 0000000..78c636e
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
@@ -0,0 +1,803 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using Tools;
+
+namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
+{
+ public class CSCodeGenerator
+ {
+ private SYMBOL m_astRoot = null;
+ private int m_braceCount; // for indentation
+
+ ///
+ /// Pass the new CodeGenerator a string containing the LSL source.
+ ///
+ /// String containing LSL source.
+ public CSCodeGenerator(string script)
+ {
+ Parser p = new LSLSyntax();
+ // Obviously this needs to be in a try/except block.
+ LSL2CSCodeTransformer codeTransformer = new LSL2CSCodeTransformer(p.Parse(script));
+ m_astRoot = codeTransformer.Transform();
+ }
+
+ ///
+ /// Pass the new CodeGenerator an abstract syntax tree.
+ ///
+ /// The root node of the AST.
+ public CSCodeGenerator(SYMBOL astRoot)
+ {
+ m_braceCount = 0;
+ m_astRoot = astRoot;
+ }
+
+ ///
+ /// Generate the code from the AST we have.
+ ///
+ /// String containing the generated C# code.
+ public string Generate()
+ {
+ string retstr = String.Empty;
+
+ // standard preamble
+ //retstr = "using OpenSim.Region.ScriptEngine.Common;\n";
+ //retstr += "using System.Collections.Generic;\n\n";
+ //retstr += "namespace SecondLife\n";
+ //retstr += "{\n";
+ //retstr += " public class Script : OpenSim.Region.ScriptEngine.Common\n";
+ //retstr += " {\n";
+
+ // here's the payload
+ m_braceCount += 2;
+ retstr += "\n";
+ foreach (SYMBOL s in m_astRoot.kids)
+ retstr += GenerateNode(s);
+
+ // close braces!
+ //retstr += " }\n";
+ //retstr += "}\n";
+ m_braceCount -= 2;
+
+ return retstr;
+ }
+
+ ///
+ /// Recursively called to generate each type of node. Will generate this
+ /// node, then all it's children.
+ ///
+ /// The current node to generate code for.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateNode(SYMBOL s)
+ {
+ string retstr = String.Empty;
+
+ // make sure to put type lower in the inheritance hierarchy first
+ // ie: since IdentArgument and ExpressionArgument inherit from
+ // Argument, put IdentArgument and ExpressionArgument before Argument
+ if (s is GlobalFunctionDefinition)
+ retstr += GenerateGlobalFunctionDefinition((GlobalFunctionDefinition) s);
+ else if (s is GlobalVariableDeclaration)
+ retstr += GenerateGlobalVariableDeclaration((GlobalVariableDeclaration) s);
+ else if (s is State)
+ retstr += GenerateState((State) s);
+ else if (s is CompoundStatement)
+ retstr += GenerateCompoundStatement((CompoundStatement) s);
+ else if (s is Declaration)
+ retstr += GenerateDeclaration((Declaration) s);
+ else if (s is Statement)
+ retstr += GenerateStatement((Statement) s);
+ else if (s is ReturnStatement)
+ retstr += GenerateReturnStatement((ReturnStatement) s);
+ else if (s is JumpLabel)
+ retstr += GenerateJumpLabel((JumpLabel) s);
+ else if (s is JumpStatement)
+ retstr += GenerateJumpStatement((JumpStatement) s);
+ else if (s is StateChange)
+ retstr += GenerateStateChange((StateChange) s);
+ else if (s is IfStatement)
+ retstr += GenerateIfStatement((IfStatement) s);
+ else if (s is WhileStatement)
+ retstr += GenerateWhileStatement((WhileStatement) s);
+ else if (s is DoWhileStatement)
+ retstr += GenerateDoWhileStatement((DoWhileStatement) s);
+ else if (s is ForLoop)
+ retstr += GenerateForLoop((ForLoop) s);
+ else if (s is ArgumentList)
+ retstr += GenerateArgumentList((ArgumentList) s);
+ else if (s is Assignment)
+ retstr += GenerateAssignment((Assignment) s);
+ else if (s is BinaryExpression)
+ retstr += GenerateBinaryExpression((BinaryExpression) s);
+ else if (s is ParenthesisExpression)
+ retstr += GenerateParenthesisExpression((ParenthesisExpression) s);
+ else if (s is UnaryExpression)
+ retstr += GenerateUnaryExpression((UnaryExpression) s);
+ else if (s is IncrementDecrementExpression)
+ retstr += GenerateIncrementDecrementExpression((IncrementDecrementExpression) s);
+ else if (s is TypecastExpression)
+ retstr += GenerateTypecastExpression((TypecastExpression) s);
+ else if (s is FunctionCall)
+ retstr += GenerateFunctionCall((FunctionCall) s);
+ else if (s is VectorConstant)
+ retstr += GenerateVectorConstant((VectorConstant) s);
+ else if (s is RotationConstant)
+ retstr += GenerateRotationConstant((RotationConstant) s);
+ else if (s is ListConstant)
+ retstr += GenerateListConstant((ListConstant) s);
+ else if (s is Constant)
+ retstr += GenerateConstant((Constant) s);
+ else if (s is IdentDotExpression)
+ retstr += ((IdentDotExpression) s).Name + "." + ((IdentDotExpression) s).Member;
+ else if (s is IdentExpression)
+ retstr += ((IdentExpression) s).Name;
+ else if (s is IDENT)
+ retstr += ((TOKEN) s).yytext;
+ else
+ {
+ foreach (SYMBOL kid in s.kids)
+ retstr += GenerateNode(kid);
+ }
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a GlobalFunctionDefinition node.
+ ///
+ /// The GlobalFunctionDefinition node.
+ /// String containing C# code for GlobalFunctionDefinition gf.
+ private string GenerateGlobalFunctionDefinition(GlobalFunctionDefinition gf)
+ {
+ string retstr = String.Empty;
+
+ // we need to separate the argument declaration list from other kids
+ List argumentDeclarationListKids = new List();
+ List remainingKids = new List();
+
+ foreach (SYMBOL kid in gf.kids)
+ if (kid is ArgumentDeclarationList)
+ argumentDeclarationListKids.Add(kid);
+ else
+ remainingKids.Add(kid);
+
+ retstr += WriteIndented(String.Format("{0} {1}(", gf.ReturnType, gf.Name));
+
+ // print the state arguments, if any
+ foreach (SYMBOL kid in argumentDeclarationListKids)
+ retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid);
+
+ retstr += ")\n";
+
+ foreach (SYMBOL kid in remainingKids)
+ retstr += GenerateNode(kid);
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a GlobalVariableDeclaration node.
+ ///
+ /// The GlobalVariableDeclaration node.
+ /// String containing C# code for GlobalVariableDeclaration gv.
+ private string GenerateGlobalVariableDeclaration(GlobalVariableDeclaration gv)
+ {
+ string retstr = String.Empty;
+
+ foreach (SYMBOL s in gv.kids)
+ {
+ retstr += Indent();
+ retstr += GenerateNode(s);
+ retstr += ";\n";
+ }
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a State node.
+ ///
+ /// The State node.
+ /// String containing C# code for State s.
+ private string GenerateState(State s)
+ {
+ string retstr = String.Empty;
+
+ foreach (SYMBOL kid in s.kids)
+ if (kid is StateEvent)
+ retstr += GenerateStateEvent((StateEvent) kid, s.Name);
+ else
+ retstr += String.Format("ERROR: State '{0}' contains a '{1}\n", s.Name, kid.GetType());
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a StateEvent node.
+ ///
+ /// The StateEvent node.
+ /// The name of the parent state.
+ /// String containing C# code for StateEvent se.
+ private string GenerateStateEvent(StateEvent se, string parentStateName)
+ {
+ string retstr = String.Empty;
+
+ // we need to separate the argument declaration list from other kids
+ List argumentDeclarationListKids = new List();
+ List remainingKids = new List();
+
+ foreach (SYMBOL kid in se.kids)
+ if (kid is ArgumentDeclarationList)
+ argumentDeclarationListKids.Add(kid);
+ else
+ remainingKids.Add(kid);
+
+ // "state" (function) declaration
+ retstr += WriteIndented(String.Format("public void {0}_event_{1}(", parentStateName, se.Name));
+
+ // print the state arguments, if any
+ foreach (SYMBOL kid in argumentDeclarationListKids)
+ retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid);
+
+ retstr += ")\n";
+
+ foreach (SYMBOL kid in remainingKids)
+ retstr += GenerateNode(kid);
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for an ArgumentDeclarationList node.
+ ///
+ /// The ArgumentDeclarationList node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateArgumentDeclarationList(ArgumentDeclarationList adl)
+ {
+ string retstr = String.Empty;
+
+ int comma = adl.kids.Count - 1; // tells us whether to print a comma
+
+ foreach (Declaration d in adl.kids)
+ {
+ retstr += String.Format("{0} {1}", d.Datatype, d.Id);
+ if (0 < comma--)
+ retstr += ", ";
+ }
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for an ArgumentList node.
+ ///
+ /// The ArgumentList node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateArgumentList(ArgumentList al)
+ {
+ string retstr = String.Empty;
+
+ int comma = al.kids.Count - 1; // tells us whether to print a comma
+
+ foreach (SYMBOL s in al.kids)
+ {
+ retstr += GenerateNode(s);
+ if (0 < comma--)
+ retstr += ", ";
+ }
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a CompoundStatement node.
+ ///
+ /// The CompoundStatement node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateCompoundStatement(CompoundStatement cs)
+ {
+ string retstr = String.Empty;
+
+ // opening brace
+ retstr += WriteIndentedLine("{");
+ m_braceCount++;
+
+ foreach (SYMBOL kid in cs.kids)
+ retstr += GenerateNode(kid);
+
+ // closing brace
+ m_braceCount--;
+ retstr += WriteIndentedLine("}");
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a Declaration node.
+ ///
+ /// The Declaration node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateDeclaration(Declaration d)
+ {
+ return String.Format("{0} {1}", d.Datatype, d.Id);
+ }
+
+ ///
+ /// Generates the code for a Statement node.
+ ///
+ /// The Statement node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateStatement(Statement s)
+ {
+ string retstr = String.Empty;
+
+ // Jump label prints its own colon, we don't need a semicolon.
+ bool printSemicolon = !(s.kids.Top is JumpLabel);
+
+ retstr += Indent();
+
+ foreach (SYMBOL kid in s.kids)
+ retstr += GenerateNode(kid);
+
+ if (printSemicolon)
+ retstr += ";\n";
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for an Assignment node.
+ ///
+ /// The Assignment node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateAssignment(Assignment a)
+ {
+ string retstr = String.Empty;
+
+ retstr += GenerateNode((SYMBOL) a.kids.Pop());
+ retstr +=String.Format(" {0} ", a.AssignmentType);
+ foreach (SYMBOL kid in a.kids)
+ retstr += GenerateNode(kid);
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a ReturnStatement node.
+ ///
+ /// The ReturnStatement node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateReturnStatement(ReturnStatement rs)
+ {
+ string retstr = String.Empty;
+
+ retstr += "return ";
+
+ foreach (SYMBOL kid in rs.kids)
+ retstr += GenerateNode(kid);
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a JumpLabel node.
+ ///
+ /// The JumpLabel node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateJumpLabel(JumpLabel jl)
+ {
+ return String.Format("{0}:\n", jl.LabelName);
+ }
+
+ ///
+ /// Generates the code for a JumpStatement node.
+ ///
+ /// The JumpStatement node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateJumpStatement(JumpStatement js)
+ {
+ return String.Format("goto {0}", js.TargetName);
+ }
+
+ ///
+ /// Generates the code for a IfStatement node.
+ ///
+ /// The IfStatement node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateIfStatement(IfStatement ifs)
+ {
+ string retstr = String.Empty;
+
+ retstr += WriteIndented("if (");
+ retstr += GenerateNode((SYMBOL) ifs.kids.Pop());
+ retstr += ")\n";
+
+ // CompoundStatement handles indentation itself but we need to do it
+ // otherwise.
+ bool indentHere = ifs.kids.Top is Statement;
+ if (indentHere) m_braceCount++;
+ retstr += GenerateNode((SYMBOL) ifs.kids.Pop());
+ if (indentHere) m_braceCount--;
+
+ if (0 < ifs.kids.Count) // do it again for an else
+ {
+ retstr += WriteIndentedLine("else");
+
+ indentHere = ifs.kids.Top is Statement;
+ if (indentHere) m_braceCount++;
+ retstr += GenerateNode((SYMBOL) ifs.kids.Pop());
+ if (indentHere) m_braceCount--;
+ }
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a StateChange node.
+ ///
+ /// The StateChange node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateStateChange(StateChange sc)
+ {
+ return String.Format("state(\"{0}\")", sc.NewState);
+ }
+
+ ///
+ /// Generates the code for a WhileStatement node.
+ ///
+ /// The WhileStatement node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateWhileStatement(WhileStatement ws)
+ {
+ string retstr = String.Empty;
+
+ retstr += WriteIndented("while (");
+ retstr += GenerateNode((SYMBOL) ws.kids.Pop());
+ retstr += ")\n";
+
+ // CompoundStatement handles indentation itself but we need to do it
+ // otherwise.
+ bool indentHere = ws.kids.Top is Statement;
+ if (indentHere) m_braceCount++;
+ retstr += GenerateNode((SYMBOL) ws.kids.Pop());
+ if (indentHere) m_braceCount--;
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a DoWhileStatement node.
+ ///
+ /// The DoWhileStatement node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateDoWhileStatement(DoWhileStatement dws)
+ {
+ string retstr = String.Empty;
+
+ retstr += WriteIndentedLine("do");
+
+ // CompoundStatement handles indentation itself but we need to do it
+ // otherwise.
+ bool indentHere = dws.kids.Top is Statement;
+ if (indentHere) m_braceCount++;
+ retstr += GenerateNode((SYMBOL) dws.kids.Pop());
+ if (indentHere) m_braceCount--;
+
+ retstr += WriteIndented("while (");
+ retstr += GenerateNode((SYMBOL) dws.kids.Pop());
+ retstr += ");\n";
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a ForLoop node.
+ ///
+ /// The ForLoop node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateForLoop(ForLoop fl)
+ {
+ string retstr = String.Empty;
+
+ retstr += WriteIndented("for (");
+
+ // for ( x = 0 ; x < 10 ; x++ )
+ // ^^^^^^^
+ retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop());
+ retstr += "; ";
+ // for ( x = 0 ; x < 10 ; x++ )
+ // ^^^^^^^^
+ retstr += GenerateNode((SYMBOL) fl.kids.Pop());
+ retstr += "; ";
+ // for ( x = 0 ; x < 10 ; x++ )
+ // ^^^^^
+ retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop());
+ retstr += ")\n";
+
+ // CompoundStatement handles indentation itself but we need to do it
+ // otherwise.
+ bool indentHere = fl.kids.Top is Statement;
+ if (indentHere) m_braceCount++;
+ retstr += GenerateNode((SYMBOL) fl.kids.Pop());
+ if (indentHere) m_braceCount--;
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a ForLoopStatement node.
+ ///
+ /// The ForLoopStatement node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateForLoopStatement(ForLoopStatement fls)
+ {
+ string retstr = String.Empty;
+
+ int comma = fls.kids.Count - 1; // tells us whether to print a comma
+
+ foreach (SYMBOL s in fls.kids)
+ {
+ retstr += GenerateNode(s);
+ if (0 < comma--)
+ retstr += ", ";
+ }
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a BinaryExpression node.
+ ///
+ /// The BinaryExpression node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateBinaryExpression(BinaryExpression be)
+ {
+ string retstr = String.Empty;
+
+ retstr += GenerateNode((SYMBOL) be.kids.Pop());
+ retstr += String.Format(" {0} ", be.ExpressionSymbol);
+ foreach (SYMBOL kid in be.kids)
+ retstr += GenerateNode(kid);
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a UnaryExpression node.
+ ///
+ /// The UnaryExpression node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateUnaryExpression(UnaryExpression ue)
+ {
+ string retstr = String.Empty;
+
+ retstr += ue.UnarySymbol;
+ retstr += GenerateNode((SYMBOL) ue.kids.Pop());
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a ParenthesisExpression node.
+ ///
+ /// The ParenthesisExpression node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateParenthesisExpression(ParenthesisExpression pe)
+ {
+ string retstr = String.Empty;
+
+ retstr += "(";
+ foreach (SYMBOL kid in pe.kids)
+ retstr += GenerateNode(kid);
+ retstr += ")";
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a IncrementDecrementExpression node.
+ ///
+ /// The IncrementDecrementExpression node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateIncrementDecrementExpression(IncrementDecrementExpression ide)
+ {
+ string retstr = String.Empty;
+
+ if (0 < ide.kids.Count)
+ {
+ IdentDotExpression dot = (IdentDotExpression) ide.kids.Top;
+ retstr += String.Format("{0}", ide.PostOperation ? dot.Name + "." + dot.Member + ide.Operation : ide.Operation + dot.Name + "." + dot.Member);
+ }
+ else
+ retstr += String.Format("{0}", ide.PostOperation ? ide.Name + ide.Operation : ide.Operation + ide.Name);
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a TypecastExpression node.
+ ///
+ /// The TypecastExpression node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateTypecastExpression(TypecastExpression te)
+ {
+ string retstr = String.Empty;
+
+ // we wrap all typecasted statements in parentheses
+ retstr += String.Format("({0}) (", te.TypecastType);
+ retstr += GenerateNode((SYMBOL) te.kids.Pop());
+ retstr += ")";
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a FunctionCall node.
+ ///
+ /// The FunctionCall node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateFunctionCall(FunctionCall fc)
+ {
+ string retstr = String.Empty;
+
+ retstr += String.Format("{0}(", fc.Id);
+
+ foreach (SYMBOL kid in fc.kids)
+ retstr += GenerateNode(kid);
+
+ retstr += ")";
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a Constant node.
+ ///
+ /// The Constant node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateConstant(Constant c)
+ {
+ string retstr = String.Empty;
+
+ // Supprt LSL's weird acceptance of floats with no trailing digits
+ // after the period. Turn float x = 10.; into float x = 10.0;
+ if ("LSL_Types.LSLFloat" == c.Type)
+ {
+ int dotIndex = c.Value.IndexOf('.') + 1;
+ if (0 < dotIndex && (dotIndex == c.Value.Length || !Char.IsDigit(c.Value[dotIndex])))
+ c.Value = c.Value.Insert(dotIndex, "0");
+ }
+
+ // need to quote strings
+ if ("LSL_Types.LSLString" == c.Type)
+ retstr += "\"";
+ retstr += c.Value;
+ if ("LSL_Types.LSLString" == c.Type)
+ retstr += "\"";
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a VectorConstant node.
+ ///
+ /// The VectorConstant node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateVectorConstant(VectorConstant vc)
+ {
+ string retstr = String.Empty;
+
+ retstr += String.Format("new {0}(", vc.Type);
+ retstr += GenerateNode((SYMBOL) vc.kids.Pop());
+ retstr += ", ";
+ retstr += GenerateNode((SYMBOL) vc.kids.Pop());
+ retstr += ", ";
+ retstr += GenerateNode((SYMBOL) vc.kids.Pop());
+ retstr += ")";
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a RotationConstant node.
+ ///
+ /// The RotationConstant node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateRotationConstant(RotationConstant rc)
+ {
+ string retstr = String.Empty;
+
+ retstr += String.Format("new {0}(", rc.Type);
+ retstr += GenerateNode((SYMBOL) rc.kids.Pop());
+ retstr += ", ";
+ retstr += GenerateNode((SYMBOL) rc.kids.Pop());
+ retstr += ", ";
+ retstr += GenerateNode((SYMBOL) rc.kids.Pop());
+ retstr += ", ";
+ retstr += GenerateNode((SYMBOL) rc.kids.Pop());
+ retstr += ")";
+
+ return retstr;
+ }
+
+ ///
+ /// Generates the code for a ListConstant node.
+ ///
+ /// The ListConstant node.
+ /// String containing C# code for SYMBOL s.
+ private string GenerateListConstant(ListConstant lc)
+ {
+ string retstr = String.Empty;
+
+ retstr += String.Format("new {0}(", lc.Type);
+
+ foreach (SYMBOL kid in lc.kids)
+ retstr += GenerateNode(kid);
+
+ retstr += ")";
+
+ return retstr;
+ }
+
+ ///
+ /// Prints text correctly indented, followed by a newline.
+ ///
+ /// String of text to print.
+ /// String containing C# code for SYMBOL s.
+ private string WriteIndentedLine(string s)
+ {
+ return WriteIndented(s) + "\n";
+ }
+
+ ///
+ /// Prints text correctly indented.
+ ///
+ /// String of text to print.
+ /// String containing C# code for SYMBOL s.
+ private string WriteIndented(string s)
+ {
+ return Indent() + s;
+ }
+
+ ///
+ /// Prints correct indentation.
+ ///
+ /// String containing C# code for SYMBOL s.
+ private string Indent()
+ {
+ string retstr = String.Empty;
+
+ for (int i = 0; i < m_braceCount; i++)
+ retstr += " ";
+
+ return retstr;
+ }
+ }
+}
--
cgit v1.1