Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Diff of /sml/branches/primop-branch-2/src/compiler/FLINT/trans/translate.sml
ViewVC logotype

Diff of /sml/branches/primop-branch-2/src/compiler/FLINT/trans/translate.sml

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

revision 587, Thu Mar 30 09:01:52 2000 UTC revision 1183, Fri Mar 29 19:09:48 2002 UTC
# Line 5  Line 5 
5  sig  sig
6    
7    (* Invariant: transDec always applies to a top-level absyn declaration *)    (* Invariant: transDec always applies to a top-level absyn declaration *)
8    val transDec : Absyn.dec * Access.lvar list    val transDec : { rootdec: Absyn.dec,
9                   * StaticEnv.staticEnv * CompBasic.compInfo                     exportLvars: Access.lvar list,
10                       env: StaticEnv.staticEnv,
11                       cproto_conv: string,
12                       compInfo: Absyn.dec CompInfo.compInfo }
13                   -> {flint: FLINT.prog,                   -> {flint: FLINT.prog,
14                       imports: (PersStamps.persstamp                       imports: (PersStamps.persstamp
15                                 * CompBasic.importTree) list}                                 * ImportTree.importTree) list}
16    
17  end (* signature TRANSLATE *)  end (* signature TRANSLATE *)
18    
# Line 21  Line 24 
24        structure DA = Access        structure DA = Access
25        structure DI = DebIndex        structure DI = DebIndex
26        structure EM = ErrorMsg        structure EM = ErrorMsg
       structure CB = CompBasic  
27        structure II = InlInfo        structure II = InlInfo
28        structure LT = PLambdaType        structure LT = PLambdaType
29        structure M  = Modules        structure M  = Modules
# Line 65  Line 67 
67  (** old-style fold for cases where it is partially applied *)  (** old-style fold for cases where it is partially applied *)
68  fun fold f l init = foldr f init l  fun fold f l init = foldr f init l
69    
 (*  
  * MAJOR CLEANUP REQUIRED ! The function mkv is currently directly taken  
  * from the LambdaVar module; I think it should be taken from the  
  * "compInfo". Similarly, should we replace all mkLvar in the backend  
  * with the mkv in "compInfo" ? (ZHONG)  
  *)  
 val mkv = LambdaVar.mkLvar  
 fun mkvN NONE = mkv()  
   | mkvN (SOME s) = LambdaVar.namedLvar s  
   
