public override InjectionValue VisitCall([NotNull] injectionParser.CallContext context) { var name = context.SYMBOL().GetText(); var argumentValues = context.argumentList().arguments()?.argument()? .Select(arg => VisitExpression(arg.expression())) .ToArray() ?? Array.Empty <InjectionValue>(); var result = InjectionValue.Unit; if (TryGetObjectSubrutine(name, argumentValues, out var objectSubrutine)) { result = objectSubrutine.Call(argumentValues); } else if (metadata.TryGetNativeSubrutine(name, argumentValues, out var nativeSubrutine)) { result = nativeSubrutine.Call(argumentValues); } else if (argumentValues.Any() && metadata.TryGetNativeSubrutine(name, Array.Empty <InjectionValue>(), out nativeSubrutine)) { result = nativeSubrutine.Call(Array.Empty <InjectionValue>()); } else { if (metadata.TryGetSubrutine(name, argumentValues.Length, out var customSubrutine)) { result = CallSubrutine(customSubrutine.Syntax, argumentValues); } else { var argumentKinds = argumentValues.Any() ? argumentValues.Select(x => x.Kind.ToString()).Aggregate((l, r) => l + "," + r) : "no arguments"; throw new ScriptFailedException($"Function not found {name} ({argumentKinds})", context.Start.Line); } } if (debugger != null) { debugger.AfterCall(new AfterCallContext(context, name, argumentValues, result)); } return(result); }