author | Christian Urban <urbanc@in.tum.de> |
Thu, 26 Sep 2019 10:59:52 +0100 | |
changeset 632 | b7b91158eded |
parent 631 | f618dd4de24a |
child 633 | e4889da2fe29 |
progs/bfi.scala | file | annotate | diff | comparison | revisions | |
slides/slides01.pdf | file | annotate | diff | comparison | revisions | |
slides/slides01.tex | file | annotate | diff | comparison | revisions |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/progs/bfi.scala Thu Sep 26 10:59:52 2019 +0100 @@ -0,0 +1,93 @@ +// An Interpreter for BF*** Programs +//=================================== + + +import io.Source +import scala.util._ + + +// loding a bf-file +def load_bff(name: String) : String = + Try(Source.fromFile(name)("ISO-8859-1").mkString).getOrElse("") + + +type Mem = Map[Int, Int] + +// reading and writing BF memory +def sread(mem: Mem, mp: Int) : Int = + mem.getOrElse(mp, 0) + +def write(mem: Mem, mp: Int, v: Int) : Mem = + mem.updated(mp, v) + + +// Right and Left Jumps in BF loops +def jumpRight(prog: String, pc: Int, level: Int) : Int = { + if (prog.length <= pc) pc + else (prog(pc), level) match { + case (']', 0) => pc + 1 + case (']', l) => jumpRight(prog, pc + 1, l - 1) + case ('[', l) => jumpRight(prog, pc + 1, l + 1) + case (_, l) => jumpRight(prog, pc + 1, l) + } +} + +def jumpLeft(prog: String, pc: Int, level: Int) : Int = { + if (pc < 0) pc + else (prog(pc), level) match { + case ('[', 0) => pc + 1 + case ('[', l) => jumpLeft(prog, pc - 1, l - 1) + case (']', l) => jumpLeft(prog, pc - 1, l + 1) + case (_, l) => jumpLeft(prog, pc - 1, l) + } +} + + +def compute(prog: String, pc: Int, mp: Int, mem: Mem) : Mem = { + if (0 <= pc && pc < prog.length) { + val (new_pc, new_mp, new_mem) = prog(pc) match { + case '>' => (pc + 1, mp + 1, mem) + case '<' => (pc + 1, mp - 1, mem) + case '+' => (pc + 1, mp, write(mem, mp, sread(mem, mp) + 1)) + case '-' => (pc + 1, mp, write(mem, mp, sread(mem, mp) - 1)) + case '.' => { print(sread(mem, mp).toChar); (pc + 1, mp, mem) } + case ',' => (pc + 1, mp, write(mem, mp, Console.in.read().toByte)) + case '[' => if (sread(mem, mp) == 0) + (jumpRight(prog, pc + 1, 0), mp, mem) + else (pc + 1, mp, mem) + case ']' => if (sread(mem, mp) != 0) + (jumpLeft(prog, pc - 1, 0), mp, mem) + else (pc + 1, mp, mem) + case _ => (pc + 1, mp, mem) + } + compute(prog, new_pc, new_mp, new_mem) + } + else mem +} + +def run(prog: String, m: Mem = Map()) = compute(prog, 0, 0, m) + + +def time_needed[T](n: Int, code: => T) = { + val start = System.nanoTime() + for (i <- 0 until n) code + val end = System.nanoTime() + (end - start)/(n * 1.0e9) +} + + + +// a Mandelbrot set generator in brainf*** written by Erik Bosman +// (http://esoteric.sange.fi/brainfuck/utils/mandelbrot/) + +println(s"${time_needed(1, run(load_bff("mandelbrot.bf")))} secs") + + +// a benchmark program (counts down from 'Z' to 'A') +val b1 = """>++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++ + [>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++ + ++++++++[>++++++++++[>++++++++++[>++++++++++[>+ + +++++++++[-]<-]<-]<-]<-]<-]<-]<-]++++++++++.""" + +println(s"${time_needed(1, run(b1))} secs") +
--- a/slides/slides01.tex Wed Sep 25 23:56:36 2019 +0100 +++ b/slides/slides01.tex Thu Sep 26 10:59:52 2019 +0100 @@ -428,7 +428,50 @@ \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{frame}[c] +\frametitle{Remember BF***?} +\begin{center} +\begin{tabular}{lcl} +\bl{\texttt{>}} & $\Rightarrow$ & move one cell right\\ +\bl{\texttt{<}} & $\Rightarrow$ & move one cell left\\ +\bl{\texttt{+}} & $\Rightarrow$ & increase cell by one\\ +\bl{\texttt{-}} & $\Rightarrow$ & decrease cell by one\\ +\bl{\texttt{.}} & $\Rightarrow$ & print current cell\\ +\bl{\texttt{,}} & $\Rightarrow$ & input current cell\\ +\bl{\texttt{[}} & $\Rightarrow$ & loop begin\\ +\bl{\texttt{]}} & $\Rightarrow$ & loop end\medskip\\ + & $\Rightarrow$ & everything else is a comment\\ +\end{tabular} +\end{center} + +\end{frame} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{frame}[c] + \frametitle{A Compiler for BF***} + + \begin{center} + \begin{tabular}{lcl} + \bl{\texttt{>}} & $\Rightarrow$ & \texttt{ptr++}\\ + \bl{\texttt{<}} & $\Rightarrow$ & \texttt{ptr--}\\ + \bl{\texttt{+}} & $\Rightarrow$ & \texttt{(*ptr)++}\\ + \bl{\texttt{-}} & $\Rightarrow$ & \texttt{(*ptr)--}\\ + \bl{\texttt{.}} & $\Rightarrow$ & \texttt{putchar(*ptr)}\\ + \bl{\texttt{,}} & $\Rightarrow$ & \texttt{*ptr = getchar()}\\ + \bl{\texttt{[}} & $\Rightarrow$ & \texttt{while(*ptr)\{}\\ + \bl{\texttt{]}} & $\Rightarrow$ & \texttt{\}}\medskip\\ + & $\Rightarrow$ & ignore everything else\\ + \end{tabular} + \end{center}\bigskip + + \texttt{char field[30000]\\ char *ptr = &field[15000]} + +\end{frame} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{frame}[c] @@ -628,26 +671,26 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\begin{frame}[c] -\frametitle{Finding Operations in Scala} - -{\bf\code{rexp.findAllIn(string)}}\medskip - -returns a list of all (sub)strings that match the -regular expression -\bigskip\bigskip - - -{\bf\code{rexp.findFirstIn(string)}}\medskip - -returns either - -\begin{itemize} -\item \code{None} if no (sub)string matches or -\item \code{Some(s)} with the first (sub)string -\end{itemize} - -\end{frame} +%\begin{frame}[c] +%\frametitle{Finding Operations in Scala} +% +%{\bf\code{rexp.findAllIn(string)}}\medskip +% +%returns a list of all (sub)strings that match the +%regular expression +%\bigskip\bigskip +% +% +%{\bf\code{rexp.findFirstIn(string)}}\medskip +% +%returns either +% +%\begin{itemize} +%\item \code{None} if no (sub)string matches or +%\item \code{Some(s)} with the first (sub)string +%\end{itemize} +% +%\end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%