public PrinterNode Visit(IndexNode node) { var pNode = new PrinterNode("Index"); pNode.AddChild(node.Operand.Accept(this)); pNode.AddChild(node.IndexExpr.Accept(this)); return(pNode); }
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); }