summaryrefslogtreecommitdiff
path: root/docs/examples/actors/fringe.scala
blob: 96edd396e9efcd9f26ee6b4b25133b8d4196bbd4 (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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package examples.actors

import scala.actors.Actor._
import scala.actors.{Channel, OutputChannel}

/**
 @author Philipp Haller
 @version 1.0, 07/09/2007
 */
object fringe extends Application {

  abstract class Tree
  case class Node(left: Tree, right: Tree) extends Tree
  case class Leaf(v: Int) extends Tree

  val comparator = actor {
    val extractor1 = actor(extractorBehavior())
    val extractor2 = actor(extractorBehavior())
    val ch1 = new Channel[Any]
    val ch2 = new Channel[Any]
    loop {
      react {
        case ('Fringe, tree1, tree2) =>
          extractor1.send(('Fringe, tree1), ch1)
          extractor2.send(('Fringe, tree2), ch2)
          self ! Triple('Equal, ch1.?, ch2.?)

        case ('Equal, atom1, atom2) =>
          println("comparing "+atom1+" and "+atom2)
          if (atom1 == atom2) atom1 match {
            case None =>
              println("same fringe")
              exit()
            case _ =>
              self ! Triple('Equal, ch1.?, ch2.?)
          } else {
            println("fringes differ")
            exit()
          }
      }
    }
  }

  val extractorBehavior = () => {
    var output: OutputChannel[Any] = null
    loop {
      react {
        case ('Fringe, tree) =>
          output = sender
          self ! ('Extract, tree)

        case ('Extract, tree) => tree match {
          case atom @ Leaf(_) =>
            println("sending "+Some(atom))
            output ! Some(atom)
            sender ! 'Continue

          case Node(left, right) =>
            val outer = self
            val outerCont = sender
            val cont = actor {
              react {
                case 'Continue =>
                  outer.send(('Extract, right), outerCont)
              }
            }
            self.send(('Extract, left), cont)
        }

        case 'Continue =>
          output ! None
          exit()
      }
    }
  }

  comparator ! ('Fringe, Node(Leaf(5), Node(Leaf(7), Leaf(3))),
                Node(Leaf(5), Node(Leaf(7), Leaf(3))))
}