/// <summary> /// Recursively called to transform each type of node. Will transform this /// node, then all it's children. /// </summary> /// <param name="s">The current node to transform.</param> private void TransformNode(SYMBOL s) { // make sure to put type lower in the inheritance hierarchy first // ie: since IdentConstant and StringConstant inherit from Constant, // put IdentConstant and StringConstant before Constant if (s is Declaration) ((Declaration) s).Datatype = m_datatypeLSL2OpenSim[((Declaration) s).Datatype]; else if (s is Constant) ((Constant) s).Type = m_datatypeLSL2OpenSim[((Constant) s).Type]; else if (s is TypecastExpression) ((TypecastExpression) s).TypecastType = m_datatypeLSL2OpenSim[((TypecastExpression) s).TypecastType]; else if (s is GlobalFunctionDefinition && "void" != ((GlobalFunctionDefinition) s).ReturnType) // we don't need to translate "void" ((GlobalFunctionDefinition) s).ReturnType = m_datatypeLSL2OpenSim[((GlobalFunctionDefinition) s).ReturnType]; for (int i = 0; i < s.kids.Count; i++) { // It's possible that a child is null, for instance when the // assignment part in a for-loop is left out, ie: // // for (; i < 10; i++) // { // ... // } // // We need to check for that here. if (null != s.kids[i]) { if (!(s is Assignment || s is ArgumentDeclarationList) && s.kids[i] is Declaration) AddImplicitInitialization(s, i); TransformNode((SYMBOL) s.kids[i]); } } }
public static object create(string cls_name, Parser yyp) { SCreator type1 = (SCreator)yyp.m_symbols.types[(object)cls_name]; if (type1 == null) { yyp.m_symbols.erh.Error(new CSToolsException(16, yyp.m_lexer, "no factory for {" + cls_name + ")")); } try { return(type1(yyp)); } catch (CSToolsException ex) { yyp.m_symbols.erh.Error(ex); } catch (Exception ex) { yyp.m_symbols.erh.Error(new CSToolsException(17, yyp.m_lexer, string.Format("Create of {0} failed ({1})", (object)cls_name, (object)ex.Message))); } int length = cls_name.LastIndexOf('_'); if (length > 0) { SCreator type2 = (SCreator)yyp.m_symbols.types[(object)cls_name.Substring(0, length)]; if (type2 != null) { SYMBOL symbol = (SYMBOL)type2(yyp); symbol.m_dollar = (object)0; return((object)symbol); } } return((object)null); }
/// <summary> /// Resets various counters and metadata. /// </summary> private void ResetCounters() { m_braceCount = 0; m_CSharpLine = 0; m_CSharpCol = 1; m_positionMap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>(); m_astRoot = null; }
public void Error(int n, SYMBOL sym, string s) { if (sym != null) { this.m_symbols.erh.Error(new CSToolsException(n, sym.yylx, sym.pos, "", s)); } else { this.m_symbols.erh.Error(new CSToolsException(n, s)); } }
public SYMBOL NextSym() { SYMBOL ungot = this.m_ungot; if (ungot == null) { return((SYMBOL)this.m_lexer.Next() ?? (SYMBOL)this.m_symbols.EOFSymbol); } this.m_ungot = (SYMBOL)null; return(ungot); }
public static void printThisTree(SYMBOL ast) { for (int i = 0; i < m_indent; i++) Console.Write(" "); Console.WriteLine(ast.ToString()); m_indent++; foreach (SYMBOL s in ast.kids) printThisTree(s); m_indent--; }
public virtual SYMBOL Action(Parser yyp) { SYMBOL symbol1 = (SYMBOL)Sfactory.create(this.m_sym.yytext, yyp); if (symbol1.yyname == this.m_sym.yytext) { SYMBOL symbol2 = yyp.StackAt(this.m_len - 1).m_value; symbol1.m_dollar = this.m_len == 0 || symbol2 == null ? (object)null : symbol2.m_dollar; } return(symbol1); }
/// <summary> /// Recursively called to transform each type of node. Will transform this /// node, then all it's children. /// </summary> /// <param name="s">The current node to transform.</param> private void TransformNode(SYMBOL s, Dictionary<string, string> GlobalMethods, Dictionary<string, ObjectList> MethodArguements) { // make sure to put type lower in the inheritance hierarchy first // ie: since IdentConstant and StringConstant inherit from Constant, // put IdentConstant and StringConstant before Constant if (s is Declaration) ((Declaration)s).Datatype = m_datatypeLSL2OpenSim[((Declaration)s).Datatype]; else if (s is Constant) ((Constant)s).Type = m_datatypeLSL2OpenSim[((Constant)s).Type]; else if (s is TypecastExpression) ((TypecastExpression)s).TypecastType = m_datatypeLSL2OpenSim[((TypecastExpression)s).TypecastType]; else if (s is GlobalFunctionDefinition) { if ("void" == ((GlobalFunctionDefinition)s).ReturnType) // we don't need to translate "void" { if (GlobalMethods != null && !GlobalMethods.ContainsKey(((GlobalFunctionDefinition)s).Name)) GlobalMethods.Add(((GlobalFunctionDefinition)s).Name, "void"); } else { ((GlobalFunctionDefinition)s).ReturnType = m_datatypeLSL2OpenSim[((GlobalFunctionDefinition)s).ReturnType]; if (GlobalMethods != null && !GlobalMethods.ContainsKey(((GlobalFunctionDefinition)s).Name)) { GlobalMethods.Add(((GlobalFunctionDefinition)s).Name, ((GlobalFunctionDefinition)s).ReturnType); MethodArguements.Add(((GlobalFunctionDefinition)s).Name, ((GlobalFunctionDefinition)s).kids); } } } for (int i = 0; i < s.kids.Count; i++) { // It's possible that a child is null, for instance when the // assignment part in a for-loop is left out, ie: // // for (; i < 10; i++) // { // ... // } // // We need to check for that here. if (null != s.kids[i]) { if (!(s is Assignment || s is ArgumentDeclarationList) && s.kids[i] is Declaration) AddImplicitInitialization(s, i); TransformNode((SYMBOL)s.kids[i], null, null); } } }
/// <summary> /// Pass the new CodeTranformer an abstract syntax tree. /// </summary> /// <param name="astRoot">The root node of the AST.</param> public LSL2CSCodeTransformer(SYMBOL astRoot) { m_astRoot = astRoot; m_datatypeLSL2CS = new Dictionary<string, string>() { { "integer", "lsl_integer" }, { "float", "lsl_float" }, { "key", "lsl_string" }, { "string", "lsl_string" }, { "vector", "lsl_vector" }, { "rotation", "lsl_rotation" }, { "list", "lsl_list" } }; }
internal void Pop(ref ParseStackEntry elt, int depth, SYMBOL ns) { for (; this.m_stack.Count > 0 && depth > 0; --depth) { elt = (ParseStackEntry)this.m_stack.Pop(); if (this.m_symbols.m_concrete) { ns.kids.Push((object)elt.m_value); } } if (depth == 0) { return; } this.m_symbols.erh.Error(new CSToolsException(14, this.m_lexer, "Pop failed")); }
/// <summary> /// Pass the new CodeTranformer an abstract syntax tree. /// </summary> /// <param name="astRoot">The root node of the AST.</param> public LSL2CSCodeTransformer(SYMBOL astRoot) { m_astRoot = astRoot; // let's populate the dictionary if (null == m_datatypeLSL2OpenSim) { m_datatypeLSL2OpenSim = new Dictionary<string, string>(); m_datatypeLSL2OpenSim.Add("integer", "LSL_Types.LSLInteger"); m_datatypeLSL2OpenSim.Add("float", "LSL_Types.LSLFloat"); m_datatypeLSL2OpenSim.Add("key", "LSL_Types.LSLString"); m_datatypeLSL2OpenSim.Add("string", "LSL_Types.LSLString"); m_datatypeLSL2OpenSim.Add("vector", "LSL_Types.Vector3"); m_datatypeLSL2OpenSim.Add("rotation", "LSL_Types.Quaternion"); m_datatypeLSL2OpenSim.Add("list", "LSL_Types.list"); } }
public override void Pass(ref ParseStackEntry top) { Parser yyps = top.yyps; SYMBOL ns = this.m_action.Action(yyps); yyps.m_ungot = top.m_value; if (yyps.m_debug) { Console.WriteLine("about to pop {0} count is {1}", (object)this.m_depth, (object)yyps.m_stack.Count); } yyps.Pop(ref top, this.m_depth, ns); if (ns.pos == 0) { ns.pos = top.m_value.pos; } top.m_value = ns; }
/// <summary> /// Pass the new CodeTransformer an abstract syntax tree. /// </summary> /// <param name="astRoot">The root node of the AST.</param> /// <param name="originalScript">The original script that we are converting</param> public LSL2CSCodeTransformer(SYMBOL astRoot, string originalScript) { m_astRoot = astRoot; m_originalScript = originalScript; // let's populate the dictionary if (null == m_datatypeLSL2OpenSim) { m_datatypeLSL2OpenSim = new Dictionary<string, string> { {"integer", "LSL_Types.LSLInteger"}, {"float", "LSL_Types.LSLFloat"}, {"key", "LSL_Types.LSLString"}, {"string", "LSL_Types.LSLString"}, {"vector", "LSL_Types.Vector3"}, {"rotation", "LSL_Types.Quaternion"}, {"list", "LSL_Types.list"} }; } }
/// <summary> /// Recursively called to transform each type of node. Will transform this /// node, then all it's children. /// </summary> /// <param name="s">The current node to transform.</param> private void TransformNode(SYMBOL s) { // make sure to put type lower in the inheritance hierarchy first // ie: since IdentConstant and StringConstant inherit from Constant, // put IdentConstant and StringConstant before Constant if (s is Declaration) ((Declaration) s).Datatype = m_datatypeLSL2OpenSim[((Declaration) s).Datatype]; else if (s is Constant) ((Constant) s).Type = m_datatypeLSL2OpenSim[((Constant) s).Type]; else if (s is TypecastExpression) ((TypecastExpression) s).TypecastType = m_datatypeLSL2OpenSim[((TypecastExpression) s).TypecastType]; else if (s is GlobalFunctionDefinition && "void" != ((GlobalFunctionDefinition) s).ReturnType) // we don't need to translate "void" ((GlobalFunctionDefinition) s).ReturnType = m_datatypeLSL2OpenSim[((GlobalFunctionDefinition) s).ReturnType]; for (int i = 0; i < s.kids.Count; i++) { if (!(s is Assignment || s is ArgumentDeclarationList) && s.kids[i] is Declaration) AddImplicitInitialization(s, i); TransformNode((SYMBOL) s.kids[i]); } }
public void Error(int n,SYMBOL sym, string s) { if (sym!=null) m_symbols.erh.Error(new CSToolsException(n,sym.yylx,sym.pos,"",s)); // 4.5b else m_symbols.erh.Error(new CSToolsException(n,s)); }
public error(Parser yyp,ParseStackEntry s):base(yyp) { state=s.m_state; sym=s.m_value; } //4.4c
/// <summary> /// Generates the code for a Statement node. /// </summary> /// <param name="s">The Statement node.</param> /// <returns>String containing C# code for Statement s.</returns> private string GenerateStatement(SYMBOL previousSymbol, Statement s) { string retstr = String.Empty; bool printSemicolon = true; bool transformToBlock = false; if (m_insertCoopTerminationChecks) { // A non-braced single line do while structure cannot contain multiple statements. // So to insert the termination check we change this to a braced control structure instead. if (previousSymbol is WhileStatement || previousSymbol is DoWhileStatement || previousSymbol is ForLoop) { transformToBlock = true; // FIXME: This will be wrongly indented because the previous for/while/dowhile will have already indented. retstr += GenerateIndentedLine("{"); retstr += GenerateIndentedLine(m_coopTerminationCheck); } } retstr += Indent(); if (0 < s.kids.Count) { // Jump label prints its own colon, we don't need a semicolon. printSemicolon = !(s.kids.Top is JumpLabel); // If we encounter a lone Ident, we skip it, since that's a C# // (MONO) error. if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count)) foreach (SYMBOL kid in s.kids) retstr += GenerateNode(s, kid); } if (printSemicolon) retstr += GenerateLine(";"); if (transformToBlock) { // FIXME: This will be wrongly indented because the for/while/dowhile is currently handling the unindent retstr += GenerateIndentedLine("}"); } return retstr; }
public CSToolsException(int n, SYMBOL t, string s) : this(n, t.yylx, t.pos, t.yyname, s) { sym = t; }
/// <summary> /// Prints text correctly indented, followed by a newline. /// </summary> /// <param name="s">String of text to print.</param> /// <param name="sym">Symbol being generated to extract original line /// number and column from.</param> /// <returns>Properly indented string s followed by newline.</returns> private string GenerateIndentedLine(string s, SYMBOL sym) { string retstr = GenerateIndented(s, sym) + "\n"; m_CSharpLine++; m_CSharpCol = 1; return retstr; }
/// <summary> /// Recursively called to generate each type of node. Will generate this /// node, then all it's children. /// </summary> /// <param name="previousSymbol">The parent node.</param> /// <param name="s">The current node to generate code for.</param> /// <returns>String containing C# code for SYMBOL s.</returns> private string GenerateNode(SYMBOL previousSymbol, 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(previousSymbol, (CompoundStatement) s); else if (s is Declaration) retstr += GenerateDeclaration((Declaration) s); else if (s is Statement) retstr += GenerateStatement(previousSymbol, (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 += Generate(CheckName(((IdentDotExpression) s).Name) + "." + ((IdentDotExpression) s).Member, s); else if (s is IdentExpression) retstr += GenerateIdentifier(((IdentExpression) s).Name, s); else if (s is IDENT) retstr += Generate(CheckName(((TOKEN) s).yytext), s); else { foreach (SYMBOL kid in s.kids) retstr += GenerateNode(s, kid); } return retstr; }
public CSToolsException(int n, TOKEN t, string s) : this(n, t.yylx, t.pos, t.yytext, s) { this.sym = (SYMBOL)t; }
/// <summary> /// Generate the code from the AST we have. /// </summary> /// <param name="script">The LSL source as a string.</param> /// <returns>String containing the generated C# code.</returns> public string Convert(string script) { // m_log.DebugFormat("[CS CODE GENERATOR]: Converting to C#\n{0}", script); m_warnings.Clear(); ResetCounters(); Parser p = new LSLSyntax(new yyLSLSyntax(), new ErrorHandler(true)); LSL2CSCodeTransformer codeTransformer; try { codeTransformer = new LSL2CSCodeTransformer(p.Parse(script)); } catch (CSToolsException e) { string message; // LL start numbering lines at 0 - geeks! // Also need to subtract one line we prepend! // string emessage = e.Message; string slinfo = e.slInfo.ToString(); // Remove wrong line number info // if (emessage.StartsWith(slinfo+": ")) emessage = emessage.Substring(slinfo.Length+2); message = String.Format("({0},{1}) {2}", e.slInfo.lineNumber - 1, e.slInfo.charPosition - 1, emessage); throw new Exception(message); } m_astRoot = codeTransformer.Transform(); string retstr = String.Empty; // standard preamble //retstr = GenerateLine("using OpenSim.Region.ScriptEngine.Common;"); //retstr += GenerateLine("using System.Collections.Generic;"); //retstr += GenerateLine(""); //retstr += GenerateLine("namespace SecondLife"); //retstr += GenerateLine("{"); m_braceCount++; //retstr += GenerateIndentedLine("public class Script : OpenSim.Region.ScriptEngine.Common"); //retstr += GenerateIndentedLine("{"); m_braceCount++; // line number m_CSharpLine += 9; // here's the payload retstr += GenerateLine(); foreach (SYMBOL s in m_astRoot.kids) retstr += GenerateNode(m_astRoot, s); // close braces! m_braceCount--; //retstr += GenerateIndentedLine("}"); m_braceCount--; //retstr += GenerateLine("}"); // Removes all carriage return characters which may be generated in Windows platform. Is there // cleaner way of doing this? retstr = retstr.Replace("\r", ""); return retstr; }
public ParenthesisExpression (Parser yyp, SYMBOL s ):base(((LSLSyntax )yyp)){ kids . Add ( s ); }
string CheckIfGlobalVariable(string varName, string type, SYMBOL kid) { string globalVarValue = ""; if (kid is Constant) { Constant c = kid as Constant; // 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"); globalVarValue = "new LSL_Types.LSLFloat(" + c.Value + ") "; } else if ("LSL_Types.LSLInteger" == c.Type) { globalVarValue = "new LSL_Types.LSLInteger(" + c.Value + ") "; } else if ("LSL_Types.LSLString" == c.Type) { globalVarValue = "new LSL_Types.LSLString(\"" + c.Value + "\") "; } if (globalVarValue == "") globalVarValue = c.Value; if (globalVarValue == null) globalVarValue = GenerateNode(c); if (GlobalVariables.ContainsKey(globalVarValue)) { //Its an assignment to another global var! //reset the global value to the other's value GlobalVar var; GlobalVariables.TryGetValue(globalVarValue, out var); //Do one last additional test before we set it. if (type == var.Type) { globalVarValue = var.Value; } c.Value = globalVarValue; } else if (GlobalVariables.ContainsKey(varName)) { } else GlobalVariables.Add(varName, new GlobalVar { Type = type, Value = globalVarValue }); return globalVarValue; } else if (kid is IdentExpression) { IdentExpression c = kid as IdentExpression; globalVarValue = c.Name; if (GlobalVariables.ContainsKey(globalVarValue)) { //Its an assignment to another global var! //reset the global value to the other's value GlobalVar var; GlobalVariables.TryGetValue(globalVarValue, out var); //Do one last additional test before we set it. if (type == var.Type) { globalVarValue = var.Value; } } GlobalVariables.Add(varName, new GlobalVar { Type = type, Value = globalVarValue }); return globalVarValue; } else if (kid is UnaryExpression) { UnaryExpression c = kid as UnaryExpression; globalVarValue = Generate(c.UnarySymbol, c); foreach (SYMBOL k in c.kids) { globalVarValue += CheckIfGlobalVariable(varName, type, k); } return globalVarValue; } else return GenerateNode(kid); }
public TypecastExpression (Parser yyp, string typecastType , SYMBOL rhs ):base(((LSLSyntax )yyp)){ m_typecastType = typecastType ; kids . Add ( rhs ); }
public virtual object Action(Parser yyp, SYMBOL yysym, int yyact) { return((object)null); }
private SYMBOL Parse() { this.Create(); ParseStackEntry s = new ParseStackEntry(this, 0, this.NextSym()); try { while (true) { do { string yyname = s.m_value.yyname; if (this.m_debug) { if (yyname.Equals("TOKEN")) { Console.WriteLine(string.Format("State {0} with {1} \"{2}\"", (object)s.m_state, (object)yyname, (object)((TOKEN)s.m_value).yytext)); } else { Console.WriteLine(string.Format("State {0} with {1}", (object)s.m_state, (object)yyname)); } } ParserEntry entry; if (s.m_value != null && s.m_value.Pass(this.m_symbols, s.m_state, out entry)) { entry.Pass(ref s); } else if (s.m_value == this.m_symbols.EOFSymbol) { if (s.m_state == this.m_symbols.m_accept.m_state) { this.Pop(ref s, 1, (SYMBOL)this.m_symbols.m_startSymbol); if (this.m_symbols.erh.counter > 0) { return((SYMBOL) new recoveredError(this, s)); } SYMBOL symbol = s.m_value; s.m_value = (SYMBOL)null; return(symbol); } if (!this.Error(ref s, "Unexpected EOF")) { return(s.m_value); } } else if (!this.Error(ref s, "syntax error")) { return(s.m_value); } }while (!this.m_debug); if (s.m_value != null) { object dollar = s.m_value.m_dollar; Console.WriteLine("In state {0} top {1} value {2}", (object)s.m_state, (object)s.m_value.yyname, dollar != null ? (object)dollar.GetType().Name : (object)"null"); if (dollar != null && dollar.GetType().Name.Equals("Int32")) { Console.WriteLine((int)dollar); } else { s.m_value.Print(); } } else { Console.WriteLine("In state {0} top NULL", (object)s.m_state); } } } catch (CSToolsStopException ex) { if (this.m_symbols.erh.throwExceptions) { throw ex; } this.m_symbols.erh.Report((CSToolsException)ex); } return((SYMBOL)null); }
// support for actions public virtual object Action(Parser yyp,SYMBOL yysym, int yyact) { return null; } // will be generated for the generated parser
/// <summary> /// Recursively called to generate each type of node. Will generate this /// node, then all it's children. /// </summary> /// <param name="s">The current node to generate code for.</param> /// <returns>String containing C# code for SYMBOL s.</returns> string GenerateNode(SYMBOL s) { // 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) { return GenerateGlobalFunctionDefinition((GlobalFunctionDefinition) s); } else if (s is GlobalVariableDeclaration) { return GenerateGlobalVariableDeclaration((GlobalVariableDeclaration) s); } else if (s is State) { return GenerateState((State) s); } else if (s is CompoundStatement) { return GenerateCompoundStatement((CompoundStatement) s); } else if (s is Declaration) { return GenerateDeclaration((Declaration) s); } else if (s is Statement) { return GenerateStatement((Statement) s); } else if (s is ReturnStatement) { return GenerateReturnStatement((ReturnStatement) s); } else if (s is JumpLabel) { return GenerateJumpLabel((JumpLabel) s); } else if (s is JumpStatement) { return GenerateJumpStatement((JumpStatement) s); } else if (s is StateChange) { return GenerateStateChange((StateChange) s); } else if (s is IfStatement) { return GenerateIfStatement((IfStatement) s); } else if (s is WhileStatement) { return GenerateWhileStatement((WhileStatement) s); } else if (s is DoWhileStatement) { return GenerateDoWhileStatement((DoWhileStatement) s); } else if (s is ForLoop) { return GenerateForLoop((ForLoop) s); } else if (s is ArgumentList) { return GenerateArgumentList((ArgumentList) s); } else if (s is Assignment) { return GenerateAssignment((Assignment) s); } else if (s is BinaryExpression) { return GenerateBinaryExpression((BinaryExpression) s, false, ""); } else if (s is ParenthesisExpression) { return GenerateParenthesisExpression((ParenthesisExpression) s); } else if (s is UnaryExpression) { return GenerateUnaryExpression((UnaryExpression) s); } else if (s is IncrementDecrementExpression) { return GenerateIncrementDecrementExpression((IncrementDecrementExpression) s); } else if (s is TypecastExpression) { return GenerateTypecastExpression((TypecastExpression) s); } else if (s is FunctionCall) { return GenerateFunctionCall((FunctionCall) s, true); } else if (s is VectorConstant) { return GenerateVectorConstant((VectorConstant) s); } else if (s is RotationConstant) { return GenerateRotationConstant((RotationConstant) s); } else if (s is ListConstant) { return GenerateListConstant((ListConstant)s); } else if (s is Constant) { return GenerateConstant((Constant)s); } else if (s is IdentDotExpression) { return Generate(CheckName(((IdentDotExpression) s).Name) + "." + ((IdentDotExpression) s).Member, s); } else if (s is IdentExpression) { return Generate(CheckName(((IdentExpression)s).Name), s); } else if (s is IDENT) { return Generate(CheckName(((TOKEN) s).yytext), s); } else { StringBuilder retVal = new StringBuilder(); foreach (SYMBOL kid in s.kids) retVal.Append(GenerateNode(kid)); return retVal.ToString(); } }
public ParseStackEntry(Parser yyp,int state,SYMBOL value) { yyps = yyp; m_state = state; m_value = value; }
/// <summary> /// Generates the code for an identifier /// </summary> /// <param name="id">The symbol name</param> /// <param name="s">The Symbol node.</param> /// <returns>String containing C# code for identifier reference.</returns> private string GenerateIdentifier(string id, SYMBOL s) { if (m_comms != null) { object value = m_comms.LookupModConstant(id); if (value != null) { string retval = null; if (value is int) retval = String.Format("new LSL_Types.LSLInteger({0})",((int)value).ToString()); else if (value is float) retval = String.Format("new LSL_Types.LSLFloat({0})",((float)value).ToString()); else if (value is string) retval = String.Format("new LSL_Types.LSLString(\"{0}\")",((string)value)); else if (value is OpenMetaverse.UUID) retval = String.Format("new LSL_Types.key(\"{0}\")",((OpenMetaverse.UUID)value).ToString()); else if (value is OpenMetaverse.Vector3) retval = String.Format("new LSL_Types.Vector3(\"{0}\")",((OpenMetaverse.Vector3)value).ToString()); else if (value is OpenMetaverse.Quaternion) retval = String.Format("new LSL_Types.Quaternion(\"{0}\")",((OpenMetaverse.Quaternion)value).ToString()); else retval = id; return Generate(retval, s); } } return Generate(CheckName(id), s); }
/// <summary> /// Prints text. /// </summary> /// <param name="s">String of text to print.</param> /// <param name="sym">Symbol being generated to extract original line /// number and column from.</param> /// <returns>String s.</returns> private string Generate(string s, SYMBOL sym) { if (null != sym) m_positionMap.Add(new KeyValuePair<int, int>(m_CSharpLine, m_CSharpCol), new KeyValuePair<int, int>(sym.Line, sym.Position)); m_CSharpCol += s.Length; return s; }
public CSToolsException(int n, TOKEN t, string s) : this(n, t.yylx, t.pos, t.yytext, s) { sym = t; }
/// <summary> /// Prints text correctly indented. /// </summary> /// <param name="s">String of text to print.</param> /// <returns>Properly indented string s.</returns> //private string GenerateIndented(string s) //{ // return GenerateIndented(s, null); //} // THIS FUNCTION IS COMMENTED OUT TO SUPPRESS WARNINGS /// <summary> /// Prints text correctly indented. /// </summary> /// <param name="s">String of text to print.</param> /// <param name="sym">Symbol being generated to extract original line /// number and column from.</param> /// <returns>Properly indented string s.</returns> private string GenerateIndented(string s, SYMBOL sym) { string retstr = Indent() + s; if (null != sym) m_positionMap.Add(new KeyValuePair<int, int>(m_CSharpLine, m_CSharpCol), new KeyValuePair<int, int>(sym.Line, sym.Position)); m_CSharpCol += s.Length; return retstr; }
protected bool Error(ref ParseStackEntry top, string str) { SYMBOL ns = (SYMBOL) new error(this, top); if (this.m_debug) { Console.WriteLine("Error encountered: " + str); } ns.pos = top.m_value.pos; if (this.m_symbols.symbolInfo[(object)0] != null && this.m_symbols.erh.counter < 1000) { while (top != null && this.m_stack.Count > 0) { if (this.m_debug) { Console.WriteLine("Error recovery uncovers state {0}", (object)top.m_state); } ParserEntry entry; if (ns.Pass(this.m_symbols, top.m_state, out entry)) { SYMBOL symbol1 = top.m_value; top.m_value = ns; entry.Pass(ref top); while (top.m_value != this.m_symbols.EOFSymbol && !top.m_value.Pass(this.m_symbols, top.m_state, out entry)) { if (entry != null && entry.IsReduce()) { SYMBOL symbol2 = (SYMBOL)null; if (entry.m_action != null) { symbol2 = entry.m_action.Action(this); } this.m_ungot = top.m_value; this.Pop(ref top, ((ParserReduce)entry).m_depth, ns); symbol2.pos = top.m_value.pos; top.m_value = symbol2; } else { string yyname = top.m_value.yyname; if (this.m_debug) { if (yyname == "TOKEN") { Console.WriteLine("Error recovery discards literal {0}", (object)((TOKEN)top.m_value).yytext); } else { Console.WriteLine("Error recovery discards token {0}", (object)yyname); } } top.m_value = this.NextSym(); } } if (this.m_debug) { Console.WriteLine("Recovery complete"); } ++this.m_symbols.erh.counter; return(true); } this.Pop(ref top, 1, ns); } } this.m_symbols.erh.Error(new CSToolsException(13, this.m_lexer, ns.pos, "syntax error", str)); top.m_value = ns; return(false); }
/// <summary> /// Generates the code for a CompoundStatement node. /// </summary> /// <param name="cs">The CompoundStatement node.</param> /// <returns>String containing C# code for CompoundStatement cs.</returns> private string GenerateCompoundStatement(SYMBOL previousSymbol, CompoundStatement cs) { string retstr = String.Empty; // opening brace retstr += GenerateIndentedLine("{"); m_braceCount++; if (m_insertCoopTerminationChecks) { // We have to check in event functions as well because the user can manually call these. if (previousSymbol is GlobalFunctionDefinition || previousSymbol is WhileStatement || previousSymbol is DoWhileStatement || previousSymbol is ForLoop || previousSymbol is StateEvent) retstr += GenerateIndentedLine(m_coopTerminationCheck); } foreach (SYMBOL kid in cs.kids) retstr += GenerateNode(cs, kid); // closing brace m_braceCount--; retstr += GenerateIndentedLine("}"); return retstr; }
public SYMBOL NextSym() { // like lexer.Next but allows a one-token pushback for reduce SYMBOL ret = m_ungot; if (ret != null) { m_ungot = null; return ret; } ret = (SYMBOL)m_lexer.Next(); if (ret==null) ret = m_symbols.EOFSymbol; return ret; }
// This code checks for LSL of the following forms, and generates a // warning if it finds them. // // list l = [ "foo" ]; // l = (l=[]) + l + ["bar"]; // (produces l=["foo","bar"] in SL but l=["bar"] in OS) // // integer i; // integer j; // i = (j = 3) + (j = 4) + (j = 5); // (produces j=3 in SL but j=5 in OS) // // Without this check, that code passes compilation, but does not do what // the end user expects, because LSL in SL evaluates right to left instead // of left to right. // // The theory here is that producing an error and alerting the end user that // something needs to change is better than silently generating incorrect code. private void checkForMultipleAssignments(List<string> identifiers, SYMBOL s) { if (s is Assignment) { Assignment a = (Assignment)s; string newident = null; if (a.kids[0] is Declaration) { newident = ((Declaration)a.kids[0]).Id; } else if (a.kids[0] is IDENT) { newident = ((IDENT)a.kids[0]).yytext; } else if (a.kids[0] is IdentDotExpression) { newident = ((IdentDotExpression)a.kids[0]).Name; // +"." + ((IdentDotExpression)a.kids[0]).Member; } else { AddWarning(String.Format("Multiple assignments checker internal error '{0}' at line {1} column {2}.", a.kids[0].GetType(), ((SYMBOL)a.kids[0]).Line - 1, ((SYMBOL)a.kids[0]).Position)); } if (identifiers.Contains(newident)) { AddWarning(String.Format("Multiple assignments to '{0}' at line {1} column {2}; results may differ between LSL and OSSL.", newident, ((SYMBOL)a.kids[0]).Line - 1, ((SYMBOL)a.kids[0]).Position)); } identifiers.Add(newident); } int index; for (index = 0; index < s.kids.Count; index++) { checkForMultipleAssignments(identifiers, (SYMBOL) s.kids[index]); } }
public CSToolsStopException(int n, SYMBOL t, string s) : base(n, t, s) { }
/// <summary> /// Replaces an instance of the node at s.kids[didx] with an assignment /// node. The assignment node has the Declaration node on the left hand /// side and a default initializer on the right hand side. /// </summary> /// <param name="s"> /// The node containing the Declaration node that needs replacing. /// </param> /// <param name="didx">Index of the Declaration node to replace.</param> private void AddImplicitInitialization(SYMBOL s, int didx) { // We take the kids for a while to play with them. int sKidSize = s.kids.Count; object [] sKids = new object[sKidSize]; for (int i = 0; i < sKidSize; i++) sKids[i] = s.kids.Pop(); // The child to be changed. Declaration currentDeclaration = (Declaration) sKids[didx]; // We need an assignment node. Assignment newAssignment = new Assignment(currentDeclaration.yyps, currentDeclaration, GetZeroConstant(currentDeclaration.yyps, currentDeclaration.Datatype), "="); sKids[didx] = newAssignment; // Put the kids back where they belong. for (int i = 0; i < sKidSize; i++) s.kids.Add(sKids[i]); }
protected bool Error(ref ParseStackEntry top, string str) { SYMBOL er = (SYMBOL)new error(this,top); // 4.4c if (m_debug) Console.WriteLine("Error encountered: "+str); er.pos = top.m_value.pos; ParserEntry pe; if (m_symbols.symbolInfo[0]!=null && m_symbols.erh.counter<1000) // 4.4c // first pop the stack until we find an item that can pass error for (;top!=null && m_stack.Count>0; Pop(ref top,1,er)) { if (m_debug) Console.WriteLine("Error recovery uncovers state {0}",top.m_state); if (er.Pass(m_symbols,top.m_state, out pe)) { SYMBOL oldtop = top.m_value; top.m_value = er; pe.Pass(ref top); // pass the error symbol // now discard tokens until we find one we can pass while (top.m_value!=m_symbols.EOFSymbol && !top.m_value.Pass(m_symbols,top.m_state, out pe)) { SYMBOL newtop; if (pe!=null && pe.IsReduce()) { newtop = null; if (pe.m_action!=null) newtop = pe.m_action.Action(this); // before we change the stack m_ungot = top.m_value; Pop(ref top,((ParserReduce)pe).m_depth,er); newtop.pos = top.m_value.pos; top.m_value = newtop; } else { // discard it string cnm = top.m_value.yyname; if (m_debug) { if (cnm=="TOKEN") Console.WriteLine("Error recovery discards literal {0}",(string)((TOKEN)top.m_value).yytext); else Console.WriteLine("Error recovery discards token {0}",cnm); } top.m_value = NextSym(); } } if (m_debug) Console.WriteLine("Recovery complete"); m_symbols.erh.counter++; return true; } } m_symbols.erh.Error(new CSToolsException(13,m_lexer,er.pos,"syntax error",str)); top.m_value = er; return false; }
/// <summary> /// Prints text, followed by a newline. /// </summary> /// <param name="s">String of text to print.</param> /// <param name="sym"> /// Symbol being generated to extract original line /// number and column from. /// </param> /// <returns>String s followed by newline.</returns> string GenerateLine(string s, SYMBOL sym) { string retstr = Generate(s, sym) + "\n"; m_CSharpLine++; m_CSharpCol = 1; return retstr; }
internal void Pop(ref ParseStackEntry elt, int depth, SYMBOL ns) { for (;m_stack.Count>0 && depth>0;depth--) { elt = (ParseStackEntry)m_stack.Pop(); if (m_symbols.m_concrete) // building the concrete syntax tree ns.kids.Push(elt.m_value); // else will be garbage collected } if (depth!=0) m_symbols.erh.Error(new CSToolsException(14,m_lexer,"Pop failed")); }