Skip to content

Commit

Permalink
Unify the command line interface under one parser (interactive and in…
Browse files Browse the repository at this point in the history
…terpreter)
  • Loading branch information
JuneRousseau committed Aug 10, 2023
1 parent 06b5b10 commit 9c89c64
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 85 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ test:
dune test

install:
@test -s interactive || ln -s ./_build/default/src/interactive.exe interactive
@test -s interpreter || ln -s ./_build/default/src/interpreter.exe interpreter
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ eval $(opam env --set-switch)
make
```

Finally, the command `make install` creates a symbolic link to the interactive interpreter in this repository.
Finally, the command `make install` creates a symbolic link to the interpreter in this repository.

## Usage
Executable: `./interactive <file>`
Assembly examples in `./tests` (for the syntax)
Executable: `./interpreter <file>`
Assembly examples in `./tests/test_files` (for the syntax)

The default version of the interpreter uses a version of Cerise with seals, uninitialized and directed capabilities.
For a version of Cerise without these features, use `./interactive --version vanilla`.
For a version of Cerise without these features, use `./interpreter --version vanilla`.

For more information about the options, `./interactive --help`.
For more information about the options, `./interpreter --help`.

Press `SPACE` to take a step, and `ESC` to exit.
20 changes: 15 additions & 5 deletions lib/cli_parser.ml
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
(* TODO only one cli command, with a -I flag for --interactive*)
(* TODO test of the CLI *)
(* TODO reuse the parser for the interpreter *)
let parse_argument_interactive addr_max =

type cli_mode = Interactive_mode | Interpreter_mode

(** Initialize the Cerise version and returns
(mode, program_filename, register_filename, size_mem) *)
let parse_arguments addr_max :
(cli_mode * string * string * Z.t)
=
let usage_msg =
"interactive [--version version] [--locality locality] [--sealing | --no-sealing] [--stack | --no-stack] [--uperms | --no-uperms] [--mem-size size] <file>"
"interpreter [-I] [--interactive] [--version version] [--locality locality] [--sealing | --no-sealing] [--stack | --no-stack] [--uperms | --no-uperms] [--mem-size size] <file>"
in
let interactive_option = ref false in
let version_option = ref "default" in
let stack_option = ref false in
let no_stack_option = ref false in
Expand All @@ -20,6 +26,8 @@ let parse_argument_interactive addr_max =
let anon_fun filename = input_files := filename :: !input_files in
let speclist =
[
("--interactive", Arg.Set interactive_option, "Interactive mode of the interpreter");
("-I", Arg.Set interactive_option, "Interactive mode of the interpreter");
("--version", Arg.Set_string version_option, "Version Cerise: default, vanilla, ucerise, mcerise, seal_cerise, custom");
("--sealing", Arg.Set sealing_option, "Enable the seals");
("--no-sealing", Arg.Set no_sealing_option, "Disable the seals");
Expand All @@ -33,6 +41,8 @@ let parse_argument_interactive addr_max =
] in
Arg.parse speclist anon_fun usage_msg;

let mode = if !interactive_option then Interactive_mode else Interpreter_mode in

(* Construct the configuration *)
let _ =
match !version_option with
Expand Down Expand Up @@ -95,4 +105,4 @@ let parse_argument_interactive addr_max =
else s)
in

(filename_prog, !regfile_name_option, size_mem)
(mode, filename_prog, !regfile_name_option, size_mem)
16 changes: 16 additions & 0 deletions lib/interpreter_ui.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
let print_exec_state (m : Machine.mchn) =
print_endline @@ Pretty_printer.string_of_exec_state (fst m)

let print_reg_state (m : Machine.mchn) =
let open Pretty_printer in
let rs = (snd m).reg in
print_endline "+-----------------------";
Machine.RegMap.iter (fun r w ->
print_endline @@ string_of_reg_word r w) rs;
print_endline "+-----------------------"

let interpreter (m_init : Machine.mchn) =
let m_final = Machine.run m_init in
print_reg_state m_final;
Printf.printf "Final execution state: %s\n"
(Pretty_printer.string_of_exec_state (fst m_final))
10 changes: 5 additions & 5 deletions src/dune
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
(executable
(name interpreter)
(modules interpreter)
(libraries libinterp))

(executable
(name interactive)
(modules interactive)
(libraries libinterp notty notty.unix containers))

; (executable
; (name interactive)
; (modules interactive)
; (libraries libinterp notty notty.unix containers))

(executable
(name awkward_ucaps)
(modules awkward_ucaps)
Expand Down
42 changes: 0 additions & 42 deletions src/interactive.ml

This file was deleted.

63 changes: 36 additions & 27 deletions src/interpreter.ml
Original file line number Diff line number Diff line change
@@ -1,38 +1,47 @@
open Libinterp

let print_exec_state (m : Machine.mchn) =
print_endline @@ Pretty_printer.string_of_exec_state (fst m)

let print_reg_state (m : Machine.mchn) =
let open Pretty_printer in
let rs = (snd m).reg in
print_endline "+-----------------------";
Machine.RegMap.iter (fun r w ->
print_endline @@ string_of_reg_word r w) rs;
print_endline "+-----------------------"

let () =
(* very basic commandline argument parsing (to be improved) *)
let filename =
match Sys.argv |> Array.to_list |> List.tl with
| [filename] -> filename
| _ ->
Printf.eprintf "usage: %s <input filename>\n" Sys.argv.(0);
exit 1
let addr_max = (Int32.to_int Int32.max_int)/4096 in
let (mode, filename_prog, regfile_name, size_mem) =
Cli_parser.parse_arguments addr_max
in

(* Parse initial memory (program) *)
let prog =
match Program.parse_prog filename with
match Program.parse_prog filename_prog with
| Ok prog -> prog
| Error msg ->
Printf.eprintf "Parse error: %s\n" msg;
Printf.eprintf "Program parse error: %s\n" msg;
exit 1
in
let addr_max = Z.of_int ((Int32.to_int Int32.max_int)/4096) in

let init_regfile = Machine.init_reg_state addr_max in
let stk_addr =
Z.(if !Parameters.flags.stack then (size_mem/ ~$2) else ~$0)
in

(* Parse initial register file *)
let regfile =
let init_regfile = (Machine.init_reg_state size_mem) in
if regfile_name = ""
then init_regfile
else
(match Program.parse_regfile regfile_name size_mem stk_addr with
| Ok regs ->
(Machine.RegMap.fold
(fun r w rf -> Machine.RegMap.add r w rf) regs) init_regfile
| Error msg ->
Printf.eprintf "Regfile parse error: %s\n" msg;
exit 1)
in
let m_init = Program.init_machine prog (Some size_mem) regfile in

match mode with
| Cli_parser.Interactive_mode ->
let module Cfg = struct let addr_max : Z.t = size_mem end in
let module Ui = Interactive_ui.MkUi (Cfg) in
let prog_panel_start = ref Z.zero in
let stk_panel_start = ref stk_addr in
Ui.render_loop ~show_stack:(!Parameters.flags.stack) prog_panel_start stk_panel_start m_init

let m_init = Program.init_machine prog (Some addr_max) init_regfile in
let m_final = Machine.run m_init in
print_reg_state m_final;
Printf.printf "Final execution state: %s\n"
(Pretty_printer.string_of_exec_state (fst m_final))
| Cli_parser.Interpreter_mode ->
Interpreter_ui.interpreter m_init

0 comments on commit 9c89c64

Please sign in to comment.