Source

ocaml-toys / brainfuck / bfjs.ml

Full commit
open Brainfuck

module Html = Dom_html
let js = Js.string

let document = Html.window##document
let jsget msg opt = Js.Opt.get opt (fun () -> failwith msg)
let get_by_id id  = jsget id (document##getElementById (js id))
let get_typed_by_id coerce id = jsget "coerce" (coerce (get_by_id id))

let source_elem = get_typed_by_id Html.CoerceTo.textarea "source"
let input_elem = get_typed_by_id Html.CoerceTo.input "io_input"
let run_elem = get_by_id "run"
let ast_elem = get_by_id "ast"
let optim_elem = get_by_id "optim"
let output_elem = get_by_id "output"

let debug s = Html.window##alert (js s)

let append_text e s = Dom.appendChild e (document##createTextNode (js s))

module JsIo = struct
  let input_pointer = ref 0

  let reset () = 
    output_elem##innerHTML <- js "";
    input_pointer := 0

  let putchar c = append_text output_elem (String.make 1 c)

  let getchar () = 
    let str = Js.to_string (input_elem##value) in
    let c = str.[!input_pointer] in
    incr input_pointer;
    c
end

let reset () = 
  JsIo.reset ();
  ast_elem##innerHTML <- js "";
  optim_elem##innerHTML <- js ""

let run () = 
  reset ();
  let module JsInterpreter = Interpreter(JsIo) in
  let source = Js.to_string (source_elem##value) in
  let stream = Stream.of_string source in
  let ast = Parser.parse stream in
  let optim = Optimizer.optimize ast in
  ast_elem##innerHTML <- js (ParseTree.string_of_ast ast);  
  optim_elem##innerHTML <- js (ParseTree.string_of_ast optim);
  JsInterpreter.exec optim

let set_handlers _ = 
  run_elem##onclick <- Html.handler (fun _ -> run (); Js._false);
  Js._false

let _ = 
  Html.window##onload <- Html.handler set_handlers