예제 #1
0
        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);
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        void PushValueFromToken()
        {
            TokenWithValue t = CurrentNode.getToken() as TokenWithValue;

            Debug.Assert(t != null, "Can't convert current node to TokenWithValue: " + CurrentNode);
            PushValue(t.getValue());
        }
예제 #4
0
        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
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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
            }
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
                }
            }
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
                }
            }
        }
예제 #14
0
        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;
        }
예제 #15
0
        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;
        }
예제 #16
0
        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);
        }
예제 #17
0
        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
            }
        }
예제 #18
0
        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);
                }
            }
        }
예제 #19
0
        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);
        }