Beispiel #1
0
        public object Execute(ICodeNode node, ref int exec_count)
        {
            // get the SELECT node's children
            var children = node.GetChildren();
            ICodeNode expr_node = children[0];

            // evaluate SELECT expression
            ExpressionInterpreter expr_interpreter =
                ExpressionInterpreter.CreateWithObservers(observers);
            object value = expr_interpreter.Execute(expr_node, ref exec_count);

            // attempt to select a SELECT_BRANCH.
            ICodeNode selected_branch = SearchBranches(value, children.Skip(1));

            // if there was a selection, execute the SELECT_BRANCH's statement
            if (selected_branch != null)
            {
                ICodeNode stmnt_node = selected_branch.GetChildren().ElementAt(1);
                StatementInterpreter stmnt_interpreter =
                    StatementInterpreter.CreateWithObservers(observers);
                stmnt_interpreter.Execute(stmnt_node, ref exec_count);
            }

            ++exec_count;
            return null;
        }
Beispiel #2
0
        public object Execute(ICodeNode node, ref int exec_count)
        {
            // get the IF node's children
            var children = node.GetChildren();
            ICodeNode expr_node = children[0];
            ICodeNode then_node = children[1];
            ICodeNode else_node = children.Count > 2 ? children[2] : null;

            ExpressionInterpreter expr_interpreter =
                ExpressionInterpreter.CreateWithObservers(observers);
            StatementInterpreter stmt_interpreter =
                StatementInterpreter.CreateWithObservers(observers);

            // evaluate the expression to determine which statement to execute.
            bool b = (bool)expr_interpreter.Execute(expr_node, ref exec_count);
            if (b)
            {
                stmt_interpreter.Execute(then_node, ref exec_count);
            } else
            {
                stmt_interpreter.Execute(else_node, ref exec_count);
            }

            ++exec_count;
            return null;
        }
Beispiel #3
0
        public object Execute(ICodeNode node, ref int exec_count)
        {
            switch (node.Type)
            {
                case ICodeNodeType.VARIABLE:
                    {
                        // Get the variable's symbol table entry and return its value.
                        SymbolTableEntry entry = (SymbolTableEntry)node.GetAttribute(ICodeKey.ID);
                        return entry.GetAttribute(SymbolTableKey.DataValue);
                    }
                case ICodeNodeType.INTEGER_CONSTANT:
                    {
                        // Return the integer value.
                        return node.GetAttribute(ICodeKey.VALUE);
                    }
                case ICodeNodeType.REAL_CONSTANT:
                    {
                        // Return the integer value.
                        return node.GetAttribute(ICodeKey.VALUE);
                    }
                case ICodeNodeType.STRING_CONSTANT:
                    {
                        // Return the integer value.
                        return node.GetAttribute(ICodeKey.VALUE);
                    }
                case ICodeNodeType.NEGATE:
                    {
                        // Get the NEGATE node's expression node child.
                        List<ICodeNode> children = node.GetChildren();
                        ICodeNode expression = children[0];

                        // Execute the expression and return the negative of its value.
                        object value = Execute(expression, ref exec_count);
                        if (value is int)
                        {
                            return -(int)value;
                        } else if (value is double)
                        {
                            return -(double)value;
                        } else
                        {
                            return null;
                        }
                    }
                case ICodeNodeType.NOT:
                    {
                        // Get the NOT node's expression node child.
                        List<ICodeNode> children = node.GetChildren();
                        ICodeNode expression = children[0];

                        // Execute the expression and return the "not" of its value
                        bool value = (bool)Execute(expression, ref exec_count);
                        return !value;
                    }
                default:
                    // must be a binary operator
                    return ExecuteBinaryOperator(node, ref exec_count);
            }
        }
Beispiel #4
0
        private void PrintAttributes(ICodeNode node)
        {
            string save = indentation;

            node.ForeachAttribute((k, v) => PrintAttribute(k.ToString(), v));

            indentation = save;
        }
Beispiel #5
0
        private void SendSourceLineMessage(ICodeNode node)
        {
            object line_number = node.GetAttribute(ICodeKey.LINE);

            // send the SourceLine message
            if (line_number != null)
            {
                var args = (Tuple<int>)Tuple.Create((int)line_number);
                Message msg = new Message(MessageType.SourceLine, args);
                Send(msg);
            }
        }
