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 AST functionDeclaration() { #if WRITE_DEBUG_INFO Console.WriteLine("function declaration"); #endif if (m_isInsideFunctionDefinition) { throw new Error("Trying to define a function inside a function (are you missing the END word?)", Error.ErrorType.SYNTAX, lookAhead(1).LineNr, lookAhead(1).LinePosition); } else { m_isInsideFunctionDefinition = true; } AST_FunctionDefinitionNode funcDeclarationTree = new AST_FunctionDefinitionNode(new Token(Token.TokenType.FUNC_DECLARATION, "<FUNC_DECL>", lookAhead(1).LineNr, lookAhead(1).LinePosition)); funcDeclarationTree.addChild(match(Token.TokenType.BUILT_IN_TYPE_NAME)); // child 0 (function return type) funcDeclarationTree.addChild(match(Token.TokenType.NAME)); // child 1 (function name) match(Token.TokenType.PARANTHESIS_LEFT); funcDeclarationTree.addChild(parameterList()); // child 2 (parameter list) match(Token.TokenType.PARANTHESIS_RIGHT); allowLineBreak(); funcDeclarationTree.addChild(statementList(false)); // child 3 match(Token.TokenType.BLOCK_END); m_isInsideFunctionDefinition = false; return(funcDeclarationTree); }
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; // } }
/// <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 AST_FunctionDefinitionNode createFunctionDefinitionNode(string returnTypeName, string functionName, AST parameterList) { AST_FunctionDefinitionNode functionNode = new AST_FunctionDefinitionNode(new Token(Token.TokenType.FUNC_DECLARATION, "<EXTERNAL_FUNC_DECLARATION>")); functionNode.addChild(new Token(Token.TokenType.BUILT_IN_TYPE_NAME, returnTypeName)); functionNode.addChild(new Token(Token.TokenType.NAME, functionName)); functionNode.addChild(parameterList); functionNode.addChild(new Token(Token.TokenType.STATEMENT_LIST, "<EMPTY_STATEMENT_LIST>")); return functionNode; }
private AST_FunctionDefinitionNode createFunctionDefinitionNode(string returnTypeName, string functionName, AST parameterList) { AST_FunctionDefinitionNode functionNode = new AST_FunctionDefinitionNode(new Token(Token.TokenType.FUNC_DECLARATION, "<EXTERNAL_FUNC_DECLARATION>")); functionNode.addChild(new Token(Token.TokenType.BUILT_IN_TYPE_NAME, returnTypeName)); functionNode.addChild(new Token(Token.TokenType.NAME, functionName)); functionNode.addChild(parameterList); functionNode.addChild(new Token(Token.TokenType.STATEMENT_LIST, "<EMPTY_STATEMENT_LIST>")); return(functionNode); }
private void evaluateReferencesForFUNCTION_CALL(AST tree) { // Function name: string functionName = tree.getTokenString(); var sym = m_currentScope.resolve(functionName); FunctionSymbol function = sym as FunctionSymbol; if (function == null) { m_errorHandler.errorOccured("Can't find function with name " + functionName, Error.ErrorType.SCOPE, tree.getToken().LineNr, tree.getToken().LinePosition ); } else { #if WRITE_DEBUG_INFO Console.WriteLine("Resolved function call with name " + functionName + " (on line " + tree.getToken().LineNr + ")"); #endif // Parameters evaluateReferencesInAllChildren(tree); AST node = function.getFunctionDefinitionNode(); AST_FunctionDefinitionNode functionDefinitionTree = (AST_FunctionDefinitionNode)(node); /*if(functionDefinitionTree.getTokenString() != "<EXTERNAL_FUNC_DECLARATION>") { * evaluateReferencesForFUNC_DECLARATION(functionDefinitionTree); * }*/ // Setup reference to Function Definition AST node AST_FunctionCall functionCallAst = tree as AST_FunctionCall; Debug.Assert(functionCallAst != null); functionCallAst.FunctionDefinitionRef = functionDefinitionTree; List <AST> calleeParameterList = functionDefinitionTree.getChild(2).getChildren(); // Check that the number of arguments is right AST callerParameterList = tree.getChild(0); List <AST> arguments = callerParameterList.getChildren(); if (arguments.Count != calleeParameterList.Count) { m_errorHandler.errorOccured( "Wrong nr of arguments to '" + functionDefinitionTree.getChild(1).getTokenString() + "' , expected " + calleeParameterList.Count + " but got " + arguments.Count , Error.ErrorType.SYNTAX, tree.getToken().LineNr, tree.getToken().LinePosition); } } }
private void evaluateFunctionScope(AST tree) { // Define function name ReturnValueType returnType = ReturnValue.getReturnValueTypeFromString(tree.getChild(0).getTokenString()); string functionName = tree.getChild(1).getTokenString(); Symbol functionScope = new FunctionSymbol(m_currentScope, functionName, returnType, tree); m_globalScope.define(functionScope); // all functions are saved in the global scope m_currentScope = (Scope)functionScope; AST_FunctionDefinitionNode functionCallNode = (AST_FunctionDefinitionNode)(tree); functionCallNode.setScope((Scope)functionScope); #if WRITE_DEBUG_INFO Console.WriteLine("\nDefined function with name " + functionName + " and return type " + returnType); #endif // Process the body of the function evaluateScopeDeclarations(tree.getChild(3)); m_currentScope = m_currentScope.getEnclosingScope(); // pop scope }
private AST functionDeclaration() { #if WRITE_DEBUG_INFO Console.WriteLine("function declaration"); #endif if (m_isInsideFunctionDefinition) { throw new Error("Trying to define a function inside a function (are you missing the END word?)", Error.ErrorType.SYNTAX, lookAhead(1).LineNr, lookAhead(1).LinePosition); } else { m_isInsideFunctionDefinition = true; } AST_FunctionDefinitionNode funcDeclarationTree = new AST_FunctionDefinitionNode(new Token(Token.TokenType.FUNC_DECLARATION, "<FUNC_DECL>", lookAhead(1).LineNr, lookAhead(1).LinePosition)); funcDeclarationTree.addChild(match(Token.TokenType.BUILT_IN_TYPE_NAME)); // child 0 (function return type) funcDeclarationTree.addChild(match(Token.TokenType.NAME)); // child 1 (function name) match(Token.TokenType.PARANTHESIS_LEFT); funcDeclarationTree.addChild(parameterList()); // child 2 (parameter list) match(Token.TokenType.PARANTHESIS_RIGHT); allowLineBreak(); funcDeclarationTree.addChild(statementList(false)); // child 3 match(Token.TokenType.BLOCK_END); m_isInsideFunctionDefinition = false; return funcDeclarationTree; }
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); }