-
Notifications
You must be signed in to change notification settings - Fork 3
/
el-run.sml
135 lines (127 loc) · 5.42 KB
/
el-run.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
123
124
125
126
127
128
129
130
131
132
133
134
135
(*
* MixML prototype implementation
*
* Based on: Derek Dreyer, Andreas Rossberg, "Mixin' Up the ML Module System"
*
* (c) 2007-2008 Andreas Rossberg
*)
signature EL_RUN =
sig
type context
val initialContext : context
val showing : bool ref
val checked : bool ref
val compile : ELElaboration.context -> string -> EL.prog * ELAux.funct * IL.modl
val check : ELElaboration.context -> string -> ELElaboration.context option
val run : context -> string -> context option
end
structure ELRun :> EL_RUN =
struct
open VarOps infix \ |-> |=> ++
open ILOps
open ELTrace
open PrettyPrint infix ^^ ^/^
val showing = ref false
val checked = ref false
type context = ELElaboration.context * ILEvaluation.context * ILMachine.modval
val initialContext = (ELElaboration.emptyContext, ILEvaluation.emptyContext, ILMachine.StructW[])
fun catch f =
(traceReset(); SOME(f()))
handle EL.Error({l = (l1, c1), r = (l2, c2)}, message) =>
(
TextIO.output(TextIO.stdErr,
Int.toString l1 ^ "." ^ Int.toString c1 ^ "-" ^
Int.toString l2 ^ "." ^ Int.toString c2 ^ ": " ^ message ^ "\n"
);
NONE
)
| ILTyping.Error message =>
(TextIO.output(TextIO.stdErr, "Internal type error: " ^ message ^ "\n"); NONE)
| ILEvaluation.Stuck s =>
(TextIO.output(TextIO.stdErr, "Evaluation is stuck\n" ^ ILPrint.strSt s); NONE)
| ILEvaluation.Black x =>
(TextIO.output(TextIO.stdErr, "Black hole encountered at " ^ x ^ "\n"); NONE)
| Fail s =>
(TextIO.output(TextIO.stdErr, "Internal failure: " ^ s ^ "\n"); NONE)
| IO.Io{name, function, cause} =>
(TextIO.output(TextIO.stdErr, "I/O failure in " ^ name ^ ", " ^ function ^ ": " ^ exnName cause ^ "\n"); NONE)
| exn =>
(TextIO.output(TextIO.stdErr, "Internal exception: " ^ exnName exn ^ "\n"); NONE)
fun compile cStat source =
let
val _ = (trace "[Parsing...]"; traceSrc "source" source)
val prog = ELParser.parse source
val _ = trace "[Elaborating...]"
val (phi as (_, betaks, _), lsigmas, f) =
case ELElaboration.elab cStat prog of
(phi as ([], betaks, ELAux.Struct(lsigmas)), f) => (phi, lsigmas, f)
| _ => raise Fail "compile: elab"
val _ = trace "[Finished.]"
in
if not(!showing) then () else
PrettyPrint.output(TextIO.stdOut,
ELPretty.ppD(map(betaks)) ^/^ ELPretty.ppG(map(lsigmas)) ^^ break,
80
);
(prog, phi, f)
end
fun check (cStat as (delta, gamma)) source =
catch (fn() =>
let
val (betaks, lsigmas) =
case compile cStat source of
(_, ([], betaks, ELAux.Struct(lsigmas)), _) => (betaks, lsigmas)
| _ => raise Fail "check: compile"
in
(delta ++ map(betaks), gamma ++ map(lsigmas))
end)
fun run (c as (cStat as (delta, gamma), cDyn as (deltaDyn, gammaDyn, omega), w)) source =
catch (fn() =>
let
val _ = (trace "[Parsing...]"; traceSrc "source" source)
val prog = ELParser.parse source
val _ = trace "[Elaborating...]"
val (betaks, lsigmas, f) =
case ELElaboration.elab cStat prog of
(([], betaks, ELAux.Struct(lsigmas)), f) => (betaks, lsigmas, f)
| _ => raise Fail "run: elab"
val delta' = map(betaks)
val gamma' = map(lsigmas)
val cStat' = (delta ++ delta', gamma ++ gamma')
val () = if not(!showing) then () else
PrettyPrint.output(TextIO.stdOut,
ELPretty.ppD(map(betaks)) ^/^ ELPretty.ppG(map(lsigmas)) ^^ break,
80
)
val deltaDyn = deltaDyn ++ mapRan IL.Up delta'
val cDyn = (deltaDyn, gammaDyn, omega)
val m' =
IL.LetM("_old", ILMachine.fromModval w,
ILOps.letM(List.map (fn x => (x, IL.DotM(IL.VarM("_old"), x))) (items(dom(gamma))),
IL.LetM("_run", ELAux.create(ELAux.Struct(lsigmas)),
ILOps.seqM[
IL.ApplyM(
IL.InstUpM(IL.InstDownM(f, []), List.map #1 betaks),
IL.VarM("_run")
),
IL.StructM(
List.map (fn x => (x, IL.VarM(x))) (items(dom(gamma) \ dom(gamma'))) @
List.map (fn x => (x, IL.DotM(IL.VarM("_run"), x))) (items(dom(gamma')))
)
]
)
)
)
val () = if not(!checked) then () else
(
trace "[Checking...]";
ignore(ILTyping.checkM (deltaDyn ++ mapRan IL.Colon delta, gammaDyn) m')
)
val _ = trace "[Running...]"
val (cDyn', w') = (if !checked then ILCheckedEvaluation.run else ILEvaluation.run)(cDyn, m')
val _ = trace "[Finished.]"
in
(*trace(ILPrint.strO omega);*)
(cStat', cDyn', w')
end)
end