Beispiel #6
0
        private void SendMessage(ICodeNode node, string variable_name, object value)
        {
            object line_number = node.GetAttribute(ICodeKey.LINE);

            // Send an ASSIGN message.
            if (line_number != null)
            {
                var args = Tuple.Create((int)line_number, variable_name, (object)value);
                Message msg = new Message(MessageType.Assign, args);
                Send(msg);
            }
        }
Beispiel #7
0
        public object Execute(ICodeNode node, ref int exec_count)
        {
            // loop and execute each child
            StatementInterpreter stmnt_interpreter = StatementInterpreter.CreateWithObservers(observers);

            foreach (var child in node.GetChildren())
            {
                stmnt_interpreter.Execute(child, ref exec_count);
            }

            return null;
        }
Beispiel #8
0
        public object Execute(ICodeNode node, ref int exec_count)
        {
            // send a message about the current source line
            SendSourceLineMessage(node);

            switch (node.Type)
            {
                case ICodeNodeType.COMPOUND:
                    {
                        CompoundInterpreter compound_interpreter =
                            CompoundInterpreter.CreateWithObservers(observers);
                        return compound_interpreter.Execute(node, ref exec_count);
                    }
                case ICodeNodeType.ASSIGN:
                    {
                        AssignmentInterpreter assign_interpreter =
                            AssignmentInterpreter.CreateWithObservers(observers);
                        return assign_interpreter.Execute(node, ref exec_count);
                    }
                case ICodeNodeType.LOOP:
                    {
                        LoopInterpreter loop_interpreter =
                            LoopInterpreter.CreateWithObservers(observers);
                        return loop_interpreter.Execute(node, ref exec_count);
                    }
                case ICodeNodeType.IF:
                    {
                        IfInterpreter if_interpreter =
                            IfInterpreter.CreateWithObservers(observers);
                        return if_interpreter.Execute(node, ref exec_count);
                    }
                case ICodeNodeType.SELECT:
                    {
                        SelectInterpreter select_interpreter =
                            SelectInterpreter.CreateWithObservers(observers);
                        return select_interpreter.Execute(node, ref exec_count);
                    }
                case ICodeNodeType.NO_OP:
                    return null;
                default:
                    RuntimeErrorHandler.Flag(node, RuntimeErrorCode.UNIMPLEMENTED_FEATURE, this);
                    return null;
            }
        }
Beispiel #9
0
        public static void Flag(ICodeNode node, RuntimeErrorCode error_code, MessageProducer backend)
        {
            //string line_number = null;
            while (node != null && node.GetAttribute(ICodeKey.LINE) == null)
            {
                node = node.Parent;
            }

            // notify observers
            var args = (Tuple<string, int>)Tuple.Create(error_code.Message, (int)node.GetAttribute(ICodeKey.LINE));
            Message msg = new Message(MessageType.RuntimeError, args);
            backend.Send(msg);

            if (++Errors > MAX_ERRORS)
            {
                Console.WriteLine("*** ABORTED AFTER TOO MANY RUNTIME ERRORS.*");
                Environment.Exit(-1);
            }
        }
Beispiel #10
0
        public object Execute(ICodeNode node, ref int exec_count)
        {
            // The ASSIGN node's children are the target variable
            // and the expression.
            List<ICodeNode> children = node.GetChildren();
            ICodeNode variable = children[0];
            ICodeNode expression = children[1];

            // Expression the expression and get its value.
            ExpressionInterpreter expr_interpreter = ExpressionInterpreter.CreateWithObservers(observers);
            object value = expr_interpreter.Execute(expression, ref exec_count);

            // Set the value as an attribute of the variable's symbol table entry.
            SymbolTableEntry variable_id = (SymbolTableEntry)variable.GetAttribute(ICodeKey.ID);
            variable_id.SetAttribute(SymbolTableKey.DataValue, value);

            SendMessage(node, variable_id.Name, value);
            ++exec_count;
            return null;
        }
Beispiel #11
0
        public object Execute(ICodeNode node, ref int exec_count)
        {
            bool exit_loop = false;
            ICodeNode expr_node = null;
            List<ICodeNode> loop_children = node.GetChildren();

            ExpressionInterpreter expr_interpreter =
                ExpressionInterpreter.CreateWithObservers(observers);
            StatementInterpreter stmt_interpreter =
                StatementInterpreter.CreateWithObservers(observers);

            // loop until the TEST expression value is true
            while (!exit_loop)
            {
                ++exec_count;

                // execute the children of the LOOP node.
                foreach (var child in loop_children)
                {
                    if (child.Type == ICodeNodeType.TEST)
                    {
                        if (expr_node == null)
                        {
                            expr_node = child.GetChildren().ElementAt(0);
                        }
                        exit_loop = (bool)expr_interpreter.Execute(expr_node, ref exec_count);
                    } else
                    {
                        stmt_interpreter.Execute(child, ref exec_count);
                    }

                    if (exit_loop)
                    {
                        break;
                    }
                }
            }

            return null;
        }
