2024-10-04 19:38:34 +02:00
|
|
|
type variable = string
|
|
|
|
|
|
|
|
|
|
type p_exp =
|
2025-01-27 01:17:53 +01:00
|
|
|
Main of variable * variable * c_exp
|
|
|
|
|
(* def main with input x output y as c *)
|
2024-10-04 19:38:34 +02:00
|
|
|
and c_exp =
|
|
|
|
|
Skip
|
2025-01-27 01:17:53 +01:00
|
|
|
| Assignment of variable * a_exp (* x := a *)
|
|
|
|
|
| Sequence of c_exp * c_exp (* c; c *)
|
|
|
|
|
| If of b_exp * c_exp * c_exp (* if b then c else c *)
|
|
|
|
|
| While of b_exp * c_exp (* while b do c *)
|
|
|
|
|
| For of c_exp * b_exp * c_exp * c_exp
|
|
|
|
|
(* for (c; b; c) do c *)
|
2024-10-04 19:38:34 +02:00
|
|
|
and b_exp =
|
2025-01-27 01:17:53 +01:00
|
|
|
Boolean of bool (* v *)
|
|
|
|
|
| BAnd of b_exp * b_exp (* b && b *)
|
|
|
|
|
| BOr of b_exp * b_exp (* b || b *)
|
|
|
|
|
| BNot of b_exp (* not b *)
|
|
|
|
|
| BCmp of a_exp * a_exp (* a == a *)
|
|
|
|
|
| BCmpLess of a_exp * a_exp (* a < a *)
|
|
|
|
|
| BCmpLessEq of a_exp * a_exp (* a <= a *)
|
|
|
|
|
| BCmpGreater of a_exp * a_exp (* a > a *)
|
|
|
|
|
| BCmpGreaterEq of a_exp * a_exp (* a >= a *)
|
2024-10-04 19:38:34 +02:00
|
|
|
and a_exp =
|
2025-01-27 01:17:53 +01:00
|
|
|
Variable of variable (* x *)
|
|
|
|
|
| Integer of int (* n *)
|
|
|
|
|
| Plus of a_exp * a_exp (* a + a *)
|
|
|
|
|
| Minus of a_exp * a_exp (* a - a *)
|
|
|
|
|
| Times of a_exp * a_exp (* a * a *)
|
|
|
|
|
| Division of a_exp * a_exp (* a / a *)
|
|
|
|
|
| Modulo of a_exp * a_exp (* a % a *)
|
|
|
|
|
| Power of a_exp * a_exp (* a ^ a *)
|
|
|
|
|
| PowerMod of a_exp * a_exp * a_exp (* a ^ a % a *)
|
|
|
|
|
| Rand of a_exp (* rand(0, a) *)
|
2024-10-04 19:38:34 +02:00
|
|
|
|
2024-12-03 17:18:42 +01:00
|
|
|
let pp_p_exp (ppf: Format.formatter) (p: p_exp) : unit =
|
2025-01-27 01:17:53 +01:00
|
|
|
let open Format in
|
2024-12-03 17:18:42 +01:00
|
|
|
let rec helper_c (ppf) (c: c_exp) : unit =
|
|
|
|
|
match c with
|
2025-01-27 01:17:53 +01:00
|
|
|
| Skip ->
|
|
|
|
|
fprintf ppf "Skip"
|
|
|
|
|
| Assignment (x, a) ->
|
|
|
|
|
fprintf ppf "%S := @[<h>%a@]" x helper_a a
|
|
|
|
|
| Sequence (c1, c2) ->
|
|
|
|
|
fprintf ppf "@[<hv>Sequence (@;<1 2>%a,@;<1 0>%a@;<0 0>)@]"
|
|
|
|
|
helper_c c1 helper_c c2
|
|
|
|
|
| If (b, c1, c2) ->
|
|
|
|
|
fprintf ppf
|
|
|
|
|
"@[<hv>If @[<h>%a@]@;<1 2>then (@[<hv>%a@])@;<1 2>else (@[<hv>%a@])@]"
|
|
|
|
|
helper_b b helper_c c1 helper_c c2
|
|
|
|
|
| While (b, c) ->
|
|
|
|
|
fprintf ppf "@[<hv>While @[<h>%a@] do@;<1 2>%a@]@;<0 0>"
|
|
|
|
|
helper_b b helper_c c
|
|
|
|
|
| For (c1, b, c2, c3) ->
|
|
|
|
|
fprintf ppf
|
|
|
|
|
"@[<h>For (@;<0 2>%a,@;<1 2>@[<h>%a@],@;<1 2>%a) do@]@;<1 4>%a@;<0 0>"
|
|
|
|
|
helper_c c1 helper_b b helper_c c2 helper_c c3
|
2024-12-03 17:18:42 +01:00
|
|
|
and helper_b (ppf) (b: b_exp) =
|
|
|
|
|
match b with
|
2025-01-27 01:17:53 +01:00
|
|
|
| Boolean (b) ->
|
|
|
|
|
fprintf ppf "%b" b
|
|
|
|
|
| BAnd (b1, b2) ->
|
|
|
|
|
fprintf ppf "(%a &&@;<1 2>%a)" helper_b b1 helper_b b2
|
|
|
|
|
| BOr (b1, b2) ->
|
|
|
|
|
fprintf ppf "(%a ||@;<1 2>%a)" helper_b b1 helper_b b2
|
|
|
|
|
| BNot (b) ->
|
|
|
|
|
fprintf ppf "(not %a)" helper_b b
|
|
|
|
|
| BCmp (a1, a2) ->
|
|
|
|
|
fprintf ppf "(%a ==@;<1 2>%a)" helper_a a1 helper_a a2
|
|
|
|
|
| BCmpLess (a1, a2) ->
|
|
|
|
|
fprintf ppf "(%a <@;<1 2>%a)" helper_a a1 helper_a a2
|
|
|
|
|
| BCmpLessEq (a1, a2) ->
|
|
|
|
|
fprintf ppf "(%a <=@;<1 2>%a)" helper_a a1 helper_a a2
|
|
|
|
|
| BCmpGreater (a1, a2) ->
|
|
|
|
|
fprintf ppf "(%a >@;<1 2>%a)" helper_a a1 helper_a a2
|
|
|
|
|
| BCmpGreaterEq (a1, a2) ->
|
|
|
|
|
fprintf ppf "(%a >=@;<1 2>%a)" helper_a a1 helper_a a2
|
2024-12-03 17:18:42 +01:00
|
|
|
and helper_a (ppf) (a: a_exp) =
|
|
|
|
|
match a with
|
2025-01-27 01:17:53 +01:00
|
|
|
| Variable v ->
|
|
|
|
|
fprintf ppf "%S" v
|
|
|
|
|
| Integer n ->
|
|
|
|
|
fprintf ppf "%i" n
|
|
|
|
|
| Plus (a1, a2) ->
|
|
|
|
|
fprintf ppf "%a +@;<1 2>%a" helper_a a1 helper_a a2
|
|
|
|
|
| Minus (a1, a2) ->
|
|
|
|
|
fprintf ppf "%a -@;<1 2>%a" helper_a a1 helper_a a2
|
|
|
|
|
| Times (a1, a2) ->
|
|
|
|
|
fprintf ppf "%a *@;<1 2>%a" helper_a a1 helper_a a2
|
|
|
|
|
| Division (a1, a2) ->
|
|
|
|
|
fprintf ppf "%a /@;<1 2>%a" helper_a a1 helper_a a2
|
|
|
|
|
| Modulo (a1, a2) ->
|
|
|
|
|
fprintf ppf "%a %%@;<1 2>%a" helper_a a1 helper_a a2
|
|
|
|
|
| Power (a1, a2) ->
|
|
|
|
|
fprintf ppf "(%a ^@;<1 2>%a)" helper_a a1 helper_a a2
|
|
|
|
|
| PowerMod (a1, a2, a3) ->
|
|
|
|
|
fprintf ppf "(%a ^ %a %% %a)" helper_a a1 helper_a a2 helper_a a3
|
|
|
|
|
| Rand (a) ->
|
|
|
|
|
fprintf ppf "Rand (%a)" helper_a a
|
2024-12-03 17:18:42 +01:00
|
|
|
in
|
|
|
|
|
match p with
|
|
|
|
|
| Main (i, o, exp) ->
|
2025-01-27 01:17:53 +01:00
|
|
|
fprintf ppf "def main with (input %S) (output %S) as @.%a" i o helper_c exp
|
2024-10-04 19:38:34 +02:00
|
|
|
|
2024-10-25 21:29:49 +02:00
|
|
|
module VariableMap = Map.Make(String)
|
2024-10-04 19:38:34 +02:00
|
|
|
|
|
|
|
|
type memory = {
|
|
|
|
|
assignments: int VariableMap.t
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 15:40:00 +01:00
|
|
|
type error = [
|
|
|
|
|
`AbsentAssignment of string
|
|
|
|
|
| `DivisionByZero of string
|
|
|
|
|
]
|