// A general purpose helper function for parsing the tail of a // binary operation (the operator and the right hand term). // Continues parsing binary operations on the same precedence level // recursively. private IExpression ParseBinaryOpTail(IExpression leftHandOperand, Func<IExpression> parseRightHandSideOperand, params string[] operators) { if (Input.NextTokenOneOf<OperatorToken>(operators)) { var opToken = Input.Consume<OperatorToken>(); var rightHandOperand = parseRightHandSideOperand(); var operatorExp = new BinaryOperatorExpression(MiniJavaInfo.ConvertOperator(opToken.Lexeme), leftHandOperand, rightHandOperand, opToken.Row, opToken.Col); return ParseBinaryOpTail(operatorExp, parseRightHandSideOperand, operators); } else return leftHandOperand; }
public override void Visit(BinaryOperatorExpression node) { var op = MiniJavaInfo.GetOperator(node.Operator); if (op.OperandType == MiniJavaInfo.AnyType) { // Operands can be of any type but they must be compatible. CheckOperandCompatibility(node, node.LeftOperand.Type, node.RightOperand.Type); } else { CheckBinaryOperatorOperands(node, node.LeftOperand.Type, node.RightOperand.Type); } }
public override void Visit(BinaryOperatorExpression node) { HandleExpressionOrStatementNode(node); }
private void CheckBinaryOperatorOperands(BinaryOperatorExpression node, IType left, IType right) { var op = MiniJavaInfo.GetOperator(node.Operator); var expected = _parent._symbolTable.ResolveType(op.OperandType).Type; if (left.IsAssignableTo(expected) && right.IsAssignableTo(expected)) { // Everything OK. return; } Debug.Assert(!(left is ErrorType && right is ErrorType)); ReportBinaryOperatorError(node, left, right); }
private void ReportBinaryOperatorError(BinaryOperatorExpression node, IType left, IType right) { string errormsg; string opRepr = MiniJavaInfo.OperatorRepr(node.Operator); if (left is ErrorType) { errormsg = String.Format("Invalid operand of type {0} for operator {1}.", right.Name, opRepr); } else if (right is ErrorType) { errormsg = String.Format("Invalid operand of type {0} for operator {1}.", left.Name, opRepr); } else { errormsg = String.Format("Cannot apply operator {0} on arguments of type {1} and {2}.", opRepr, left.Name, right.Name); } ReportError(ErrorTypes.TypeError, errormsg, node); }
private void CheckOperandCompatibility(BinaryOperatorExpression node, IType left, IType right) { if (left.IsAssignableTo(right) || right.IsAssignableTo(left)) return; ReportError(ErrorTypes.TypeError, String.Format("Cannot apply operator {0} on arguments of type {1} and {2}.", node.Operator, left.Name, right.Name), node); }