forked from CakeML/pure
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pure_compilerScript.sml
122 lines (109 loc) · 3.58 KB
/
pure_compilerScript.sml
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
(*
PureLang compiler: concrete syntax -> CakeML AST
*)
open HolKernel Parse boolLib bossLib term_tactic;
open fixedPointTheory arithmeticTheory listTheory stringTheory alistTheory
optionTheory pairTheory ltreeTheory llistTheory bagTheory dep_rewrite
BasicProvers pred_setTheory relationTheory rich_listTheory finite_mapTheory;
open pure_cexpTheory pure_to_cakeTheory pureParseTheory pure_inferenceTheory
pure_letrec_cexpTheory pure_demands_analysisTheory pure_inline_cexpTheory
fromSexpTheory simpleSexpParseTheory pure_printTheory;
val _ = set_grammar_ancestry
["pure_cexp", "pure_to_cake", "pureParse", "pure_inference",
"pure_letrec_cexp", "pure_demands_analysis",
"pure_inline_cexp", "fromSexp", "simpleSexpParse"];
val _ = new_theory "pure_compiler";
Definition ast_to_string_def:
ast_to_string prog = print_sexp (listsexp (MAP decsexp prog))
End
Overload debug_print = ``λs. empty_ffi (implode s)``;
Overload explore_print =
``λc s. if c.do_explore then debug_print s else ()``;
Definition compile_def:
compile c s =
let _ = debug_print "starting..." in
let r = string_to_cexp s in
let _ = debug_print "parsing" in
case r of
| NONE => NONE
| SOME (e,ns) =>
let e = transform_cexp c e in
let _ = debug_print "transform_cexp" in
let e = inline_top_level c e in
let _ = debug_print "inlining" in
let _ = explore_print c $
"after inlining:\n" ++ pure_print$str_of e ++ "\n" in
let i = infer_types ns e in
let _ = debug_print "infer_types" in
case to_option i of
| NONE => NONE
| SOME _ =>
let e = clean_cexp c e in
let _ = debug_print "clean_cexp" in
let e = demands_analysis c e in
let _ = debug_print "demands_analysis" in
let _ = explore_print c $
"after demands:\n" ++ pure_print$str_of e ++ "\n" in
SOME (ast_to_string $ pure_to_cake c ns e)
End
Definition compile_to_ast_def:
compile_to_ast c s =
case string_to_cexp s of
| NONE => NONE
| SOME (e,ns) =>
let e = transform_cexp c e in
let e = inline_top_level c e in
let i = infer_types ns e in
case to_option i of
| NONE => NONE
| SOME _ =>
let e = clean_cexp c e in
let e = demands_analysis c e in
SOME (pure_to_cake c ns e)
End
(********** Alternative phrasings **********)
Theorem compile_monadically:
compile c s =
do
(e,ns) <- string_to_cexp s ;
e <<- transform_cexp c e ;
e <<- inline_top_level c e ;
to_option $ infer_types ns e ;
e <<- clean_cexp c e ;
e <<- demands_analysis c e ;
return (ast_to_string $ pure_to_cake c ns e)
od
Proof
simp[compile_def]>> EVERY_CASE_TAC >> simp[]
QED
Definition frontend_def:
frontend c s =
case string_to_cexp s of
| NONE => NONE
| SOME (e,ns) =>
let e = transform_cexp c e in
let e = inline_top_level c e in
let i = infer_types ns e in
case to_option i of
| NONE => NONE
| SOME _ => SOME (e,ns)
End
Theorem compile_to_string:
compile c s = OPTION_MAP ast_to_string $ compile_to_ast c s
Proof
rw[compile_def, compile_to_ast_def] >>
rpt (TOP_CASE_TAC >> gvs[])
QED
Theorem compile_to_ast_alt_def:
compile_to_ast c s =
case frontend c s of
| NONE => NONE
| SOME (e,ns) =>
let e = clean_cexp c e in
let e = demands_analysis c e in
SOME (pure_to_cake c ns e)
Proof
rw[compile_to_ast_def, frontend_def] >>
rpt (TOP_CASE_TAC >> simp[])
QED
val _ = export_theory();