예제 #1
0
        public PrinterNode Visit(IndexNode node)
        {
            var pNode = new PrinterNode("Index");

            pNode.AddChild(node.Operand.Accept(this));
            pNode.AddChild(node.IndexExpr.Accept(this));
            return(pNode);
        }
예제 #2
0
        public bool Visit(IndexNode node)
        {
            if (node.Type != null)
            {
                return(true);
            }

            node.Operand.Accept(this);
            node.IndexExpr.Accept(this);

            var token = ExprNode.GetClosestToken(node.Operand);

            if (node.Operand.Type is SymArray arrayType)
            {
                node.Type = arrayType.Type;
            }
            else if (node.Operand.Type is OpenArray openArrayType)
            {
                node.Type = openArrayType.InnerType;
            }
            else
            {
                throw new ArrayExpectedException(node.Operand.Type, token.Lexeme, token.Line, token.Column);
            }

            node.IsLvalue = true;

            _typeChecker.RequireCast(_stack.SymInt, ref node.IndexExpr);

            //try to compute index value
            var indexEvalVisitor = new EvalConstExprVisitor(ExprNode.GetClosestToken(node.IndexExpr), _stack);

            try {
                var indexConst = node.IndexExpr.Accept(indexEvalVisitor) as SymIntConst;
                // requireCast above guarantees that it is not null
                node.IndexExpr = new IntegerNode(new IntegerToken(indexConst.Value, token.Line, token.Column));

                if (!(node.Operand.Type is SymArray arrayT))
                {
                    return(true);
                }

                if (!(arrayT.MinIndex.Value <= indexConst.Value && indexConst.Value <= arrayT.MaxIndex.Value))
                {
                    throw new RangeCheckErrorException(indexConst.Value, arrayT.MinIndex.Value,
                                                       arrayT.MaxIndex.Value, token.Line, token.Column);
                }
            }
            catch (ConstExprEvalException) {
                return(true);
            }

            return(true);
        }