(* * Copyright (C) 2005 Michael Velten * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *) (* * An interpreter for Brainfuck written in Standard ML. (2005-03-09) *) fun bf f = let exception Syntax of string exception Runtime of string val c = Array.fromList (explode (TextIO.inputAll (TextIO.openIn f))) val t = Array.array (30000, 0) val cp = ref 0 (* code pointer *) val tp = ref 0 (* the pointer *) val lp = ref nil (* loop pointer *) in while (!cp < Array.length c) do ( case Array.sub (c, !cp) of #">" => tp := !tp + 1 | #"<" => tp := !tp - 1 | #"+" => Array.update (t, !tp, (Array.sub (t, !tp) + 1) mod 256) | #"-" => Array.update (t, !tp, (Array.sub (t, !tp) - 1) mod 256) | #"." => print (str (chr (Array.sub (t, !tp)))) | #"," => Array.update (t, !tp, ord (String.sub (TextIO.inputN (TextIO.stdIn, 1), 0)) handle Subscript => raise Runtime "EOF while reading from stdin") | #"[" => if Array.sub (t, !tp) <> 0 then lp := !cp :: !lp else let val ll = ref 1 in while !ll > 0 do ( cp := !cp + 1 ; case Array.sub (c, !cp) of #"[" => ll := !ll + 1 | #"]" => ll := !ll - 1 | _ => () ) end | #"]" => (if Array.sub (t, !tp) <> 0 then cp := hd (!lp) - 1 else () ; lp := tl (!lp)) | #"#" => let val i = ref 0 in while !i < 10 do (print (Int.toString (!i) ^ ": " ^ Int.toString (Array.sub (t, !i)) ^ "\n") ; i := !i + 1) end | _ => () ; cp := !cp + 1 ) handle Empty => raise Syntax "unmatched bracket: ]" | Subscript => if !tp < 0 orelse !tp >= 30000 then raise Runtime ("dereferencing invalid pointer value: " ^ (Int.toString (!tp))) else raise Syntax "unmatched bracket: [" ; if null (!lp) then () else raise Syntax "unmatched bracket: [" end