70  (** sorting the record fields for record types and record expressions *)  (** sorting the record fields for record types and record expressions *)
71  fun elemgtr ((LABEL{number=x,...},_),(LABEL{number=y,...},_)) = (x>y)  fun elemgtr ((LABEL{number=x,...},_),(LABEL{number=y,...},_)) = (x>y)
72  fun sorted x = ListMergeSort.sorted elemgtr x  fun sorted x = ListMergeSort.sorted elemgtr x
# Line 95  Line 87 
87   *                 * StaticEnv.staticEnv * CompBasic.compInfo               *   *                 * StaticEnv.staticEnv * CompBasic.compInfo               *
88   *                 -> {flint: FLINT.prog,                                   *   *                 -> {flint: FLINT.prog,                                   *
89   *                     imports: (PersStamps.persstamp                       *   *                     imports: (PersStamps.persstamp                       *
90   *                               * CompBasic.importTree) list}              *   *                               * ImportTree.importTree) list}             *
91   ****************************************************************************)   ****************************************************************************)
92    
93  fun transDec (rootdec, exportLvars, env,  fun transDec
94                compInfo as {coreEnv,errorMatch,error,...}: CB.compInfo) =          { rootdec, exportLvars, env, cproto_conv,
95             compInfo as {errorMatch,error,...}: Absyn.dec CompInfo.compInfo } =
96  let  let
97    
98    (* We take mkLvar from compInfo.  This should answer Zhong's question... *)
99    (*
100    (*
101     * MAJOR CLEANUP REQUIRED ! The function mkv is currently directly taken
102     * from the LambdaVar module; I think it should be taken from the
103     * "compInfo". Similarly, should we replace all mkLvar in the backend
104     * with the mkv in "compInfo" ? (ZHONG)
105     *)
106    val mkv = LambdaVar.mkLvar
107    fun mkvN NONE = mkv()
108      | mkvN (SOME s) = LambdaVar.namedLvar s
109    *)
110    
111    val mkvN = #mkLvar compInfo
112    fun mkv () = mkvN NONE
113    
114  (** generate the set of ML-to-FLINT type translation functions *)  (** generate the set of ML-to-FLINT type translation functions *)
115  val {tpsKnd, tpsTyc, toTyc, toLty, strLty, fctLty} = TT.genTT()  val {tpsKnd, tpsTyc, toTyc, toLty, strLty, fctLty, markLBOUND} =
116        TT.genTT()
117  fun toTcLt d = (toTyc d, toLty d)  fun toTcLt d = (toTyc d, toLty d)
118    
119  (** translating the typ field in DATACON into lty; constant datacons  (** translating the typ field in DATACON into lty; constant datacons
# Line 120  Line 130 
130    
131  (** the special lookup functions for the Core environment *)  (** the special lookup functions for the Core environment *)
132  fun coreLookup(id, env) =  fun coreLookup(id, env) =
133    let val sp = SymPath.SPATH [S.strSymbol "Core", S.varSymbol id]    let val sp = SymPath.SPATH [CoreSym.coreSym, S.varSymbol id]
134        val err = fn _ => fn _ => fn _ => raise NoCore        val err = fn _ => fn _ => fn _ => raise NoCore
135     in Lookup.lookVal(env, sp, err)     in Lookup.lookVal(env, sp, err)
136    end    end
# Line 174  Line 184 
184    
185  (** hashkey of accesspath + accesspath + resvar *)  (** hashkey of accesspath + accesspath + resvar *)
186  type info = (key * int list * lvar)  type info = (key * int list * lvar)
187  val hashtable : info list Intmap.intmap = Intmap.new(32,HASHTABLE)  val hashtable : info list IntHashTable.hash_table =
188        IntHashTable.mkTable(32,HASHTABLE)
189  fun hashkey l = foldr (fn (x,y) => ((x * 10 + y) mod 1019)) 0 l  fun hashkey l = foldr (fn (x,y) => ((x * 10 + y) mod 1019)) 0 l
190    
191  fun buildHdr v =  fun buildHdr v =
192    let val info = Intmap.map hashtable v    let val info = IntHashTable.lookup hashtable v
193        fun h((_, l, w), hdr) =        fun h((_, l, w), hdr) =
194               let val le = foldl (fn (k,e) => SELECT(k,e)) (VAR v) l               let val le = foldl (fn (k,e) => SELECT(k,e)) (VAR v) l
195                in fn e => hdr(LET(w, le, e))                in fn e => hdr(LET(w, le, e))
# Line 188  Line 199 
199    
200  fun bindvar (v, [], _) =  v  fun bindvar (v, [], _) =  v
201    | bindvar (v, l, nameOp) =    | bindvar (v, l, nameOp) =
202        let val info = (Intmap.map hashtable v) handle _ => []        let val info = (IntHashTable.lookup hashtable v) handle _ => []
203            val key = hashkey l            val key = hashkey l
204            fun h [] =            fun h [] =
205                  let val u = mkvN nameOp                  let val u = mkvN nameOp
206                   in Intmap.add hashtable (v,(key,l,u)::info); u                   in IntHashTable.insert hashtable (v,(key,l,u)::info); u
207                  end                  end
208              | h((k',l',w)::r) =              | h((k',l',w)::r) =
209                  if (k' = key) then (if (l'=l) then w else h r) else h r                  if (k' = key) then (if (l'=l) then w else h r) else h r
# Line 281  Line 292 
292   * clean up this is to put all the core constructors and primitives into   * clean up this is to put all the core constructors and primitives into
293   * the primitive environment. (ZHONG)   * the primitive environment. (ZHONG)
294   *)   *)
295    exception NoCore
296    
297  fun coreExn id =  fun coreExn id =
298    ((case coreLookup(id, coreEnv)      (case CoreAccess.getCon' (fn () => raise NoCore) (env, id) of
299       of V.CON(TP.DATACON{name, rep as DA.EXN _, typ, ...}) =>           TP.DATACON { name, rep as DA.EXN _, typ, ... } =>
300            let val nt = toDconLty DI.top typ            let val nt = toDconLty DI.top typ
301                val nrep = mkRep(rep, nt, name)                val nrep = mkRep(rep, nt, name)
302             in CON'((name, nrep, nt), [], unitLexp)             in CON'((name, nrep, nt), [], unitLexp)
303            end            end
304        | _ => bug "coreExn in translate")        | _ => bug "coreExn in translate")
305     handle NoCore => (say "WARNING: no Core access \n"; INT 0))      handle NoCore => (say "WARNING: no Core access\n"; INT 0)
306    
307  and coreAcc id =  and coreAcc id =
308    ((case coreLookup(id, coreEnv)      (case CoreAccess.getVar' (fn () => raise NoCore) (env, id) of
309       of V.VAL(V.VALvar{access, typ, path, ...}) =>           V.VALvar { access, typ, path, ... } =>
310             mkAccT(access, toLty DI.top (!typ), getNameOp path)             mkAccT(access, toLty DI.top (!typ), getNameOp path)
311        | _ => bug "coreAcc in translate")        | _ => bug "coreAcc in translate")
312     handle NoCore => (say "WARNING: no Core access \n"; INT 0))      handle NoCore => (say "WARNING: no Core access\n"; INT 0)
   
