/// <summary> /// Sets the program to execute function. /// Returns true if the program had the function. /// </summary> public ProgramFunctionCallStatus SetProgramToExecuteFunction(string functionName, object[] args) { //Console.WriteLine ("Will execute '" + functionName + "' in global scope '" + m_globalScope + "'"); FunctionSymbol functionSymbol = (FunctionSymbol)m_globalScope.resolve(functionName); //Console.WriteLine("Found function symbol: " + functionSymbol.ToString()); if (functionSymbol == null) { return(ProgramFunctionCallStatus.NO_FUNCTION); } if (IsFunctionExternal(functionName)) { CallExternalFunction(functionName, args); return(ProgramFunctionCallStatus.EXTERNAL_FUNCTION); } else { AST_FunctionDefinitionNode functionDefinitionNode = (AST_FunctionDefinitionNode)functionSymbol.getFunctionDefinitionNode(); if (functionDefinitionNode != null) { var parameters = functionDefinitionNode.getChild(2).getChildren(); int nrOfParameters = parameters.Count; if (nrOfParameters != args.Length) { throw new Error("The function " + functionName + " takes " + nrOfParameters + " arguments, not " + args.Length); } Reset(); m_topLevelDepth = 1; m_currentScope = functionDefinitionNode.getScope(); m_currentScope.ClearMemorySpaces(); string nameOfNewMemorySpace = functionName + "_memorySpace" + functionCounter++; PushNewScope(functionDefinitionNode.getScope(), nameOfNewMemorySpace, functionDefinitionNode); for (int i = args.Length - 1; i >= 0; i--) { var declaration = parameters[i].getChild(0) as AST_VariableDeclaration; object convertedValue = ReturnValueConversions.ChangeTypeBasedOnReturnValueType(args[i], declaration.Type); PushValue(convertedValue); // reverse order } //Console.WriteLine ("Ready to start running function '" + functionName + "' with memory space '" + nameOfNewMemorySpace + "'"); } else { throw new Error(functionName + " has got no function definition node!"); } } return(ProgramFunctionCallStatus.NORMAL_FUNCTION); // all went well (starting the function) }
private void JumpToFunction() { AST_FunctionDefinitionNode functionDefinitionNode = (CurrentNode as AST_FunctionCall).FunctionDefinitionRef; string functionName = functionDefinitionNode.getChild(1).getTokenString(); int nrOfParameters = functionDefinitionNode.getChild(2).getChildren().Count; ReturnValue[] parameters = new ReturnValue[nrOfParameters]; for (int i = nrOfParameters - 1; i >= 0; i--) { parameters[i] = PopValue(); } if (m_externalFunctionCreator.externalFunctions.ContainsKey(functionName)) { //Console.WriteLine("Calling external function " + functionName); ExternalFunctionCreator.OnFunctionCall fc = m_externalFunctionCreator.externalFunctions[functionName]; ReturnValue rv = fc(parameters); if (rv.getReturnValueType() != ReturnValueType.VOID) { PushValue(rv); } } else { PushNewScope(functionDefinitionNode.getScope(), functionName + "_memorySpace" + functionCounter++, functionDefinitionNode); for (int i = nrOfParameters - 1; i >= 0; i--) { PushValue(parameters[i]); // reverse order } } }
private void JumpToFunction() { AST_FunctionDefinitionNode functionDefinitionNode = (CurrentNode as AST_FunctionCall).FunctionDefinitionRef; string functionName = functionDefinitionNode.getChild(1).getTokenString(); #if BUILT_IN_PROFILING ProfileData data = null; if (m_profileData.TryGetValue(functionName, out data)) { data.calls++; } else { m_profileData.Add(functionName, new ProfileData() { calls = 1, totalTime = 0f, }); } #endif var parameterDefs = functionDefinitionNode.getChild(2).getChildren(); //ASTPainter painter = new ASTPainter(); int nrOfParameters = parameterDefs.Count; object[] parameters = new object[nrOfParameters]; for (int i = nrOfParameters - 1; i >= 0; i--) { //painter.PaintAST(parameterDefs[i]); var paramDef = parameterDefs[i]; var declaration = paramDef.getChild(0) as AST_VariableDeclaration; parameters[i] = ReturnValueConversions.ChangeTypeBasedOnReturnValueType(PopValue(), declaration.Type); } //try { if (IsFunctionExternal(functionName)) { CallExternalFunction(functionName, parameters); } else { PushNewScope(functionDefinitionNode.getScope(), functionName + "_memorySpace" + functionCounter++, functionDefinitionNode); for (int i = nrOfParameters - 1; i >= 0; i--) { PushValue(parameters[i]); // reverse order } } // } // catch(Exception e) { // Console.WriteLine("Exception when calling " + functionName + ": " + e.StackTrace); // throw e; // } }
private ReturnValue function(AST tree, List <ReturnValue> parameterValues) { // Push scope Scope m_previousScope = m_currentScope; AST_FunctionDefinitionNode functionDefinitionNode = (AST_FunctionDefinitionNode)(tree); Assert.IsNotNull(functionDefinitionNode); m_currentScope = (Scope)functionDefinitionNode.getScope(); Assert.IsNotNull(m_currentScope); // Push memory space MemorySpace m_previousMemorySpace = m_currentMemorySpace; MemorySpace functionMemorySpace = new MemorySpace("<FUNCTION_SPACE " + tree.getChild(1).getTokenString() + ">"); m_memoryStack.Push(functionMemorySpace); m_currentMemorySpace = functionMemorySpace; // Add parameters to memory space List <AST> parameterDeclarations = tree.getChild(2).getChildren(); if (parameterDeclarations != null) { if (parameterDeclarations.Count != parameterValues.Count) { m_errorHandler.errorOccured( "The number of arguments in function " + tree.getChild(1).getTokenString() + " does not match!", Error.ErrorType.SYNTAX); } foreach (AST parameter in parameterDeclarations) { varDeclaration(parameter); } } // Assign values to parameters if (parameterValues != null) { int i = 0; foreach (ReturnValue parameterValue in parameterValues) { string parameterName = parameterDeclarations[i].getChild(1).getTokenString(); assignValue(parameterName, parameterValue); i++; } } // Execute function ReturnValue returnValue = null; try { executeAllChildNodes(tree.getChild(3)); // child 3 is the function body } catch (ReturnValue functionReturnValue) { returnValue = functionReturnValue; } // Pop memory space m_memoryStack.Pop(); m_currentMemorySpace = m_previousMemorySpace; // Pop scope m_currentScope = m_previousScope; Assert.IsNotNull(m_currentScope); return(returnValue); }