///|
/// The operator's text.
fn binop(op : @ast.BinOp) -> @pretty.Doc {
t(
match op {
And => "&&"
Or => "||"
LtInt => "<"
LtEqInt => "<="
LtFloat => "<."
LtEqFloat => "<=."
Eq => "=="
NotEq => "!="
GtEqInt => ">="
GtInt => ">"
GtEqFloat => ">=."
GtFloat => ">."
AddInt => "+"
AddFloat => "+."
SubInt => "-"
SubFloat => "-."
MultInt => "*"
MultFloat => "*."
DivInt => "/"
DivFloat => "/."
RemainderInt => "%"
Concatenate => "<>"
},
)
}
///|
/// `BinOp::precedence` (the pipe is 6).
fn precedence(op : @ast.BinOp) -> Int32 {
match op {
Or => 1
And => 2
Eq | NotEq => 3
LtInt
| LtEqInt
| LtFloat
| LtEqFloat
| GtEqInt
| GtInt
| GtEqFloat
| GtFloat => 4
Concatenate => 5
AddInt | AddFloat | SubInt | SubFloat => 7
MultInt | MultFloat | DivInt | DivFloat | RemainderInt => 8
}
}
///|
priv enum OperatorKind {
StringConcatenation
Equality
BooleanLogic
IntComparison
FloatComparison
IntMath
FloatMath
} derive(Eq)
///|
fn operator_kind(op : @ast.BinOp) -> OperatorKind {
match op {
Concatenate => StringConcatenation
Eq | NotEq => Equality
And | Or => BooleanLogic
LtInt | LtEqInt | GtEqInt | GtInt => IntComparison
LtFloat | LtEqFloat | GtEqFloat | GtFloat => FloatComparison
AddInt | SubInt | MultInt | RemainderInt | DivInt => IntMath
AddFloat | SubFloat | MultFloat | DivFloat => FloatMath
}
}
///|
/// `BinOp::can_be_grouped_with`.
fn can_be_grouped_with(a : @ast.BinOp, b : @ast.BinOp) -> Bool {
operator_kind(a) == operator_kind(b)
}
///|
/// The compiler's `operator_side`: wrap in a block when the operator binds
/// tighter than the side.
fn operator_side(doc : @pretty.Doc, op : Int32, side : Int32) -> @pretty.Doc {
if op > side {
group(wrap_block(doc))
} else {
doc
}
}
///|
/// `u8::MAX` for a side that is not a binary operator.
let max_precedence : Int32 = 255