summaryrefslogtreecommitdiff
path: root/src/isail.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/isail.ml')
-rw-r--r--src/isail.ml153
1 files changed, 103 insertions, 50 deletions
diff --git a/src/isail.ml b/src/isail.ml
index c3f869a3..18c59e0b 100644
--- a/src/isail.ml
+++ b/src/isail.ml
@@ -57,6 +57,7 @@ open Pretty_print_sail
type mode =
| Evaluation of frame
+ | Bytecode of Value2.vl Bytecode_interpreter.gstate * Value2.vl Bytecode_interpreter.stack
| Normal
let current_mode = ref Normal
@@ -65,6 +66,7 @@ let prompt () =
match !current_mode with
| Normal -> "sail> "
| Evaluation _ -> "eval> "
+ | Bytecode _ -> "ir> "
let eval_clear = ref true
@@ -72,6 +74,7 @@ let mode_clear () =
match !current_mode with
| Normal -> ()
| Evaluation _ -> if !eval_clear then LNoise.clear_screen () else ()
+ | Bytecode _ -> () (* if !eval_clear then LNoise.clear_screen () else () *)
let rec user_input callback =
match LNoise.linenoise (prompt ()) with
@@ -80,7 +83,7 @@ let rec user_input callback =
mode_clear ();
begin
try callback v with
- | Reporting_basic.Fatal_error e -> Reporting_basic.report_error e
+ | Reporting.Fatal_error e -> Reporting.report_error e
end;
user_input callback
@@ -105,16 +108,35 @@ let vs_ids = ref (Initial_check.val_spec_ids !interactive_ast)
let interactive_state = ref (initial_state !interactive_ast Value.primops)
+let interactive_bytecode = ref []
+
+let sep = "-----------------------------------------------------" |> Util.blue |> Util.clear
+
let print_program () =
match !current_mode with
| Normal -> ()
| Evaluation (Step (out, _, _, stack)) ->
- let sep = "-----------------------------------------------------" |> Util.blue |> Util.clear in
List.map stack_string stack |> List.rev |> List.iter (fun code -> print_endline (Lazy.force code); print_endline sep);
print_endline (Lazy.force out)
| Evaluation (Done (_, v)) ->
print_endline (Value.string_of_value v |> Util.green |> Util.clear)
| Evaluation _ -> ()
+ | Bytecode (_, stack) ->
+ let open Bytecode_interpreter in
+ let open Bytecode_util in
+ let pc = stack.top.pc in
+ let instrs = stack.top.instrs in
+ for i = 0 to stack.top.pc - 1 do
+ print_endline (" " ^ Pretty_print_sail.to_string (pp_instr instrs.(i)))
+ done;
+ print_endline (">> " ^ Pretty_print_sail.to_string (pp_instr instrs.(stack.top.pc)));
+ for i = stack.top.pc + 1 to Array.length instrs - 1 do
+ print_endline (" " ^ Pretty_print_sail.to_string (pp_instr instrs.(i)))
+ done;
+ print_endline sep;
+ print_endline (Util.string_of_list ", "
+ (fun (id, vl) -> Printf.sprintf "%s = %s" (string_of_id id) (string_of_value vl))
+ (Bindings.bindings stack.top.locals))
let rec run () =
match !current_mode with
@@ -138,6 +160,7 @@ let rec run () =
print_endline "Breakpoint";
current_mode := Evaluation frame
end
+ | Bytecode _ -> ()
let rec run_steps n =
print_endline ("step " ^ string_of_int n);
@@ -163,6 +186,7 @@ let rec run_steps n =
print_endline "Breakpoint";
current_mode := Evaluation frame
end
+ | Bytecode _ -> ()
let help = function
| ":t" | ":type" ->
@@ -232,6 +256,8 @@ let handle_input' input =
| Command (cmd, arg) ->
begin
match cmd with
+ | ":n" | ":normal" ->
+ current_mode := Normal
| ":t" | ":type" ->
let typq, typ = Type_check.Env.get_val_spec (mk_id arg) !interactive_env in
pretty_sail stdout (doc_binding (typq, typ));
@@ -240,10 +266,13 @@ let handle_input' input =
Value.output_close ();
exit 0
| ":i" | ":infer" ->
- let exp = Initial_check.exp_of_string dec_ord arg in
+ let exp = Initial_check.exp_of_string arg in
let exp = Type_check.infer_exp !interactive_env exp in
pretty_sail stdout (doc_typ (Type_check.typ_of exp));
print_newline ()
+ | ":canon" ->
+ let typ = Initial_check.typ_of_string arg in
+ print_endline (string_of_typ (Type_check.canonicalize !interactive_env typ))
| ":v" | ":verbose" ->
Type_check.opt_tc_debug := (!Type_check.opt_tc_debug + 1) mod 3;
print_endline ("Verbosity: " ^ string_of_int !Type_check.opt_tc_debug)
@@ -285,19 +314,26 @@ let handle_input' input =
interactive_env := env;
interactive_state := initial_state !interactive_ast Value.primops
| ":pretty" ->
- print_endline (Pretty_print_sail.to_string (Latex.latex_defs "sail_latex" !interactive_ast))
- | ":bytecode" ->
+ print_endline (Pretty_print_sail.to_string (Latex.defs !interactive_ast))
+ | ":compile" ->
let open PPrint in
let open C_backend in
let ast = Process_file.rewrite_ast_c !interactive_ast in
let ast, env = Specialize.specialize ast !interactive_env in
let ctx = initial_ctx env in
- let byte_ast = bytecode_ast ctx (List.map flatten_instrs) ast in
- let chan = open_out arg in
- Util.opt_colors := false;
- Pretty_print_sail.pretty_sail chan (separate_map hardline Bytecode_util.pp_cdef byte_ast);
- Util.opt_colors := true;
- close_out chan
+ interactive_bytecode := bytecode_ast ctx (List.map flatten_cdef) ast
+ | ":ir" ->
+ print_endline arg;
+ let open Bytecode in
+ let open Bytecode_util in
+ let open PPrint in
+ let is_cdef = function
+ | CDEF_fundef (id, _, _, _) when Id.compare id (mk_id arg) = 0 -> true
+ | CDEF_spec (id, _, _) when Id.compare id (mk_id arg) = 0 -> true
+ | _ -> false
+ in
+ let cdefs = List.filter is_cdef !interactive_bytecode in
+ print_endline (Pretty_print_sail.to_string (separate_map hardline pp_cdef cdefs))
| ":ast" ->
let chan = open_out arg in
Pretty_print_sail.pp_defs chan !interactive_ast;
@@ -335,63 +371,80 @@ let handle_input' input =
vs_ids := Initial_check.val_spec_ids !interactive_ast;
(* See initial_check.mli for an explanation of why we need this. *)
Initial_check.have_undefined_builtins := false
+ | ":exec" ->
+ let open Bytecode_interpreter in
+ let exp = Type_check.infer_exp !interactive_env (Initial_check.exp_of_string arg) in
+ let anf = Anf.anf exp in
+ let ctx = C_backend.initial_ctx !interactive_env in
+ let ctyp = C_backend.ctyp_of_typ ctx (Type_check.typ_of exp) in
+ let setup, call, cleanup = C_backend.compile_aexp ctx anf in
+ let instrs = C_backend.flatten_instrs (setup @ [call (CL_id (mk_id "interactive#", ctyp))] @ cleanup) in
+ current_mode := Bytecode (new_gstate !interactive_bytecode, new_stack instrs);
+ print_program ()
| _ -> unrecognised_command cmd
end
| Expression str ->
(* An expression in normal mode is type checked, then puts
us in evaluation mode. *)
- let exp = Type_check.infer_exp !interactive_env (Initial_check.exp_of_string Ast_util.dec_ord str) in
+ let exp = Type_check.infer_exp !interactive_env (Initial_check.exp_of_string str) in
current_mode := Evaluation (eval_frame (Step (lazy "", !interactive_state, return exp, [])));
print_program ()
| Empty -> ()
end
| Evaluation frame ->
- begin
- match input with
- | Command (cmd, arg) ->
- (* Evaluation mode commands *)
- begin
- match cmd with
- | ":r" | ":run" ->
- run ()
- | ":s" | ":step" ->
- run_steps (int_of_string arg)
- | ":n" | ":normal" ->
- current_mode := Normal
- | _ -> unrecognised_command cmd
- end
- | Expression str ->
- print_endline "Already evaluating expression"
- | Empty ->
- (* Empty input will evaluate one step, or switch back to
+ begin match input with
+ | Command (cmd, arg) ->
+ (* Evaluation mode commands *)
+ begin
+ match cmd with
+ | ":r" | ":run" ->
+ run ()
+ | ":s" | ":step" ->
+ run_steps (int_of_string arg)
+ | _ -> unrecognised_command cmd
+ end
+ | Expression str ->
+ print_endline "Already evaluating expression"
+ | Empty ->
+ (* Empty input will evaluate one step, or switch back to
normal mode when evaluation is completed. *)
- begin
- match frame with
- | Done (state, v) ->
+ begin match frame with
+ | Done (state, v) ->
+ interactive_state := state;
+ print_endline ("Result = " ^ Value.string_of_value v);
+ current_mode := Normal
+ | Step (out, state, _, stack) ->
+ begin
+ try
interactive_state := state;
- print_endline ("Result = " ^ Value.string_of_value v);
- current_mode := Normal
- | Step (out, state, _, stack) ->
- begin
- try
- interactive_state := state;
- current_mode := Evaluation (eval_frame frame);
- print_program ()
- with
- | Failure str -> print_endline str; current_mode := Normal
- end
- | Break frame ->
- print_endline "Breakpoint";
- current_mode := Evaluation frame
- end
+ current_mode := Evaluation (eval_frame frame);
+ print_program ()
+ with
+ | Failure str -> print_endline str; current_mode := Normal
+ end
+ | Break frame ->
+ print_endline "Breakpoint";
+ current_mode := Evaluation frame
+ end
+ end
+ | Bytecode (gstate, stack) ->
+ begin match input with
+ | Command (cmd, arg) ->
+ ()
+ | Expression str ->
+ print_endline "Evaluating IR, cannot evaluate expression"
+ | Empty ->
+ let gstate, stack = Bytecode_interpreter.step (gstate, stack) in
+ current_mode := Bytecode (gstate, stack);
+ print_program ()
end
let handle_input input =
try handle_input' input with
| Type_check.Type_error (l, err) ->
print_endline (Type_error.string_of_type_error err)
- | Reporting_basic.Fatal_error err ->
- Reporting_basic.print_error err
+ | Reporting.Fatal_error err ->
+ Reporting.print_error err
| exn ->
print_endline (Printexc.to_string exn)