(* BrainFuck Interpreter in SML © 2003 by Andreas Hartl http://www.runicsoft.com *) fun BrainFuck file = let val Buffer = Array.array ( 30000, 0 ) val CodeBuffer = Array.fromList ( explode ( TextIO.inputAll ( TextIO.openIn ( file ) ) ) ) val ThePointer = ref 0 val InsPointer = ref 0 val CurrentSymbol = ref #"0" in while ( Array.length(CodeBuffer) > !InsPointer ) do ( CurrentSymbol := Array.sub ( CodeBuffer, !InsPointer ); case !CurrentSymbol of #">" => ThePointer := !ThePointer + 1 | #"<" => ThePointer := !ThePointer - 1 | #"+" => Array.update ( Buffer, !ThePointer, Array.sub ( Buffer, !ThePointer ) + 1 ) | #"-" => Array.update ( Buffer, !ThePointer, Array.sub ( Buffer, !ThePointer ) - 1 ) | #"." => print ( Char.toString ( chr ( Array.sub ( Buffer, !ThePointer ) ) ) ) | #"," => Array.update ( Buffer, !ThePointer, ord ( String.sub ( TextIO.inputN ( TextIO.stdIn, 1 ), 0 ) ) ) | #"[" => if Array.sub ( Buffer, !ThePointer ) = 0 then let val looplevel = ref 1 in while !looplevel <> 0 do ( InsPointer := !InsPointer + 1; if Array.sub ( CodeBuffer, !InsPointer ) = #"[" then looplevel := !looplevel + 1 else if Array.sub ( CodeBuffer, !InsPointer ) = #"]" then looplevel := !looplevel - 1 else looplevel := !looplevel ) end else InsPointer := !InsPointer | #"]" => let val looplevel = ref ~1 in while !looplevel <> 0 do ( InsPointer := !InsPointer - 1; if Array.sub ( CodeBuffer, !InsPointer ) = #"]" then looplevel := !looplevel - 1 else if Array.sub ( CodeBuffer, !InsPointer ) = #"[" then ( if !looplevel = ~1 then (InsPointer := !InsPointer - 1; looplevel := !looplevel + 1) else looplevel := !looplevel + 1) else looplevel := !looplevel ) end | n => InsPointer := !InsPointer; InsPointer := !InsPointer + 1 ) end;