private bool TryGetFunction( TurtleScriptParser.FunctionCallContext context, out TurtleScriptFunction function) { function = null; var functionCallName = context.Identifier().GetText(); int parameterCount = 0; if (context.expressionList() != null) { parameterCount = context.expressionList().expression().Length; } functionCallName += "_" + parameterCount; foreach (var functionToTest in m_ScriptFunctions) { if ((functionToTest.Key == functionCallName) && (functionToTest.Value.Parameters.Count == parameterCount)) { function = functionToTest.Value; return(true); } } return(false); }
private static bool TryGetRuntimeFunction( TurtleScriptParser.FunctionCallContext context, ITurtleScriptRuntime runtime, string functionName, out TurtleScriptRuntimeFunction function) { int parameterCount = 0; if (context.expressionList() != null) { parameterCount = context.expressionList().expression().Length; } functionName += "_" + parameterCount; return(runtime.Functions.TryGetValue(functionName, out function)); }
private TurtleScriptValue CallRuntimeFunction( TurtleScriptParser.FunctionCallContext context, ITurtleScriptRuntime runtime, string functionName) { TurtleScriptRuntimeFunction function; if (TryGetRuntimeFunction(context, runtime, functionName, out function)) { TurtleScriptParser.ExpressionContext[] parameterExpressions = new TurtleScriptParser.ExpressionContext[0]; if (context.expressionList() != null) { parameterExpressions = context.expressionList().expression(); } if (parameterExpressions.Length != function.ParameterCount) { throw new InvalidOperationException(string.Format("Invalid number of parameters specified for function call at Line {0}, Column {1}", context.Start.Line, context.Start.Column)); } List <TurtleScriptValue> functionParameters = new List <TurtleScriptValue>(); for (int parameterIndex = 0; parameterIndex < parameterExpressions.Length; parameterIndex++) { List <TurtleScriptParser.ExpressionContext> parameterContexts = parameterExpressions.ToList(); TurtleScriptValue parameterValue = Visit(parameterContexts[parameterIndex]); functionParameters.Add(parameterValue); } TurtleScriptValue returnValue = function.Function(functionParameters); return(returnValue); } throw new InvalidOperationException(string.Format("Invalid function name in runtime. Line {0}, Column {1}", context.Start.Line, context.Start.Column)); }
public override TurtleScriptValue VisitFunctionCall(TurtleScriptParser.FunctionCallContext context) { TurtleScriptFunction function; if ((context.Identifier() != null) && (TryGetFunction(context, out function))) { TurtleScriptParser.ExpressionContext[] parameterExpressions = new TurtleScriptParser.ExpressionContext[0]; if (context.expressionList() != null) { parameterExpressions = context.expressionList().expression(); if (parameterExpressions.Length != function.Parameters.Count) { // TODO: This cannot happen as number of parameters is used to find the function initially. Will fail before here. throw new InvalidOperationException( string.Format( "Invalid number of parameters specified for function call. Line {0}, Column {1}", context.Start.Line, context.Start.Column)); } } List <TurtleScriptParser.ExpressionContext> parameterContexts = parameterExpressions.ToList(); for (int parameterIndex = 0; parameterIndex < function.Parameters.Count; parameterIndex++) { string parameterName = function.Parameters[parameterIndex].GetText(); TurtleScriptValue parameterValue = Visit(parameterContexts[parameterIndex]); SetVariableValue(parameterName, parameterValue); } TurtleScriptValue returnValue = Visit(function.Body); return(returnValue); } if (context.QualifiedIdentifier() != null) { string fullIdentifier = context.QualifiedIdentifier().GetText(); string[] identifierParts = fullIdentifier.Split('.'); string runtimeName = identifierParts[0]; string functionName = identifierParts[1]; ITurtleScriptRuntime runtime = GetRuntimeLibrary(context, runtimeName); TurtleScriptValue returnValue = CallRuntimeFunction(context, runtime, functionName); return(returnValue); } var invalidOperationException = new InvalidOperationException( string.Format( "Invalid identifier. Function name not previously defined. Line {0}, Column {1}", context.Start.Line, context.Start.Column)); throw invalidOperationException; }