Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Diff of /branches/vis15/src/compiler/cxx-util/tree-to-cxx.sml
ViewVC logotype

Diff of /branches/vis15/src/compiler/cxx-util/tree-to-cxx.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

branches/vis15/src/compiler/c-util/tree-to-c.sml revision 3869, Tue May 17 12:41:49 2016 UTC branches/vis15/src/compiler/c-util/tree-to-cxx.sml revision 3873, Wed May 18 13:38:23 2016 UTC
# Line 11  Line 11 
11    
12  structure TreeToCxx : sig  structure TreeToCxx : sig
13    
     type env = CLang.typed_var TreeVar.Map.map  
   
     val empty : env  
   
14      val trType : TreeTypes.t -> CLang.ty      val trType : TreeTypes.t -> CLang.ty
15    
16      val trBlock : env * TreeIR.block -> CLang.stm      val trBlock : CodeGenEnv.t * TreeIR.block -> CLang.stm
17    
18      val trExp : env * TreeIR.exp -> CLang.exp      val trExp : CodeGenEnv.t * TreeIR.exp -> CLang.exp
19    
20    (* translate an expression to a variable form; return the variable (as an expression)    (* translate an expression to a variable form; return the variable (as an expression)
21     * and the (optional) declaration.     * and the (optional) declaration.
22     *)     *)
23      val expToVar : env * CLang.ty * string * TreeIR.exp -> CLang.exp * CLang.stm list      val expToVar : CodeGenEnv.t * CLang.ty * string * TreeIR.exp -> CLang.exp * CLang.stm list
24    
25      val trAssign : env * CLang.exp * TreeIR.exp -> CLang.stm list      val trAssign : CodeGenEnv.t * CLang.exp * TreeIR.exp -> CLang.stm list
26    
27    end = struct    end = struct
28    
# Line 35  Line 31 
31      structure Op = TreeOps      structure Op = TreeOps
32      structure Ty = TreeTypes      structure Ty = TreeTypes
33      structure V = TreeVar      structure V = TreeVar
34      structure VMap = VMap      structure Env = CodeGenEnv
35    
36      datatype var = datatype CL.typed_var      datatype var = datatype CL.typed_var
     type env = CLang.typed_var VMap.map  
