private object ExecuteProcedureCall(ParseTreeNode procedureCallNode) { var isFunction = string.Equals(procedureCallNode.Term.Name, "FUNCTION_CALL", StringComparison.InvariantCultureIgnoreCase); var procedureName = string.Empty; ParseTreeNodeList argumentNodes = null; if (isFunction) { procedureName = procedureCallNode.ChildNodes[1].Token.Text; argumentNodes = procedureCallNode.ChildNodes[2].ChildNodes; } else { procedureName = procedureCallNode.ChildNodes[0].Token.Text; argumentNodes = procedureCallNode.ChildNodes[1].ChildNodes; } var hasArguments = argumentNodes.Count > 0; var callingProcedureArguments = new List <object>(); if (hasArguments) { foreach (var argumentNode in argumentNodes) { if (argumentNode.Term.Name == "EXPRESSION") { callingProcedureArguments.Add(EvaluateArithmeticExpression(argumentNode).Value); } } } var procedure = procedures.FirstOrDefault(x => string.Equals(procedureName, x.Name, StringComparison.InvariantCultureIgnoreCase)); if (procedure != null) { if (callingProcedureArguments.Count != procedure.Arguments.Count()) { throw new RuntimeException($"Procedure call argument count mismatch."); } var procedureScope = new ProcedureScope(procedureName); for (var idx = 0; idx < procedure.Arguments.Count(); idx++) { procedureScope[procedure.Arguments.ElementAt(idx)] = callingProcedureArguments[idx]; } procedureScopes.Push(procedureScope); procedure.Invoke(this, out var result); procedureScopes.Pop(); return(result); } else { throw new RuntimeException($"The calling procedure {procedureName} is not defined."); } }
/// <summary> /// Executes the function invocation. /// </summary> /// <param name="procedureScope">The <see cref="ProcedureScope"/> which provides the variables /// in the calling procedure.</param> /// <returns>The execution return value.</returns> protected override float Execute(ProcedureScope procedureScope) { var iVal = Convert.ToInt32(procedureScope["p"]); return(rnd.Next(iVal)); }
/// <summary> /// Executes the function invocation. /// </summary> /// <param name="procedureScope">The <see cref="ProcedureScope"/> which provides the variables /// in the calling procedure.</param> /// <returns>The execution return value.</returns> protected abstract float Execute(ProcedureScope procedureScope);
/// <summary> /// Executes the function invocation. /// </summary> /// <param name="procedureScope">The <see cref="ProcedureScope"/> which provides the variables /// in the calling procedure.</param> /// <returns>The execution return value.</returns> protected override float Execute(ProcedureScope procedureScope) => Convert.ToSingle(Math.Sqrt(Convert.ToDouble(procedureScope["p"])));