-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPump.Extract.fst
60 lines (47 loc) · 2 KB
/
Pump.Extract.fst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
(* Compiling a simple example to C.
The program to translate is defined in Pump.Check.fst. *)
module Pump.Extract
module Pump = Pump.Check
module XX = Pipit.Exec.Exp
module XL = Pipit.Exec.LowStar
module Tac = FStar.Tactics
module SugarBase = Pipit.Sugar.Base
module Sugar = Pipit.Sugar.Vanilla
module PPV = Pipit.Prim.Vanilla
(* We will translate just the controller node with two input streams (estop and
level). We do not want the expression's internal representation to show up in
the C code, so we mark it as noextract.
*)
[@@(Tac.postprocess_with (XL.tac_normalize_pure ["Pump"]))]
noextract
inline_for_extraction
let expr = SugarBase.exp_of_stream2 Pump.controller
(* Define the state type so it shows up as a type definition in the C code.
The "postprocess_with" annotation ensures that the state_of_exp is inlined
into the type and simplified to a regular type *)
[@@(Tac.postprocess_with (XL.tac_normalize_pure ["Pump"]))]
type state = XX.state_of_exp expr
type result = bool & bool
type input = {
estop: bool;
level_low: bool;
}
(* Translate the expression to a transition system.
Annotate with result type (bool & bool) so system is clearer. If we leave
out the type annotation, then the generated KRML code may infer the result
of the `step` function to be `any`, which breaks compilation.
*)
// #push-options "--debug Pump.Extract --debug_level NBE"
noextract
[@@(Tac.postprocess_with (XL.tac_normalize_pure ["Pump"]))]
let system: XX.esystem (bool & (bool & unit)) state result =
assert_norm (XX.extractable expr);
XX.exec_of_exp expr
(* Define the reset function, which takes a pointer to the internal state and
initialises it. *)
[@@(Tac.postprocess_with (XL.tac_extract ["Pump"]))]
let reset = XL.mk_reset system
(* Define the step function, which takes two input booleans and a pointer to the
internal state, and returns the result as a pair. *)
[@@(Tac.postprocess_with (XL.tac_extract ["Pump"]))]
let step (inp: input) = XL.mk_step system (inp.estop, (inp.level_low, ()))