62 lines
1.8 KiB
OCaml
62 lines
1.8 KiB
OCaml
open Ast
|
|
open Tape
|
|
open Helpers
|
|
|
|
let run program tape =
|
|
let program = Array.of_list program in
|
|
let rec loop i =
|
|
if i < Array.length program
|
|
then (
|
|
match program.(i) with
|
|
| Up when tape.ptr - 1 < 0 -> failwith "Tried to move past beginning of tape."
|
|
| Up ->
|
|
tape.ptr <- tape.ptr - 1;
|
|
loop (i + 1)
|
|
| Down when tape.ptr + 1 >= Array.length tape.data ->
|
|
failwith "Tried to move past end of tape."
|
|
| Down ->
|
|
tape.ptr <- tape.ptr + 1;
|
|
loop (i + 1)
|
|
| Five ->
|
|
tape.data.(tape.ptr) <- (tape.data.(tape.ptr) + 5) mod 7;
|
|
loop (i + 1)
|
|
| Write ->
|
|
let a = tape.data.(tape.ptr) in
|
|
tape.ptr <- tape.ptr + 1;
|
|
let b = tape.data.(tape.ptr) in
|
|
tape.ptr <- tape.ptr + 1;
|
|
let c = tape.data.(tape.ptr) in
|
|
tape.ptr <- tape.ptr + 1;
|
|
print_char (char_of_int (base7_to_base10 (a, b, c)));
|
|
loop (i + 1)
|
|
| Read ->
|
|
(* TODO: read input character-wise without pressing enter (perhaps in raw mode) *)
|
|
let c =
|
|
try Some (input_char stdin) with
|
|
| End_of_file -> None
|
|
in
|
|
let a, b, c =
|
|
match c with
|
|
| Some ch -> base10_to_base7 (Char.code ch)
|
|
| None -> base10_to_base7 (Char.code '\n')
|
|
in
|
|
tape.data.(tape.ptr) <- a;
|
|
tape.ptr <- tape.ptr + 1;
|
|
tape.data.(tape.ptr) <- b;
|
|
tape.ptr <- tape.ptr + 1;
|
|
tape.data.(tape.ptr) <- c;
|
|
tape.ptr <- tape.ptr + 1;
|
|
loop (i + 1)
|
|
| Start ->
|
|
if tape.data.(tape.ptr) = 6
|
|
then loop (find_loop_end program (i + 1) + 1)
|
|
else loop (i + 1)
|
|
| End ->
|
|
if tape.data.(tape.ptr) <> 6
|
|
then loop (find_loop_start program (i - 1) + 1)
|
|
else loop (i + 1))
|
|
in
|
|
let () = loop 0 in
|
|
tape
|
|
;;
|