public AppliedFunction(IValue[] arguments, ICompilableFunction definition, IScope parent, object body) { Definition = definition; _parent = parent; _body = body switch { ExpressionBody b => b, // No need to clone expression bodies Scope scopeBody => scopeBody.Clone(this), _ => throw new InternalCompilerException("Cannot create function instance as function body type is not recognized") }; Inputs = definition.Inputs.Skip(arguments.Length).ToArray(); SetRange(arguments.WithoutDiscardedArguments(definition.Inputs)); }
private static IValue ResolveCall(ICompilableFunction function, IScope callScope, TypeAnnotation returnType, CompilationContext compilationContext) { if (compilationContext.ContainsFunction(function.Definition)) { return(compilationContext.LogError(11, $"Multiple references to {function} in same call stack - Recursion is disallowed")); } compilationContext.PushFunction(function.Definition); try { var result = function.Compile(callScope, compilationContext); var resultConstraint = returnType?.ResolveConstraint(callScope, compilationContext) ?? AnyConstraint.Instance; return(!resultConstraint.MatchesConstraint(result, compilationContext) ? compilationContext.LogError(8, $"Result '{result}' for function '{function.Definition}' does not match '{returnType}' constraint") : result); } finally { compilationContext.PopFunction(); } }
public bool ContainsFunction(ICompilableFunction function) => FunctionStack.Contains(function);
public static IValue ApplyArguments(this ICompilableFunction function, IValue[] arguments, Port[] inputs, TypeAnnotation returnType, object body, IScope callScope, CompilationContext compilationContext) => !(arguments.Length > 0) || arguments.ValidateArguments(inputs, callScope, compilationContext) ? arguments.Length > 0 ? new AppliedFunction(arguments, function, callScope, body).ResolveNullaryFunction(compilationContext) : ResolveCall(function, callScope, returnType, compilationContext) : CompilationErr.Instance;
public void PushFunction(ICompilableFunction function) => FunctionStack.Push(function);