-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.ml
158 lines (142 loc) · 4.34 KB
/
main.ml
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
(* Module Main: The main program. Deals with processing the command
line, reading files, building and connecting lexers and parsers, etc.
For most experiments with the implementation, it should not be
necessary to change this file.
*)
open Format
open Support.Pervasive
open Support.Error
open Syntax
open Core
let di = dummyinfo
let cmds2 = [
Eval(di,
TmApp(di,
TmAbs(di, "x", TyInt([(1, 5)]), TmPlus(di, TmVar(di, 0, 1), TmInt(di, 2))),
TmInt(di,1)));
Eval(di,
TmAbs(di, "y", TyInt([(4, 7); (10, 13)]),
TmMinus(di,
TmVar(di, 0, 1),
TmInt(di, 3))));
Eval(di,
TmApp(di,
TmAbs(di, "x", TyInt([(20, 40)]),
TmIf(di,
TmGreater(di,
TmVar(di, 0, 0),
TmInt(di, 30)),
TmPlus(di,
TmVar(di, 0, 0),
TmInt(di, 10)),
TmMinus(di,
TmVar(di, 0, 0),
TmInt(di, 10)))),
TmInt(di, 35)));
Eval(di,
TmApp(di,
TmAbs(di, "x", TyInt([(20, 40)]),
TmIf(di,
TmLess(di,
TmVar(di, 0, 0),
TmInt(di, 30)),
TmInt(di, 10),
TmInt(di, 50))),
TmInt(di, 25)));
Eval(di,
TmAbs(di, "x", TyInt([(0,65535)]),
TmAbs(di, "y", TyInt([(0,65535)]),
TmPlus(di,
TmVar(di, 1, 0),
TmVar(di, 0, 0)))));
]
let searchpath = ref [""]
let argDefs = [
"-I",
Arg.String (fun f -> searchpath := f::!searchpath),
"Append a directory to the search path"]
let parseArgs () =
let inFile = ref (None : string option) in
Arg.parse argDefs
(fun s ->
match !inFile with
Some(_) -> err "You must specify exactly one input file"
| None -> inFile := Some(s))
"";
match !inFile with
None -> err "You must specify an input file"
| Some(s) -> s
let openfile infile =
let rec trynext l = match l with
[] -> err ("Could not find " ^ infile)
| (d::rest) ->
let name = if d = "" then infile else (d ^ "/" ^ infile) in
try open_in name
with Sys_error m -> trynext rest
in trynext !searchpath
let parseFile inFile =
let pi = openfile inFile in
let lexbuf = Lexer.create inFile pi in
let result =
try Parser.toplevel Lexer.main lexbuf with Parsing.Parse_error ->
error (Lexer.info lexbuf) "Parse error"
in
Parsing.clear_parser(); close_in pi; result
let alreadyImported = ref ([] : string list)
let checkbinding fi ctx b = match b with
NameBind -> NameBind
| VarBind(tyT) -> VarBind(tyT)
| TmAbbBind(t,None) -> TmAbbBind(t, Some(typeof ctx t))
| TmAbbBind(t,Some(tyT)) ->
let tyT' = typeof ctx t in
if subtype ctx tyT' tyT then TmAbbBind(t,Some(tyT))
else error fi "Type of binding does not match declared type"
| TyVarBind -> TyVarBind
| TyAbbBind(tyT) -> TyAbbBind(tyT)
let prbindingty ctx b = match b with
NameBind -> ()
| TyVarBind -> ()
| VarBind(tyT) -> pr ": "; printty ctx tyT
| TmAbbBind(t, tyT_opt) -> pr ": ";
(match tyT_opt with
None -> printty ctx (typeof ctx t)
| Some(tyT) -> printty ctx tyT)
| TyAbbBind(tyT) -> pr ":: *"
let rec process_command ctx cmd = match cmd with
| Eval(fi,t) ->
let tyT = typeof ctx t in
let t' = eval ctx t in
printtm_ATerm true ctx t';
print_break 1 2;
pr ": ";
printty ctx tyT;
force_newline();
ctx
| Bind(fi,x,bind) ->
let bind = checkbinding fi ctx bind in
let bind' = evalbinding ctx bind in
pr x; pr " "; prbindingty ctx bind'; force_newline();
addbinding ctx x bind'
let process_file f ctx =
alreadyImported := f :: !alreadyImported;
let cmds,_ = parseFile f ctx in
let g ctx c =
open_hvbox 0;
let results = process_command ctx c in
print_flush();
results
in
List.fold_left g ctx cmds
let main () =
let inFile = parseArgs() in
let _ = process_file inFile emptycontext in
()
let () = set_max_boxes 1000
let () = set_margin 67
let res =
Printexc.catch (fun () ->
try main();0
with Exit x -> x)
()
let () = print_flush()
let () = exit res