37    
     val empty = VMap.empty  
   
     fun lookup (env, x) = (case VMap.find (env, x)  
            of SOME(V(_, x')) => x'  
             | NONE => raise Fail(concat["lookup(_, ", V.name x, ")"])  
           (* end case *))  
   
     local  
       fun global env = CL.mkVar(lookup(env, PseudoVars.global))  
       fun selfIn env = CL.mkVar(lookup(env, PseudoVars.selfIn))  
       fun selfOut env = CL.mkVar(lookup(env, PseudoVars.selfOut))  
     in  
38    (* translate a local variable that occurs in an l-value context *)    (* translate a local variable that occurs in an l-value context *)
39      fun lvalueVar (env, x) = CL.mkVar(lookup(env, x))      fun lvalueVar (env, x) = CL.mkVar(Env.lookup(env, x))
40    (* translate a variable that occurs in an r-value context *)    (* translate a variable that occurs in an r-value context *)
41      fun rvalueVar (env, x) = CL.mkVar(lookup(env, x))      fun rvalueVar (env, x) = CL.mkVar(Env.lookup(env, x))
42    
43    (* translate a global variable that occurs in an l-value context *)    (* translate a global variable that occurs in an l-value context *)
44      fun lvalueGlobalVar (env, x) = CL.mkIndirect(global env, TreeGlobalVar.name x)      fun lvalueGlobalVar (env, x) = CL.mkIndirect(Env.global env, TreeGlobalVar.name x)
45    (* translate a global variable that occurs in an r-value context *)    (* translate a global variable that occurs in an r-value context *)
46      val rvalueGlobalVar = lvalueGlobalVar      val rvalueGlobalVar = lvalueGlobalVar
47    
48    (* translate a strand state variable that occurs in an l-value context *)    (* translate a strand state variable that occurs in an l-value context *)
49      fun lvalueStateVar (env, x) = CL.mkIndirect(selfOut env, TreeStateVar.name x)      fun lvalueStateVar (env, x) = CL.mkIndirect(Env.selfOut env, TreeStateVar.name x)
50    (* translate a strand state variable that occurs in an r-value context *)    (* translate a strand state variable that occurs in an r-value context *)
51      fun rvalueStateVar (env, x) = CL.mkIndirect(selfIn env, TreeStateVar.name x)      fun rvalueStateVar (env, x) = CL.mkIndirect(Env.selfIn env, TreeStateVar.name x)
     end (* local *)  
52    
53    (* generate new variables *)    (* generate new variables *)
54      local      local
# Line 92  Line 74 
74    
75    (* make an application of a function from the "diderot" namespace *)    (* make an application of a function from the "diderot" namespace *)
76      fun mkDiderotApply (f, args) = CL.mkApply("diderot::" ^ f, args)      fun mkDiderotApply (f, args) = CL.mkApply("diderot::" ^ f, args)
77        fun mkDiderotCall (f, args) = CL.mkCall("diderot::" ^ f, args)
78    
79    (* Translate a TreeIR operator application to a CLang expression *)    (* Translate a TreeIR operator application to a CLang expression *)
80      fun trOp (rator, args) = (case (rator, args)      fun trOp (rator, args) = (case (rator, args)
81              | (Op.IAdd, [a, b]) => CL.mkBinOp(a, CL.#+, b)             of (Op.IAdd, [a, b]) => CL.mkBinOp(a, CL.#+, b)
82              | (Op.ISub, [a, b]) => CL.mkBinOp(a, CL.#-, b)              | (Op.ISub, [a, b]) => CL.mkBinOp(a, CL.#-, b)
83              | (Op.IMul, [a, b]) => CL.mkBinOp(a, CL.#*, b)              | (Op.IMul, [a, b]) => CL.mkBinOp(a, CL.#*, b)
84              | (Op.IDiv, [a, b]) => CL.mkBinOp(a, CL.#/, b)              | (Op.IDiv, [a, b]) => CL.mkBinOp(a, CL.#/, b)
# Line 106  Line 89 
89              | (Op.RMul, [a, b]) => CL.mkBinOp(a, CL.#*, b)              | (Op.RMul, [a, b]) => CL.mkBinOp(a, CL.#*, b)
90              | (Op.RDiv, [a, b]) => CL.mkBinOp(a, CL.#/, b)              | (Op.RDiv, [a, b]) => CL.mkBinOp(a, CL.#/, b)
91              | (Op.RNeg, [a]) => CL.mkUnOp(CL.%-, a)              | (Op.RNeg, [a]) => CL.mkUnOp(CL.%-, a)
92              | (Op.RClamp, [a, b, c]) =>              | (Op.RClamp, [a, b, c]) => CL.mkApply("clamp", [a, b, c])
93              | (Op.RLerp, [a, b, c]) =>              | (Op.RLerp, [a, b, c]) => CL.mkApply("lerp", [a, b, c])
94              | (Op.LT ty, [a, b]) => CL.mkBinOp(a, CL.#<, b)              | (Op.LT ty, [a, b]) => CL.mkBinOp(a, CL.#<, b)
95              | (Op.LTE ty, [a, b]) => CL.mkBinOp(a, CL.#<=, b)              | (Op.LTE ty, [a, b]) => CL.mkBinOp(a, CL.#<=, b)
96              | (Op.EQ ty, [a, b]) => CL.mkBinOp(a, CL.#==, b)              | (Op.EQ ty, [a, b]) => CL.mkBinOp(a, CL.#==, b)
# Line 120  Line 103 
103              | (Op.Min ty, args) => mkStdApply("max", args)              | (Op.Min ty, args) => mkStdApply("max", args)
104              | (Op.VAdd d, [a, b]) => CL.mkBinOp(a, CL.#+, b)              | (Op.VAdd d, [a, b]) => CL.mkBinOp(a, CL.#+, b)
105              | (Op.VSub d, [a, b]) => CL.mkBinOp(a, CL.#-, b)              | (Op.VSub d, [a, b]) => CL.mkBinOp(a, CL.#-, b)
106              | (Op.VScale d, [a, b]) =>              | (Op.VScale d, [a, b]) => CL.mkApply("vscale", [a, b])
107              | (Op.VMul d, [a, b]) => CL.mkBinOp(a, CL.#*, b)              | (Op.VMul d, [a, b]) => CL.mkBinOp(a, CL.#*, b)
108              | (Op.VNeg d, [a]) => CL.mkUnOp(CL.%-, a)              | (Op.VNeg d, [a]) => CL.mkUnOp(CL.%-, a)
109              | (Op.VSum d, [a, b]) =>              | (Op.VSum d, [a]) => CL.mkApply("vsum", [a])
110              | (Op.VIndex(d, i), [a]) =>              | (Op.VIndex(d, i), [a]) => CL.mkSubscript(a, intExp i)
111              | (Op.VClamp d, [a, b, c]) =>              | (Op.VClamp d, [a, b, c]) => CL.mkApply("clamp", [a, b, c])
112              | (Op.VMapClamp d, [a, b, c]) =>              | (Op.VMapClamp d, [a, b, c]) => CL.mkApply("clamp", [a, b, c])
113              | (Op.VLerp d, [a, b, c]) =>              | (Op.VLerp d, [a, b, c]) => CL.mkApply("lerp", [a, b, c])
114              | (Op.TensorIndex(ty, idxs), [a]) =>              | (Op.TensorIndex(ty, idxs), [a]) => ??
115              | (Op.ProjectLast(ty, idxs), [a]) =>              | (Op.ProjectLast(ty, idxs), [a]) => ??
116              | (Op.EigenVecs2x2, []) =>              | (Op.EigenVals2x2, [a]) => ??
117              | (Op.EigenVecs3x3, []) =>              | (Op.EigenVals3x3, [a]) => ??
118              | (Op.EigenVals2x2, []) =>              | (Op.Zero ty, []) => ??
119              | (Op.EigenVals3x3, []) =>              | (Op.Select(ty, i), [a]) => ??
120              | (Op.Zero ty, []) =>              | (Op.Subscript ty, [a, b]) => ??
121              | (Op.Select(ty * int), []) =>              | (Op.MkDynamic(ty, i), [a]) => ??
122              | (Op.Subscript ty, []) =>              | (Op.Append ty, [a, b]) => ??
123              | (Op.MkDynamic(ty * int), []) =>              | (Op.Prepend ty, [a, b]) => ??
124              | (Op.Append ty, []) =>              | (Op.Concat ty, [a, b]) => ??
125              | (Op.Prepend ty, []) =>              | (Op.Range, [a, b]) => ??
126              | (Op.Concat ty, []) =>              | (Op.Length ty, [a]) => ??
127              | (Op.Range, []) =>              | (Op.SphereQuery(ty1, ty2), []) => ??
128              | (Op.Length ty, []) =>              | (Op.Sqrt, [a]) => mkStdApply("sqrt", [a])
129              | (Op.SphereQuery(ty * ty), []) =>              | (Op.Cos, [a]) => mkStdApply("cos", [a])
130              | (Op.Sqrt, []) =>              | (Op.ArcCos, [a]) => mkStdApply("acos", [a])
131              | (Op.Cos, []) =>              | (Op.Sin, [a]) => mkStdApply("sin", [a])
132              | (Op.ArcCos, []) =>              | (Op.ArcSin, [a]) => mkStdApply("asin", [a])
133              | (Op.Sin, []) =>              | (Op.Tan, [a]) => mkStdApply("tan", [a])
134              | (Op.ArcSin, []) =>              | (Op.ArcTan, [a]) => mkStdApply("atan", [a])
135              | (Op.Tan, []) =>              | (Op.Exp, [a]) => mkStdApply("exp", [a])
136              | (Op.ArcTan, []) =>              | (Op.Ceiling 1, [a]) => mkStdApply("ceil", [a])
137              | (Op.Exp, []) =>              | (Op.Ceiling d, [a]) => ??
138              | (Op.Ceiling d, []) =>              | (Op.Floor 1, [a]) => mkStdApply("floor", [a])
139              | (Op.Floor d, []) =>              | (Op.Floor d, [a]) => ??
140              | (Op.Round d, []) =>              | (Op.Round 1, [a]) => mkStdApply("round", [a])
141              | (Op.Trunc d, []) =>              | (Op.Round d, [a]) => ??
142              | (Op.IntToReal, []) =>              | (Op.Trunc 1, [a]) => mkStdApply("trunc", [a])
143              | (Op.RealToInt d, []) =>              | (Op.Trunc d, [a]) => ??
144                | (Op.IntToReal, [a]) => ??
145                | (Op.RealToInt 1, [a]) => ??
146                | (Op.RealToInt d, [a]) => ??
147  (*  (*
148              | R_All of ty              | R_All of ty
149              | R_Exists of ty              | R_Exists of ty
# Line 168  Line 154 
154              | R_Mean of ty              | R_Mean of ty
155              | R_Variance of ty              | R_Variance of ty
156  *)  *)
157              | (Op.Transform(ImageInfo.info * int), []) =>              | (Op.Transform info, [img]) => ??
158              | (Op.Translate(ImageInfo.info), []) =>              | (Op.Translate info, [img]) => ??
159              | (Op.BaseAddress(ImageInfo.info), []) =>              | (Op.BaseAddress info, [img]) => ??
160              | (Op.ControlIndex(ImageInfo.info * idxctl * int), []) =>              | (Op.ControlIndex(info, ctl, i), [a]) => ??
161              | (Op.Inside(ImageInfo.info * int), []) =>              | (Op.Inside(info, i), [pos, img]) => ??
162              | (Op.ImageDim(ImageInfo.info * int), []) =>              | (Op.ImageDim(info, i), [img]) => ??
163              | (Op.LoadSeq(ty * string), []) =>              | (Op.LoadSeq(ty, file), []) => ??
164              | (Op.LoadImage(ty * string), []) =>              | (Op.LoadImage(ty, file), []) => ??
165              | (Op.MathFn f, args) => CL.mkApply(??, args)              | (Op.MathFn f, args) => mkStdApply(MathFns.toString f, args)
166              | _ => raise Fail(concat[              | _ => raise Fail(concat[
167                     "unknown or incorrect operator ", Op.toString rator                     "unknown or incorrect operator ", Op.toString rator
168                   ])                   ])
# Line 184  Line 170 
170    
171      fun trExp (env, e) = (case e      fun trExp (env, e) = (case e
172             of IR.E_Global x => rvalueGlobalVar (env, x)             of IR.E_Global x => rvalueGlobalVar (env, x)
173              | IR.E_State x => rvalueStateVar (env, x)              | IR.E_State(NONE, x) => rvalueStateVar (env, x)
174                | IR.E_State(SOME e, x) => CL.mkIndirect(trExp(env, e), TreeStateVar.name x)
175              | IR.E_Var x => rvalueVar (env, x)              | IR.E_Var x => rvalueVar (env, x)
176              | IR.E_Lit(Literal.Int n) => CL.mkIntTy(n, !CTyN.gIntTy)              | IR.E_Lit(Literal.Int n) => CL.mkIntTy(n, !CTyN.gIntTy)
177              | IR.E_Lit(Literal.Bool b) => CL.mkBool b              | IR.E_Lit(Literal.Bool b) => CL.mkBool b
178              | IR.E_Lit(Literal.Float f) => CL.mkFlt(f, !CTyN.gRealTy)              | IR.E_Lit(Literal.Real f) => CL.mkFlt(f, !CTyN.gRealTy)
179              | IR.E_Lit(Literal.String s) => CL.mkStr s              | IR.E_Lit(Literal.String s) => CL.mkStr s
180              | IR.E_Op(rator, args) => trOp (rator, trExps(env, args))              | IR.E_Op(rator, args) => trOp (rator, trExps(env, args))
181              | IR.E_Apply(f, args) => trApply(f, trExps(env, args))              | IR.E_Vec(d, args) => ??
182              | IR.E_Cons(Ty.TensorTy[n], args) => CL.mkApply(MathN.mkVec n, trExps(env, args))              | IR.E_Cons(args, Ty.TensorTy shape) => ??
183              | IR.E_Cons(ty, _) => raise Fail(concat["E_Cons(", Ty.toString ty, ", _) in expression"])              | IR.E_Seq(args, ty) => ??
184                | IR.E_Pack(layout, args) => ??
185                | IR.E_VLoad(layout, e, i) => ??
186            (* end case *))            (* end case *))
187    
188      and trExps (env, exps) = List.map (fn exp => trExp(env, exp)) exps      and trExps (env, exps) = List.map (fn exp => trExp(env, exp)) exps
189    
190    (* translate a print expression *)  (* QUESTION: not sure that we need this function? *)
191      fun trPrint (env, tys, args) = let      fun trExpToVar (env, ty, name, exp) = (case trExp (env, exp)
192            val args = List.map (fn e => trExp(env, e)) args             of e as CL.E_Var _ => (e, [])
193                | e => let
194                    val x = freshName name
195            in            in
196              GenPrint.genPrintStm (CL.mkIndirect(CL.mkVar "wrld", "_output"), tys, args)                    (CL.mkVar x, pCL.mkDeclInit(ty, x, e))
197            end            end
198              (* end case *))
199    
200        fun trRHS mkStm (env, rhs) = (case rhs
201               of IR.E_Op(??, args) => ???
202                | IR.E_Cons(args, Ty.TensorTy shape) => ??
203                | IR.E_Seq(args, ty) => ??
204                | _ => mkStm (trExp (env, rhs)) (* generic case *)
205              (* end case *))
206    
207        fun trAssign (env, lhs, rhs) =
208              trRHS (fn rhs => CL.mkAssign(lhs, rhs)) (env, rhs)
209    
210      fun trLocals (env : env, locals) =      fun trDecl (env, ty, lhs, rhs) =
211            List.foldl            trRHS (fn rhs => CL.mkDeclInit(ty, lhs, rhs)) (env, rhs)
212              (fn (x, env) => VMap.insert(env, x, V(trType(V.ty x), V.name x)))  
213                env locals      fun trMultiAssign (env, lhs, IR.E_Op(rator, args)) = (case (lhs, rator, args)
214               of ([vals, vecs], Op.EigenVecs2x2, [m]) =>
215      fun trStms (env, stms) = let                  mkDiderotCall("eigenvecs", [trExp (env, exp), vals, vecs])
216            fun trStm (stm, (env, stms)) = (case stm              | ([vals, vecs], Op.EigenVecs3x3, [m]) =>
217                   of IR.S_Comment text => CL.mkComment text :: stms                  mkDiderotCall("eigenvecs", [trExp (env, exp), vals, vecs])
218                    | IR.S_Assign(isDecl, x, exp) => let              | _ => raise Fail "bogus multi-assignment"
219              (* end case *))
220          | trMultiAssign (env, lhs, rhs) = raise Fail "bogus multi-assignment"
221    
222        fun trStms (env, stms : TreeIR.stm list) = let
223              fun trStm (stm, (env, stms : CL.stm list)) = (case stm
224                     of IR.S_Comment text => (env, CL.mkComment text :: stms)
225                      | IR.S_Assign(true, x, exp) => let
226                          val (env, stm) = trDecl (env, ??, Env.lookup (env, x), exp)
227                          in
228                            (env, stm::stms)
229                          end
230                      | IR.S_Assign(false, x, exp) => let
231                        val (env, stm) = trAssign (env, lvalueVar (env, x), exp)                        val (env, stm) = trAssign (env, lvalueVar (env, x), exp)
232                        in                        in
233                          (env, stm::stms)                          (env, stm::stms)
234                        end                        end
235                    | IR.S_MAssign(xs, exp) =>                    | IR.S_MAssign(xs, exp) =>
236                        (env, trMultiAssign (env, List.map (fn x => lvalueVar (env, x)) xs, exp) :: stms)                        (env, trMultiAssign (env, List.map (fn x => lvalueVar (env, x)) xs, exp) @ stms)
237                    | IR.S_GAssign(x, exp) =>                    | IR.S_GAssign(x, exp) =>
238                        (env, trAssign (env, lvalueGlobalVar (env, x), exp) :: stms)                        (env, trAssign (env, lvalueGlobalVar (env, x), exp) :: stms)
239                    | IR.S_IfThen(cond, thenBlk) =>                    | IR.S_IfThen(cond, thenBlk) =>
240                        (env, CL.mkIfThen(trExp(env, cond), trBlk(env, thenBlk)) :: stms)                        (env, CL.mkIfThen(trExp(env, cond), trBlock(env, thenBlk)) :: stms)
241                    | IR.S_IfThenElse(cond, thenBlk, elseBlk) => let                    | IR.S_IfThenElse(cond, thenBlk, elseBlk) => let
242                        val stm = CL.mkIfThenElse(trExp(env, cond),                        val stm = CL.mkIfThenElse(trExp(env, cond),
243                              trBlk(env, thenBlk),                              trBlock(env, thenBlk),
244                              trBlk(env, elseBlk))                              trBlock(env, elseBlk))
245                        in                        in
246                          (env, stm :: stms)                          (env, stm :: stms)
247                        end                        end
# Line 235  Line 249 
249                    | IR.S_Foreach(x, e, blk) => ??                    | IR.S_Foreach(x, e, blk) => ??
250                    | IR.S_New(strand, args) => ??                    | IR.S_New(strand, args) => ??
251                    | IR.S_Save(x, exp) => trAssign (env, lvalueStateVar(env, x), exp)                    | IR.S_Save(x, exp) => trAssign (env, lvalueStateVar(env, x), exp)
252                    | IR.S_LoadNrrd(lhs, Ty.DynSeqTy ty, nrrd) =>                    | IR.S_LoadNrrd(lhs, Ty.SeqTy(ty, NONE), nrrd) =>
253                        [GenLoadNrrd.loadSeqFromFile (lvalueVar (env, lhs), ty, CL.mkStr nrrd)]                        (env, GenLoadNrrd.loadSeqFromFile (lvalueVar (env, lhs), ty, CL.mkStr nrrd) :: stms)
254                    | IR.S_LoadNrrd(lhs, Ty.ImageTy info, nrrd) =>                    | IR.S_LoadNrrd(lhs, Ty.ImageTy info, nrrd) =>
255                        [GenLoadNrrd.loadImage (lvalueVar (env, lhs), info, CL.mkStr nrrd)]                        (env, GenLoadNrrd.loadImage (lvalueVar (env, lhs), info, CL.mkStr nrrd) :: stms)
256                    | IR.S_Input(_, _, _, NONE) => []                    | IR.S_Input(_, _, _, NONE) => (env, stms)
257                    | IR.S_Input(gv, name, _, SOME dflt) => [                    | IR.S_Input(gv, name, _, SOME dflt) =>
258                          CL.mkAssign(lvalueGlobalVar (env, gv), trExp(env, dflt))                        (env, CL.mkAssign(lvalueGlobalVar (env, gv), trExp(env, dflt)) :: stms)
                       ]  
259                    | IR.S_InputNrrd _ => (env, stms)                    | IR.S_InputNrrd _ => (env, stms)
260                    | IR.S_Exit args => (env, stms)                    | IR.S_Exit => (env, stms)
261                    | IR.S_Print(tys, args) => ??                    | IR.S_Print(tys, args) => let
262                          val args = List.map (fn e => trExp(env, e)) args
263                          val stm = GenPrint.genPrintStm (
264                                CL.mkIndirect(CL.mkVar "wrld", "_output"),
265                                tys, args)
266                          in
267                            (env, stm::stms)
268                          end
269                    | IR.S_Active => (env, CL.mkReturn(SOME(CL.mkVar RN.kActive)) :: stms)                    | IR.S_Active => (env, CL.mkReturn(SOME(CL.mkVar RN.kActive)) :: stms)
270                    | IR.S_Stabilize => (env, CL.mkReturn(SOME(CL.mkVar RN.kStabilize)) :: stms)                    | IR.S_Stabilize => (env, CL.mkReturn(SOME(CL.mkVar RN.kStabilize)) :: stms)
271                    | IR.S_Die => (env, CL.mkReturn(SOME(CL.mkVar RN.kDie)) :: stms)                    | IR.S_Die => (env, CL.mkReturn(SOME(CL.mkVar RN.kDie)) :: stms)
# Line 255  Line 275 
275            end            end
276    
277      and trBlock (env, IR.Block{locals, body}) = let      and trBlock (env, IR.Block{locals, body}) = let
278            val env = trLocals (env, locals)            fun trLocal (x, (env, dcls)) = let
279            val stms = trStms (env, body)                  val x' = V.name x
280            fun mkDecl (x, stms) = (case VMap.find (env, x)                  in
281                   of SOME(V(ty, x')) => CL.mkDecl(ty, x', NONE) :: stms                    (Env.insert(env, x, x'), CL.mkDecl(ty, x', NONE) :: dcls)
282                    | NONE => raise Fail(concat["mkDecl(", V.name x, ", _)"])                  end
283                  (* end case *))            val (env, dcls) = List.foldl trLocal (env, []) (!locals)
           val stms = List.foldr mkDecl stms locals  
284            in            in
285              CL.mkBlock stms              CL.mkBlock (dcls @ trStms (env, body))
286            end            end
287    
288    end    end

Legend:
Removed from v.3869  
changed lines
  Added in v.3873

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0