private void evaluateReferencesForNAME(AST tree) { Symbol symbol = m_currentScope.resolve(tree.getTokenString()); if (symbol == null) { m_errorHandler.errorOccured( new Error("Can't find anything called '" + tree.getTokenString() + "'", Error.ErrorType.SYNTAX, tree.getToken().LineNr, tree.getToken().LinePosition)); } else if (symbol is FunctionSymbol) { m_errorHandler.errorOccured( new Error("'" + tree.getTokenString() + "' is a function and must be called with ()", Error.ErrorType.SYNTAX, tree.getToken().LineNr, tree.getToken().LinePosition)); } #if WRITE_DEBUG_INFO Console.WriteLine("Resolved symbol with name " + tree.getTokenString() + " (on line " + tree.getToken().LineNr + ")" + " in " + m_currentScope); #endif evaluateReferencesInAllChildren(tree); }
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); } } }
void PushValueFromToken() { TokenWithValue t = CurrentNode.getToken() as TokenWithValue; Debug.Assert(t != null, "Can't convert current node to TokenWithValue: " + CurrentNode); PushValue(t.getValue()); }
private void PushNewScope(Scope newScope, string nameOfNewMemorySpace, AST startNode) { #if DEBUG Debug.Assert(newScope != null); Debug.Assert(startNode != null); #endif if (m_memorySpaceStack.Count > 100) { var token = startNode.getToken(); throw new Error("Stack overflow!", Error.ErrorType.RUNTIME, token.LineNr, token.LinePosition); } m_currentScope = newScope; m_memorySpaceStack.Push(m_currentMemorySpace); m_currentMemorySpace = new MemorySpace(nameOfNewMemorySpace, startNode, m_currentScope, m_memorySpaceNodeListCache); m_currentScope.PushMemorySpace(m_currentMemorySpace); #if LOG_SCOPES //m_currentMemorySpace.TraceParentScopes(); //Console.WriteLine("Pushed new scope " + newScope.getName() + " with memory space " + m_currentMemorySpace.getName() + ", stack: " + DumpStack()); //Console.WriteLine("CREATED " + m_currentMemorySpace.getName()); nrOfScopes++; #endif }
private void evaluateReferencesForARRAY_LOOKUP(AST tree) { AST lookup = tree; Symbol variableNameSymbol = m_currentScope.resolve(lookup.getTokenString()); if (variableNameSymbol == null) { m_errorHandler.errorOccured("Can't lookup in undefined array " + lookup.getTokenString(), Error.ErrorType.SYNTAX, lookup.getToken().LineNr, lookup.getToken().LinePosition); } evaluateReferencesInAllChildren(tree); }
private ReturnValue execute(AST tree) { Token.TokenType tokenType = tree.getToken().getTokenType(); ReturnValue returnValue = null; if (tokenType == Token.TokenType.FUNC_DECLARATION) { return(new ReturnValue()); } #if WRITE_DEBUG_INFO Console.WriteLine("Executing " + tree.getTokenType() + " " + tree.getTokenString()); #endif if (tokenType == Token.TokenType.STATEMENT_LIST) { executeAllChildNodes(tree); } else if (tokenType == Token.TokenType.FUNCTION_CALL) { returnValue = functionCall(tree); } else if (tokenType == Token.TokenType.NAME) { returnValue = name(tree); } else if (tokenType == Token.TokenType.NUMBER) { returnValue = number(tree); } else if (tokenType == Token.TokenType.OPERATOR) { returnValue = operation(tree); } else if (tokenType == Token.TokenType.QUOTED_STRING) { returnValue = quotedString(tree); } else if (tokenType == Token.TokenType.IF) { ifThenElse(tree); } else if (tokenType == Token.TokenType.VAR_DECLARATION) { varDeclaration(tree); } else if (tokenType == Token.TokenType.ASSIGNMENT) { assignment(tree); } else if (tokenType == Token.TokenType.RETURN) { returnStatement(tree); } else { throw new NotImplementedException("The interpreter hasn't got support for token type " + tokenType + " yet!"); } return(returnValue); }
private void evaluateReferencesForASSIGNMENT_TO_ARRAY(AST tree) { AST_Assignment assignment = tree as AST_Assignment; Symbol variableNameSymbol = m_currentScope.resolve(assignment.VariableName); if (variableNameSymbol == null) { m_errorHandler.errorOccured("Can't assign to undefined array " + assignment.VariableName, Error.ErrorType.SYNTAX, tree.getToken().LineNr, tree.getToken().LinePosition); } evaluateReferencesInAllChildren(tree); }
private void evaluateReferencesForNAME(AST tree) { #if DEBUG if (m_currentScope == null) { throw new Exception("m_currentScope is null"); } if (tree == null) { throw new Exception("tree is null"); } #endif Symbol symbol = m_currentScope.resolve(tree.getTokenString()); if (symbol == null) { m_errorHandler.errorOccured( new Error("Can't find variable or function '" + tree.getTokenString() + "' (forgot quotes?)", Error.ErrorType.SYNTAX, tree.getToken().LineNr, tree.getToken().LinePosition)); } else if (symbol is FunctionSymbol) { m_errorHandler.errorOccured( new Error("'" + tree.getTokenString() + "' is a function and must be called with ()", Error.ErrorType.SYNTAX, tree.getToken().LineNr, tree.getToken().LinePosition)); } #if WRITE_DEBUG_INFO Console.WriteLine("Resolved symbol with name " + tree.getTokenString() + " (on line " + tree.getToken().LineNr + ")" + " in " + m_currentScope); #endif evaluateReferencesInAllChildren(tree); }
private void evaluateReferencesForVAR_DECLARATION(AST tree) { AST_VariableDeclaration varDeclaration = tree as AST_VariableDeclaration; ReturnValueType typeToDeclare = varDeclaration.Type; string variableName = varDeclaration.Name; if (m_currentScope.isDefined(variableName)) { m_errorHandler.errorOccured( new Error("There is already a variable called '" + variableName + "'", Error.ErrorType.LOGIC, tree.getToken().LineNr, tree.getToken().LinePosition)); } else { m_currentScope.define(new VariableSymbol(variableName, typeToDeclare)); #if WRITE_DEBUG_INFO Console.WriteLine("Defined variable with name " + variableName + " and type " + typeToDeclare + " (on line " + tree.getToken().LineNr + ")" + " in " + m_currentScope); #endif } }
private void evaluateReferencesForNAME(AST tree) { Symbol symbol = m_currentScope.resolve(tree.getTokenString()); if(symbol == null) { m_errorHandler.errorOccured( new Error("Can't find anything called '" + tree.getTokenString() + "'", Error.ErrorType.SYNTAX, tree.getToken().LineNr, tree.getToken().LinePosition)); } else if (symbol is FunctionSymbol) { m_errorHandler.errorOccured( new Error("'" + tree.getTokenString() + "' is a function and must be called with ()", Error.ErrorType.SYNTAX, tree.getToken().LineNr, tree.getToken().LinePosition)); } #if WRITE_DEBUG_INFO Console.WriteLine("Resolved symbol with name " + tree.getTokenString() + " (on line " + tree.getToken().LineNr + ")" + " in " + m_currentScope); #endif evaluateReferencesInAllChildren(tree); }
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); } } }
private void ArrayLookup() { object index = PopValue(); object array = m_currentScope.getValue(CurrentNode.getTokenString()); object val = null; if (array is Range) { //Console.WriteLine ("LOOKING UP KEY " + index + " IN RANGE " + array.ToString ()); if (index.GetType() == typeof(float)) { Range range = (Range)array; float i = range.step * (int)(float)index; float theNumber = range.start + i; float lowerBound = 0; float upperBound = 0; if (range.step > 0) { lowerBound = range.start; upperBound = range.end; } else { lowerBound = range.end; upperBound = range.start; } if (theNumber < lowerBound) { throw new Error("Index " + index.ToString() + " is outside the range " + array.ToString()); } else if (theNumber > upperBound) { throw new Error("Index " + index.ToString() + " is outside the range " + array.ToString()); } val = (float)theNumber; //Console.WriteLine("The result was " + val); } else { throw new Error("Can't look up " + index.ToString() + " in the range " + array.ToString()); } } else if (array.GetType() == typeof(SortedDictionary <KeyWrapper, object>)) { //Console.WriteLine ("LOOKING UP KEY " + index + " of type " + index.GetType() + " IN ARRAY " + ReturnValueConversions.PrettyStringRepresenation(array)); var a = array as SortedDictionary <KeyWrapper, object>; if (a.TryGetValue(new KeyWrapper(index), out val)) { //Console.WriteLine("The result was " + val); } else { throw new Error("Can't find the index '" + index + "' (" + ReturnValueConversions.PrettyObjectType(index.GetType()) + ") in the array '" + CurrentNode.getTokenString() + "'", Error.ErrorType.RUNTIME, CurrentNode.getToken().LineNr, CurrentNode.getToken().LinePosition); } } else if (array.GetType() == typeof(object[])) { throw new Error("Illegal object[] array: " + ReturnValueConversions.PrettyStringRepresenation(array)); // var a = (object[])array; // if(index.GetType() != typeof(float)) { // throw new Exception("Index " + index + " is of wrong type: " + index.GetType()); // } // int i = (int)(float)index; // val = a[i]; } else if (array.GetType() == typeof(string)) { int i = 0; if (index.GetType() == typeof(float)) { i = (int)(float)index; } else if (index.GetType() == typeof(int)) { i = (int)index; } else { throw new Error("Must use nr when looking up index in string"); } string s = (string)array; if (i >= 0 && i < s.Length) { val = s[i].ToString(); } else { throw new Error("The index '" + i + "' (" + index.GetType() + ") is outside the bounds of the string '" + CurrentNode.getTokenString() + "'", Error.ErrorType.RUNTIME, CurrentNode.getToken().LineNr, CurrentNode.getToken().LinePosition); } } else { throw new Error("Can't convert " + array.ToString() + " to an array (for lookup)"); } PushValue(val); }
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 ReturnValue execute(AST tree) { Token.TokenType tokenType = tree.getToken().getTokenType(); ReturnValue returnValue = null; if (tokenType == Token.TokenType.FUNC_DECLARATION) { return new ReturnValue(); } #if WRITE_DEBUG_INFO Console.WriteLine("Executing " + tree.getTokenType() + " " + tree.getTokenString()); #endif if (tokenType == Token.TokenType.STATEMENT_LIST) { executeAllChildNodes(tree); } else if (tokenType == Token.TokenType.FUNCTION_CALL) { returnValue = functionCall(tree); } else if (tokenType == Token.TokenType.NAME) { returnValue = name(tree); } else if (tokenType == Token.TokenType.NUMBER) { returnValue = number(tree); } else if (tokenType == Token.TokenType.OPERATOR) { returnValue = operation(tree); } else if (tokenType == Token.TokenType.QUOTED_STRING) { returnValue = quotedString(tree); } else if (tokenType == Token.TokenType.IF) { ifThenElse(tree); } else if (tokenType == Token.TokenType.VAR_DECLARATION) { varDeclaration(tree); } else if (tokenType == Token.TokenType.ASSIGNMENT) { assignment(tree); } else if (tokenType == Token.TokenType.RETURN) { returnStatement(tree); } else { throw new NotImplementedException("The interpreter hasn't got support for token type " + tokenType + " yet!"); } return returnValue; }
private ReturnValue functionCall(AST tree) { ReturnValue returnValue = null; if (m_externalFunctionCreator.externalFunctions.ContainsKey(tree.getTokenString())) { ExternalFunctionCreator.OnFunctionCall functionCall = m_externalFunctionCreator.externalFunctions[tree.getTokenString()]; if (functionCall != null) { ReturnValue[] parameters = new ReturnValue[tree.getChildren().Count]; int i = 0; foreach (AST parameter in tree.getChildren()) { parameters[i] = execute(parameter); i++; } returnValue = functionCall(parameters); } else { throw new Error("Can't find external function " + tree.getTokenString(), Error.ErrorType.UNDEFINED, tree.getToken().LineNr, tree.getToken().LinePosition); } } else { // Call user defined function string functionName = tree.getTokenString(); AST functionTree = getFunctionTreeNode(functionName); Assert.IsNotNull(functionTree); // Create list of parameter values List<ReturnValue> parameterValues = new List<ReturnValue>(); List<AST> functionCallChildNodes = tree.getChildren(); if (functionCallChildNodes != null) { foreach(AST parameter in tree.getChildren()) { ReturnValue val = execute(parameter); parameterValues.Add(val); } } returnValue = function(functionTree, parameterValues); } return returnValue; }
private ReturnValue functionCall(AST tree) { ReturnValue returnValue = null; if (m_externalFunctionCreator.externalFunctions.ContainsKey(tree.getTokenString())) { ExternalFunctionCreator.OnFunctionCall functionCall = m_externalFunctionCreator.externalFunctions[tree.getTokenString()]; if (functionCall != null) { ReturnValue[] parameters = new ReturnValue[tree.getChildren().Count]; int i = 0; foreach (AST parameter in tree.getChildren()) { parameters[i] = execute(parameter); i++; } returnValue = functionCall(parameters); } else { throw new Error("Can't find external function " + tree.getTokenString(), Error.ErrorType.UNDEFINED, tree.getToken().LineNr, tree.getToken().LinePosition); } } else { // Call user defined function string functionName = tree.getTokenString(); AST functionTree = getFunctionTreeNode(functionName); Assert.IsNotNull(functionTree); // Create list of parameter values List <ReturnValue> parameterValues = new List <ReturnValue>(); List <AST> functionCallChildNodes = tree.getChildren(); if (functionCallChildNodes != null) { foreach (AST parameter in tree.getChildren()) { ReturnValue val = execute(parameter); parameterValues.Add(val); } } returnValue = function(functionTree, parameterValues); } return(returnValue); }
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 evaluateReferencesForASSIGNMENT_TO_ARRAY(AST tree) { AST_Assignment assignment = tree as AST_Assignment; Symbol variableNameSymbol = m_currentScope.resolve(assignment.VariableName); if(variableNameSymbol == null) { m_errorHandler.errorOccured("Can't assign to undefined array " + assignment.VariableName, Error.ErrorType.SYNTAX, tree.getToken().LineNr, tree.getToken().LinePosition); } evaluateReferencesInAllChildren(tree); }