home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / src / compiler / Tr_env.sml < prev    next >
Encoding:
Text File  |  1997-08-18  |  6.0 KB  |  210 lines  |  [TEXT/R*ch]

  1. (* tr_env.ml: handling of the translation environment. *)
  2.  
  3. open List Fnlib Mixture Const Prim Lambda Globals Units Types Asynt Asyntfn;
  4.  
  5. type RenEnv = (string * int) list;
  6.  
  7. datatype AccessPath =
  8.     Path_local of int
  9.   | Path_global of (QualifiedIdent * int)
  10.   | Path_son of int * AccessPath
  11.   | Path_virtual_son of int * AccessPath
  12. ;
  13.  
  14. type TranslEnv = (string, AccessPath) Env * int;
  15.  
  16. fun lookupRenEnv q =
  17.   let val {qual, id} = q in
  18.     if qual = "" then fatalError "lookupRenEnv: empty qualifier"
  19.     else ();
  20.     if qual = currentUnitName() then
  21.       (mkUniqueGlobalName (id, Hasht.find (!currentRenEnv) id)
  22.        handle Subscript => fatalError
  23.          ("lookupRenEnv: unknown variable: " ^ showQualId q))
  24.     else
  25.       (q, 0)
  26.   end
  27. ;
  28.  
  29. fun updateCurrentRenEnv RE =
  30.   app (fn (x,y) => Hasht.insert (!currentRenEnv) x y)
  31.       (rev RE)
  32. ;
  33.  
  34. fun renameId id = (id, newValStamp());
  35.  
  36. (* Generating lambda expressions from access pahts *)
  37.  
  38. fun translatePath depth = fn
  39.     Path_local i => Lvar (depth-(i+1))
  40.   | Path_global uid => Lprim(Pget_global uid, [])
  41.   | Path_virtual_son(arity, p) =>
  42.       translatePath depth p
  43.   | Path_son(n, p)
  44.       => Lprim(Pfield n, [translatePath depth p])
  45. ;
  46.  
  47. fun translateTopOfPath depth = fn
  48.     Path_virtual_son(arity, Path_local i) =>
  49.       let val lvar = Lvar (depth-(i+1)) in
  50.         Lprim(Pmakeblock(CONtag(0,1)),
  51.               tabulate(arity, (fn n => Lprim(Pfield n, [lvar]))))
  52.       end
  53.   | Path_virtual_son(arity, p) =>
  54.       Llet([translatePath depth p],
  55.         Lprim(Pmakeblock(CONtag(0,1)),
  56.               tabulate(arity, (fn n => Lprim(Pfield n, [Lvar 0])))))
  57.   | p => translatePath depth p
  58. ;
  59.  
  60. fun translateLocalAccess (rho, depth) id =
  61.   translateTopOfPath depth (lookupEnv rho id)
  62.   handle Subscript =>
  63.     fatalError "translateLocalAccess"
  64. ;
  65.  
  66. fun lookupInLocalEnv env q =
  67.   let val {qual, id} = q in
  68.     if qual = "" orelse qual = currentUnitName() then
  69.       lookupEnv env id
  70.     else
  71.       raise Subscript
  72.   end
  73. ;
  74.  
  75. fun translateAccess (rho, depth) q =
  76.   translateTopOfPath depth (lookupInLocalEnv rho q)
  77.   handle Subscript =>
  78.     Lprim(Pget_global (lookupRenEnv q), [])
  79. ;
  80.  
  81. fun translateExName env (ii : IdInfo) =
  82.   let val {qualid, info} = ii in
  83.     case #info(!(#idKind info)) of
  84.         EXCONik _ =>
  85.           translateAccess env qualid
  86.       | _ => fatalError "translateExName"
  87.   end;
  88.  
  89. fun pair x y = (x, y);
  90.  
  91. fun pathsOfPatAcc path ((loc, pat') : Pat) acc =
  92.   case pat' of
  93.     SCONpat _ => acc
  94.   | VARpat ii =>
  95.       bindInEnv acc (#id(#qualid ii)) path
  96.   | WILDCARDpat => acc
  97.   | NILpat _ => acc
  98.   | CONSpat(ii, p) =>
  99.       let val ci = getConInfo ii in
  100.         if #conSpan(!ci) = 1 then
  101.           pathsOfPatAcc path p acc
  102.         else if #conIsGreedy(!ci) then
  103.           (if #conTag(!ci) = 0 then
  104.              pathsOfPatAcc path p acc
  105.            else
  106.              pathsOfPatAcc (Path_virtual_son(#conArity(!ci), path)) p acc)
  107.         else
  108.           pathsOfPatAcc (Path_son(0, path)) p acc
  109.       end
  110.   | EXNILpat _ => acc
  111.   | EXCONSpat(ii, p) =>
  112.       let val ei = getExConInfo ii in
  113.         case (isExConStatic ei, #exconIsGreedy(!ei)) of
  114.              (true,  true ) =>
  115.                pathsOfPatAcc (Path_virtual_son(#exconArity(!ei), path))
  116.                              p acc
  117.            | (true,  false) =>
  118.                pathsOfPatAcc (Path_son(0, path)) p acc
  119.            | (false, _    ) =>
  120.                pathsOfPatAcc (Path_son(1, path)) p acc
  121.       end
  122.   | EXNAMEpat _ => fatalError "pathsOfPatAcc"
  123.   | REFpat p =>
  124.       pathsOfPatAcc (Path_son(0, path)) p acc
  125.   | RECpat(ref (TUPLErp ps)) =>
  126.       foldR (fn(i,p) => fn acc => pathsOfPatAcc (Path_son(i,path)) p acc)
  127.             acc (mapFrom pair 0 ps)
  128.   | RECpat(ref (RECrp _)) =>
  129.       fatalError "pathsOfPatAcc: unresolved record pattern"
  130.   | VECpat ps =>
  131.       foldR (fn(i,p) => fn acc => pathsOfPatAcc (Path_son(i,path)) p acc)
  132.             acc (mapFrom pair 0 ps)
  133.   | INFIXpat _ => fatalError "pathsOfPatAcc"
  134.   | PARpat p =>
  135.       pathsOfPatAcc path p acc
  136.   | TYPEDpat(p, _) =>
  137.       pathsOfPatAcc path p acc
  138.   | LAYEREDpat(p1, p2) =>
  139.       pathsOfPatAcc path p1 (pathsOfPatAcc path p2 acc)
  140. ;
  141.  
  142. fun pathsOfPat path pat = pathsOfPatAcc path pat NILenv;
  143.  
  144. fun mutableVarsOfPatAcc ((loc, pat') : Pat) acc =
  145.   case pat' of
  146.     SCONpat _ => acc
  147.   | VARpat _ => acc
  148.   | WILDCARDpat => acc
  149.   | NILpat _ => acc
  150.   | CONSpat(_, p) =>
  151.       mutableVarsOfPatAcc p acc
  152.   | EXNILpat _ => acc
  153.   | EXCONSpat(ii, p) =>
  154.       mutableVarsOfPatAcc p acc
  155.   | EXNAMEpat _ => fatalError "mutableVarsOfPatAcc"
  156.   | REFpat p =>
  157.       domPatAcc p acc
  158.   | RECpat(ref (TUPLErp ps)) =>
  159.       foldR mutableVarsOfPatAcc acc ps
  160.   | RECpat(ref (RECrp _)) =>
  161.       fatalError "mutableVarsOfPatAcc: unresolved record pattern"
  162.   | VECpat ps =>
  163.       foldR mutableVarsOfPatAcc acc ps
  164.   | INFIXpat _ => fatalError "mutableVarsOfPatAcc"
  165.   | PARpat p =>
  166.       mutableVarsOfPatAcc p acc
  167.   | TYPEDpat(p, _) =>
  168.       mutableVarsOfPatAcc p acc
  169.   | LAYEREDpat(p1, p2) =>
  170.       mutableVarsOfPatAcc p1 (mutableVarsOfPatAcc p2 acc)
  171. ;
  172.  
  173. (* Since the program is supposed to be well-typed, *)
  174. (* the patterns in a `val rec' can't contain mutable variables. *)
  175. (* Thus there's no danger in accessing variable values via *)
  176. (* their access paths... *)
  177.  
  178. fun mkEnvOfRecPats depth pats =
  179.   foldL (fn pat => fn (rho, depth) =>
  180.            (pathsOfPatAcc (Path_local depth) pat rho, depth+1))
  181.         (NILenv, depth) pats
  182. ;
  183.  
  184. (* If a `val' declaration isn't recursive, the mutable variables *)
  185. (* appearing in its patterns must be taken special care of... *)
  186.  
  187. fun mutableVarsOfPat pat = mutableVarsOfPatAcc pat [];
  188.  
  189. fun addLetsToEnv varlist (env as (rho, depth)) =
  190.   case varlist of
  191.     [] => env
  192.   | var::rest =>
  193.       addLetsToEnv rest (bindInEnv rho var (Path_local depth), depth+1)
  194. ;
  195.  
  196. fun addLetsToExp varlist (rho, depth) exp =
  197.   case varlist of
  198.       [] => exp
  199.     | _ =>
  200.        Llet(mapFrom (fn i => fn var => translateLocalAccess (rho, i) var)
  201.                     depth varlist,
  202.            exp)
  203. ;
  204.  
  205. fun mkEnvOfPats depth pats =
  206.   let val env' = mkEnvOfRecPats depth pats
  207.       val mut_vars = foldR mutableVarsOfPatAcc [] pats
  208.   in (addLetsToEnv mut_vars env', addLetsToExp mut_vars env') end
  209. ;
  210.