open Instr;; open Memory;; open Machine;; open System;; let new_label = let n = ref 0 in fun () -> let res = !n in incr n; res;; let loop = new_label ();; let loop2 = new_label ();; let son = new_label ();; let son2 = new_label ();; let cont = new_label ();; let unlinked_codes = [| [| Const (12,a0); Store (a0,15); Load (15, a0); Const (sys_Write, v0); System; Const (13,a0); Store (a0,15); Load (15, a0); Const (sys_Write, v0); System; Const (0,a0); Const (sys_Exit, v0); System; |]; [| Const (12,a0); Store (a0,15); Load (15, a0); Const (sys_Write, v0); System; Const (sys_Fork, v0); System; Const (sys_Fork, v0); System; Move (v0,t0); Load (15, a0); Const (sys_Write, v0); System; Const (0, a0); If (Eq, t0, a0, son); Const (13,a0); Store (a0,15); Load (15, a0); Const (sys_Write, v0); System; Const (sys_Exit, v0); System; Label son; Const (14,a0); Store (a0,15); Load (15, a0); Const (sys_Write, v0); System; Store (a0, 20); Const (sys_Exit, v0); System; |]; [| Const (15,a0); Const (sys_Brk, v0); System; Const (12,a0); Store (a0,15); Const (sys_Fork, v0); System; Const (sys_Fork, v0); System; Move (v0,t0); Load (15, a0); Const (sys_Write, v0); System; Const (0, a0); If (Eq, t0, a0, son); Const (13,a0); Store (a0,15); Load (15, a0); Const (sys_Write, v0); System; Const (0,a0); Const (sys_Brk, v0); System; Const (sys_Exit, v0); System; Label son; Const (14,a0); Store (a0,15); Load (15, a0); Const (sys_Write, v0); System; Store (a0, 20); Const (sys_Exit, v0); System; |] |];; let link label_number code = let table = Array.create label_number (-1) in let add pos = function Label l -> table.(l) <- pos | _ -> () in Array.iteri add code; let fix = function | Label lab -> Label table.(lab) | If (cmp, r1, r2, lab) -> If (cmp, r1, r2, table.(lab)) | Goto lab -> Goto table.(lab) | x -> x in Array.map fix code;; let label_number = new_label ();; let codes = Array.map (link label_number) unlinked_codes;; let opt = [ ("-v", Arg.Set verbose, "verbose output") ];; let usage_message = "Usage: "^Sys.argv.(0)^" [-v] ";; let usage () = Arg.usage opt usage_message; exit (1);; let code_number = ref (-1);; let update_code_number v = try if !code_number == -1 then code_number := int_of_string v else usage () with _ -> usage ();; let main () = if Array.length Sys.argv < 2 then usage () else begin Arg.parse opt update_code_number usage_message; let system_state = init_state !code_number codes in try machine.reg <- system_state.current.preg; run system_state with | Halt -> print_endline "No more active processes"; let count x y z = z + 1 in let size = Hashtbl.fold count system_state.processes 0 in if size != 0 then Printf.printf "Process table still contains %d processes \n%!" size; if used_page () then Printf.printf "Some pages are still used\n%!"; | Not_implemented i -> Printf.printf "Syscall %d not implemented\n%!" i | Invalid_code -> print_endline "Provided code number is not valid" end;; main();;