/// <summary> /// Decides how an expression will be handled and which actions to perform, based on the expression type. /// </summary> /// <param name="output">The output.</param> /// <param name="expression">The expression, which is being handled.</param> /// <param name="newLine">Indicates whether the expressions of the branch start on a new line.</param> private void HandleExpression(IndentedTextWriter output, ScriptExpression expression, bool newLine) { ushort ifOp = _opcodes.GetFunctionInfo("if")[0].Opcode; ushort funcNameOp = _opcodes.GetTypeInfo("function_name").Opcode; short clippedtype = (short)((short)expression.Type & 0xFF); bool _ = (ScriptExpressionType)clippedtype switch { ScriptExpressionType.Group when expression.Opcode == ifOp && expression.LineNumber == 0 => GenerateCond(output, expression, newLine), ScriptExpressionType.Group => GenerateGroup(output, expression, newLine), ScriptExpressionType.Expression when expression.ReturnType == funcNameOp => true, ScriptExpressionType.Expression => GenerateExpression(output, expression, newLine), ScriptExpressionType.ScriptReference => GenerateScriptReference(output, expression, newLine), ScriptExpressionType.GlobalsReference => GenerateGlobalsReference(output, expression, newLine), ScriptExpressionType.ParameterReference => GenerateParameterReference(output, expression, newLine), _ => throw new NotImplementedException($"The Decompiler encountered an unknown Expression Type: \"{(ScriptExpressionType)clippedtype}\".") }; }
private void GenerateCode(ScriptExpression expression, IndentedTextWriter output, bool firstrun = false) { int firstIndentedArg = int.MaxValue; bool isFunctionCall = false; if (expression.Type == ScriptExpressionType.Expression || expression.Type == ScriptExpressionType.Expression4) { ScriptValueType type = _opcodes.GetTypeInfo((ushort)expression.ReturnType); if (type.Name == "function_name") { isFunctionCall = true; if (!_nextFunctionIsScript) { FunctionInfo info = _opcodes.GetFunctionInfo(expression.Opcode); if (info != null) { if (info.Name.StartsWith("begin")) { firstIndentedArg = 0; if (expression.LineNumber > 0 && !_onNewLine) { output.Indent++; output.WriteLine(); } } else if (info.Name == "if") { firstIndentedArg = 1; } } } if (expression.LineNumber > 0) { output.Write("("); } } } bool wroteAnything = HandleExpression(expression, output); int startIndent = output.Indent; int currentArg = 0; if (_h4 && firstrun) { firstIndentedArg = 0; currentArg = 1; _h4 = false; } ScriptExpression sibling = expression.NextExpression; while (sibling != null) { if (wroteAnything && !_nextExpressionIsVar) { if (currentArg == firstIndentedArg) { output.Indent++; } if (currentArg >= firstIndentedArg) { output.WriteLine(); _onNewLine = true; } else if (output.Indent != startIndent) { output.WriteLine(); _onNewLine = true; } else { output.Write(" "); } } if (!_nextExpressionIsVar) { wroteAnything = HandleExpression(sibling, output); } else if ((_nextExpressionIsVar && sibling.Opcode != 0xFFFF)) { if (!_varTypeWritten) { ScriptValueType type = _opcodes.GetTypeInfo((ushort)sibling.ReturnType); output.Write(type.Name + " var_" + localVarCounter.ToString() + " "); _varTypeWritten = true; } wroteAnything = HandleExpression(sibling, output); } sibling = sibling.NextExpression; currentArg++; } if (isFunctionCall && expression.LineNumber > 0) { if (output.Indent != startIndent) { output.Indent = startIndent; if (wroteAnything) { output.WriteLine(); } output.Write(")"); _onNewLine = true; } else { output.Write(")"); } } }
private void GenerateCode(ScriptExpression expression, IndentedTextWriter output) { int firstIndentedArg = int.MaxValue; bool isFunctionCall = false; if (expression.Type == ScriptExpressionType.Expression) { ScriptValueType type = _opcodes.GetTypeInfo((ushort)expression.ReturnType); if (type.Name == "function_name") { isFunctionCall = true; if (!_nextFunctionIsScript) { ScriptFunctionInfo info = _opcodes.GetFunctionInfo(expression.Opcode); if (info != null) { if (info.Name.StartsWith("begin")) { firstIndentedArg = 0; if (expression.LineNumber > 0 && !_onNewLine) { output.Indent++; output.WriteLine(); } } else if (info.Name == "if") { firstIndentedArg = 1; } } } if (expression.LineNumber > 0) { output.Write("("); } } } bool wroteAnything = HandleExpression(expression, output); int startIndent = output.Indent; int currentArg = 0; ScriptExpression sibling = expression.Next; while (sibling != null) { if (wroteAnything) { if (currentArg == firstIndentedArg) { output.Indent++; } if (currentArg >= firstIndentedArg || output.Indent != startIndent) { output.WriteLine(); _onNewLine = true; } else { output.Write(" "); } } wroteAnything = HandleExpression(sibling, output); sibling = sibling.Next; currentArg++; } if (isFunctionCall && expression.LineNumber > 0) { if (output.Indent != startIndent) { output.Indent = startIndent; if (wroteAnything) { output.WriteLine(); } output.Write(")"); _onNewLine = true; } else { output.Write(")"); } } }