Fixes for RISC evaluation
This commit is contained in:
9
bin/dune
9
bin/dune
@ -27,3 +27,12 @@
|
||||
(package miniImp)
|
||||
(modes byte exe)
|
||||
)
|
||||
|
||||
(executable
|
||||
(name miniImpInterpreterReg)
|
||||
(public_name miniImpInterpreterReg)
|
||||
(libraries miniImp
|
||||
clap)
|
||||
(package miniImp)
|
||||
(modes byte exe)
|
||||
)
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
def main with input n output result as
|
||||
if (n % 2) == 0 then result := 1
|
||||
else (
|
||||
|
||||
result := 0;
|
||||
s := 0;
|
||||
while (0 == ((n - 1) / (2 ^ s)) % 2) do (
|
||||
@ -11,6 +10,7 @@ def main with input n output result as
|
||||
for (i := 20, i > 0, i := i - 1) do (
|
||||
a := rand(n - 4) + 2;
|
||||
x := powmod(a, d, n);
|
||||
y := 0;
|
||||
for (j := 0, j < s, j := j+1) do (
|
||||
y := powmod(x, 2, n);
|
||||
if (y == 1 && (not x == 1) && (not x == n - 1)) then
|
||||
|
||||
@ -58,7 +58,8 @@ let () =
|
||||
| Lexer.LexingError msg ->
|
||||
Printf.fprintf stderr "%a: %s\n" print_position lexbuf msg;
|
||||
exit (-1)
|
||||
| Parser.Error -> Printf.fprintf stderr "%a: syntax error\n" print_position lexbuf;
|
||||
| Parser.Error ->
|
||||
Printf.fprintf stderr "%a: syntax error\n" print_position lexbuf;
|
||||
exit (-1)
|
||||
in
|
||||
let return_value =
|
||||
|
||||
119
bin/miniImpInterpreterReg.ml
Normal file
119
bin/miniImpInterpreterReg.ml
Normal file
@ -0,0 +1,119 @@
|
||||
open MiniImp
|
||||
open Lexing
|
||||
|
||||
(* -------------------------------------------------------------------------- *)
|
||||
(* Command Arguments *)
|
||||
|
||||
let () =
|
||||
Clap.description "Interpreter for MiniImp language.";
|
||||
|
||||
let files = Clap.section ~description: "Files to consider." "FILES" in
|
||||
let values = Clap.section ~description: "Input values." "VALUES" in
|
||||
|
||||
let input = Clap.mandatory_string
|
||||
~description: "Input file."
|
||||
~placeholder: "FILENAME"
|
||||
~section: files
|
||||
~long: "input"
|
||||
~short: 'i'
|
||||
()
|
||||
in
|
||||
|
||||
let registers = Clap.default_int
|
||||
~description: "Optional number of registers available."
|
||||
~placeholder: "INT"
|
||||
~section: values
|
||||
~long: "registers"
|
||||
~short: 'r'
|
||||
4
|
||||
in
|
||||
|
||||
let evalb = Clap.flag
|
||||
~description: "Optional flag for evaluating the generated risc code."
|
||||
~section: values
|
||||
~set_long: "eval"
|
||||
~set_short: 'e'
|
||||
false
|
||||
in
|
||||
|
||||
let inputval = Clap.default_int
|
||||
~description: "Optional input value to feed to the program. \
|
||||
If not specified it is read from stdin."
|
||||
~placeholder: "INT"
|
||||
~section: values
|
||||
~long: "value"
|
||||
~short: 'v'
|
||||
0
|
||||
in
|
||||
|
||||
let output = Clap.optional_string
|
||||
~description: "Output file. If not specified output is printed on stdout."
|
||||
~placeholder: "FILENAME"
|
||||
~section: files
|
||||
~long: "output"
|
||||
~long_synonyms: ["out"; "result"]
|
||||
~short: 'o'
|
||||
()
|
||||
in
|
||||
|
||||
Clap.close ();
|
||||
|
||||
(* -------------------------------------------------------------------------- *)
|
||||
(* Interpreter *)
|
||||
|
||||
let print_position outx lexbuf =
|
||||
let pos = lexbuf.lex_curr_p in
|
||||
Printf.fprintf outx "Encountered \"%s\" at %s:%d:%d"
|
||||
(Lexing.lexeme lexbuf) pos.pos_fname
|
||||
pos.pos_lnum (pos.pos_cnum - pos.pos_bol + 1)
|
||||
in
|
||||
|
||||
let interpret_file inch (registers: int) outch =
|
||||
let lexbuf = Lexing.from_channel inch in
|
||||
let program =
|
||||
try Parser.prg Lexer.read lexbuf with
|
||||
| Lexer.LexingError msg ->
|
||||
Printf.fprintf stderr "%a: %s\n" print_position lexbuf msg;
|
||||
exit (-1)
|
||||
| Parser.Error ->
|
||||
Printf.fprintf stderr "%a: syntax error\n" print_position lexbuf;
|
||||
exit (-1)
|
||||
in
|
||||
let return_value =
|
||||
program |>
|
||||
CfgImp.convert_io inputval |>
|
||||
CfgRISC.convert
|
||||
in
|
||||
|
||||
let () = (
|
||||
match DefinedVariables.compute_defined_variables return_value |>
|
||||
DefinedVariables.check_undefined_variables
|
||||
with
|
||||
| None -> ()
|
||||
| Some l ->
|
||||
Printf.printf "Error: undefined variables: %a\n"
|
||||
DefinedVariables.Variable.pplist l;
|
||||
exit (-1)
|
||||
) in
|
||||
|
||||
let return_value =
|
||||
return_value |>
|
||||
LiveVariables.compute_live_variables |>
|
||||
LiveVariables.optimize_cfg |>
|
||||
LiveVariables.compute_cfg |>
|
||||
ReduceRegisters.reduceregisters registers |>
|
||||
RISC.convert
|
||||
in
|
||||
|
||||
if not evalb
|
||||
then Printf.fprintf outch "%a\n" RISC.RISCAssembly.pp return_value
|
||||
else Printf.fprintf outch "%d\n" (RISCSemantics.reduce return_value)
|
||||
in
|
||||
|
||||
let inx = In_channel.open_text input in
|
||||
let outx = match output with
|
||||
None -> stdout
|
||||
| Some f -> Out_channel.open_text f
|
||||
in
|
||||
|
||||
interpret_file inx registers outx;
|
||||
25
bin/test.miniimp
Normal file
25
bin/test.miniimp
Normal file
@ -0,0 +1,25 @@
|
||||
def main with input n output result as
|
||||
if (n % 2) == 0 then result := 1
|
||||
else (
|
||||
result := 0;
|
||||
s := 0;
|
||||
while (0 == ((n - 1) / (2 ^ s)) % 2) do (
|
||||
s := s + 1
|
||||
);
|
||||
d := ((n - 1) / 2 ^ s);
|
||||
for (i := 20, i > 0, i := i - 1) do (
|
||||
a := rand(n - 4) + 2;
|
||||
x := powmod(a, d, n);
|
||||
y := 0;
|
||||
for (j := 0, j < s, j := j+1) do (
|
||||
y := powmod(x, 2, n);
|
||||
if (y == 1 && (not x == 1) && (not x == n - 1)) then
|
||||
result := 1;
|
||||
else
|
||||
skip;
|
||||
x := y;
|
||||
);
|
||||
if not y == 1 then result := 1;
|
||||
else skip;
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user