annotate src/checknest.sml @ 1018:9304474170ed

Extend Fuse to work on non-recursive functions
author Adam Chlipala <adamc@hcoop.net>
date Sun, 25 Oct 2009 13:02:13 -0400
parents b2a175a0f2ef
children 217eb87dde31
rev   line source
adamc@879 1 (* Copyright (c) 2009, Adam Chlipala
adamc@879 2 * All rights reserved.
adamc@879 3 *
adamc@879 4 * Redistribution and use in source and binary forms, with or without
adamc@879 5 * modification, are permitted provided that the following conditions are met:
adamc@879 6 *
adamc@879 7 * - Redistributions of source code must retain the above copyright notice,
adamc@879 8 * this list of conditions and the following disclaimer.
adamc@879 9 * - Redistributions in binary form must reproduce the above copyright notice,
adamc@879 10 * this list of conditions and the following disclaimer in the documentation
adamc@879 11 * and/or other materials provided with the distribution.
adamc@879 12 * - The names of contributors may not be used to endorse or promote products
adamc@879 13 * derived from this software without specific prior written permission.
adamc@879 14 *
adamc@879 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
adamc@879 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
adamc@879 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
adamc@879 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
adamc@879 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
adamc@879 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
adamc@879 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
adamc@879 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
adamc@879 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
adamc@879 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
adamc@879 25 * POSSIBILITY OF SUCH DAMAGE.
adamc@879 26 *)
adamc@879 27
adamc@879 28 structure Checknest :> CHECKNEST = struct
adamc@879 29
adamc@879 30 open Cjr
adamc@879 31
adamc@879 32 structure IS = IntBinarySet
adamc@879 33 structure IM = IntBinaryMap
adamc@879 34
adamc@879 35 fun expUses globals =
adamc@879 36 let
adamc@879 37 fun eu (e, _) =
adamc@879 38 case e of
adamc@879 39 EPrim _ => IS.empty
adamc@879 40 | ERel _ => IS.empty
adamc@879 41 | ENamed n => Option.getOpt (IM.find (globals, n), IS.empty)
adamc@879 42 | ECon (_, _, NONE) => IS.empty
adamc@879 43 | ECon (_, _, SOME e) => eu e
adamc@879 44 | ENone _ => IS.empty
adamc@879 45 | ESome (_, e) => eu e
adamc@879 46 | EFfi _ => IS.empty
adamc@879 47 | EFfiApp (_, _, es) => foldl IS.union IS.empty (map eu es)
adamc@879 48 | EApp (e, es) => foldl IS.union (eu e) (map eu es)
adamc@879 49
adamc@879 50 | EUnop (_, e) => eu e
adamc@879 51 | EBinop (_, e1, e2) => IS.union (eu e1, eu e2)
adamc@879 52
adamc@879 53 | ERecord (_, xes) => foldl (fn ((_, e), s) => IS.union (eu e, s)) IS.empty xes
adamc@879 54 | EField (e, _) => eu e
adamc@879 55
adamc@879 56 | ECase (e, pes, _) => foldl (fn ((_, e), s) => IS.union (eu e, s)) (eu e) pes
adamc@879 57
adamc@879 58 | EError (e, _) => eu e
adamc@879 59 | EReturnBlob {blob, mimeType, ...} => IS.union (eu blob, eu mimeType)
adamc@879 60
adamc@879 61 | EWrite e => eu e
adamc@879 62 | ESeq (e1, e2) => IS.union (eu e1, eu e2)
adamc@879 63 | ELet (_, _, e1, e2) => IS.union (eu e1, eu e2)
adamc@879 64
adamc@879 65 | EQuery {query, body, initial, prepared, ...} =>
adamc@879 66 let
adamc@879 67 val s = IS.union (eu query, IS.union (eu body, eu initial))
adamc@879 68 in
adamc@879 69 case prepared of
adamc@879 70 SOME {id, ...} => IS.add (s, id)
adamc@879 71 | _ => s
adamc@879 72 end
adamc@879 73 | EDml {dml, prepared, ...} =>
adamc@879 74 let
adamc@879 75 val s = eu dml
adamc@879 76 in
adamc@879 77 case prepared of
adamc@879 78 SOME {id, ...} => IS.add (s, id)
adamc@879 79 | _ => s
adamc@879 80 end
adamc@879 81 | ENextval {seq, prepared, ...} =>
adamc@879 82 let
adamc@879 83 val s = eu seq
adamc@879 84 in
adamc@879 85 case prepared of
adamc@879 86 SOME {id, ...} => IS.add (s, id)
adamc@879 87 | _ => s
adamc@879 88 end
adamc@879 89
adamc@879 90 | EUnurlify (e, _) => eu e
adamc@879 91 in
adamc@879 92 eu
adamc@879 93 end
adamc@879 94
adamc@879 95 fun annotateExp globals =
adamc@879 96 let
adamc@879 97 fun ae (e as (_, loc)) =
adamc@879 98 case #1 e of
adamc@879 99 EPrim _ => e
adamc@879 100 | ERel _ => e
adamc@879 101 | ENamed n => e
adamc@879 102 | ECon (_, _, NONE) => e
adamc@879 103 | ECon (dk, pc, SOME e) => (ECon (dk, pc, SOME (ae e)), loc)
adamc@879 104 | ENone _ => e
adamc@879 105 | ESome (t, e) => (ESome (t, ae e), loc)
adamc@879 106 | EFfi _ => e
adamc@879 107 | EFfiApp (m, f, es) => (EFfiApp (m, f, map ae es), loc)
adamc@879 108 | EApp (e, es) => (EApp (ae e, map ae es), loc)
adamc@879 109
adamc@879 110 | EUnop (uo, e) => (EUnop (uo, ae e), loc)
adamc@879 111 | EBinop (bo, e1, e2) => (EBinop (bo, ae e1, ae e2), loc)
adamc@879 112
adamc@879 113 | ERecord (n, xes) => (ERecord (n, map (fn (x, e) => (x, ae e)) xes), loc)
adamc@879 114 | EField (e, f) => (EField (ae e, f), loc)
adamc@879 115
adamc@879 116 | ECase (e, pes, ts) => (ECase (ae e, map (fn (p, e) => (p, ae e)) pes, ts), loc)
adamc@879 117
adamc@879 118 | EError (e, t) => (EError (ae e, t), loc)
adamc@879 119 | EReturnBlob {blob, mimeType, t} => (EReturnBlob {blob = ae blob, mimeType = ae mimeType, t = t}, loc)
adamc@879 120
adamc@879 121 | EWrite e => (EWrite (ae e), loc)
adamc@879 122 | ESeq (e1, e2) => (ESeq (ae e1, ae e2), loc)
adamc@879 123 | ELet (x, t, e1, e2) => (ELet (x, t, ae e1, ae e2), loc)
adamc@879 124
adamc@879 125 | EQuery {exps, tables, rnum, state, query, body, initial, prepared} =>
adamc@879 126 (EQuery {exps = exps,
adamc@879 127 tables = tables,
adamc@879 128 rnum = rnum,
adamc@879 129 state = state,
adamc@879 130 query = ae query,
adamc@879 131 body = ae body,
adamc@879 132 initial = ae initial,
adamc@879 133 prepared = case prepared of
adamc@879 134 NONE => NONE
adamc@879 135 | SOME {id, query, ...} => SOME {id = id, query = query,
adamc@879 136 nested = IS.member (expUses globals body, id)}},
adamc@879 137 loc)
adamc@879 138 | EDml {dml, prepared} =>
adamc@879 139 (EDml {dml = ae dml,
adamc@879 140 prepared = prepared}, loc)
adamc@879 141
adamc@879 142 | ENextval {seq, prepared} =>
adamc@879 143 (ENextval {seq = ae seq,
adamc@879 144 prepared = prepared}, loc)
adamc@879 145
adamc@879 146 | EUnurlify (e, t) => (EUnurlify (ae e, t), loc)
adamc@879 147 in
adamc@879 148 ae
adamc@879 149 end
adamc@879 150
adamc@879 151 fun annotate (ds, syms) =
adamc@879 152 let
adamc@879 153 val globals =
adamc@879 154 foldl (fn ((d, _), globals) =>
adamc@879 155 case d of
adamc@879 156 DVal (_, n, _, e) => IM.insert (globals, n, expUses globals e)
adamc@879 157 | DFun (_, n, _, _, e) => IM.insert (globals, n, expUses globals e)
adamc@879 158 | DFunRec fs =>
adamc@879 159 let
adamc@879 160 val s = foldl (fn ((_, _, _, _, e), s) => IS.union (expUses globals e, s)) IS.empty fs
adamc@879 161 in
adamc@879 162 foldl (fn ((_, n, _, _, _), globals) => IM.insert (globals, n, s)) globals fs
adamc@879 163 end
adamc@879 164 | _ => globals) IM.empty ds
adamc@879 165
adamc@879 166 val ds =
adamc@879 167 map (fn d as (_, loc) =>
adamc@879 168 case #1 d of
adamc@879 169 DVal (x, n, t, e) => (DVal (x, n, t, annotateExp globals e), loc)
adamc@879 170 | DFun (x, n, ts, t, e) => (DFun (x, n, ts, t, annotateExp globals e), loc)
adamc@879 171 | DFunRec fs => (DFunRec
adamc@879 172 (map (fn (x, n, ts, t, e) => (x, n, ts, t, annotateExp globals e)) fs), loc)
adamc@879 173 | _ => d) ds
adamc@879 174 in
adamc@879 175 (ds, syms)
adamc@879 176 end
adamc@879 177
adamc@879 178 end