private void CheckVariableAssignmentUsedInStartEndExpression(IdentifierNode loopVariable, Node startExpression, Node endExpression, Node loopBody)
        {
            var stack = new Stack<Node>();
            stack.Push(endExpression);
            stack.Push(startExpression);

            var loopExpressionVariables = new Dictionary<IdentifierNode, IdentifierNode>();

            while (stack.Count != 0)
            {
                var current = stack.Pop();

                if (current is IdentifierNode && ((IdentifierNode)current).Name != loopVariable.Name)
                {
                    var id = (IdentifierNode)current;
                    if (!loopExpressionVariables.ContainsKey(id))
                    {
                        loopExpressionVariables.Add(id, id);
                    }
                }

                foreach (var child in current.Children)
                {
                    stack.Push(child);
                }
            }

            stack.Push(loopBody);
            while (stack.Count != 0)
            {
                var current = stack.Pop();

                if (current is VariableAssignmentNode &&
                    loopExpressionVariables.ContainsKey(new IdentifierNode(0, 0, ((VariableAssignmentNode)current).Name)))
                {
                    reporter.ReportError(
                        Error.WARNING,
                        "Possibly incorrect or confusing assignment to a variable '" +
                        ((VariableAssignmentNode)current).Name + "', used in loop expression,",
                        current.Line,
                        current.Column);

                    var id = loopExpressionVariables[new IdentifierNode(0, 0, ((VariableAssignmentNode)current).Name)];

                    reporter.ReportError(
                        Error.NOTE,
                        "Previous usage here",
                        id.Line,
                        id.Column);

                    reporter.ReportError(
                        Error.NOTE_GENERIC,
                        "Loop start and end expressions are evaluated only once before entering the loop",
                        0,
                        0);
                    break;
                }

                foreach (var child in current.Children)
                {
                    stack.Push(child);
                }
            }
        }
 private void ReportUndeclaredVariable(IdentifierNode node)
 {
     ReportUndeclaredVariable(node, node.Name);
 }
        private void CheckLoopControlVariableUsageInStartEndExpression(ForNode node, IdentifierNode loopVariable, Node startExpression, Node endExpression)
        {
            var stack = new Stack<Node>();
            stack.Push(endExpression);
            stack.Push(startExpression);

            while (stack.Count != 0)
            {
                var current = stack.Pop();

                if (current is IdentifierNode && ((IdentifierNode)current).Name == loopVariable.Name)
                {
                    reporter.ReportError(
                        Error.WARNING,
                        "Possibly incorrect or confusing usage of loop control variable '" + loopVariable.Name + "' in loop expression",
                        current.Line,
                        current.Column);

                    reporter.ReportError(
                        Error.NOTE,
                        "Loop is here",
                        node.Line,
                        node.Column);

                    reporter.ReportError(
                        Error.NOTE_GENERIC,
                        "Loop start and end expressions are evaluated only once before entering the loop",
                        0,
                        0);
                    break;
                }

                foreach (var child in current.Children)
                {
                    stack.Push(child);
                }
            }
        }
        private void CheckLoopControlVariableAssignmentInBody(ForNode node, IdentifierNode loopVariable, Node loopBody)
        {
            var stack = new Stack<Node>();
            stack.Push(loopBody);

            while (stack.Count != 0)
            {
                var current = stack.Pop();

                if (current is VariableAssignmentNode && ((VariableAssignmentNode)current).Name == loopVariable.Name)
                {
                    reporter.ReportError(
                        Error.SEMANTIC_ERROR,
                        "Cannot reassign control variable '" + loopVariable.Name + "'",
                        current.Line,
                        current.Column);

                    reporter.ReportError(
                        Error.NOTE,
                        "Loop is here",
                        node.Line,
                        node.Column);
                    break;
                }

                foreach (var child in current.Children)
                {
                    stack.Push(child);
                }
            }
        }
 public void Visit(IdentifierNode node)
 {
     if (SymbolTable.ContainsKey(node.Name))
     {
         node.SetType(SymbolTable[node.Name].node.NodeType());
     }
     else
     {
         node.SetType(VariableType.ERROR_TYPE);
         ReportUndeclaredVariable(node);
     }
 }
Пример #6
0
 public ReadNode(int line, int column, IdentifierNode identifier)
     : base(line, column)
 {
     Children.Add(identifier);
 }
Пример #7
0
        public void Visit(IdentifierNode node)
        {
            var data = symbolTable[node.Name];
            switch (data.node.Type)
            {
                case VariableType.INTEGER:
                    Emit(Bytecode.PUSH_INT_VAR);
                    break;
                case VariableType.STRING:
                    Emit(Bytecode.PUSH_STRING_VAR);
                    break;
                case VariableType.BOOLEAN:
                    Emit(Bytecode.PUSH_BOOLEAN_VAR);
                    break;
                default:
                    throw new InternalCompilerError("Invalid variable type");
            }

            Emit(data.id);
        }