-
Notifications
You must be signed in to change notification settings - Fork 3.1k
/
Precedence.scala
48 lines (43 loc) · 1.56 KB
/
Precedence.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/
package scala.reflect.internal
import scala.annotation.switch
import Chars.{isOperatorPart, isScalaLetter}
final class Precedence private (val level: Int) extends AnyVal with Ordered[Precedence] {
def compare(that: Precedence): Int = level.compare(that.level)
override def toString = s"Precedence($level)"
}
object Precedence extends (Int => Precedence) {
type CodePoint = Int
private[this] val ErrorName = "<error>"
private def isAssignmentOp(name: String) = name match {
case "!=" | "<=" | ">=" | "" => false
case _ => name.last == '=' && name.head != '=' && isOperatorPart(name.codePointAt(0))
}
private def firstChar(c: CodePoint): Precedence = apply((c: @switch) match {
case '|' => 2
case '^' => 3
case '&' => 4
case '=' | '!' => 5
case '<' | '>' => 6
case ':' => 7
case '+' | '-' => 8
case '*' | '/' | '%' => 9
case _ => if (isScalaLetter(c)) 1 else 10
})
def apply(level: Int): Precedence = new Precedence(level)
def apply(name: String): Precedence = name match {
case "" | ErrorName => this(-1)
case _ if isAssignmentOp(name) => this(0)
case _ => firstChar(name.codePointAt(0))
}
}