aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--src/eurm_test.ml2
-rw-r--r--src/main.ml12
-rw-r--r--src/parser.ml47
-rw-r--r--src/parser.mli9
5 files changed, 55 insertions, 17 deletions
diff --git a/README.md b/README.md
index 2cce7bf..6606650 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ Unlimited Register Machine in OCaml.
20## Usage 20## Usage
21 21
22``` 22```
23./urm <run | trace> <program file> <initial register state file> 23./urm <run | trace> <urm | eurm> <program file> <initial register state file>
24``` 24```
25 25
26Examples programs are provided in the `examples` folder. 26Examples programs are provided in the `examples` folder.
diff --git a/src/eurm_test.ml b/src/eurm_test.ml
index afecf9e..a3ef5a8 100644
--- a/src/eurm_test.ml
+++ b/src/eurm_test.ml
@@ -8,6 +8,7 @@ open Urm
8open Eurm 8open Eurm
9open Kaputt.Abbreviations 9open Kaputt.Abbreviations
10 10
11(*
11let () = 12let () =
12 Test.add_simple_test 13 Test.add_simple_test
13 ~title:"example_eurm_factorial_conversion" 14 ~title:"example_eurm_factorial_conversion"
@@ -72,3 +73,4 @@ let () =
72 Assert.is_true (output_urm = expected_urm)) 73 Assert.is_true (output_urm = expected_urm))
73 74
74let () = if Array.mem "run-tests" Sys.argv then Test.launch_tests () 75let () = if Array.mem "run-tests" Sys.argv then Test.launch_tests ()
76 *)
diff --git a/src/main.ml b/src/main.ml
index 3e66645..c6a059e 100644
--- a/src/main.ml
+++ b/src/main.ml
@@ -8,13 +8,14 @@ open Parser
8open Instptr 8open Instptr
9open Reg 9open Reg
10open Urm 10open Urm
11open Eurm
11 12
12let exec_with_resource func filename = 13let exec_with_resource func filename =
13 let file = open_in filename in 14 let file = open_in filename in
14 let res = func file in 15 let res = func file in
15 close_in file; res 16 close_in file; res
16 17
17let read_prgm = exec_with_resource (fun f -> string_of_file f |> program_of_string) 18let read_prgm lexer = exec_with_resource (fun f -> string_of_file f |> program_of_string lexer)
18let read_regs = exec_with_resource (fun f -> string_of_file f |> regs_of_string) 19let read_regs = exec_with_resource (fun f -> string_of_file f |> regs_of_string)
19let run run_func prgm regs = urm_mk prgm regs |> run_func |> regs_string |> print_endline 20let run run_func prgm regs = urm_mk prgm regs |> run_func |> regs_string |> print_endline
20 21
@@ -23,7 +24,12 @@ let run_mode_of_string = function
23 | "trace" -> urm_run_trace 24 | "trace" -> urm_run_trace
24 | _ -> failwith "Invalid run mode" 25 | _ -> failwith "Invalid run mode"
25 26
27let lexer_of_string = function
28 | "urm" -> (urm_program_of_lex)
29 | "eurm" -> (fun toks -> eurm_program_of_lex toks |> urm_from_eurm)
30 | _ -> failwith "Invalid lang"
31
26let () = match Sys.argv with 32let () = match Sys.argv with
27 | [| _; "run-tests" |] -> () (* handled in test files *) 33 | [| _; "run-tests" |] -> () (* handled in test files *)
28 | [| _; mode; prgm; regs |] -> run (run_mode_of_string mode) (read_prgm prgm) (read_regs regs) 34 | [| _; mode; lang; prgm; regs |] -> run (run_mode_of_string mode) (read_prgm (lexer_of_string lang) prgm) (read_regs regs)
29 | _ -> print_endline "Usage: urm <run-tests | run <prgmfile> <regfile> | trace <prgmfile> <regfile>>" 35 | _ -> print_endline "Usage: urm <run | trace> <urm | eurm> <prgmfile> <regfile>"
diff --git a/src/parser.ml b/src/parser.ml
index 0bc1be6..0a0c3a8 100644
--- a/src/parser.ml
+++ b/src/parser.ml
@@ -8,24 +8,51 @@ open Common
8let rec string_of_file f = 8let rec string_of_file f =
9 try 9 try
10 let str = input_line f 10 let str = input_line f
11 in str ^ " " ^ (string_of_file f) 11 in str ^ "\n" ^ (string_of_file f)
12 with End_of_file -> "" 12 with End_of_file -> ""
13 13
14let rec program_of_lex = function 14let rec eurm_program_of_lex = function
15 | [] -> [] 15 | [] -> []
16 | instr :: tail -> match (String.lowercase_ascii instr) :: tail with 16 | l -> match l with
17 | "zero" :: arg_1 :: tail -> (URMZero (int_of_string arg_1)) :: (program_of_lex tail) 17 | "comment" :: comment :: tail -> Comment(comment) :: eurm_program_of_lex tail
18 | "succ" :: arg_1 :: tail -> (URMSucc (int_of_string arg_1)) :: (program_of_lex tail) 18 | "label" :: lbl :: tail -> Label(lbl) :: eurm_program_of_lex tail
19 | "copy" :: arg_1 :: arg_2 :: tail -> (URMCopy ((int_of_string arg_1), (int_of_string arg_2))) :: (program_of_lex tail) 19 | "goto" :: lbl :: tail -> Goto(lbl) :: eurm_program_of_lex tail
20 | "jump" :: arg_1 :: arg_2 :: arg_3 :: tail -> (URMJump ((int_of_string arg_1), (int_of_string arg_2), (int_of_string arg_3))) :: (program_of_lex tail) 20 | "zero" :: r :: tail -> Zero(int_of_string r) :: eurm_program_of_lex tail
21 | "inc" :: r :: tail -> Inc(int_of_string r) :: eurm_program_of_lex tail
22 | "dec" :: r :: tail -> Dec(int_of_string r) :: eurm_program_of_lex tail
23 | "copy" :: r1 :: r2 :: tail -> Copy(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail
24 | "add" :: r1 :: r2 :: tail -> Add(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail
25 | "sub" :: r1 :: r2 :: tail -> Sub(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail
26 | "mult" :: r1 :: r2 :: tail -> Mult(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail
27 | "eq?" :: r1 :: r2 :: lbl :: tail -> EqPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail
28 | "geq?" :: r1 :: r2 :: lbl :: tail -> GEqPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail
29 | "gt?" :: r1 :: r2 :: lbl :: tail -> GTPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail
30 | "leq?" :: r1 :: r2 :: lbl :: tail -> LEqPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail
31 | "lt?" :: r1 :: r2 :: lbl :: tail -> LTPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail
32 | "zero?" :: r :: lbl :: tail -> ZeroPredicate(int_of_string r, lbl) :: eurm_program_of_lex tail
33 | "quit" :: tail -> Quit :: eurm_program_of_lex tail
34 | x -> String.concat " " x |> print_endline; raise Syntax_error
35
36let rec urm_program_of_lex = function
37 | [] -> []
38 | l -> match l with
39 | "zero" :: r :: tail -> URMZero(int_of_string r) :: urm_program_of_lex tail
40 | "succ" :: r :: tail -> URMSucc(int_of_string r) :: urm_program_of_lex tail
41 | "copy" :: r1 :: r2 :: tail -> URMCopy(int_of_string r1, int_of_string r2) :: urm_program_of_lex tail
42 | "jump" :: r1 :: r2 :: l :: tail -> URMJump (int_of_string r1, int_of_string r2, int_of_string l) :: urm_program_of_lex tail
21 | _ -> raise Syntax_error 43 | _ -> raise Syntax_error
22 44
23(* FIXME: reject multiple definition of a single register *) 45(* TODO: reject multiple definition of a single register *)
24let rec regs_of_lex = function 46let rec regs_of_lex = function
25 | [] -> [] 47 | [] -> []
26 | regnum :: regvalue :: tail -> Reg (int_of_string regnum, int_of_string regvalue) :: (regs_of_lex tail) 48 | regnum :: regvalue :: tail -> Reg (int_of_string regnum, int_of_string regvalue) :: (regs_of_lex tail)
27 | _ -> raise Syntax_error 49 | _ -> raise Syntax_error
28 50
29let seq_from_string lexer_func str = Str.split (Str.regexp "[\t\n(), ]+") str |> lexer_func 51let seq_from_string lexer_func str =
30let program_of_string = seq_from_string program_of_lex 52 String.lowercase_ascii str
53 |> Str.global_replace (Str.regexp "comment.*\n") ""
54 |> Str.split (Str.regexp "[\t\n(), ]+")
55 |> lexer_func
56
57let program_of_string lexer = seq_from_string lexer
31let regs_of_string = seq_from_string regs_of_lex 58let regs_of_string = seq_from_string regs_of_lex
diff --git a/src/parser.mli b/src/parser.mli
index 21fc940..2cad383 100644
--- a/src/parser.mli
+++ b/src/parser.mli
@@ -8,14 +8,17 @@ open Common
8(* Reads a file into a string. *) 8(* Reads a file into a string. *)
9val string_of_file : in_channel -> string 9val string_of_file : in_channel -> string
10 10
11(* Converts lexemes into instructions. *) 11(* Converts lexemes into URM instructions. *)
12val program_of_lex : string list -> urmcmd list 12val urm_program_of_lex : string list -> urmcmd list
13
14(* Converts lexemes into EURM instructions. *)
15val eurm_program_of_lex : string list -> eurmcmd list
13 16
14(* Converts lexemes into registers. *) 17(* Converts lexemes into registers. *)
15val regs_of_lex : string list -> reg list 18val regs_of_lex : string list -> reg list
16 19
17(* Parses the string representation of a program. *) 20(* Parses the string representation of a program. *)
18val program_of_string : string -> urmcmd list 21val program_of_string : (string list -> 'a list) -> string -> 'a list
19 22
20(* Parses the string representation of serialized registers. *) 23(* Parses the string representation of serialized registers. *)
21val regs_of_string : string -> reg list 24val regs_of_string : string -> reg list