313    
314  (** expands the flex record pattern and convert the EXN access pat *)  (** expands the flex record pattern and convert the EXN access pat *)
315  (** internalize the conrep's access, always exceptions *)  (** internalize the conrep's access, always exceptions *)
# Line 432  Line 444 
444     in FN(v, argt, COND(APP(eq, VAR v), falseLexp, trueLexp))     in FN(v, argt, COND(APP(eq, VAR v), falseLexp, trueLexp))
445    end    end
446    
 fun intOp p = PRIM(p, lt_intop, [])  
447  fun cmpOp p = PRIM(p, lt_icmp, [])  fun cmpOp p = PRIM(p, lt_icmp, [])
448  fun inegOp p = PRIM(p, lt_ineg, [])  fun inegOp p = PRIM(p, lt_ineg, [])
449    
 fun ADD(b,c) = APP(intOp(PO.IADD), RECORD[b, c])  
 fun SUB(b,c) = APP(intOp(PO.ISUB), RECORD[b, c])  
 fun MUL(b,c) = APP(intOp(PO.IMUL), RECORD[b, c])  
 fun DIV(b,c) = APP(intOp(PO.IDIV), RECORD[b, c])  
450  val LESSU = PO.CMP{oper=PO.LTU, kind=PO.UINT 31}  val LESSU = PO.CMP{oper=PO.LTU, kind=PO.UINT 31}
451    
452  val lt_len = LT.ltc_poly([LT.tkc_mono], [lt_arw(LT.ltc_tv 0, lt_int)])  val lt_len = LT.ltc_poly([LT.tkc_mono], [lt_arw(LT.ltc_tv 0, lt_int)])
# Line 489  Line 496 
496                            RECORD [vw, vcnt])))))                            RECORD [vw, vcnt])))))
497    end    end
498    
499    fun inlops nk = let
500        val (lt_arg, zero, overflow) =
501            case nk of
502                PO.INT 31 => (LT.ltc_int, INT 0, true)
503              | PO.UINT 31 => (LT.ltc_int, WORD 0w0, false)
504              | PO.INT 32 => (LT.ltc_int32, INT32 0, true)
505              | PO.UINT 32 => (LT.ltc_int32, WORD32 0w0, false)
506              | PO.FLOAT 64 => (LT.ltc_real, REAL "0.0", false)
507              | _ => bug "inlops: bad numkind"
508        val lt_argpair = lt_tup [lt_arg, lt_arg]
509        val lt_cmp = lt_arw (lt_argpair, lt_bool)
510        val lt_neg = lt_arw (lt_arg, lt_arg)
511        val less = PRIM (PO.CMP { oper = PO.<, kind = nk }, lt_cmp, [])
512        val greater = PRIM (PO.CMP { oper = PO.>, kind = nk }, lt_cmp, [])
513        val negate =
514            PRIM (PO.ARITH { oper = PO.~, overflow = overflow, kind = nk },
515                  lt_neg, [])
516    in
517        { lt_arg = lt_arg, lt_argpair = lt_argpair, lt_cmp = lt_cmp,
518          less = less, greater = greater,
519          zero = zero, negate = negate }
520    end
521    
522    fun inlminmax (nk, ismax) = let
523        val { lt_argpair, less, greater, lt_cmp, ... } = inlops nk
524        val x = mkv () and y = mkv () and z = mkv ()
525        val cmpop = if ismax then greater else less
526        val elsebranch =
527            case nk of
528                PO.FLOAT _ => let
529                    (* testing for NaN *)
530                    val fequal =
531                        PRIM (PO.CMP { oper = PO.EQL, kind = nk }, lt_cmp, [])
532                in
533                    COND (APP (fequal, RECORD [VAR y, VAR y]), VAR x, VAR y)
534                end
535              | _ => VAR y
536    in
537        FN (z, lt_argpair,
538            LET (x, SELECT (0, VAR z),
539                 LET (y, SELECT (1, VAR z),
540                      COND (APP (cmpop, RECORD [VAR x, VAR y]),
541                            VAR x, elsebranch))))
542    end
543    
544    fun inlabs nk = let
545        val { lt_arg, greater, zero, negate, ... } = inlops nk
546        val x = mkv ()
547    in
548        FN (x, lt_arg,
549            COND (APP (greater, RECORD [VAR x, zero]),
550                  VAR x, APP (negate, VAR x)))
551    end
552    
553  fun transPrim (prim, lt, ts) =  fun transPrim (prim, lt, ts) =
554    let fun g (PO.INLLSHIFT k) = inlineShift(lshiftOp, k, fn _ => lword0(k))    let fun g (PO.INLLSHIFT k) = inlineShift(lshiftOp, k, fn _ => lword0(k))
# Line 499  Line 559 
559                 in inlineShift(rshiftOp, k, clear)                 in inlineShift(rshiftOp, k, clear)
560                end                end
561    
562          | g (PO.INLDIV) =          | g (PO.INLMIN nk) = inlminmax (nk, false)
563                let val a = mkv() and b = mkv() and z = mkv()          | g (PO.INLMAX nk) = inlminmax (nk, true)
564                 in FN(z, lt_ipair,          | g (PO.INLABS nk) = inlabs nk
565                      LET(a, SELECT(0, VAR z),  
                       LET(b, SELECT(1, VAR z),  
                         COND(APP(cmpOp(PO.IGE), RECORD[VAR b, INT 0]),  
                           COND(APP(cmpOp(PO.IGE), RECORD[VAR a, INT 0]),  
                                DIV(VAR a, VAR b),  
                                SUB(DIV(ADD(VAR a, INT 1), VAR b), INT 1)),  
                           COND(APP(cmpOp(PO.IGT), RECORD[VAR a, INT 0]),  
                                SUB(DIV(SUB(VAR a, INT 1), VAR b), INT 1),  
                                DIV(VAR a, VAR b))))))  
               end  
   
         | g (PO.INLMOD) =  
               let val a = mkv() and b = mkv() and z = mkv()  
                in FN(z, lt_ipair,  
                     LET(a,SELECT(0, VAR z),  
                       LET(b,SELECT(1,VAR z),  
                         COND(APP(cmpOp(PO.IGE), RECORD[VAR b, INT 0]),  
                           COND(APP(cmpOp(PO.IGE), RECORD[VAR a, INT 0]),  
                                SUB(VAR a, MUL(DIV(VAR a, VAR b), VAR b)),  
                                ADD(SUB(VAR a,MUL(DIV(ADD(VAR a,INT 1), VAR b),  
                                                  VAR b)), VAR b)),  
                           COND(APP(cmpOp(PO.IGT), RECORD[VAR a,INT 0]),  
                                ADD(SUB(VAR a,MUL(DIV(SUB(VAR a,INT 1), VAR b),  
                                                  VAR b)), VAR b),  
                                COND(APP(cmpOp(PO.IEQL),RECORD[VAR a,  
                                                          INT ~1073741824]),  
                                     COND(APP(cmpOp(PO.IEQL),  
                                              RECORD[VAR b,INT 0]),  
                                          INT 0,  
                                          SUB(VAR a, MUL(DIV(VAR a, VAR b),  
                                                     VAR b))),  
                                     SUB(VAR a, MUL(DIV(VAR a, VAR b),  
                                                    VAR b))))))))  
               end  
   
         | g (PO.INLREM) =  
               let val a = mkv() and b = mkv() and z = mkv()  
                in FN(z, lt_ipair,  
                     LET(a, SELECT(0,VAR z),  
                       LET(b, SELECT(1,VAR z),  
                           SUB(VAR a, MUL(DIV(VAR a,VAR b),VAR b)))))  
               end  
   
         | g (PO.INLMIN) =  
               let val x = mkv() and y = mkv() and z = mkv()  
                in FN(z, lt_ipair,  
                     LET(x, SELECT(0,VAR z),  
                        LET(y, SELECT(1,VAR z),  
                          COND(APP(cmpOp(PO.ILT), RECORD[VAR x,VAR y]),  
                               VAR x, VAR y))))  
               end  
         | g (PO.INLMAX) =  
               let val x = mkv() and y = mkv() and z = mkv()  
                in FN(z, lt_ipair,  
                     LET(x, SELECT(0,VAR z),  
                        LET(y, SELECT(1,VAR z),  
                          COND(APP(cmpOp(PO.IGT), RECORD[VAR x,VAR y]),  
                               VAR x, VAR y))))  
               end  
         | g (PO.INLABS) =  
               let val x = mkv()  
                in FN(x, lt_int,  
                      COND(APP(cmpOp(PO.IGT), RECORD[VAR x,INT 0]),  
                           VAR x, APP(inegOp(PO.INEG), VAR x)))  
               end  
