diff --git a/Underanalyzer/Decompiler/AST/Nodes/FunctionDeclNode.cs b/Underanalyzer/Decompiler/AST/Nodes/FunctionDeclNode.cs
index a273088..07c4a78 100644
--- a/Underanalyzer/Decompiler/AST/Nodes/FunctionDeclNode.cs
+++ b/Underanalyzer/Decompiler/AST/Nodes/FunctionDeclNode.cs
@@ -12,7 +12,7 @@ namespace Underanalyzer.Decompiler.AST;
///
/// A function declaration within the AST.
///
-public class FunctionDeclNode : IFragmentNode, IExpressionNode, IConditionalValueNode
+public class FunctionDeclNode : IFragmentNode, IMultiExpressionNode, IConditionalValueNode
{
///
/// Name of the function, or null if anonymous.
diff --git a/Underanalyzer/Decompiler/AST/Nodes/VariableCallNode.cs b/Underanalyzer/Decompiler/AST/Nodes/VariableCallNode.cs
index bbea88e..f43dab6 100644
--- a/Underanalyzer/Decompiler/AST/Nodes/VariableCallNode.cs
+++ b/Underanalyzer/Decompiler/AST/Nodes/VariableCallNode.cs
@@ -73,6 +73,7 @@ IStatementNode IASTNode.Clean(ASTCleaner cleaner)
public void Print(ASTPrinter printer)
{
+ bool canGenerateParentheses = true;
if (Instance is not null)
{
if (Function is VariableNode variable && variable is { Left: InstanceTypeNode instType } &&
@@ -86,10 +87,20 @@ public void Print(ASTPrinter printer)
{
Instance.Print(printer);
printer.Write('.');
+ canGenerateParentheses = false;
}
}
}
- Function.Print(printer);
+ if (canGenerateParentheses && Function is IMultiExpressionNode)
+ {
+ printer.Write('(');
+ Function.Print(printer);
+ printer.Write(')');
+ }
+ else
+ {
+ Function.Print(printer);
+ }
printer.Write('(');
for (int i = 0; i < Arguments.Count; i++)
{
diff --git a/UnderanalyzerTest/DecompileContext.DecompileToString.cs b/UnderanalyzerTest/DecompileContext.DecompileToString.cs
index 37106f5..d599605 100644
--- a/UnderanalyzerTest/DecompileContext.DecompileToString.cs
+++ b/UnderanalyzerTest/DecompileContext.DecompileToString.cs
@@ -2164,4 +2164,65 @@ b [8]
"""
);
}
+
+ [Fact]
+ public void TestFunctionDeclCall()
+ {
+ TestUtil.VerifyDecompileResult(
+ """
+ :[0]
+ call.i @@This@@ 0
+ b [2]
+
+ > gml_Script_anon@1@A (locals=0, args=0)
+ :[1]
+ pushi.e 1
+ pop.v.i builtin.a
+ exit.i
+
+ :[2]
+ push.i [function]gml_Script_anon@1@A
+ conv.i.v
+ pushi.e -1
+ conv.i.v
+ call.i method 2
+ callv.v 0
+ popz.v
+ push.v builtin.a
+ push.v builtin.c
+ pushi.e -9
+ push.v [stacktop]self.d
+ dup.v 1 1
+ dup.v 0
+ push.v stacktop.b
+ callv.v 1
+ popz.v
+ pushi.e 123
+ conv.i.v
+ call.i @@This@@ 0
+ push.v builtin.a
+ conv.v.b
+ bf [4]
+
+ :[3]
+ push.v builtin.b
+ b [5]
+
+ :[4]
+ push.v builtin.c
+
+ :[5]
+ callv.v 1
+ popz.v
+ """,
+ """
+ (function()
+ {
+ a = 1;
+ })();
+ a.b(c.d);
+ (a ? b : c)(123);
+ """
+ );
+ }
}