mirror of
				https://github.com/GayPizzaSpecifications/pork.git
				synced 2025-11-03 17:39:38 +00:00 
			
		
		
		
	language: add binary operators (#6)
- unary binary not - infix bitwise and - infix bitwise or - infix bitwise exclusive or (xor)
This commit is contained in:
		@ -96,6 +96,15 @@ types:
 | 
				
			|||||||
    - name: LesserEqual
 | 
					    - name: LesserEqual
 | 
				
			||||||
      values:
 | 
					      values:
 | 
				
			||||||
        token: "<="
 | 
					        token: "<="
 | 
				
			||||||
 | 
					    - name: BinaryAnd
 | 
				
			||||||
 | 
					      values:
 | 
				
			||||||
 | 
					        token: "&"
 | 
				
			||||||
 | 
					    - name: BinaryOr
 | 
				
			||||||
 | 
					      values:
 | 
				
			||||||
 | 
					        token: "|"
 | 
				
			||||||
 | 
					    - name: BinaryExclusiveOr
 | 
				
			||||||
 | 
					      values:
 | 
				
			||||||
 | 
					        token: "^"
 | 
				
			||||||
  InfixOperation:
 | 
					  InfixOperation:
 | 
				
			||||||
    parent: Expression
 | 
					    parent: Expression
 | 
				
			||||||
    values:
 | 
					    values:
 | 
				
			||||||
@ -196,6 +205,9 @@ types:
 | 
				
			|||||||
    - name: UnaryMinus
 | 
					    - name: UnaryMinus
 | 
				
			||||||
      values:
 | 
					      values:
 | 
				
			||||||
        token: "-"
 | 
					        token: "-"
 | 
				
			||||||
 | 
					    - name: BinaryNot
 | 
				
			||||||
 | 
					      values:
 | 
				
			||||||
 | 
					        token: "~"
 | 
				
			||||||
  PrefixOperation:
 | 
					  PrefixOperation:
 | 
				
			||||||
    parent: Expression
 | 
					    parent: Expression
 | 
				
			||||||
    values:
 | 
					    values:
 | 
				
			||||||
 | 
				
			|||||||
@ -18,5 +18,8 @@ enum class InfixOperator(val token: String) {
 | 
				
			|||||||
  Lesser("<"),
 | 
					  Lesser("<"),
 | 
				
			||||||
  Greater(">"),
 | 
					  Greater(">"),
 | 
				
			||||||
  GreaterEqual(">="),
 | 
					  GreaterEqual(">="),
 | 
				
			||||||
  LesserEqual("<=")
 | 
					  LesserEqual("<="),
 | 
				
			||||||
 | 
					  BinaryAnd("&"),
 | 
				
			||||||
 | 
					  BinaryOr("|"),
 | 
				
			||||||
 | 
					  BinaryExclusiveOr("^")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -9,5 +9,6 @@ import kotlinx.serialization.Serializable
 | 
				
			|||||||
enum class PrefixOperator(val token: String) {
 | 
					enum class PrefixOperator(val token: String) {
 | 
				
			||||||
  Negate("!"),
 | 
					  Negate("!"),
 | 
				
			||||||
  UnaryPlus("+"),
 | 
					  UnaryPlus("+"),
 | 
				
			||||||
  UnaryMinus("-")
 | 
					  UnaryMinus("-"),
 | 
				
			||||||
 | 
					  BinaryNot("~")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -75,7 +75,7 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        !value
 | 
					        !value
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      PrefixOperator.UnaryPlus, PrefixOperator.UnaryMinus -> {
 | 
					      PrefixOperator.UnaryPlus, PrefixOperator.UnaryMinus, PrefixOperator.BinaryNot -> {
 | 
				
			||||||
        if (value !is Number) {
 | 
					        if (value !is Number) {
 | 
				
			||||||
          throw RuntimeException("Numeric unary '${node.op.token}' illegal on non-numeric type '${value.javaClass.simpleName}'")
 | 
					          throw RuntimeException("Numeric unary '${node.op.token}' illegal on non-numeric type '${value.javaClass.simpleName}'")
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -91,7 +91,8 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
        value,
 | 
					        value,
 | 
				
			||||||
        convert = { it.toDouble() },
 | 
					        convert = { it.toDouble() },
 | 
				
			||||||
        plus = { +it },
 | 
					        plus = { +it },
 | 
				
			||||||
        minus = { -it }
 | 
					        minus = { -it },
 | 
				
			||||||
 | 
					        binaryNot = unaryFloatingPointTypeError("binary not")
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    is Float -> {
 | 
					    is Float -> {
 | 
				
			||||||
@ -100,7 +101,8 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
        value,
 | 
					        value,
 | 
				
			||||||
        convert = { it.toFloat() },
 | 
					        convert = { it.toFloat() },
 | 
				
			||||||
        plus = { +it },
 | 
					        plus = { +it },
 | 
				
			||||||
        minus = { -it }
 | 
					        minus = { -it },
 | 
				
			||||||
 | 
					        binaryNot = unaryFloatingPointTypeError("binary not")
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    is Long -> {
 | 
					    is Long -> {
 | 
				
			||||||
@ -109,7 +111,8 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
        value,
 | 
					        value,
 | 
				
			||||||
        convert = { it.toLong() },
 | 
					        convert = { it.toLong() },
 | 
				
			||||||
        plus = { +it },
 | 
					        plus = { +it },
 | 
				
			||||||
        minus = { -it }
 | 
					        minus = { -it },
 | 
				
			||||||
 | 
					        binaryNot = { it.inv() }
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    is Int -> {
 | 
					    is Int -> {
 | 
				
			||||||
@ -118,7 +121,8 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
        value,
 | 
					        value,
 | 
				
			||||||
        convert = { it.toInt() },
 | 
					        convert = { it.toInt() },
 | 
				
			||||||
        plus = { +it },
 | 
					        plus = { +it },
 | 
				
			||||||
        minus = { -it }
 | 
					        minus = { -it },
 | 
				
			||||||
 | 
					        binaryNot = { it.inv() }
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else -> throw RuntimeException("Unknown numeric type: ${value.javaClass.name}")
 | 
					    else -> throw RuntimeException("Unknown numeric type: ${value.javaClass.name}")
 | 
				
			||||||
@ -179,6 +183,9 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
        subtract = { a, b -> a - b },
 | 
					        subtract = { a, b -> a - b },
 | 
				
			||||||
        multiply = { a, b -> a * b },
 | 
					        multiply = { a, b -> a * b },
 | 
				
			||||||
        divide = { a, b -> a / b },
 | 
					        divide = { a, b -> a / b },
 | 
				
			||||||
 | 
					        binaryAnd = { _, _ -> floatingPointTypeError("binary and") },
 | 
				
			||||||
 | 
					        binaryOr = { _, _ -> floatingPointTypeError("binary or") },
 | 
				
			||||||
 | 
					        binaryExclusiveOr = { _, _ -> floatingPointTypeError("binary exclusive-or") },
 | 
				
			||||||
        euclideanModulo = { _, _ -> floatingPointTypeError("integer modulo") },
 | 
					        euclideanModulo = { _, _ -> floatingPointTypeError("integer modulo") },
 | 
				
			||||||
        remainder = { _, _ -> floatingPointTypeError("integer remainder") },
 | 
					        remainder = { _, _ -> floatingPointTypeError("integer remainder") },
 | 
				
			||||||
        lesser = { a, b -> a < b },
 | 
					        lesser = { a, b -> a < b },
 | 
				
			||||||
@ -198,6 +205,9 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
        subtract = { a, b -> a - b },
 | 
					        subtract = { a, b -> a - b },
 | 
				
			||||||
        multiply = { a, b -> a * b },
 | 
					        multiply = { a, b -> a * b },
 | 
				
			||||||
        divide = { a, b -> a / b },
 | 
					        divide = { a, b -> a / b },
 | 
				
			||||||
 | 
					        binaryAnd = { _, _ -> floatingPointTypeError("binary and") },
 | 
				
			||||||
 | 
					        binaryOr = { _, _ -> floatingPointTypeError("binary or") },
 | 
				
			||||||
 | 
					        binaryExclusiveOr = { _, _ -> floatingPointTypeError("binary exclusive-or") },
 | 
				
			||||||
        euclideanModulo = { _, _ -> floatingPointTypeError("integer modulo") },
 | 
					        euclideanModulo = { _, _ -> floatingPointTypeError("integer modulo") },
 | 
				
			||||||
        remainder = { _, _ -> floatingPointTypeError("integer remainder") },
 | 
					        remainder = { _, _ -> floatingPointTypeError("integer remainder") },
 | 
				
			||||||
        lesser = { a, b -> a < b },
 | 
					        lesser = { a, b -> a < b },
 | 
				
			||||||
@ -217,6 +227,9 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
        subtract = { a, b -> a - b },
 | 
					        subtract = { a, b -> a - b },
 | 
				
			||||||
        multiply = { a, b -> a * b },
 | 
					        multiply = { a, b -> a * b },
 | 
				
			||||||
        divide = { a, b -> a / b },
 | 
					        divide = { a, b -> a / b },
 | 
				
			||||||
 | 
					        binaryAnd = { a, b -> a and b },
 | 
				
			||||||
 | 
					        binaryOr = { a, b -> a or b },
 | 
				
			||||||
 | 
					        binaryExclusiveOr = { a, b -> a xor b },
 | 
				
			||||||
        euclideanModulo = { x, d -> (x % d).let { q -> if (q < 0) q + abs(d) else q } },
 | 
					        euclideanModulo = { x, d -> (x % d).let { q -> if (q < 0) q + abs(d) else q } },
 | 
				
			||||||
        remainder = { x, d -> x % d },
 | 
					        remainder = { x, d -> x % d },
 | 
				
			||||||
        lesser = { a, b -> a < b },
 | 
					        lesser = { a, b -> a < b },
 | 
				
			||||||
@ -236,6 +249,9 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
        subtract = { a, b -> a - b },
 | 
					        subtract = { a, b -> a - b },
 | 
				
			||||||
        multiply = { a, b -> a * b },
 | 
					        multiply = { a, b -> a * b },
 | 
				
			||||||
        divide = { a, b -> a / b },
 | 
					        divide = { a, b -> a / b },
 | 
				
			||||||
 | 
					        binaryAnd = { a, b -> a and b },
 | 
				
			||||||
 | 
					        binaryOr = { a, b -> a or b },
 | 
				
			||||||
 | 
					        binaryExclusiveOr = { a, b -> a xor b },
 | 
				
			||||||
        euclideanModulo = { x, d -> (x % d).let { q -> if (q < 0) q + abs(d) else q } },
 | 
					        euclideanModulo = { x, d -> (x % d).let { q -> if (q < 0) q + abs(d) else q } },
 | 
				
			||||||
        remainder = { x, d -> x % d },
 | 
					        remainder = { x, d -> x % d },
 | 
				
			||||||
        lesser = { a, b -> a < b },
 | 
					        lesser = { a, b -> a < b },
 | 
				
			||||||
@ -257,6 +273,9 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
    subtract: (T, T) -> T,
 | 
					    subtract: (T, T) -> T,
 | 
				
			||||||
    multiply: (T, T) -> T,
 | 
					    multiply: (T, T) -> T,
 | 
				
			||||||
    divide: (T, T) -> T,
 | 
					    divide: (T, T) -> T,
 | 
				
			||||||
 | 
					    binaryAnd: (T, T) -> T,
 | 
				
			||||||
 | 
					    binaryOr: (T, T) -> T,
 | 
				
			||||||
 | 
					    binaryExclusiveOr: (T, T) -> T,
 | 
				
			||||||
    euclideanModulo: (T, T) -> T,
 | 
					    euclideanModulo: (T, T) -> T,
 | 
				
			||||||
    remainder: (T, T) -> T,
 | 
					    remainder: (T, T) -> T,
 | 
				
			||||||
    lesser: (T, T) -> Boolean,
 | 
					    lesser: (T, T) -> Boolean,
 | 
				
			||||||
@ -269,13 +288,16 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
      InfixOperator.Minus -> subtract(convert(left), convert(right))
 | 
					      InfixOperator.Minus -> subtract(convert(left), convert(right))
 | 
				
			||||||
      InfixOperator.Multiply -> multiply(convert(left), convert(right))
 | 
					      InfixOperator.Multiply -> multiply(convert(left), convert(right))
 | 
				
			||||||
      InfixOperator.Divide -> divide(convert(left), convert(right))
 | 
					      InfixOperator.Divide -> divide(convert(left), convert(right))
 | 
				
			||||||
 | 
					      InfixOperator.Equals, InfixOperator.NotEquals -> throw RuntimeException("Unable to handle operation $op")
 | 
				
			||||||
 | 
					      InfixOperator.BinaryAnd -> binaryAnd(convert(left), convert(right))
 | 
				
			||||||
 | 
					      InfixOperator.BinaryOr -> binaryOr(convert(left), convert(right))
 | 
				
			||||||
 | 
					      InfixOperator.BinaryExclusiveOr -> binaryExclusiveOr(convert(left), convert(right))
 | 
				
			||||||
      InfixOperator.EuclideanModulo -> euclideanModulo(convert(left), convert(right))
 | 
					      InfixOperator.EuclideanModulo -> euclideanModulo(convert(left), convert(right))
 | 
				
			||||||
      InfixOperator.Remainder -> remainder(convert(left), convert(right))
 | 
					      InfixOperator.Remainder -> remainder(convert(left), convert(right))
 | 
				
			||||||
      InfixOperator.Lesser -> lesser(convert(left), convert(right))
 | 
					      InfixOperator.Lesser -> lesser(convert(left), convert(right))
 | 
				
			||||||
      InfixOperator.Greater -> greater(convert(left), convert(right))
 | 
					      InfixOperator.Greater -> greater(convert(left), convert(right))
 | 
				
			||||||
      InfixOperator.LesserEqual -> lesserEqual(convert(left), convert(right))
 | 
					      InfixOperator.LesserEqual -> lesserEqual(convert(left), convert(right))
 | 
				
			||||||
      InfixOperator.GreaterEqual -> greaterEqual(convert(left), convert(right))
 | 
					      InfixOperator.GreaterEqual -> greaterEqual(convert(left), convert(right))
 | 
				
			||||||
      else -> throw RuntimeException("Unable to handle operation $op")
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -284,12 +306,14 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
    value: Number,
 | 
					    value: Number,
 | 
				
			||||||
    convert: (Number) -> T,
 | 
					    convert: (Number) -> T,
 | 
				
			||||||
    plus: (T) -> T,
 | 
					    plus: (T) -> T,
 | 
				
			||||||
    minus: (T) -> T
 | 
					    minus: (T) -> T,
 | 
				
			||||||
 | 
					    binaryNot: (T) -> T
 | 
				
			||||||
  ): Any {
 | 
					  ): Any {
 | 
				
			||||||
    return when (op) {
 | 
					    return when (op) {
 | 
				
			||||||
 | 
					      PrefixOperator.Negate -> throw RuntimeException("Unable to handle operation $op")
 | 
				
			||||||
      PrefixOperator.UnaryPlus -> plus(convert(value))
 | 
					      PrefixOperator.UnaryPlus -> plus(convert(value))
 | 
				
			||||||
      PrefixOperator.UnaryMinus -> minus(convert(value))
 | 
					      PrefixOperator.UnaryMinus -> minus(convert(value))
 | 
				
			||||||
      else -> throw RuntimeException("Unable to handle operation $op")
 | 
					      PrefixOperator.BinaryNot -> binaryNot(convert(value))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -328,6 +352,10 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private fun unaryFloatingPointTypeError(operation: String): Nothing {
 | 
				
			||||||
 | 
					    throw RuntimeException("Can't perform $operation on a floating point type")
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private fun floatingPointTypeError(operation: String): Nothing {
 | 
					  private fun floatingPointTypeError(operation: String): Nothing {
 | 
				
			||||||
    throw RuntimeException("Can't perform $operation between floating point types")
 | 
					    throw RuntimeException("Can't perform $operation between floating point types")
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -83,7 +83,7 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private fun readPrefixOperation(): PrefixOperation = within {
 | 
					  private fun readPrefixOperation(): PrefixOperation = within {
 | 
				
			||||||
    expect(TokenType.Negation, TokenType.Plus, TokenType.Minus) {
 | 
					    expect(TokenType.Negation, TokenType.Plus, TokenType.Minus, TokenType.Tilde) {
 | 
				
			||||||
      PrefixOperation(convertPrefixOperator(it), readExpression())
 | 
					      PrefixOperation(convertPrefixOperator(it), readExpression())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -148,7 +148,7 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
 | 
				
			|||||||
        readParentheses()
 | 
					        readParentheses()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      TokenType.Negation, TokenType.Plus, TokenType.Minus -> {
 | 
					      TokenType.Negation, TokenType.Plus, TokenType.Minus, TokenType.Tilde -> {
 | 
				
			||||||
        readPrefixOperation()
 | 
					        readPrefixOperation()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -192,6 +192,9 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
 | 
				
			|||||||
        TokenType.Minus,
 | 
					        TokenType.Minus,
 | 
				
			||||||
        TokenType.Multiply,
 | 
					        TokenType.Multiply,
 | 
				
			||||||
        TokenType.Divide,
 | 
					        TokenType.Divide,
 | 
				
			||||||
 | 
					        TokenType.Ampersand,
 | 
				
			||||||
 | 
					        TokenType.Pipe,
 | 
				
			||||||
 | 
					        TokenType.Caret,
 | 
				
			||||||
        TokenType.Equality,
 | 
					        TokenType.Equality,
 | 
				
			||||||
        TokenType.Inequality,
 | 
					        TokenType.Inequality,
 | 
				
			||||||
        TokenType.Mod,
 | 
					        TokenType.Mod,
 | 
				
			||||||
@ -311,6 +314,9 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
 | 
				
			|||||||
    TokenType.Minus -> InfixOperator.Minus
 | 
					    TokenType.Minus -> InfixOperator.Minus
 | 
				
			||||||
    TokenType.Multiply -> InfixOperator.Multiply
 | 
					    TokenType.Multiply -> InfixOperator.Multiply
 | 
				
			||||||
    TokenType.Divide -> InfixOperator.Divide
 | 
					    TokenType.Divide -> InfixOperator.Divide
 | 
				
			||||||
 | 
					    TokenType.Ampersand -> InfixOperator.BinaryAnd
 | 
				
			||||||
 | 
					    TokenType.Pipe -> InfixOperator.BinaryOr
 | 
				
			||||||
 | 
					    TokenType.Caret -> InfixOperator.BinaryExclusiveOr
 | 
				
			||||||
    TokenType.Equality -> InfixOperator.Equals
 | 
					    TokenType.Equality -> InfixOperator.Equals
 | 
				
			||||||
    TokenType.Inequality -> InfixOperator.NotEquals
 | 
					    TokenType.Inequality -> InfixOperator.NotEquals
 | 
				
			||||||
    TokenType.Mod -> InfixOperator.EuclideanModulo
 | 
					    TokenType.Mod -> InfixOperator.EuclideanModulo
 | 
				
			||||||
@ -325,6 +331,7 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
 | 
				
			|||||||
  private fun convertPrefixOperator(token: Token): PrefixOperator = when (token.type) {
 | 
					  private fun convertPrefixOperator(token: Token): PrefixOperator = when (token.type) {
 | 
				
			||||||
    TokenType.Plus -> PrefixOperator.UnaryPlus
 | 
					    TokenType.Plus -> PrefixOperator.UnaryPlus
 | 
				
			||||||
    TokenType.Minus -> PrefixOperator.UnaryMinus
 | 
					    TokenType.Minus -> PrefixOperator.UnaryMinus
 | 
				
			||||||
 | 
					    TokenType.Tilde -> PrefixOperator.BinaryNot
 | 
				
			||||||
    else -> throw RuntimeException("Unknown Prefix Operator")
 | 
					    else -> throw RuntimeException("Unknown Prefix Operator")
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,10 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
 | 
				
			|||||||
  Minus(SingleChar('-'), OperatorFamily, Promotion('-', MinusMinus)),
 | 
					  Minus(SingleChar('-'), OperatorFamily, Promotion('-', MinusMinus)),
 | 
				
			||||||
  Multiply(SingleChar('*'), OperatorFamily),
 | 
					  Multiply(SingleChar('*'), OperatorFamily),
 | 
				
			||||||
  Divide(SingleChar('/'), OperatorFamily),
 | 
					  Divide(SingleChar('/'), OperatorFamily),
 | 
				
			||||||
 | 
					  Tilde(SingleChar('~'), OperatorFamily),
 | 
				
			||||||
 | 
					  Ampersand(SingleChar('&'), OperatorFamily),
 | 
				
			||||||
 | 
					  Pipe(SingleChar('|'), OperatorFamily),
 | 
				
			||||||
 | 
					  Caret(SingleChar('^'), OperatorFamily),
 | 
				
			||||||
  LesserEqual(OperatorFamily),
 | 
					  LesserEqual(OperatorFamily),
 | 
				
			||||||
  GreaterEqual(OperatorFamily),
 | 
					  GreaterEqual(OperatorFamily),
 | 
				
			||||||
  Lesser(SingleChar('<'), OperatorFamily, Promotion('=', LesserEqual)),
 | 
					  Lesser(SingleChar('<'), OperatorFamily, Promotion('=', LesserEqual)),
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user