| author | Christian Urban <christian.urban@kcl.ac.uk> | 
| Mon, 21 Jul 2025 16:38:07 +0100 | |
| changeset 491 | 2a30c7dfe3ed | 
| parent 460 | f5c0749858fd | 
| permissions | -rw-r--r-- | 
| 399 | 1 | // Main Part 5 about a "Compiler" for the Brainf*** language | 
| 2 | //============================================================ | |
| 233 | 3 | |
| 285 | 4 | |
| 399 | 5 | object M5b {
 | 
| 285 | 6 | |
| 233 | 7 | // !!! Copy any function you need from file bf.scala !!! | 
| 8 | // | |
| 9 | // If you need any auxiliary function, feel free to | |
| 10 | // implement it, but do not make any changes to the | |
| 11 | // templates below. | |
| 12 | ||
| 285 | 13 | |
| 14 | // DEBUGGING INFORMATION FOR COMPILERS!!! | |
| 15 | // | |
| 16 | // Compiler, even real ones, are fiendishly difficult to get | |
| 17 | // to produce correct code. One way to debug them is to run | |
| 18 | // example programs ``unoptimised''; and then optimised. Does | |
| 19 | // the optimised version still produce the same result? | |
| 20 | ||
| 21 | ||
| 22 | // for timing purposes | |
| 233 | 23 | def time_needed[T](n: Int, code: => T) = {
 | 
| 24 | val start = System.nanoTime() | |
| 25 | for (i <- 0 until n) code | |
| 26 | val end = System.nanoTime() | |
| 27 | (end - start)/(n * 1.0e9) | |
| 28 | } | |
| 29 | ||
| 285 | 30 | |
| 233 | 31 | type Mem = Map[Int, Int] | 
| 32 | ||
| 33 | import io.Source | |
| 34 | import scala.util._ | |
| 35 | ||
| 425 
6e990ae2c6a3
updated solutions and templates
 Christian Urban <christian.urban@kcl.ac.uk> parents: 
417diff
changeset | 36 | // ADD YOUR CODE BELOW | 
| 
6e990ae2c6a3
updated solutions and templates
 Christian Urban <christian.urban@kcl.ac.uk> parents: 
417diff
changeset | 37 | //====================== | 
| 233 | 38 | |
| 426 | 39 | // (6) | 
| 347 | 40 | def jtable(pg: String) : Map[Int, Int] = ??? | 
| 233 | 41 | |
| 42 | // testcase | |
| 285 | 43 | // | 
| 233 | 44 | // jtable("""+++++[->++++++++++<]>--<+++[->>++++++++++<<]>>++<<----------[+>.>.<+<]""")
 | 
| 45 | // => Map(69 -> 61, 5 -> 20, 60 -> 70, 27 -> 44, 43 -> 28, 19 -> 6) | |
| 46 | ||
| 47 | ||
| 347 | 48 | def compute2(pg: String, tb: Map[Int, Int], pc: Int, mp: Int, mem: Mem) : Mem = ??? | 
| 49 | def run2(pg: String, m: Mem = Map()) = ??? | |
| 233 | 50 | |
| 285 | 51 | // testcases | 
| 52 | // time_needed(1, run2(load_bff("benchmark.bf")))
 | |
| 333 | 53 | // time_needed(1, run2(load_bff("sierpinski.bf")))
 | 
| 233 | 54 | |
| 55 | ||
| 56 | ||
| 426 | 57 | // (7) | 
| 233 | 58 | |
| 347 | 59 | def optimise(s: String) : String = ??? | 
| 233 | 60 | |
| 347 | 61 | def compute3(pg: String, tb: Map[Int, Int], pc: Int, mp: Int, mem: Mem) : Mem = ??? | 
| 233 | 62 | |
| 347 | 63 | def run3(pg: String, m: Mem = Map()) = ??? | 
| 233 | 64 | |
| 65 | ||
| 66 | // testcases | |
| 285 | 67 | // | 
| 68 | // optimise(load_bff("benchmark.bf"))          // should have inserted 0's
 | |
| 460 | 69 | // optimise(load_bff("mandelbrot.bf")).length  // => 11205
 | 
| 285 | 70 | // | 
| 71 | // time_needed(1, run3(load_bff("benchmark.bf")))
 | |
| 233 | 72 | |
| 73 | ||
| 74 | ||
| 426 | 75 | // (8) | 
| 347 | 76 | def combine(s: String) : String = ??? | 
| 233 | 77 | |
| 285 | 78 | // testcase | 
| 79 | // combine(load_bff("benchmark.bf"))
 | |
| 233 | 80 | |
| 347 | 81 | def compute4(pg: String, tb: Map[Int, Int], pc: Int, mp: Int, mem: Mem) : Mem = ??? | 
| 233 | 82 | |
| 83 | // should call first optimise and then combine on the input string | |
| 285 | 84 | // | 
| 347 | 85 | def run4(pg: String, m: Mem = Map()) = ??? | 
| 233 | 86 | |
| 87 | ||
| 88 | // testcases | |
| 285 | 89 | // combine(optimise(load_bff("benchmark.bf"))) // => """>A+B[<A+M>A-A]<A[[....."""
 | 
| 233 | 90 | |
| 285 | 91 | // testcases (they should now run much faster) | 
| 92 | // time_needed(1, run4(load_bff("benchmark.bf")))
 | |
| 93 | // time_needed(1, run4(load_bff("sierpinski.bf"))) 
 | |
| 94 | // time_needed(1, run4(load_bff("mandelbrot.bf")))
 | |
| 233 | 95 | |
| 96 | ||
| 285 | 97 | } |