caml-urm

A OCaml module for manipulating unlimited register machines

Commit
be8f1b0db18b47dddebccc9aad86124f5f836fd4
Parent
accf21fd370d049d1bb9df8ffde82d74c64aed18
Author
Pablo <pablo-escobar@riseup.net>
Date

Fixed a bunch of bugs

Diffstat

3 files changed, 57 insertions, 62 deletions

Status File Name N° Changes Insertions Deletions
Modified docs.pdf 0 0 0
Modified urm.ml 72 35 37
Modified urm.mli 47 22 25
diff --git a/docs.pdf b/docs.pdf
Binary files differ.
diff --git a/urm.ml b/urm.ml
@@ -1,4 +1,5 @@
 open Array
+open Genlex
 
 type instruction = 
   | T of int * int
@@ -6,17 +7,19 @@ type instruction =
   | S of int
   | J of int * int * int
 
-type t = machine = 
+type t = 
   { instruction_pointer : int;
-    registers : nat -> nat;
+    registers : int -> int;
   }
 
+type machine = t
+
 let of_registers f =
-  { intruction_pointer = 0;
+  { instruction_pointer = 0;
     registers = f
   }
 
-let zero = from_registers (fun _ -> 0)
+let zeros = of_registers (fun _ -> 0)
 
 let register m = m.registers 
 
@@ -70,36 +73,31 @@ let nexec max program m =
       else None
     in exec_safe_tail m 0
 
-module Parse = struct
-  open Genlex
-
-  exception Syntax_error of string
-
-  (** A simple lexer for instructions *)
-  let lex = make_lexes ["T"; "Z"; "S"; "J"; "("; ")"; ","]
-
-  (** Parse a single instruction *)
-  let parse_instruction (i: token list) : instruction =
-    match i with
-    | [ Kwd "T"; Kwd "("; Int r1; Kwd ","; Int r2; Kwd ")" ] ->
-        T (r1, r2)
-    | [ Kwd "Z"; Kwd "("; Int r; Kwd ")" ] ->
-        Z r
-    | [ Kwd "S"; Kwd "("; Int r; Kwd ")" ] ->
-        S r
-    | [ Kwd "J"; Kwd "("; Int r1; Kwd ","; Int r2; Kwd ","; Int i; Kwd ")" ]
-    when i > 0 ->
-        J (r1, r2, i)
-    | [ Kwd "J"; Kwd "("; Int _; Kwd ","; Int _; Kwd ","; Int i; Kwd ")" ] ->
-        raise (Syntax_error (Printf.sprintf "invalid jump address: %d" i))
-    | _ -> raise (Syntax_error "invalid syntax")
-
-  let parse (s : string) : instruction array =
-    let f s = 
-      if String.trim s <> "" then None
-      else
-        match Stream.npeek 8 (lex (Stream.of_string s)) with
-        | Some l -> Some (parse_instruction l)
-        | None -> raise (Syntax_error (Prinf.sprintf "invalid syntax: %s" s))
-    in Array.of_list (List.filter_map f (String.split_on_char '\n' s))
-end
+
+(********************************** Parsing **********************************)
+
+exception Syntax_error of string
+
+(** A simple lexer for instructions *)
+let lex = make_lexer ["T"; "Z"; "S"; "J"; "("; ")"; ","]
+
+(** Parse a single instruction *)
+let parse_instruction (i : token list) : instruction =
+  match i with
+  | [ Kwd "T"; Kwd "("; Int r1; Kwd ","; Int r2; Kwd ")" ] ->
+      T (r1, r2)
+  | [ Kwd "Z"; Kwd "("; Int r; Kwd ")" ] ->
+      Z r
+  | [ Kwd "S"; Kwd "("; Int r; Kwd ")" ] ->
+      S r
+  | [ Kwd "J"; Kwd "("; Int r1; Kwd ","; Int r2; Kwd ","; Int i; Kwd ")" ]
+  when i > 0 ->
+      J (r1, r2, i)
+  | [ Kwd "J"; Kwd "("; Int _; Kwd ","; Int _; Kwd ","; Int i; Kwd ")" ] ->
+      raise (Syntax_error (Printf.sprintf "invalid jump address: %d" i))
+  | _ -> raise (Syntax_error "invalid syntax")
+
+let parse (s : string) : instruction array =
+  let f s = parse_instruction (Stream.npeek 8 (lex (Stream.of_string s)))
+  in Array.of_list (List.map f (String.split_on_char '\n' s))
+
diff --git a/urm.mli b/urm.mli
@@ -38,49 +38,46 @@ type t
 (** An alias for {! t } *)
 type machine
 
-(** Returns a machine whose value of the [n]-th register is given by [f n]. *)
-val of_registers : f:(int -> int) -> machine
+(** Returns a machine whose register values are given by a function. *)
+val of_registers : (int -> int) -> machine
 
-(** Returns the value of the [i]-th register of [m]. *)
-val register : m:machine -> i:int -> int
+(** [register m i] the value of the [i]-th register of [m]. *)
+val register : machine -> int -> int
 
 (** A machine whose registers are all zeros. *)
 val zeros : machine
 
-(** Returns a machine whose register values are given by the register values of
+(** [exec m program] returns a machine whose register values are given by the
+    register values of
     [m] with updates corresponding to the execution of [program]. 
 
     This function only returns when [program] actually halts. Please use {!
-    nexec } if you don't trust the [program]. 
+    nexec } if you don't trust [program]. 
 
     @raise Invalid_argument if [program] attempts to jump to a non-positive
     integer. *)
-val exec : program:instruction array -> m:machine -> machine
+val exec : instruction array -> machine -> machine
 
 (** A safe version of {! exec }, where the maximum number of clock-cycles
-    allowed is controlled by [n]. Each instruction takes a single clock-cycle
-    to execute.
+    allowed is controlled the first argument. Each instruction takes a single
+    clock-cycle to execute.
 
-    Returns [Some _] if [program] halts in at most [n] clock-cycles and
-    [None] otherwise. 
+    [nexec n program] returns [Some _] if [program] halts in at most [n]
+    clock-cycles and [None] otherwise. 
 
     @raise Invalid_argument if [program] attempts to jump to a non-positive
-    integer.
-    @raise Invalid_argument if [n] is not a positive integer. *)
-val nexec : n:int -> program: instruction array -> machine -> machine option
+    integer.  @raise Invalid_argument if [n] is not a positive integer. *)
+val nexec : int -> instruction array -> machine -> machine option
 
-(** Parse URM programs from strings. The syntax used by the parser is based on
+(** Exception raised when parsing fails. *)
+exception Syntax_error of string
+
+(** Parse a program from a string. The syntax used by the parser is based on
     the one used by Ramin Naimi's URM simulator, but again the register indexes
     can be arbitrary integers.
 
-    @see <https://sites.oxy.edu/rnaimi/home/URMsim.htm> URM simulator. *)
-module Parse : sig
-  (** Exception raised when parsing fails. *)
-  exception Syntax_error of string
-
-  (** Parse a program from a string. 
+    @see <https://sites.oxy.edu/rnaimi/home/URMsim.htm> URM simulator.
 
-      @raise Syntax_error in case any syntax error is encountered, including
-      invalid syntax and jumps to invalid addresses. *)
-  val parse : string -> instruction array
-end
+    @raise Syntax_error in case any syntax error is encountered, including
+    invalid syntax and jumps to invalid addresses. *)
+val parse : string -> instruction array