private void assignment(AST tree) { string variableName = tree.getChild(0).getTokenString(); AST expression = tree.getChild(1); ReturnValue expressionValue = execute(expression); assignValue(variableName, expressionValue); }
private void ifThenElse(AST tree) { // Push scope AST_IfNode ifNode = (AST_IfNode)(tree); Assert.IsNotNull(ifNode); m_currentScope = (Scope)ifNode.getScope(); Assert.IsNotNull(m_currentScope); // Evaluate conditional ReturnValue conditionalExpression = execute(tree.getChild(0)); if (conditionalExpression.FloatValue != 0) { Assert.IsNotNull(tree.getChild(1)); execute(tree.getChild(1)); } else { if (tree.getChildren().Count == 3) { Assert.IsNotNull(tree.getChild(2)); execute(tree.getChild(2)); } } // Pop scope m_currentScope = (Scope)ifNode.getScope().getEnclosingScope(); Assert.IsNotNull(m_currentScope); }
private void assignment(AST tree) { string variableName = tree.getChild(0).getTokenString(); AST expression = tree.getChild(1); ReturnValue expressionValue = execute(expression); assignValue(variableName, expressionValue); }
private void evaluateReferencesForFUNC_DECLARATION(AST tree) { string functionName = tree.getChild(1).getTokenString(); m_currentScope = (Scope)m_currentScope.resolve(functionName); // push the scope with the function #if WRITE_DEBUG_INFO Console.WriteLine("\n Trying to resolve function parameters and body of " + functionName); #endif evaluateReferencesInAllChildren(tree.getChild(2)); // parameters evaluateReferencesInAllChildren(tree.getChild(3)); // function body m_currentScope = m_currentScope.getEnclosingScope(); // pop scope }
private ExternalFunctionCreator AddExternalFunctions(FunctionDefinition[] functionDefinitions, AST ast) { List <FunctionDefinition> allFunctionDefinitions = new List <FunctionDefinition>(); allFunctionDefinitions.AddRange(builtInFunctions); allFunctionDefinitions.AddRange(functionDefinitions); // HasFunction requires a reference to the SprakRunner FunctionDocumentation functionDoc_HasFunction = new FunctionDocumentation("Check if a function exists on the object", new string[] { "The name of the function" }); allFunctionDefinitions.Add(new FunctionDefinition("bool", "HasFunction", new string[] { "string" }, new string[] { "functionName" }, new ExternalFunctionCreator.OnFunctionCall(API_hasFunction), functionDoc_HasFunction)); FunctionDocumentation functionDoc_ListFunctions = new FunctionDocumentation("List all functions on the object", new string[] { }); allFunctionDefinitions.Add(new FunctionDefinition("array", "ListFunctions", new string[] { }, new string[] { }, new ExternalFunctionCreator.OnFunctionCall(API_listFunction), functionDoc_ListFunctions)); ExternalFunctionCreator externalFunctionCreator = new ExternalFunctionCreator(allFunctionDefinitions.ToArray()); AST functionList = ast.getChild(1); foreach (AST externalFunction in externalFunctionCreator.FunctionASTs) { functionList.addChild(externalFunction); } return(externalFunctionCreator); }
void AddLocalVariables(AST ast, VariableDefinition[] variableDefinitions) { AST nodeForDefiningGlobalVariables = ast.getChild(0).getChild(0); if (variableDefinitions == null) { return; } foreach (VariableDefinition vd in variableDefinitions) { Token token = new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>", ast.getToken().LineNr, ast.getToken().LinePosition); AST_VariableDeclaration declarationTree = new AST_VariableDeclaration(token, ReturnValueConversions.SystemTypeToReturnValueType(vd.initValue.GetType()), vd.variableName); if (vd.initValue != null) { AST assignmentTree = CreateAssignmentTreeFromInitValue(vd.variableName, vd.initValue); AST declarationAndAssignmentTree = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<DECLARATION_AND_ASSIGNMENT>", declarationTree.getToken().LineNr, declarationTree.getToken().LinePosition)); declarationAndAssignmentTree.addChild(declarationTree); declarationAndAssignmentTree.addChild(assignmentTree); nodeForDefiningGlobalVariables.addChild(declarationAndAssignmentTree); } else { nodeForDefiningGlobalVariables.addChild(declarationTree); } } }
public void ChangeGlobalVariableInitValue(string pName, object pobject) { bool foundVariable = false; AST statementListTree = m_ast.getChild(0); AST globalVarDefs = statementListTree.getChild(0); if (globalVarDefs.getTokenString() != "<GLOBAL_VARIABLE_DEFINITIONS_LIST>") { throw new Exception("Wrong node, " + globalVarDefs.getTokenString()); } if (globalVarDefs.getChildren() != null && globalVarDefs.getChildren().Count > 0) { foreach (AST defAndAssignmentNode in globalVarDefs.getChildren()) { AST_Assignment assigmentNode = (AST_Assignment)defAndAssignmentNode.getChild(1); if (assigmentNode.VariableName == pName) { defAndAssignmentNode.removeChild(1); defAndAssignmentNode.addChild(CreateAssignmentTreeFromInitValue(pName, pobject)); foundVariable = true; break; } } } if (!foundVariable) { throw new Exception("Couldn't find and change the variable " + pName); } }
private void evaluateIfScope(AST tree) { Scope subscope = new Scope(Scope.ScopeType.IF_SCOPE, "<IF-SUBSCOPE>", m_currentScope); m_currentScope = subscope; AST_IfNode ifNode = (tree as AST_IfNode); Debug.Assert(ifNode != null); #if WRITE_DEBUG_INFO Console.WriteLine("\nDefined IF-subscope for ifNode at line " + ifNode.getToken().LineNr); #endif ifNode.setScope(subscope); // save the new scope in the IF-token tree node // Evaluate expression evaluateScopeDeclarationsInAllChildren(tree.getChild(0)); AST trueNode = ifNode.getChild(1); AST falseNode = null; if (ifNode.getChildren().Count == 3) { falseNode = ifNode.getChild(2); } evaluateScopeDeclarationsInAllChildren(trueNode); if (falseNode != null) { evaluateScopeDeclarationsInAllChildren(falseNode); } m_currentScope = m_currentScope.getEnclosingScope(); // pop scope }
private void varDeclaration(AST tree) { string typeName = tree.getChild(0).getTokenString(); ReturnValueType variableType = ReturnValue.getReturnValueTypeFromString(typeName); string variableName = tree.getChild(1).getTokenString(); switch (variableType) { case ReturnValueType.FLOAT: m_currentMemorySpace.setValue(variableName, new ReturnValue(0.0f)); break; case ReturnValueType.STRING: m_currentMemorySpace.setValue(variableName, new ReturnValue(0.0f)); break; default: throw new InvalidOperationException("Can't declare a variable of type " + typeName); } }
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 void addToList(List <AST> list, AST ast) { switch (ast.getTokenType()) { case Token.TokenType.FUNC_DECLARATION: addToList(list, ast.getChild(2)); addToList(list, ast.getChild(3)); break; case Token.TokenType.IF: addToList(list, ast.getChild(0)); list.Add(ast); #if WRITE_DEBUG_INFO Console.WriteLine(": " + ast.getTokenString() + " of type " + ast.getTokenType()); #endif break; case Token.TokenType.LOOP: list.Add(ast); #if WRITE_DEBUG_INFO Console.WriteLine(": " + ast.getTokenString() + " of type " + ast.getTokenType()); #endif break; case Token.TokenType.LOOP_BLOCK: list.Add(ast); #if WRITE_DEBUG_INFO Console.WriteLine(": " + ast.getTokenString() + " of type " + ast.getTokenType()); #endif break; default: addChildren(list, ast); #if WRITE_DEBUG_INFO Console.WriteLine(": " + ast.getTokenString() + " of type " + ast.getTokenType()); #endif list.Add(ast); break; } }
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 }
public void BasicEvaluation() { Tokenizer tokenizer = new Tokenizer(s_errorHandler, true); List <Token> tokens = tokenizer.process(File.OpenText("code9.txt")); Parser parser = new Parser(tokens, s_errorHandler); parser.process(); AST root = parser.getAST(); AST expressionTree = root.getChild(0).getChild(0); ExpressionEvaluator e1 = new ExpressionEvaluator(expressionTree); Assert.AreEqual(26, e1.getValue()); }
public void HandleNegativeNumbers() { Tokenizer tokenizer = new Tokenizer(s_errorHandler, true); List <Token> tokens = tokenizer.process(File.OpenText("code10.txt")); Parser parser = new Parser(tokens, s_errorHandler); parser.process(); AST root = parser.getAST(); AST expressionTree = root.getChild(0).getChild(0); ExpressionEvaluator e = new ExpressionEvaluator(expressionTree); Assert.AreEqual(-5, e.getValue()); }
private void returnStatement(AST tree) { ReturnValue returnValue = new ReturnValue(); if (tree.getChildren().Count > 0) { returnValue = execute(tree.getChild(0)); } if (returnValue != null) { #if WRITE_DEBUG_INFO Console.Write("Return value was: "); printReturnValue(returnValue); #endif throw returnValue; } }
private ExternalFunctionCreator AddExternalFunctions(FunctionDefinition[] functionDefinitions, AST ast) { List <FunctionDefinition> allFunctionDefinitions = new List <FunctionDefinition>(); allFunctionDefinitions.AddRange(builtInFunctions); allFunctionDefinitions.AddRange(functionDefinitions); ExternalFunctionCreator externalFunctionCreator = new ExternalFunctionCreator(allFunctionDefinitions.ToArray()); AST functionList = ast.getChild(1); foreach (AST externalFunction in externalFunctionCreator.FunctionASTs) { functionList.addChild(externalFunction); } return(externalFunctionCreator); }
private void evaluateIfScope(AST tree) { Scope subscope = new Scope(Scope.ScopeType.IF_SCOPE,"<IF-SUBSCOPE>", m_currentScope); #if WRITE_DEBUG_INFO Console.WriteLine("\nDefined IF-subscope"); #endif m_currentScope = subscope; AST_IfNode ifNode = (tree as AST_IfNode); Debug.Assert(ifNode != null); ifNode.setScope(subscope); // save the new scope in the IF-token tree node // Evaluate expression evaluateScopeDeclarationsInAllChildren(tree.getChild(0)); AST trueNode = ifNode.getChild(1); AST falseNode = null; if (ifNode.getChildren().Count == 3) { falseNode = ifNode.getChild(2); } evaluateScopeDeclarationsInAllChildren(trueNode); if (falseNode != null) { evaluateScopeDeclarationsInAllChildren(falseNode); } m_currentScope = m_currentScope.getEnclosingScope(); // pop scope }
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); }
private ReturnValue operation(AST tree) { ReturnValue returnValue = null; float lhs = execute(tree.getChild(0)).FloatValue; float rhs = execute(tree.getChild(1)).FloatValue; if (tree.getTokenString() == "+") { returnValue = new ReturnValue(lhs + rhs); } else if (tree.getTokenString() == "-") { returnValue = new ReturnValue(lhs - rhs); } else if (tree.getTokenString() == "*") { returnValue = new ReturnValue(lhs * rhs); } else if (tree.getTokenString() == "/") { returnValue = new ReturnValue(lhs / rhs); } else if (tree.getTokenString() == "<") { float v = lhs < rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if (tree.getTokenString() == ">") { float v = lhs > rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if (tree.getTokenString() == "<=") { float v = lhs <= rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if (tree.getTokenString() == ">=") { float v = lhs >= rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if (tree.getTokenString() == "==") { float v = lhs == rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if (tree.getTokenString() == "!=") { float v = lhs != rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if (tree.getTokenString() == "&&") { float v = ((lhs != 0 ? true : false) && (rhs != 0 ? true : false)) ? 1 : 0; returnValue = new ReturnValue(v); } else if (tree.getTokenString() == "||") { float v = ((lhs != 0 ? true : false) || (rhs != 0 ? true : false)) ? 1 : 0; returnValue = new ReturnValue(v); } else { throw new NotImplementedException("Operator " + tree.getTokenString() + " isn't implemented yet!"); } return(returnValue); }
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; }
private void returnStatement(AST tree) { ReturnValue returnValue = new ReturnValue(); if (tree.getChildren().Count > 0) { returnValue = execute(tree.getChild(0)); } if(returnValue != null) { #if WRITE_DEBUG_INFO Console.Write("Return value was: "); printReturnValue(returnValue); #endif throw returnValue; } }
private void addToList(List<AST> list, AST ast) { switch (ast.getTokenType()) { case Token.TokenType.FUNC_DECLARATION: addToList(list, ast.getChild(2)); addToList(list, ast.getChild(3)); break; case Token.TokenType.IF: addToList(list, ast.getChild(0)); list.Add(ast); #if WRITE_DEBUG_INFO Console.WriteLine(": " + ast.getTokenString() + " of type " + ast.getTokenType()); #endif break; case Token.TokenType.LOOP: list.Add(ast); #if WRITE_DEBUG_INFO Console.WriteLine(": " + ast.getTokenString() + " of type " + ast.getTokenType()); #endif break; case Token.TokenType.LOOP_BLOCK: list.Add(ast); #if WRITE_DEBUG_INFO Console.WriteLine(": " + ast.getTokenString() + " of type " + ast.getTokenType()); #endif break; default: addChildren(list, ast); #if WRITE_DEBUG_INFO Console.WriteLine(": " + ast.getTokenString() + " of type " + ast.getTokenType()); #endif list.Add(ast); break; } }
private float evaluate(AST tree) { float returnValue = 0; if(tree.getTokenType() == Token.TokenType.NUMBER) { returnValue = (float)System.Convert.ToDouble(tree.getTokenString()); } else if(tree.getTokenType() == Token.TokenType.OPERATOR) { if(tree.getTokenString() == "+") { returnValue = evaluate(tree.getChild(0)) + evaluate(tree.getChild(1)); } else if(tree.getTokenString() == "-") { returnValue = evaluate(tree.getChild(0)) - evaluate(tree.getChild(1)); } else if(tree.getTokenString() == "*") { returnValue = evaluate(tree.getChild(0)) * evaluate(tree.getChild(1)); } else if(tree.getTokenString() == "/") { returnValue = evaluate(tree.getChild(0)) / evaluate(tree.getChild(1)); } else if(tree.getTokenString() == "<") { returnValue = (evaluate(tree.getChild(0)) < evaluate(tree.getChild(1))) ? 1 : 0; } else if(tree.getTokenString() == ">") { returnValue = (evaluate(tree.getChild(0)) > evaluate(tree.getChild(1))) ? 1 : 0; } else if(tree.getTokenString() == "<=") { returnValue = (evaluate(tree.getChild(0)) <= evaluate(tree.getChild(1))) ? 1 : 0; } else if(tree.getTokenString() == ">=") { returnValue = (evaluate(tree.getChild(0)) >= evaluate(tree.getChild(1))) ? 1 : 0; } else if(tree.getTokenString() == "&&") { returnValue = (evaluate(tree.getChild(0)) != 0 && evaluate(tree.getChild(1)) != 0) ? 1 : 0; } else if(tree.getTokenString() == "||") { returnValue = (evaluate(tree.getChild(0)) != 0 || evaluate(tree.getChild(1)) != 0) ? 1 : 0; } else if(tree.getTokenString() == "!=") { returnValue = (evaluate(tree.getChild(0)) != evaluate(tree.getChild(1))) ? 1 : 0; } else if(tree.getTokenString() == "==") { returnValue = (evaluate(tree.getChild(0)) == evaluate(tree.getChild(1))) ? 1 : 0; } else { throw new InvalidOperationException("ExpressionEvaluator can't handle operators with string " + tree.getTokenString()); } } else { throw new InvalidOperationException("ExpressionEvaluator can't handle tokens of type " + tree.getTokenType()); } return returnValue; }
private ReturnValue operation(AST tree) { ReturnValue returnValue = null; float lhs = execute(tree.getChild(0)).FloatValue; float rhs = execute(tree.getChild(1)).FloatValue; if(tree.getTokenString() == "+") { returnValue = new ReturnValue(lhs + rhs); } else if(tree.getTokenString() == "-") { returnValue = new ReturnValue(lhs - rhs); } else if(tree.getTokenString() == "*") { returnValue = new ReturnValue(lhs * rhs); } else if(tree.getTokenString() == "/") { returnValue = new ReturnValue(lhs / rhs); } else if(tree.getTokenString() == "<") { float v = lhs < rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if(tree.getTokenString() == ">") { float v = lhs > rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if(tree.getTokenString() == "<=") { float v = lhs <= rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if(tree.getTokenString() == ">=") { float v = lhs >= rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if(tree.getTokenString() == "==") { float v = lhs == rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if(tree.getTokenString() == "!=") { float v = lhs != rhs ? 1 : 0; returnValue = new ReturnValue(v); } else if(tree.getTokenString() == "&&") { float v = ((lhs != 0 ? true : false) && (rhs != 0 ? true : false)) ? 1 : 0; returnValue = new ReturnValue(v); } else if(tree.getTokenString() == "||") { float v = ((lhs != 0 ? true : false) || (rhs != 0 ? true : false)) ? 1 : 0; returnValue = new ReturnValue(v); } else { throw new NotImplementedException("Operator " + tree.getTokenString() + " isn't implemented yet!"); } return returnValue; }
private float evaluate(AST tree) { float returnValue = 0; if (tree.getTokenType() == Token.TokenType.NUMBER) { returnValue = (float)System.Convert.ToDouble(tree.getTokenString()); } else if (tree.getTokenType() == Token.TokenType.OPERATOR) { if (tree.getTokenString() == "+") { returnValue = evaluate(tree.getChild(0)) + evaluate(tree.getChild(1)); } else if (tree.getTokenString() == "-") { returnValue = evaluate(tree.getChild(0)) - evaluate(tree.getChild(1)); } else if (tree.getTokenString() == "*") { returnValue = evaluate(tree.getChild(0)) * evaluate(tree.getChild(1)); } else if (tree.getTokenString() == "/") { returnValue = evaluate(tree.getChild(0)) / evaluate(tree.getChild(1)); } else if (tree.getTokenString() == "<") { returnValue = (evaluate(tree.getChild(0)) < evaluate(tree.getChild(1))) ? 1 : 0; } else if (tree.getTokenString() == ">") { returnValue = (evaluate(tree.getChild(0)) > evaluate(tree.getChild(1))) ? 1 : 0; } else if (tree.getTokenString() == "<=") { returnValue = (evaluate(tree.getChild(0)) <= evaluate(tree.getChild(1))) ? 1 : 0; } else if (tree.getTokenString() == ">=") { returnValue = (evaluate(tree.getChild(0)) >= evaluate(tree.getChild(1))) ? 1 : 0; } else if (tree.getTokenString() == "&&") { returnValue = (evaluate(tree.getChild(0)) != 0 && evaluate(tree.getChild(1)) != 0) ? 1 : 0; } else if (tree.getTokenString() == "||") { returnValue = (evaluate(tree.getChild(0)) != 0 || evaluate(tree.getChild(1)) != 0) ? 1 : 0; } else if (tree.getTokenString() == "!=") { returnValue = (evaluate(tree.getChild(0)) != evaluate(tree.getChild(1))) ? 1 : 0; } else if (tree.getTokenString() == "==") { returnValue = (evaluate(tree.getChild(0)) == evaluate(tree.getChild(1))) ? 1 : 0; } else { throw new InvalidOperationException("ExpressionEvaluator can't handle operators with string " + tree.getTokenString()); } } else { throw new InvalidOperationException("ExpressionEvaluator can't handle tokens of type " + tree.getTokenType()); } return(returnValue); }
private ExternalFunctionCreator AddExternalFunctions(FunctionDefinition[] functionDefinitions, AST ast) { List<FunctionDefinition> allFunctionDefinitions = new List<FunctionDefinition>(); allFunctionDefinitions.AddRange(builtInFunctions); allFunctionDefinitions.AddRange(functionDefinitions); // HasFunction requires a reference to the SprakRunner FunctionDocumentation functionDoc_HasFunction = new FunctionDocumentation("Check if a function exists on the object", new string[] { "The name of the function" }); allFunctionDefinitions.Add(new FunctionDefinition("bool", "HasFunction", new string[] { "string" }, new string[] { "functionName" }, new ExternalFunctionCreator.OnFunctionCall(API_hasFunction), functionDoc_HasFunction)); ExternalFunctionCreator externalFunctionCreator = new ExternalFunctionCreator(allFunctionDefinitions.ToArray()); AST functionList = ast.getChild(1); foreach (AST externalFunction in externalFunctionCreator.FunctionASTs) { functionList.addChild(externalFunction); } return externalFunctionCreator; }
private void evaluateReferencesForFUNC_DECLARATION(AST tree) { string functionName = tree.getChild(1).getTokenString(); m_currentScope = (Scope)m_currentScope.resolve(functionName); // push the scope with the function #if WRITE_DEBUG_INFO Console.WriteLine("\n Trying to resolve function parameters and body of " + functionName); #endif evaluateReferencesInAllChildren(tree.getChild(2)); // parameters evaluateReferencesInAllChildren(tree.getChild(3)); // function body m_currentScope = m_currentScope.getEnclosingScope(); // pop scope }
private ExternalFunctionCreator AddExternalFunctions(FunctionDefinition[] functionDefinitions, AST ast) { List<FunctionDefinition> allFunctionDefinitions = new List<FunctionDefinition>(); allFunctionDefinitions.AddRange(builtInFunctions); allFunctionDefinitions.AddRange(functionDefinitions); ExternalFunctionCreator externalFunctionCreator = new ExternalFunctionCreator(allFunctionDefinitions.ToArray()); AST functionList = ast.getChild(1); foreach (AST externalFunction in externalFunctionCreator.FunctionASTs) { functionList.addChild(externalFunction); } return externalFunctionCreator; }
void AddLocalVariables(AST ast, VariableDefinition[] variableDefinitions) { AST nodeForDefiningGlobalVariables = ast.getChild(0).getChild(0); if(variableDefinitions == null) { return; } foreach(VariableDefinition vd in variableDefinitions) { Token token = new Token(Token.TokenType.VAR_DECLARATION,"<VAR_DECL>", ast.getToken().LineNr, ast.getToken().LinePosition); AST_VariableDeclaration declarationTree = new AST_VariableDeclaration(token, vd.initValue.getReturnValueType(), vd.variableName); if(vd.initValue != null) { AST assignmentTree = CreateAssignmentTreeFromInitValue(vd.variableName, vd.initValue); AST declarationAndAssignmentTree = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<DECLARATION_AND_ASSIGNMENT>", declarationTree.getToken().LineNr, declarationTree.getToken().LinePosition)); declarationAndAssignmentTree.addChild(declarationTree); declarationAndAssignmentTree.addChild(assignmentTree); nodeForDefiningGlobalVariables.addChild(declarationAndAssignmentTree); } else { nodeForDefiningGlobalVariables.addChild(declarationTree); } } }
private void ifThenElse(AST tree) { // Push scope AST_IfNode ifNode = (AST_IfNode)(tree); Assert.IsNotNull(ifNode); m_currentScope = (Scope)ifNode.getScope(); Assert.IsNotNull(m_currentScope); // Evaluate conditional ReturnValue conditionalExpression = execute(tree.getChild(0)); if (conditionalExpression.FloatValue != 0) { Assert.IsNotNull(tree.getChild(1)); execute(tree.getChild(1)); } else { if (tree.getChildren().Count == 3) { Assert.IsNotNull(tree.getChild(2)); execute(tree.getChild(2)); } } // Pop scope m_currentScope = (Scope)ifNode.getScope().getEnclosingScope(); Assert.IsNotNull(m_currentScope); }
private void evaluateReferencesForFUNCTION_CALL(AST tree) { // Function name: string functionName = tree.getTokenString(); FunctionSymbol function = (FunctionSymbol)m_currentScope.resolve(functionName); 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 number of arguments to function" , Error.ErrorType.SYNTAX, tree.getToken().LineNr, tree.getToken().LinePosition); } } }
private void varDeclaration(AST tree) { string typeName = tree.getChild(0).getTokenString(); ReturnValueType variableType = ReturnValue.getReturnValueTypeFromString(typeName); string variableName = tree.getChild(1).getTokenString(); switch(variableType) { case ReturnValueType.FLOAT: m_currentMemorySpace.setValue(variableName, new ReturnValue(0.0f)); break; case ReturnValueType.STRING: m_currentMemorySpace.setValue(variableName, new ReturnValue(0.0f)); break; default: throw new InvalidOperationException("Can't declare a variable of type " + typeName); } }