summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala
blob: 95f4418759e90df8166024285996f4160437bae1 (plain) (blame)
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
/* NSC -- new Scala compiler
 * Copyright 2005-2010 LAMP/EPFL
 * @author  Martin Odersky
 */

// $Id$

package scala.tools.nsc
package backend.icode.analysis

/** A complete lattice.
 */
trait CompleteLattice {
  type Elem <: AnyRef

  /** Hold together local variable and stack state. The
   *  equals method uses reference equality for top and bottom,
   *  and structural equality for other values.
   */
  case class IState[V, S](val vars: V, val stack: S) {
    override def equals(other: Any): Boolean = other match {
      case that: IState[_, _] =>
        if ((this eq bottom) || (that eq bottom)) this eq that
        else if ((this eq top) || (that eq top)) this eq that
        else (stack == that.stack && vars == that.vars)
      case _ => false
    }
  }

  /** Return the least upper bound of <code>a</code> and <code>b</code> */
  def lub2(exceptional: Boolean)(a: Elem, b: Elem): Elem

  /** Return the top element. */
  def top: Elem

  /** Return the bottom element. */
  def bottom: Elem

  /** Compute the least upper bound of a list of elements. */
  def lub(xs: List[Elem], exceptional: Boolean): Elem = try {
    if (xs == Nil) bottom else xs reduceLeft lub2(exceptional)
  } catch {
      case e: LubException =>
        Console.println("Lub on blocks: " + xs)
        throw e
  }
}