Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh |
2 | * Jagannathan, and Stephen Weeks. | |
3 | * Copyright (C) 1997-2000 NEC Research Institute. | |
4 | * | |
5 | * MLton is released under a BSD-style license. | |
6 | * See the file MLton-LICENSE for details. | |
7 | *) | |
8 | ||
9 | functor ImplementSuffix (S: XML_TRANSFORM_STRUCTS): XML_TRANSFORM = | |
10 | struct | |
11 | ||
12 | open S | |
13 | datatype z = datatype Dec.t | |
14 | datatype z = datatype PrimExp.t | |
15 | structure Dexp = DirectExp | |
16 | ||
17 | fun transform (Program.T {datatypes, body, overflow, ...}): Program.t = | |
18 | let | |
19 | (* topLevelSuffix holds the ref cell containing the function of | |
20 | * type unit -> unit that should be called on program exit. | |
21 | *) | |
22 | val topLevelSuffixType = Type.arrow (Type.unit, Type.unit) | |
23 | val topLevelSuffixVar = Var.newNoname () | |
24 | ||
25 | fun loop (e: Exp.t): Exp.t = | |
26 | let | |
27 | val {decs, result} = Exp.dest e | |
28 | val decs = List.rev (List.fold (decs, [], fn (d, ds) => | |
29 | loopDec d :: ds)) | |
30 | in | |
31 | Exp.make {decs = decs, | |
32 | result = result} | |
33 | end | |
34 | and loopDec (dec: Dec.t): Dec.t = | |
35 | case dec of | |
36 | MonoVal b => loopMonoVal b | |
37 | | Fun {decs, ...} => | |
38 | Fun {tyvars = Vector.new0 (), | |
39 | decs = Vector.map (decs, fn {var, ty, lambda} => | |
40 | {var = var, | |
41 | ty = ty, | |
42 | lambda = loopLambda lambda})} | |
43 | | Exception {...} => dec | |
44 | | _ => Error.bug "ImplementSuffix: saw unexpected dec" | |
45 | and loopMonoVal {var, ty, exp} : Dec.t = | |
46 | let | |
47 | fun primExp e = MonoVal {var = var, ty = ty, exp = e} | |
48 | fun keep () = primExp exp | |
49 | in | |
50 | case exp of | |
51 | Case {test, cases, default} => | |
52 | primExp (Case {cases = Cases.map (cases, loop), | |
53 | default = (Option.map | |
54 | (default, fn (e, r) => | |
55 | (loop e, r))), | |
56 | test = test}) | |
57 | | ConApp {...} => keep () | |
58 | | Handle {try, catch = (catch, ty), handler} => | |
59 | primExp (Handle {try = loop try, | |
60 | catch = (catch, ty), | |
61 | handler = loop handler}) | |
62 | | Lambda l => primExp (Lambda (loopLambda l)) | |
63 | | PrimApp {args, prim, ...} => | |
64 | let | |
65 | datatype z = datatype Prim.Name.t | |
66 | fun deref (var, ty) = | |
67 | primExp | |
68 | (PrimApp {prim = Prim.deref, | |
69 | targs = Vector.new1 ty, | |
70 | args = Vector.new1 (VarExp.mono var)}) | |
71 | fun assign (var, ty) = | |
72 | primExp | |
73 | (PrimApp {prim = Prim.assign, | |
74 | targs = Vector.new1 ty, | |
75 | args = Vector.new2 (VarExp.mono var, | |
76 | Vector.first args)}) | |
77 | in | |
78 | case Prim.name prim of | |
79 | TopLevel_getSuffix => | |
80 | deref (topLevelSuffixVar, | |
81 | topLevelSuffixType) | |
82 | | TopLevel_setSuffix => | |
83 | assign (topLevelSuffixVar, | |
84 | topLevelSuffixType) | |
85 | | _ => keep () | |
86 | end | |
87 | | _ => keep () | |
88 | end | |
89 | and loopLambda l = | |
90 | let | |
91 | val {arg, argType, body, mayInline} = Lambda.dest l | |
92 | in | |
93 | Lambda.make {arg = arg, | |
94 | argType = argType, | |
95 | body = loop body, | |
96 | mayInline = mayInline} | |
97 | end | |
98 | val body = Dexp.fromExp (loop body, Type.unit) | |
99 | val body = | |
100 | (Dexp.sequence o Vector.new2) | |
101 | (body, | |
102 | Dexp.app {func = (Dexp.deref | |
103 | (Dexp.monoVar | |
104 | (topLevelSuffixVar, | |
105 | Type.reff topLevelSuffixType))), | |
106 | arg = Dexp.unit (), | |
107 | ty = Type.unit}) | |
108 | val body = | |
109 | Dexp.let1 | |
110 | {var = topLevelSuffixVar, | |
111 | exp = Dexp.reff (Dexp.lambda | |
112 | {arg = Var.newNoname (), | |
113 | argType = Type.unit, | |
114 | body = Dexp.bug "toplevel suffix not installed", | |
115 | bodyType = Type.unit, | |
116 | mayInline = true}), | |
117 | body = body} | |
118 | val body = Dexp.toExp body | |
119 | in | |
120 | Program.T {datatypes = datatypes, | |
121 | body = body, | |
122 | overflow = overflow} | |
123 | end | |
124 | end |