From 0027c7b647e1b345badbb01bcafd22feee075470 Mon Sep 17 00:00:00 2001 From: pacien Date: Sun, 22 Apr 2018 22:39:56 +0200 Subject: Implement program execution from command line --- README.md | 6 +++++- examples/add.reg | 2 ++ examples/add.urm | 11 +++++++++++ main.ml | 19 +++++++++++++++++++ makefile | 3 ++- parser.ml | 12 +++++++++--- parser.mli | 7 +++++++ reg.ml | 3 +++ reg.mli | 4 ++++ 9 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 examples/add.reg create mode 100644 examples/add.urm diff --git a/README.md b/README.md index 2971b4c..2cce7bf 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,11 @@ Unlimited Register Machine in OCaml. ## Usage -TODO: describe usage of the `urm` program. +``` +./urm +``` + +Examples programs are provided in the `examples` folder. ## Authors diff --git a/examples/add.reg b/examples/add.reg new file mode 100644 index 0000000..c24e1f9 --- /dev/null +++ b/examples/add.reg @@ -0,0 +1,2 @@ +1 2 +2 3 diff --git a/examples/add.urm b/examples/add.urm new file mode 100644 index 0000000..d11eff7 --- /dev/null +++ b/examples/add.urm @@ -0,0 +1,11 @@ +ZERO 0 +ZERO 3 +JUMP 1 3 6 +SUCC 0 +SUCC 3 +JUMP 3 3 2 +ZERO 3 +JUMP 2 3 11 +SUCC 0 +SUCC 3 +JUMP 3 3 7 diff --git a/main.ml b/main.ml index 1bb6704..2f8d57c 100644 --- a/main.ml +++ b/main.ml @@ -9,3 +9,22 @@ open Instptr open Reg open Urm +let exec_with_resource func filename = + let file = open_in filename in + let res = func file in + close_in file; res + +let read_prgm = exec_with_resource (fun f -> string_of_file f |> program_of_string) +let read_regs = exec_with_resource (fun f -> string_of_file f |> regs_of_string) +let run run_func prgm regs = urm_mk prgm regs |> run_func |> regs_string |> print_endline + +let run_mode_of_string = function + | "run" -> urm_run + | "trace" -> urm_run_trace + | _ -> failwith "Invalid run mode" + +let () = match Sys.argv with + | [| _; "run-tests" |] -> () (* handled in test files *) + | [| _; mode; prgm; regs |] -> run (run_mode_of_string mode) (read_prgm prgm) (read_regs regs) + | _ -> print_endline "Usage: urm | trace >" + diff --git a/makefile b/makefile index 2ccd250..6345a40 100644 --- a/makefile +++ b/makefile @@ -6,7 +6,8 @@ SOURCES = \ parser.mli parser.ml \ instptr.mli instptr.ml \ reg.mli reg.ml \ - urm.mli urm.ml urm_test.ml + urm.mli urm.ml urm_test.ml \ + main.ml OCAMLMAKEFILE = /usr/share/ocamlmakefile/OCamlMakefile include $(OCAMLMAKEFILE) diff --git a/parser.ml b/parser.ml index 72042d2..1f367d1 100644 --- a/parser.ml +++ b/parser.ml @@ -20,7 +20,13 @@ let rec program_of_lex = function | "jump" :: arg_1 :: arg_2 :: arg_3 :: tail -> (Jump ((int_of_string arg_1), (int_of_string arg_2), (int_of_string arg_3))) :: (program_of_lex tail) | _ -> raise Syntax_error -let program_of_string str = - let lex = Str.split (Str.regexp "[\t\n(),]+") str - in List.iter (fun s -> print_string s; print_newline ()) lex; program_of_lex lex +(* FIXME: reject multiple definition of a single register *) +let rec regs_of_lex = function + | [] -> [] + | regnum :: regvalue :: tail -> Reg (int_of_string regnum, int_of_string regvalue) :: (regs_of_lex tail) + | _ -> raise Syntax_error + +let seq_from_string lexer_func str = Str.split (Str.regexp "[\t\n(), ]+") str |> lexer_func +let program_of_string = seq_from_string program_of_lex +let regs_of_string = seq_from_string regs_of_lex diff --git a/parser.mli b/parser.mli index d210396..f7609f9 100644 --- a/parser.mli +++ b/parser.mli @@ -11,5 +11,12 @@ val string_of_file : in_channel -> string (* Converts lexemes into instructions. *) val program_of_lex : string list -> urmcmd list +(* Converts lexemes into registers. *) +val regs_of_lex : string list -> reg list + (* Parses the string representation of a program. *) val program_of_string : string -> urmcmd list + +(* Parses the string representation of serialized registers. *) +val regs_of_string : string -> reg list + diff --git a/reg.ml b/reg.ml index c452282..45bbb4b 100644 --- a/reg.ml +++ b/reg.ml @@ -8,6 +8,7 @@ open Common let reg_idx (Reg(idx, _)) = idx let reg_val (Reg(_, value)) = value let reg_compar l r = (reg_val l) - (reg_val r) +let reg_string (Reg (index, value)) = (string_of_int index) ^ ": " ^ (string_of_int value) let regs_get reglist index = List.find (fun (Reg(idx, _)) -> idx = index) reglist |> reg_val @@ -15,3 +16,5 @@ let regs_get reglist index = let regs_set reglist index value = Reg(index, value) :: List.filter (fun (Reg(idx, _)) -> idx != index) reglist +let rec regs_string reglist = List.map (reg_string) reglist |> String.concat ", " + diff --git a/reg.mli b/reg.mli index 15d53de..f5e41a0 100644 --- a/reg.mli +++ b/reg.mli @@ -21,3 +21,7 @@ val regs_get : reg list -> regidx -> regval (* Set the value of the register to value, * or creates it to the value specified if it does not exist *) val regs_set : reg list -> regidx -> regval -> reg list + +(* Returns the string representation of a register list. *) +val regs_string : reg list -> string + -- cgit v1.2.3