566          | g (PO.INLNOT) =          | g (PO.INLNOT) =
567                let val x = mkv()                let val x = mkv()
568                 in FN(x, lt_bool, COND(VAR x, falseLexp, trueLexp))                 in FN(x, lt_bool, COND(VAR x, falseLexp, trueLexp))
# Line 594  Line 590 
590                    val x = mkv()                    val x = mkv()
591                 in FN(x, argt, SELECT(0,VAR x))                 in FN(x, argt, SELECT(0,VAR x))
592                end                end
593            | g (PO.INLIGNORE) =
594              let val argt =
595                      case ts of [a] => lt_tyc a
596                               | _ => bug "unexpected type for INLIGNORE"
597              in FN (mkv (), argt, unitLexp)
598              end
599    
600          | g (PO.INLSUBSCRIPTV) =          | g (PO.INLSUBSCRIPTV) =
601                let val (tc1, t1) = case ts of [z] => (z, lt_tyc z)                let val (tc1, t1) = case ts of [z] => (z, lt_tyc z)
# Line 735  Line 737 
737        mkAccInfo(access, info, fn () => toLty d (!typ), getNameOp path)        mkAccInfo(access, info, fn () => toLty d (!typ), getNameOp path)
738    | mkVar _ = bug "unexpected vars in mkVar"    | mkVar _ = bug "unexpected vars in mkVar"
739    
740  fun mkVE (v as V.VALvar {info=II.INL_PRIM(p, SOME typ), ...}, ts, d) =  fun mkVE (v, ts, d) = let
741        (case (p, ts)      fun otherwise () =
742          of (PO.POLYEQL, [t]) => eqGen(typ, t, toTcLt d)          case ts of
743           | (PO.POLYNEQ, [t]) => composeNOT(eqGen(typ, t, toTcLt d), toLty d t)              [] => mkVar (v, d)
744              | _ => TAPP(mkVar(v, d), map (toTyc d) ts)
745    in
746        case v of
747            V.VALvar { info, ... } =>
748            II.match info
749               { inl_prim = fn (p, typ) =>
750                 (case (p, ts) of
751                      (PO.POLYEQL, [t]) => eqGen(typ, t, toTcLt d)
752                    | (PO.POLYNEQ, [t]) =>
753                      composeNOT(eqGen(typ, t, toTcLt d), toLty d t)
754           | (PO.INLMKARRAY, [t]) =>           | (PO.INLMKARRAY, [t]) =>
755                  let val dict =                  let val dict =
756                        {default = coreAcc "mkNormArray",                        {default = coreAcc "mkNormArray",
757                         table = [([LT.tcc_real], coreAcc "mkRealArray")]}                         table = [([LT.tcc_real], coreAcc "mkRealArray")]}
758                   in GENOP (dict, p, toLty d typ, map (toTyc d) ts)                   in GENOP (dict, p, toLty d typ, map (toTyc d) ts)
759                  end                  end
760           | _ => transPrim(p, (toLty d typ), map (toTyc d) ts))                  | (PO.RAW_CCALL NONE, [a, b, c]) =>
761                      let val i = SOME (CProto.decode cproto_conv
762    | mkVE (v as V.VALvar {info=II.INL_PRIM(p, NONE), typ, ...}, ts, d) =                                                    { fun_ty = a, encoding = b })
763        (case ts of [] => transPrim(p, (toLty d (!typ)), [])                                handle CProto.BadEncoding => NONE
764                  | [x] =>                    in PRIM (PO.RAW_CCALL i, toLty d typ, map (toTyc d) ts)
765                     (* a temporary hack to resolve the boot/built-in.sml file *)                    end
766                     (let val lt = toLty d (!typ)                  | _ => transPrim(p, (toLty d typ), map (toTyc d) ts)),
767                          val nt = toLty d x               inl_str = fn _ => otherwise (),
768                       in if LT.lt_eqv(LT.ltc_top, lt)               inl_no = fn () => otherwise () }
769                          then transPrim(p, nt, [])        | _ => otherwise ()
770                          else bug "unexpected primop in mkVE"  end
                     end)  
                 | _ => bug "unexpected poly primops in mkVE")  
   
   | mkVE (v, [], d) = mkVar(v, d)  
   | mkVE (v, ts, d) = TAPP(mkVar(v, d), map (toTyc d) ts)  