Beispiel #12
0
        private bool SearchConstants(object value, ICodeNode child)
        {
            // are the values integer or string?
            bool integer_mode = value is int;

            // get the list of SELECT_CONSTANTS values
            ICodeNode constants_node = child.GetChildren().ElementAt(0);
            var all_constants = constants_node.GetChildren();

            // search the list of constants
            if (integer_mode)
            {
                int v = (int)value;
                foreach (var constant in all_constants)
                {
                    int con = (int)constant.GetAttribute(ICodeKey.VALUE);
                    if (v == con)
                    {
                        return true;
                    }
                }
            } else
            {
                string v = (string)value;
                foreach (var constant in all_constants)
                {
                    string con = (string)constant.GetAttribute(ICodeKey.VALUE);
                    if (v == con)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
Beispiel #13
0
        private object ExecuteBinaryOperator(ICodeNode node, ref int exec_count)
        {
            // Get the two operand children of the operator node.
            List<ICodeNode> children = node.GetChildren();
            ICodeNode operand_node1 = children[0];
            ICodeNode operand_node2 = children[1];

            // Operands.
            object operand1 = Execute(operand_node1, ref exec_count);
            object operand2 = Execute(operand_node2, ref exec_count);

            bool integer_mode = (operand1 is int) && (operand2 is int);

            // ====================
            // Arithmetic operators
            // ====================
            if (ARITH_OPS.Contains(node.Type))
            {
                if (integer_mode)
                {
                    int value1 = (int)operand1;
                    int value2 = (int)operand2;

                    // Integer operation
                    switch (node.Type)
                    {
                        case ICodeNodeType.ADD:
                            return value1 + value2;
                        case ICodeNodeType.SUBTRACT:
                            return value1 - value2;
                        case ICodeNodeType.MULTIPLY:
                            return value1 * value2;
                        case ICodeNodeType.FLOAT_DIVIDE:
                            // check for division by error:
                            if (value2 != 0)
                            {
                                return (double)value1 / (double)value2;
                            } else
                            {
                                RuntimeErrorHandler.Flag(node, RuntimeErrorCode.DIVISION_BY_ZERO, this);
                                return 0;
                            }
                        case ICodeNodeType.INTEGER_DIVIDE:
                            // check for division by error:
                            if (value2 != 0)
                            {
                                return value1 / value2;
                            }
                            else
                            {
                                RuntimeErrorHandler.Flag(node, RuntimeErrorCode.DIVISION_BY_ZERO, this);
                                return 0;
                            }
                        case ICodeNodeType.MOD:
                            // check for division by error:
                            if (value2 != 0)
                            {
                                return value1 % value2;
                            }
                            else
                            {
                                RuntimeErrorHandler.Flag(node, RuntimeErrorCode.DIVISION_BY_ZERO, this);
                                return 0;
                            }
                    }
                } else
                {
                    double value1 = operand1 is int ? (int)operand1 : (double)operand1;
                    double value2 = operand2 is int ? (int)operand2 : (double)operand2;

                    // float operations
                    switch (node.Type)
                    {
                        case ICodeNodeType.ADD:
                            return value1 + value2;
                        case ICodeNodeType.SUBTRACT:
                            return value1 - value2;
                        case ICodeNodeType.MULTIPLY:
                            return value1 * value2;
                        case ICodeNodeType.FLOAT_DIVIDE:
                            // check for division by zero
                            if (value2 != 0.0f)
                            {
                                return value1 / value2;
                            } else
                            {
                                RuntimeErrorHandler.Flag(node, RuntimeErrorCode.DIVISION_BY_ZERO, this);
                                return 0.0f;
                            }
                    }
                }
            } else if (node.Type == ICodeNodeType.AND || node.Type == ICodeNodeType.OR)
            {
                bool value1 = (bool)operand1;
                bool value2 = (bool)operand2;

                switch (node.Type)
                {
                    case ICodeNodeType.AND:
                        return value1 && value2;
                    case ICodeNodeType.OR:
                        return value1 || value2;
                }
            } else if (integer_mode)
            {
                int value1 = (int)operand1;
                int value2 = (int)operand2;

                // integer operands
                switch (node.Type)
                {
                    case ICodeNodeType.EQ:
                        return value1 == value2;
                    case ICodeNodeType.NE:
                        return value1 != value2;
                    case ICodeNodeType.LT:
                        return value1 < value2;
                    case ICodeNodeType.LE:
                        return value1 <= value2;
                    case ICodeNodeType.GT:
                        return value1 > value2;
                    case ICodeNodeType.GE:
                        return value1 >= value2;
                }
            } else
            {
                double value1 = operand1 is int ? (int)operand1 : (double)operand1;
                double value2 = operand2 is int ? (int)operand2 : (double)operand2;

                // float operands
                switch (node.Type)
                {
                    case ICodeNodeType.EQ:
                        return value1 == value2;
                    case ICodeNodeType.NE:
                        return value1 != value2;
                    case ICodeNodeType.LT:
                        return value1 < value2;
                    case ICodeNodeType.LE:
                        return value1 <= value2;
                    case ICodeNodeType.GT:
                        return value1 > value2;
                    case ICodeNodeType.GE:
                        return value1 <= value2;
                }
            }
            return 0; // should never get here.
        }
Beispiel #14
0
 private void PrintTypeSpec(ICodeNode node)
 {
 }
Beispiel #15
0
        private void PrintNode(ICodeNode node)
        {
            // opening tag
            Append(indentation); Append("<" + node.ToString());

            PrintAttributes(node);
            PrintTypeSpec(node);

            List<ICodeNode> children = node.GetChildren();
            if (children.Count > 0)
            {
                Append(">");
                PrintLine();
                PrintChildNodes(children);
                Append(indentation);
                Append("</" + node.ToString() + ">");
            } else
            {
                Append(" "); Append("/>");
            }
            PrintLine();
        }
Beispiel #16
0
 public ICodeNode Add(ICodeNode node)
 {
     Contract.Requires(!children.Contains(node));
     if (node != null)
     {
         children.Add(node);
         node.Parent = this;
     }
     return node;
 }
Beispiel #17
0
 private void SetLineNumber(ICodeNode node, int line)
 {
     node.SetAttribute(ICodeKey.LINE, line);
 }
Beispiel #18
0
        public void ParseList(Token token, ICodeNode parent, TokenType terminator, ErrorCode error)
        {
            var terminator_set = new HashSet<TokenType>(STMT_START_SET);
            terminator_set.Add(terminator);

            while(!token.IsEof && token.TokenType != terminator)
            {
                // parse a statement. The parent node adopts the statement node.
                ICodeNode statement_node = Parse(token);
                parent.Add(statement_node);
                token = InternalScanner.CurrentToken;

                // look for the semicolon between the statements.
                if (token.TokenType == TokenType.SEMICOLON)
                {
                    token = InternalScanner.GetNextToken();
                }
                else if (STMT_START_SET.Contains(token.TokenType))
                {
                    ErrorHandler.Flag(token, ErrorCode.MISSING_SEMICOLON, this);
                }

                // Synchronize at the start of the next statement
                // or at the terminator.
                token = Parser.Synchronize(terminator_set, InternalScanner, this);
            }

            // look for the terminator token
            if (token.TokenType == terminator)
            {
                token = InternalScanner.GetNextToken();
            } else
            {
                ErrorHandler.Flag(token, error, this);
            }
        }
Beispiel #19
0
        private void ParseConstantList(Token token, ICodeNode constants_node, HashSet<object> constant_set)
        {
            // loop to parse each constant.
            while (CONSTANT_START_SET.Contains(token.TokenType))
            {
                // the constants list node adopts the constant node.
                constants_node.Add(ParseConstant(token, constant_set));

                // synchronize at the comma between constants.
                token = Parser.Synchronize(COMMA_SET, InternalScanner, this);

                // look for the COMMA
                if (token.TokenType == TokenType.COMMA)
                {
                    token = InternalScanner.GetNextToken(); // consume the ,
                } else if (CONSTANT_START_SET.Contains(token.TokenType))
                {
                    ErrorHandler.Flag(token, ErrorCode.MISSING_COMMA, this);
                }
            }
        }