diff --git a/README.md b/README.md index 8078b9e54c7f9f299abaef9097dc71fff2c896a4..56925ca9be424f6ea109821a195764d3936bb733 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,12 @@ evaluating the program. ## Options: - `-show-ast` Enables the printing of the AST + - `-heap-size` Set the heap size + - `-stack-size` Set the stack size - `-trace` Prints the intermediate execution steps - `-lin` Linearizes the program before evalution + - `-lir` Check if the program is low-level + - `-unsafe` Don't do the static checks - `-help` Displays the list of options - `--help` Displays the list of options diff --git a/bin/main.ml b/bin/main.ml index 36a4ff567f8f96d9a58bd443776dd9a2698b05a7..7e64d60fe2af473abce85f3c1e88b1c1db7072cf 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -1,11 +1,20 @@ open Ovm open Utils +open Exceptions let globaldescr = "OVM is a virtual machine for the Tree Language" +let heap_msg = Format.sprintf "Set the heap size (default : %d)" !heapsize +let stack_msg = Format.sprintf "Set the stack size (default : %d)" !stacksize + let options = + let set_size (size : int ref) (x : int) : unit = + size := Memory.sizeOfInt * div_ceiling x Memory.sizeOfInt + in [ ("-show-ast", Arg.Set show_ast, "Enables the printing of the AST") - ; ("-trace", Arg.Set trace, "Printing of intermediate execution steps") + ; ("-heap-size", Arg.Int (set_size heapsize), heap_msg) + ; ("-stack-size", Arg.Int (set_size stacksize), stack_msg) + ; ("-trace", Arg.Set trace, "Print the trace execution") ; ("-lin", Arg.Set linearize, "Linearizes the program before evalution") ; ("-lir", Arg.Set lir_check, "Check if the program is low-level") ; ("-unsafe", Arg.Set unsafe, "Don't do the static checks") ] @@ -59,8 +68,32 @@ let () = Vmio.init ~out_channel:output ~err_channel:errors ~trace:Format.std_formatter In_channel.stdin else Vmio.init ~out_channel:output ~err_channel:errors In_channel.stdin; - let _ = Eval.eval_prog prog in - (* TODO Change trace channel *) + Option.iter (fun out -> Format.fprintf out "%!") !Vmio.trace; + let end_state = + try + let end_state, code = + Eval.eval_prog ~heapsize:!heapsize ~stacksize:!stacksize prog + in + Option.iter (fun out -> Format.fprintf out "%!") !Vmio.trace; + Vmio.trace_with_offset !Vmio.trace 0 + (Format.sprintf "Exit with code : %d\n" code); + end_state + with VM_runtime_exception (msg, end_state) -> + Option.iter (fun out -> Format.fprintf out "%!") !Vmio.trace; + (match !Vmio.trace with + | Some out -> + Vmio.trace_with_offset !Vmio.trace 0 + (Format.sprintf "Runtime Error : %s\n%!" msg); + Format.fprintf out "%!" + | None -> Format.eprintf "Runtime Error : %s\n%!" msg); + end_state + in + (* Show temporaries *) + Vmio.print_trace !Vmio.trace + (Format.asprintf "\n%a\n%!" Memory.print_temp end_state); + (* Show out and err *) + Format.fprintf output "%!"; + Format.fprintf errors "%!"; Format.printf "%s%!" (String.of_seq (Buffer.to_seq out_buff)); Format.eprintf "%s%!" (String.of_seq (Buffer.to_seq err_buff)) with diff --git a/lib/eval.ml b/lib/eval.ml index fa078a77e08602cdd374431fc76bb929574370a2..9be78528ee81f8eaf5de4fcd5c1396eb3d375dd9 100644 --- a/lib/eval.ml +++ b/lib/eval.ml @@ -343,17 +343,16 @@ and eval_stmts_stack (mem : Memory.t) (s : stmt option) (stack : stmt list list) Vmio.set_offset !Vmio.trace ~number:level ~size:2 ; eval_stmts_stack nmem s stack -(** eval_prog * Evaluate a program * TODO : Call [eval_routine "main"] * TODO : - Change how memory size is initialized *) -let eval_prog (prog : stmt list) : Memory.t = - let mem = Memory.initialize ~heapsize:65536 ~stacksize:16384 prog in - Vmio.print_trace !Vmio.trace (Format.asprintf "%a\n" print_code_labels mem) ; - let end_state = - try eval_stmts_stack mem None [Memory.cfetch mem "main"] - with VM_runtime_exception (msg, end_state) -> - Vmio.eprintf "Runtime Error : %s\n%!" msg ; - end_state +(** eval_prog + * Evaluate a program + * TODO : Call [eval_routine "main"] + *) +let eval_prog ~(heapsize : int) ~(stacksize : int) (prog : stmt list) : + Memory.t * int = + let mem = Memory.initialize ~heapsize ~stacksize prog in + let main = + try Memory.cfetch mem "main" + with Failure _ -> raise (VM_runtime_exception ("No routine main", mem)) in - Vmio.print_trace !Vmio.trace (Format.asprintf "\n%a\n" print_temp end_state) ; - (* Show temporaries *) - end_state + try (eval_stmts_stack mem None [ main ], 0) + with Exit_exception (code, mem') -> (mem', code) diff --git a/lib/memory.ml b/lib/memory.ml index ce2520b74639a134fb13af5505a372a7c9f3d904..e869d3b5c12f247a7b577cd29e4fc791d79b4ca1 100644 --- a/lib/memory.ml +++ b/lib/memory.ml @@ -14,11 +14,6 @@ type t = { let sizeOfInt = 4 (* Size of int32 (in bytes) *) -(** div_ceiling - * Return the smallest integer greater than or equal to n/d - *) -let div_ceiling (n : int) (d : int) : int = ((n - 1) / d) + 1 - (** create * Create the VM's memory state *) diff --git a/lib/utils.ml b/lib/utils.ml index 7558c489638e8e1847273ef42ba7e3584699476b..b387f9c15c690e37c0e35ceb5494d66542b8e91a 100644 --- a/lib/utils.ml +++ b/lib/utils.ml @@ -13,6 +13,10 @@ let lir_check = ref false let unsafe = ref false +let heapsize = ref 65536 + +let stacksize = ref 16384 + module SSet = Set.Make (String) module SMap = Map.Make (String) @@ -26,3 +30,8 @@ let print_sset fmt ~pp_sep sset = Format.fprintf fmt "%a" (Format.pp_print_list ~pp_sep Format.pp_print_string) (List.of_seq (SSet.to_seq sset)) + +(** div_ceiling + * Return the smallest integer greater than or equal to n/d + *) +let div_ceiling (n : int) (d : int) : int = ((n - 1) / d) + 1 diff --git a/tests/testsuite.ml b/tests/testsuite.ml index 897ba01aa7a4ea48b52a61fd5ce6476cae52d154..9ac6b8b4ad54362cbdd46590914d99cd74dd4a94 100644 --- a/tests/testsuite.ml +++ b/tests/testsuite.ml @@ -138,7 +138,9 @@ let run file lin = (if lin then "(linearized)" else ""); Vmio.init ~out_channel:output ~err_channel:errors input; try - let memory = Eval.eval_prog prog in + let memory, _ = + Eval.eval_prog ~heapsize:!Utils.heapsize ~stacksize:!Utils.stacksize prog + in check file memory.Memory.temporaries out_buff with e -> let msg = Printexc.to_string e in