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

SCM Repository

[diderot] Diff of /branches/vis12-cl/src/compiler/cl-target/tree-to-cl.sml
ViewVC logotype

Diff of /branches/vis12-cl/src/compiler/cl-target/tree-to-cl.sml

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

revision 3094, Wed Mar 18 04:45:43 2015 UTC revision 3095, Wed Mar 18 13:12:57 2015 UTC
# Line 26  Line 26 
26    end = struct    end = struct
27    
28      structure CL = CLang      structure CL = CLang
29      structure CLN = CLNames      structure N = OCLNames
30      structure IL = TreeIL      structure IL = TreeIL
31      structure Op = IL.Op      structure Op = IL.Op
32      structure Ty = IL.Ty      structure Ty = IL.Ty
# Line 95  Line 95 
95      fun vecIndex (v, ix) = CL.mkSelect(v, Vector.sub(fields, ix))      fun vecIndex (v, ix) = CL.mkSelect(v, Vector.sub(fields, ix))
96      end      end
97    
98      fun unionTy n = CL.T_Named(concat["union", Int.toString n, !RuntimeNames.gRealSuffix, "_t"])      fun unionTy n = CL.T_Named(concat["union", Int.toString n, !CNames.gRealSuffix, "_t"])
99    
100    (* matrix indexing *)    (* matrix indexing *)
101      fun matIndex (m, ix, jx) = CL.mkSelect(CL.mkSubscript(m, ix), concat["s",jx])      fun matIndex (m, ix, jx) = CL.mkSelect(CL.mkSubscript(m, ix), concat["s",jx])
# Line 113  Line 113 
113              | (Op.Div ty, [a, b]) => CL.mkBinOp(a, CL.#/, b)              | (Op.Div ty, [a, b]) => CL.mkBinOp(a, CL.#/, b)
114              | (Op.Neg ty, [a]) => CL.mkUnOp(CL.%-, a)              | (Op.Neg ty, [a]) => CL.mkUnOp(CL.%-, a)
115              | (Op.Abs(Ty.IntTy), args) => CL.mkApply("abs", args)              | (Op.Abs(Ty.IntTy), args) => CL.mkApply("abs", args)
116              | (Op.Abs(Ty.TensorTy[]), args) => CL.mkApply(CLN.fabs, args)              | (Op.Abs(Ty.TensorTy[]), args) => CL.mkApply(N.fabs, args)
117              | (Op.Abs(Ty.TensorTy[_]), args) => CL.mkApply(CLN.fabs, args)              | (Op.Abs(Ty.TensorTy[_]), args) => CL.mkApply(N.fabs, args)
118              | (Op.Abs ty, [a]) => raise Fail(concat["Abs<", Ty.toString ty, ">"])              | (Op.Abs ty, [a]) => raise Fail(concat["Abs<", Ty.toString ty, ">"])
119              | (Op.LT ty, [a, b]) => CL.mkBinOp(a, CL.#<, b)              | (Op.LT ty, [a, b]) => CL.mkBinOp(a, CL.#<, b)
120              | (Op.LTE ty, [a, b]) => CL.mkBinOp(a, CL.#<=, b)              | (Op.LTE ty, [a, b]) => CL.mkBinOp(a, CL.#<=, b)
# Line 123  Line 123 
123              | (Op.GTE ty, [a, b]) => CL.mkBinOp(a, CL.#>=, b)              | (Op.GTE ty, [a, b]) => CL.mkBinOp(a, CL.#>=, b)
124              | (Op.GT ty, [a, b]) => CL.mkBinOp(a, CL.#>, b)              | (Op.GT ty, [a, b]) => CL.mkBinOp(a, CL.#>, b)
125              | (Op.Not, [a]) => CL.mkUnOp(CL.%!, a)              | (Op.Not, [a]) => CL.mkUnOp(CL.%!, a)
126              | (Op.Max, args) => CL.mkApply(CLN.max, castArgs (!CLN.gRealTy) args)              | (Op.Max, args) => CL.mkApply(N.max, castArgs (!N.gRealTy) args)
127              | (Op.Min, args) => CL.mkApply(CLN.min, castArgs (!CLN.gRealTy) args)              | (Op.Min, args) => CL.mkApply(N.min, castArgs (!N.gRealTy) args)
128              | (Op.Clamp ty, [lo, hi, x]) => CL.mkApply(CLN.clamp, [x, lo, hi])              | (Op.Clamp ty, [lo, hi, x]) => CL.mkApply(N.clamp, [x, lo, hi])
129              | (Op.Lerp ty, args) => (case ty              | (Op.Lerp ty, args) => (case ty
130                   of Ty.TensorTy[] => CL.mkApply(CLN.lerp, castArgs (!CLN.gRealTy) args)                   of Ty.TensorTy[] => CL.mkApply(N.lerp, castArgs (!N.gRealTy) args)
131                    | Ty.TensorTy[n] => CL.mkApply(CLN.lerp, castArgs (CL.T_Named(CLN.vecTy n)) args)                    | Ty.TensorTy[n] => CL.mkApply(N.lerp, castArgs (N.vecTy n) args)
132                    | _ => raise Fail(concat[                    | _ => raise Fail(concat[
133                      "lerp<", Ty.toString ty, "> not supported"                      "lerp<", Ty.toString ty, "> not supported"
134                        ])                        ])
135                  (* end case *))                  (* end case *))
136              | (Op.Dot d, args) => CL.mkApply(CLN.dot, args)              | (Op.Dot d, args) => CL.mkApply(N.dot, args)
137              | (Op.MulVecMat(m, n), args) =>              | (Op.MulVecMat(m, n), args) =>
138                  if (1 < m) andalso (m < 4) andalso (m = n)                  if (1 < m) andalso (m < 4) andalso (m = n)
139                    then CL.mkApply(CLN.mulVecMat(m,n), args)                    then CL.mkApply(N.mulVecMat(m,n), args)
140                    else raise Fail "unsupported vector-matrix multiply"                    else raise Fail "unsupported vector-matrix multiply"
141              | (Op.MulMatVec(m, n), args) =>              | (Op.MulMatVec(m, n), args) =>
142                  if (1 < m) andalso (m < 4) andalso (m = n)                  if (1 < m) andalso (m < 4) andalso (m = n)
143                    then CL.mkApply(CLN.mulMatVec(m,n), args)                    then CL.mkApply(N.mulMatVec(m,n), args)
144                    else raise Fail "unsupported matrix-vector multiply"                    else raise Fail "unsupported matrix-vector multiply"
145              | (Op.MulMatMat(m, n, p), args) =>              | (Op.MulMatMat(m, n, p), args) =>
146                  if (1 < m) andalso (m < 4) andalso (m = n) andalso (n = p)                  if (1 < m) andalso (m < 4) andalso (m = n) andalso (n = p)
147                    then CL.mkApply(CLN.mulMatMat(m,n,p), args)                    then CL.mkApply(N.mulMatMat(m,n,p), args)
148                    else raise Fail "unsupported matrix-matrix multiply"                    else raise Fail "unsupported matrix-matrix multiply"
149              | (Op.Cross, args) => CL.mkApply(CLN.cross, args)              | (Op.Cross, args) => CL.mkApply(N.cross, args)
150              | (Op.Norm(Ty.TensorTy[n]), args) => CL.mkApply(CLN.length, args)              | (Op.Norm(Ty.TensorTy[n]), args) => CL.mkApply(N.length, args)
151              | (Op.Norm(Ty.TensorTy[m,n]), args) => CL.mkApply(CLN.norm(m,n), args)              | (Op.Norm(Ty.TensorTy[m,n]), args) => CL.mkApply(N.normMat(m,n), args)
152              | (Op.Normalize d, args) => CL.mkApply(CLN.normalize, args)              | (Op.Normalize d, args) => CL.mkApply(N.normalize, args)
153              | (Op.Scale(Ty.TensorTy[n]), [s, v]) => CL.mkBinOp(s, CL.#*, v)              | (Op.Scale(Ty.TensorTy[n]), [s, v]) => CL.mkBinOp(s, CL.#*, v)
154              | (Op.PrincipleEvec ty, _) => raise Fail "PrincipleEvec unimplemented"              | (Op.PrincipleEvec ty, _) => raise Fail "PrincipleEvec unimplemented"
155              | (Op.Select(Ty.TupleTy tys, i), [a]) => raise Fail "Select unimplemented"              | (Op.Select(Ty.TupleTy tys, i), [a]) => raise Fail "Select unimplemented"
# Line 181  Line 181 
181              | (Op.Floor d, args) => CL.mkApply("floor", args)              | (Op.Floor d, args) => CL.mkApply("floor", args)
182              | (Op.Round d, args) => CL.mkApply("round", args)              | (Op.Round d, args) => CL.mkApply("round", args)
183              | (Op.Trunc d, args) => CL.mkApply("trunc", args)              | (Op.Trunc d, args) => CL.mkApply("trunc", args)
184              | (Op.IntToReal, [a]) => CL.mkCast(!CLN.gRealTy, a)              | (Op.IntToReal, [a]) => CL.mkCast(!N.gRealTy, a)
185              | (Op.RealToInt 1, [a]) => CL.mkCast(!CLN.gIntTy, a)              | (Op.RealToInt 1, [a]) => CL.mkCast(!N.gIntTy, a)
186              | (Op.RealToInt d, args) => CL.mkApply(CLN.vecftoi d, args)              | (Op.RealToInt d, args) => CL.mkApply(N.vecftoi d, args)
187              | (Op.ImageAddress info, [a]) => let              | (Op.ImageAddress info, [a]) => let
188                  val cTy = CL.T_Ptr(CL.T_Num(ImageInfo.sampleTy info))                  val cTy = CL.T_Ptr(CL.T_Num(ImageInfo.sampleTy info))
189                  in                  in
190                    CL.mkCast(cTy, CL.mkSelect(a, "data"))                    CL.mkCast(cTy, CL.mkSelect(a, "data"))
191                  end                  end
192              | (Op.LoadVoxels(info, 1), [a]) => let              | (Op.LoadVoxels(info, 1), [a]) => let
193                  val realTy as CL.T_Num rTy = !CLN.gRealTy                  val realTy as CL.T_Num rTy = !N.gRealTy
194                  val a = CL.mkUnOp(CL.%*, a)                  val a = CL.mkUnOp(CL.%*, a)
195                  in                  in
196                    if (rTy = ImageInfo.sampleTy info)                    if (rTy = ImageInfo.sampleTy info)
# Line 200  Line 200 
200              | (Op.LoadVoxels _, [a]) =>              | (Op.LoadVoxels _, [a]) =>
201                  raise Fail("impossible " ^ Op.toString rator)                  raise Fail("impossible " ^ Op.toString rator)
202              | (Op.PosToImgSpace info, [img, pos]) =>              | (Op.PosToImgSpace info, [img, pos]) =>
203                  CL.mkApply(CLN.toImageSpace(ImageInfo.dim info), [CL.mkUnOp(CL.%&,img), pos])                  CL.mkApply(N.toImageSpace(ImageInfo.dim info), [CL.mkUnOp(CL.%&,img), pos])
204              | (Op.TensorToWorldSpace(info, ty), [v, x]) =>              | (Op.TensorToWorldSpace(info, ty), [v, x]) =>
205                  CL.mkApply(CLN.toWorldSpace ty, [CL.mkUnOp(CL.%&,v), x])                  CL.mkApply(N.toWorldSpace ty, [CL.mkUnOp(CL.%&,v), x])
206              | (Op.Inside(info, s), [pos, img]) =>              | (Op.Inside(info, s), [pos, img]) =>
207                  CL.mkApply(CLN.inside(ImageInfo.dim info), [pos, CL.mkUnOp(CL.%&,img), intExp s])                  CL.mkApply(N.inside(ImageInfo.dim info), [pos, CL.mkUnOp(CL.%&,img), intExp s])
208              | (Op.Input _, []) => raise Fail("impossible " ^ Op.toString rator)              | (Op.Input _, []) => raise Fail("impossible " ^ Op.toString rator)
209              | _ => raise Fail(concat[              | _ => raise Fail(concat[
210                "unknown or incorrect operator ", Op.toString rator                "unknown or incorrect operator ", Op.toString rator
# Line 215  Line 215 
215             of IL.E_Global x => rvalueGlobalVar (env, x)             of IL.E_Global x => rvalueGlobalVar (env, x)
216              | IL.E_State x => rvalueStateVar (env, x)              | IL.E_State x => rvalueStateVar (env, x)
217              | IL.E_Var x => rvalueVar (env, x)              | IL.E_Var x => rvalueVar (env, x)
218              | IL.E_Lit(Literal.Int n) => CL.mkIntTy(n, !CLN.gIntTy)              | IL.E_Lit(Literal.Int n) => CL.mkIntTy(n, !N.gIntTy)
219              | IL.E_Lit(Literal.Bool b) => CL.mkBool b              | IL.E_Lit(Literal.Bool b) => CL.mkBool b
220              | IL.E_Lit(Literal.Float f) => CL.mkFlt(f, !CLN.gRealTy)              | IL.E_Lit(Literal.Float f) => CL.mkFlt(f, !N.gRealTy)
221              | IL.E_Lit(Literal.String s) => CL.mkStr s              | IL.E_Lit(Literal.String s) => CL.mkStr s
222              | IL.E_Op(rator, args) => trOp (rator, trExps(env, args))              | IL.E_Op(rator, args) => trOp (rator, trExps(env, args))
223              | IL.E_Apply(f, args) => trApply(f, trExps(env, args))              | IL.E_Apply(f, args) => trApply(f, trExps(env, args))
224              | IL.E_Cons(Ty.TensorTy[n], args) => CL.mkApply(CLN.mkVec n, trExps(env, args))              | IL.E_Cons(Ty.TensorTy[n], args) => CL.mkVec(N.vecTy n, trExps(env, args))
225              | IL.E_Cons(ty, _) => raise Fail(concat["E_Cons(", Ty.toString ty, ", _) in expression"])              | IL.E_Cons(ty, _) => raise Fail(concat["E_Cons(", Ty.toString ty, ", _) in expression"])
226            (* end case *))            (* end case *))
227    
# Line 245  Line 245 
245           *)           *)
246            case rhs            case rhs
247             of IL.E_Op(Op.Add(Ty.TensorTy[m,n]), args) =>             of IL.E_Op(Op.Add(Ty.TensorTy[m,n]), args) =>
248                  [CL.mkCall(CLN.addMat(m,n),  lhs :: trExps(env, args))]                  [CL.mkCall(N.addMat(m,n),  lhs :: trExps(env, args))]
249              | IL.E_Op(Op.Sub(Ty.TensorTy[m,n]), args) =>              | IL.E_Op(Op.Sub(Ty.TensorTy[m,n]), args) =>
250                  [CL.mkCall(CLN.subMat(m,n),  lhs :: trExps(env, args))]                  [CL.mkCall(N.subMat(m,n),  lhs :: trExps(env, args))]
251              | IL.E_Op(Op.Neg(Ty.TensorTy[m,n]), args) =>              | IL.E_Op(Op.Neg(Ty.TensorTy[m,n]), args) =>
252                  [CL.mkCall(CLN.scaleMat(m,n),  lhs :: intExp ~1 :: trExps(env, args))]                  [CL.mkCall(N.scaleMat(m,n),  lhs :: intExp ~1 :: trExps(env, args))]
253              | IL.E_Op(Op.Scale(Ty.TensorTy[m,n]), args) =>              | IL.E_Op(Op.Scale(Ty.TensorTy[m,n]), args) =>
254                  [CL.mkCall(CLN.scaleMat(m,n),  lhs :: trExps(env, args))]                  [CL.mkCall(N.scaleMat(m,n),  lhs :: trExps(env, args))]
255              | IL.E_Op(Op.MulMatMat(m,n,p), args) =>              | IL.E_Op(Op.MulMatMat(m,n,p), args) =>
256                  [CL.mkCall(CLN.mulMatMat(m,n,p), lhs :: trExps(env, args))]                  [CL.mkCall(N.mulMatMat(m,n,p), lhs :: trExps(env, args))]
257              | IL.E_Op(Op.Identity n, args) =>              | IL.E_Op(Op.Identity n, args) =>
258                  [CL.mkCall(CLN.identityMat n, [lhs])]                  [CL.mkCall(N.identityMat n, [lhs])]
259              | IL.E_Op(Op.Zero(Ty.TensorTy[m,n]), args) =>              | IL.E_Op(Op.Zero(Ty.TensorTy[m,n]), args) =>
260                  [CL.mkCall(CLN.zeroMat(m,n), [lhs])]                  [CL.mkCall(N.zeroMat(m,n), [lhs])]
261              | IL.E_Op(Op.TensorToWorldSpace(info, ty as Ty.TensorTy[_,_]), [img,src]) =>              | IL.E_Op(Op.TensorToWorldSpace(info, ty as Ty.TensorTy[_,_]), [img,src]) =>
262                  [CL.mkCall(CLN.toWorldSpace ty, lhs :: [CL.mkUnOp(CL.%&,trExp(env, img)),trExp(env, src)] )]                  [CL.mkCall(N.toWorldSpace ty, lhs :: [CL.mkUnOp(CL.%&,trExp(env, img)),trExp(env, src)] )]
263              | IL.E_Op(Op.LoadVoxels(info, n), [a]) =>              | IL.E_Op(Op.LoadVoxels(info, n), [a]) =>
264                  if (n > 1)                  if (n > 1)
265                    then let                    then let
266                      val stride = ImageInfo.stride info                      val stride = ImageInfo.stride info
267                      val rTy = ImageInfo.sampleTy info                      val rTy = ImageInfo.sampleTy info
268                      val vp = freshVar "vp"                      val vp = freshVar "vp"
269                      val needsCast = (CL.T_Num rTy <> !CLN.gRealTy)                      val needsCast = (CL.T_Num rTy <> !N.gRealTy)
270                      fun mkLoad i = let                      fun mkLoad i = let
271                            val e = CL.mkSubscript(CL.mkVar vp, intExp(i*stride))                            val e = CL.mkSubscript(CL.mkVar vp, intExp(i*stride))
272                            in                            in
273                              if needsCast then CL.mkCast(!CLN.gRealTy, e) else e                              if needsCast then CL.mkCast(!N.gRealTy, e) else e
274                            end                            end
275                      in [                      in [
276                        CL.mkDeclInit(CLTyTranslate.imageDataPtrTy info, vp, trExp(env, a)),                        CL.mkDeclInit(CLTyTranslate.imageDataPtrTy info, vp, trExp(env, a)),
277                        CL.mkAssign(lhs,                        CL.mkAssign(lhs,
278                        CL.mkApply(CLN.mkVec n, List.tabulate (n, mkLoad)))                          CL.mkVec(N.vecTy n, List.tabulate (n, mkLoad)))
279                      ] end                      ] end
280                  else [CL.mkAssign(lhs, trExp(env, rhs))]                  else [CL.mkAssign(lhs, trExp(env, rhs))]
281              | IL.E_Op(Op.EigenVals2x2, [m]) => let              | IL.E_Op(Op.EigenVals2x2, [m]) => let
282                  val (m, stms) = expToVar (env, CL.T_Named(CLN.matTy(2,2)), "m", m)                  val (m, stms) = expToVar (env, N.matTy(2,2), "m", m)
283                  in                  in
284                    stms @ [CL.mkCall(CLN.evals2x2, [                    stms @ [CL.mkCall(N.evals2x2, [
285                        CL.mkUnOp(CL.%&,lhs),                        CL.mkUnOp(CL.%&,lhs),
286                        matIndex (m, CL.mkInt 0,  "0"),                        matIndex (m, CL.mkInt 0,  "0"),
287                        matIndex (m, CL.mkInt 0, "1"),                        matIndex (m, CL.mkInt 0, "1"),
# Line 289  Line 289 
289                      ])]                      ])]
290                  end                  end
291              | IL.E_Op(Op.EigenVals3x3, [m]) => let              | IL.E_Op(Op.EigenVals3x3, [m]) => let
292                  val (m, stms) = expToVar (env, CL.T_Named(CLN.matTy(3,3)), "m", m)                  val (m, stms) = expToVar (env, N.matTy(3,3), "m", m)
293                  in                  in
294                    stms @ [CL.mkCall(CLN.evals3x3, [                    stms @ [CL.mkCall(N.evals3x3, [
295                        CL.mkUnOp(CL.%&,lhs),                        CL.mkUnOp(CL.%&,lhs),
296                        matIndex (m, CL.mkInt 0, "0"),                        matIndex (m, CL.mkInt 0, "0"),
297                        matIndex (m, CL.mkInt 0, "1"),                        matIndex (m, CL.mkInt 0, "1"),
# Line 312  Line 312 
312                    doRows (0, trExps(env, args))                    doRows (0, trExps(env, args))
313                  end                  end
314              | IL.E_Var x => (case IL.Var.ty x              | IL.E_Var x => (case IL.Var.ty x
315                   of Ty.TensorTy[n,m] => [CL.mkCall(CLN.copyMat(n,m), [lhs, rvalueVar(env, x)])]                   of Ty.TensorTy[n,m] => [CL.mkCall(N.copyMat(n,m), [lhs, rvalueVar(env, x)])]
316                    | _ => [CL.mkAssign(lhs, rvalueVar(env, x))]                    | _ => [CL.mkAssign(lhs, rvalueVar(env, x))]
317                  (* end case *))                  (* end case *))
318              | _ => [CL.mkAssign(lhs, trExp(env, rhs))]              | _ => [CL.mkAssign(lhs, trExp(env, rhs))]
# Line 320  Line 320 
320    
321      fun trMultiAssign (env, lhs, IL.E_Op(rator, args)) = (case (lhs, rator, args)      fun trMultiAssign (env, lhs, IL.E_Op(rator, args)) = (case (lhs, rator, args)
322             of ([vals, vecs], Op.EigenVecs2x2, [m]) => let             of ([vals, vecs], Op.EigenVecs2x2, [m]) => let
323                  val (m, stms) = expToVar (env, CL.T_Named(CLN.matTy(2,2)), "m", m)                  val (m, stms) = expToVar (env, N.matTy(2,2), "m", m)
324                  in                  in
325                    stms @ [CL.mkCall(CLN.evecs2x2, [                    stms @ [CL.mkCall(N.evecs2x2, [
326                        CL.mkUnOp(CL.%&,vals), vecs,                        CL.mkUnOp(CL.%&,vals), vecs,
327                        matIndex (m, CL.mkInt 0, "0"),                        matIndex (m, CL.mkInt 0, "0"),
328                        matIndex (m, CL.mkInt 0, "1"),                        matIndex (m, CL.mkInt 0, "1"),
# Line 330  Line 330 
330                      ])]                      ])]
331                  end                  end
332              | ([vals, vecs], Op.EigenVecs3x3, [m]) => let              | ([vals, vecs], Op.EigenVecs3x3, [m]) => let
333                  val (m, stms) = expToVar (env, CL.T_Named(CLN.matTy(3,3)), "m", m)                  val (m, stms) = expToVar (env, N.matTy(3,3), "m", m)
334                  in                  in
335                    stms @ [CL.mkCall(CLN.evecs3x3, [                    stms @ [CL.mkCall(N.evecs3x3, [
336                        CL.mkUnOp(CL.%&,vals), vecs,                        CL.mkUnOp(CL.%&,vals), vecs,
337                        matIndex (m, CL.mkInt 0, "0"),                        matIndex (m, CL.mkInt 0, "0"),
338                        matIndex (m, CL.mkInt 0, "1"),                        matIndex (m, CL.mkInt 0, "1"),
# Line 372  Line 372 
372                    | IL.S_Input _ => raise Fail "impossible S_Input in OpenCL"                    | IL.S_Input _ => raise Fail "impossible S_Input in OpenCL"
373                    | IL.S_InputNrrd _ => raise Fail "impossible S_InputNrrd in OpenCL"                    | IL.S_InputNrrd _ => raise Fail "impossible S_InputNrrd in OpenCL"
374                    | IL.S_Exit args => []                    | IL.S_Exit args => []
375                    | IL.S_Active => [CL.mkReturn(SOME(CL.mkVar CLN.kActive))]                    | IL.S_Active => [CL.mkReturn(SOME(CL.mkVar N.kActive))]
376                    | IL.S_Stabilize => [CL.mkReturn(SOME(CL.mkVar CLN.kStabilize))]                    | IL.S_Stabilize => [CL.mkReturn(SOME(CL.mkVar N.kStabilize))]
377                    | IL.S_Die => [CL.mkReturn(SOME(CL.mkVar CLN.kDie))]                    | IL.S_Die => [CL.mkReturn(SOME(CL.mkVar N.kDie))]
378                  (* end case *))                  (* end case *))
379            in            in
380              List.foldr (fn (stm, stms) => trStmt(env, stm)@stms) [] stms              List.foldr (fn (stm, stms) => trStmt(env, stm)@stms) [] stms

Legend:
Removed from v.3094  
changed lines
  Added in v.3095

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