home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Caml Light 0.61 / Source / src / compiler / tr_env.ml < prev    next >
Encoding:
Text File  |  1994-07-07  |  5.1 KB  |  182 lines  |  [TEXT/MPS ]

  1. (* tr_env.ml: handling of the translation environment. *)
  2.  
  3. #open "misc";;
  4. #open "const";;
  5. #open "syntax";;
  6. #open "lambda";;
  7. #open "prim";;
  8. #open "globals";;
  9. #open "ty_error";;
  10.  
  11. type access_path =
  12.     Path_root
  13.   | Path_son of int * access_path
  14.   | Path_tuple of access_path list
  15. ;;
  16.  
  17. type transl_env =
  18.     Tnullenv
  19.   | Treserved of transl_env
  20.   | Tenv of (string * access_path) list * transl_env
  21. ;; 
  22.  
  23. let translate_path root =
  24.   let rec transl = function
  25.       Path_root -> root
  26.     | Path_son(n, p) -> Lprim(Pfield n, [transl p])
  27.     | Path_tuple pl -> Lprim(Pmakeblock(ConstrRegular(0,1)), map transl pl)
  28.   in transl
  29. ;;
  30.  
  31. let rec translate_access s env =
  32.   let rec transl i = function
  33.     Tnullenv      -> fatal_error "translate_env"
  34.   | Treserved env -> transl (i+1) env
  35.   | Tenv(L,env)   ->
  36.       try
  37.         let path = assoc s L in
  38.           translate_path (Lvar i) path
  39.       with Not_found ->
  40.         transl (i+1) env
  41.   in transl 0 env
  42. ;;
  43.  
  44. let translate_update s env newval =
  45.   let rec transl i = function
  46.     Tnullenv      -> fatal_error "translate_update"
  47.   | Treserved env -> transl (i+1) env
  48.   | Tenv(L,env)   ->
  49.       try
  50.         match assoc s L with
  51.           Path_root -> transl (i+1) env
  52.             (* We have two occurrences of s in the environment:
  53.                one is let-bound (path = Path_root) and is the value
  54.                at the time of the matching,
  55.                the other is a non-trivial access path in the data structure.
  56.                The latter is the one that should be modified, so we skip the
  57.                former. *)
  58.         | Path_son(start,rest) ->
  59.             Lprim(Psetfield start, [translate_path (Lvar i) rest; newval])
  60.         | Path_tuple pl -> fatal_error "translate_update"
  61.       with Not_found ->
  62.         transl (i+1) env
  63.   in transl 0 env
  64. ;;
  65.  
  66. let rec pat_is_named (Pat(desc,loc)) =
  67.   match desc with
  68.     Zvarpat s -> true
  69.   | Zaliaspat(pat, s) -> true
  70.   | Zconstraintpat(pat, _) -> pat_is_named pat
  71.   | _ -> false
  72. ;;
  73.  
  74. let tuple_path nfields path =
  75.   let rec list_of_fields i =
  76.     if i >= nfields then [] else Path_son(i, path) :: list_of_fields (succ i)
  77.   in
  78.     Path_tuple(list_of_fields 0)
  79. ;;
  80.  
  81. let rec paths_of_pat path (Pat(desc,loc)) =
  82.   match desc with
  83.     Zvarpat s ->
  84.       [s, path]
  85.   | Zaliaspat(pat,s) ->
  86.       (s, path) :: paths_of_pat path pat
  87.   | Ztuplepat(patlist) ->
  88.       let rec paths_of_patlist i = function
  89.         [] -> []
  90.       | p::pl ->
  91.           paths_of_pat (Path_son(i,path)) p @ paths_of_patlist (i+1) pl in
  92.       paths_of_patlist 0 patlist
  93.   | Zconstruct0pat(cstr) ->
  94.       []
  95.   | Zconstruct1pat(cstr, p) ->
  96.       begin match cstr.info.cs_kind with
  97.         Constr_superfluous n ->
  98.           paths_of_pat (if pat_is_named p then tuple_path n path else path) p
  99.       | _ ->
  100.           paths_of_pat (Path_son(0, path)) p
  101.       end
  102.   | Zconstraintpat(pat,_) ->
  103.       paths_of_pat path pat
  104.   | Zrecordpat lbl_pat_list ->
  105.       let rec paths_of_lbl_pat_list = function
  106.         [] -> []
  107.       | (lbl,p)::pl ->
  108.           paths_of_pat (Path_son(lbl.info.lbl_pos,path)) p @
  109.           paths_of_lbl_pat_list pl in
  110.       paths_of_lbl_pat_list lbl_pat_list
  111.   | _ -> []
  112. ;;
  113.  
  114. let rec mutable_vars_of_pat (Pat(desc,loc)) =
  115.   match desc with
  116.     Zaliaspat(pat,v) -> mutable_vars_of_pat pat
  117.   | Zconstraintpat(pat, _) -> mutable_vars_of_pat pat
  118.   | Ztuplepat patl -> flat_map mutable_vars_of_pat patl
  119.   | Zconstruct1pat(cstr,pat) ->
  120.       begin match cstr.info.cs_mut with
  121.         Mutable -> free_vars_of_pat pat
  122.       | Notmutable -> mutable_vars_of_pat pat
  123.       end
  124.   | Zrecordpat lbl_pat_list ->
  125.       flat_map
  126.         (fun (lbl,pat) ->
  127.           match lbl.info.lbl_mut with
  128.             Mutable -> free_vars_of_pat pat
  129.           | Notmutable -> mutable_vars_of_pat pat)
  130.         lbl_pat_list
  131.   | _ -> []
  132. ;;
  133.  
  134. let rec add_lets_to_env varlist env =
  135.   match varlist with
  136.     [] -> env
  137.   | var::rest -> add_lets_to_env rest (Tenv([var,Path_root], env))
  138. ;;      
  139.  
  140. let add_lets_to_expr varlist env expr =
  141.   let rec add env = function
  142.       [] -> []
  143.     | var::rest ->
  144.         translate_access var env :: add (Treserved env) rest in
  145.   match add env varlist with
  146.     [] -> expr
  147.   | el -> Llet(el, expr)
  148. ;;
  149.  
  150. let add_pat_to_env env pat =
  151.   let env' = Tenv(paths_of_pat Path_root pat, env) in
  152.   let mut_vars = mutable_vars_of_pat pat in
  153.     (add_lets_to_env mut_vars env', add_lets_to_expr mut_vars env')
  154. ;;
  155.  
  156. let add_pat_list_to_env env patl =
  157.   let env' =
  158.     it_list (fun env pat -> Tenv(paths_of_pat Path_root pat, env)) env patl in
  159.   let mut_vars =
  160.     flat_map mutable_vars_of_pat patl in
  161.   (add_lets_to_env mut_vars env', add_lets_to_expr mut_vars env')
  162. ;;
  163.  
  164. let add_for_parameter_to_env env id =
  165.   Treserved(Tenv([id, Path_son(0, Path_root)], env))
  166. ;;
  167. (* The parameter of a "for" loop is stored as a reference, with index 1.
  168.    The variable with index 0 is the end-of-loop value. *)
  169.  
  170. let add_let_rec_to_env env pat_expr_list =
  171.   let add env (Pat(p,loc), expr) =
  172.     match p with
  173.       Zvarpat v -> Tenv([v, Path_root], env)
  174.     | _ -> illegal_letrec_pat loc in
  175.   it_list add env pat_expr_list
  176. ;;
  177.     
  178. let env_for_toplevel_let patl =
  179.   it_list (fun env pat -> Tenv(paths_of_pat Path_root pat, env)) Tnullenv patl
  180. ;;
  181.  
  182.