private DynValue InvokeFunction(FunctionCallNode functionCallNode, DynValue funcValue) { var funcName = "<anonymous>"; if (functionCallNode.Left is VariableNode vn) { funcName = vn.Identifier; funcValue = Environment.LocalScope.FindInScopeChain(vn.Identifier); if (funcValue == null) { throw new RuntimeException( $"'{funcName}' was not found in the current scope.", functionCallNode.Line ); } } var parameters = new ClrFunctionArguments(); foreach (var node in functionCallNode.Parameters) { parameters.Add(Visit(node)); } if (Environment.CallStack.Count > Environment.CallStackLimit) { throw new RuntimeException("Call stack overflow.", functionCallNode.Line); } DynValue retVal; if (funcValue.Type == DynValueType.ClrFunction) { retVal = ExecuteClrFunction(funcValue.ClrFunction, funcName, parameters); } else { Environment.EnterScope(Environment.GlobalScope.HasMember(funcName)); { retVal = ExecuteScriptFunction(funcValue.ScriptFunction, funcName, parameters, functionCallNode); } Environment.ExitScope(); } return(retVal); }
public override DynValue Visit(FunctionCallNode functionCallNode) { var name = functionCallNode.FunctionName; var parameters = new ClrFunctionArguments(); foreach (var node in functionCallNode.Parameters) { parameters.Add(Visit(node)); } if (Environment.Functions.ContainsKey(name)) { var scriptFunction = Environment.Functions[name]; if (CallStack.Count > 255) { while (CallStack.Count != 0) { CallStack.Pop(); } throw new RuntimeException("Call stack overflow.", functionCallNode.Line); } var callStackItem = new CallStackItem(name); var iterator = 0; foreach (var parameterName in scriptFunction.ParameterNames) { if (callStackItem.ParameterScope.ContainsKey(parameterName)) { throw new RuntimeException($"Parameter {parameterName} already defined.", functionCallNode.Line); } if (iterator < parameters.Count) { callStackItem.ParameterScope.Add(parameterName, parameters[iterator++]); } else { callStackItem.ParameterScope.Add(parameterName, DynValue.Zero); } } CallStack.Push(callStackItem); var retval = DynValue.Zero; try { retval = ExecuteStatementList(scriptFunction.StatementList).Result; } catch (ScriptTerminationException) { throw; } catch (RuntimeException) { throw; } catch (ExitStatementException) { } catch (Exception e) { if (!(e.InnerException is ScriptTerminationException)) { throw new RuntimeException(e.Message, functionCallNode.Line); } } finally { CallStack.Pop(); } return(retval); } else if (Environment.BuiltIns.ContainsKey(name)) { var clrFunction = Environment.BuiltIns[name]; if (CallStack.Count > 255) { while (CallStack.Count != 0) { CallStack.Pop(); } throw new RuntimeException("Call stack overflow.", functionCallNode.Line); } var callStackitem = new CallStackItem($"kernel![{name}]"); CallStack.Push(callStackitem); DynValue retVal; try { retVal = clrFunction(this, parameters); } finally { CallStack.Pop(); } return(retVal); } else { throw new RuntimeException($"Function '{name}' does not exist.", functionCallNode.Line); } }