PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/scala/scala-impl/testdata/uast/complex/ComplexSample2.scala

http://github.com/JetBrains/intellij-scala
Scala | 76 lines | 65 code | 10 blank | 1 comment | 10 complexity | bb9afbce45f9dcbde828e26d3527326a MD5 | raw file
Possible License(s): CC0-1.0, Unlicense, Apache-2.0
  1. // Contributed by Daniel Gronau
  2. import scala.annotation._
  3. trait Func[T] {
  4. val zero: T
  5. def inc(t: T): T
  6. def dec(t: T): T
  7. def in: T
  8. def out(t: T): Unit
  9. }
  10. object ByteFunc extends Func[Byte] {
  11. override val zero: Byte = 0
  12. override def inc(t: Byte) = ((t + 1) & 0xFF).toByte
  13. override def dec(t: Byte) = ((t - 1) & 0xFF).toByte
  14. override def in: Byte = scala.io.StdIn.readByte
  15. override def out(t: Byte) { print(t.toChar) }
  16. }
  17. case class Tape[T](left: List[T], cell: T, right: List[T])(
  18. implicit func: Func[T]
  19. ) {
  20. private def headOf(list: List[T]) = if (list.isEmpty) func.zero else list.head
  21. private def tailOf(list: List[T]) = if (list.isEmpty) Nil else list.tail
  22. def isZero: Boolean = cell == func.zero
  23. def execute(ch: Char): Tape[T] = ch match {
  24. case '+' => copy(cell = func.inc(cell))
  25. case '-' => copy(cell = func.dec(cell))
  26. case '<' => Tape(tailOf(left), headOf(left), cell :: right)
  27. case '>' => Tape(cell :: left, headOf(right), tailOf(right))
  28. case '.' => func.out(cell); this
  29. case ',' => copy(cell = func.in)
  30. case '[' | ']' => this
  31. case _ => sys.error("Unexpected token: " + ch)
  32. }
  33. }
  34. object Tape {
  35. def empty[T](func: Func[T]): Tape[T] = Tape(Nil, func.zero, Nil)(func)
  36. }
  37. class Brainfuck[T](func: Func[T]) {
  38. private var prog: String = _
  39. private var open2close: Map[Int, Int] = _
  40. private var close2open: Map[Int, Int] = _
  41. @tailrec private def braceMatcher(pos: Int,
  42. stack: List[Int],
  43. o2c: Map[Int, Int]): Map[Int, Int] =
  44. if (pos == prog.length) o2c
  45. else
  46. prog(pos) match {
  47. case '[' => braceMatcher(pos + 1, pos :: stack, o2c)
  48. case ']' =>
  49. braceMatcher(pos + 1, stack.tail, o2c + (stack.head -> pos))
  50. case _ => braceMatcher(pos + 1, stack, o2c)
  51. }
  52. @tailrec private def ex(pos: Int, tape: Tape[T]): Unit =
  53. if (pos < prog.length) ex(prog(pos) match {
  54. case '[' if tape.isZero => open2close(pos)
  55. case ']' if !tape.isZero => close2open(pos)
  56. case _ => pos + 1
  57. }, tape.execute(prog(pos)))
  58. def execute(p: String) {
  59. prog = p.replaceAll("[^\\+\\-\\[\\]\\.\\,\\>\\<]", "")
  60. open2close = braceMatcher(0, Nil, Map())
  61. close2open = open2close.map(it => it.swap)
  62. println("---running---")
  63. ex(0, Tape.empty(func))
  64. println("\n---done---")
  65. }
  66. }