771    
772  fun mkCE (TP.DATACON{const, rep, name, typ, ...}, ts, apOp, d) =  fun mkCE (TP.DATACON{const, rep, name, typ, ...}, ts, apOp, d) =
773    let val lt = toDconLty d typ    let val lt = toDconLty d typ
# Line 813  Line 820 
820        let val savedtvs = map ! boundtvs        let val savedtvs = map ! boundtvs
821    
822            fun g (i, []) = ()            fun g (i, []) = ()
823              | g (i, (tv as ref (TP.OPEN _))::rest) =              | g (i, (tv as ref (TP.OPEN _))::rest) = let
824                     (tv := TP.LBOUND{depth=d, num=i}; g(i+1,rest))                    val m = markLBOUND (d, i);
825              | g (i, (tv as ref (TP.LBOUND _))::res) =                in
826                     bug ("unexpected tyvar LBOUND in mkPE")                    tv := TP.TV_MARK m;
827                      g (i+1, rest)
828                  end
829                | g (i, (tv as ref (TP.TV_MARK _))::res) =
830                       bug ("unexpected tyvar TV_MARK in mkPE")
831              | g _ = bug "unexpected tyvar INSTANTIATED in mkPE"              | g _ = bug "unexpected tyvar INSTANTIATED in mkPE"
832    
833            val _ = g(0, boundtvs) (* assign the LBOUND tyvars *)            val _ = g(0, boundtvs) (* assign the TV_MARK tyvars *)
834            val exp' = mkExp(exp, DI.next d)            val exp' = mkExp(exp, DI.next d)
835    
836            fun h ([], []) = ()            fun h ([], []) = ()
# Line 1117  Line 1128 
1128  fun wrapPidInfo (body, pidinfos) =  fun wrapPidInfo (body, pidinfos) =
1129    let val imports =    let val imports =
1130          let fun p2itree (ANON xl) =          let fun p2itree (ANON xl) =
1131                    CB.ITNODE (map (fn (i,z) => (i, p2itree z)) xl)                    ImportTree.ITNODE (map (fn (i,z) => (i, p2itree z)) xl)
1132                | p2itree (NAMED _) = CB.ITNODE []                | p2itree (NAMED _) = ImportTree.ITNODE []
1133           in map (fn (p, pi) => (p, p2itree pi)) pidinfos           in map (fn (p, pi) => (p, p2itree pi)) pidinfos
1134          end          end
1135  (*  (*
1136        val _ = let val _ = say "\n ****************** \n"        val _ = let val _ = say "\n ****************** \n"
1137                    val _ = say "\n the current import tree is :\n"                    val _ = say "\n the current import tree is :\n"
1138                    fun tree (CB.ITNODE []) = ["\n"]                    fun tree (ImportTree.ITNODE []) = ["\n"]
1139                      | tree (CB.ITNODE xl) =                      | tree (ImportTree.ITNODE xl) =
1140                          foldr (fn ((i, x), z) =>                          foldr (fn ((i, x), z) =>
1141                            let val ts = tree x                            let val ts = tree x
1142                                val u = (Int.toString i)  ^ "   "                                val u = (Int.toString i)  ^ "   "
# Line 1187  Line 1198 
1198    
1199  end (* top-level local *)  end (* top-level local *)
1200  end (* structure Translate *)  end (* structure Translate *)
   
   

Legend:
Removed from v.587  
changed lines
  Added in v.1183

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