/[svn]/compile/compile.ml
ViewVC logotype

Contents of /compile/compile.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1496 - (show annotations)
Tue Jul 10 18:56:12 2007 UTC (5 years, 11 months ago) by abate
File size: 9284 byte(s)
[r2005-03-04 01:16:24 by afrisch] More uniform treatment of cduce,ocaml,schema units

Original author: afrisch
Date: 2005-03-04 01:16:26+00:00
1 open Ident
2 open Lambda
3
4 type env = {
5 cu: Types.CompUnit.t option; (* None: toplevel *)
6 vars: var_loc Env.t;
7 stack_size: int;
8 global_size: int
9 }
10
11 let global_size env = env.global_size
12
13 let dump ppf env =
14 Env.iter
15 (fun id loc ->
16 Format.fprintf ppf "Var %a : %a@\n"
17 Ident.print id
18 Lambda.print_var_loc loc)
19 env.vars
20
21
22 let mk cu = { cu = cu; vars = Env.empty; stack_size = 0; global_size = 0 }
23 let empty_toplevel = mk None
24 let empty x = mk (Some x)
25
26
27 let serialize s env =
28 assert (env.stack_size = 0);
29 (match env.cu with
30 | Some cu -> Types.CompUnit.serialize s cu
31 | None -> assert false);
32 Serialize.Put.env Id.serialize Lambda.Put.var_loc Env.iter s env.vars;
33 Serialize.Put.int s env.global_size
34
35 let deserialize s =
36 let cu = Types.CompUnit.deserialize s in
37 let vars =
38 Serialize.Get.env Id.deserialize Lambda.Get.var_loc Env.add Env.empty s in
39 let size = Serialize.Get.int s in
40 { cu = Some cu; vars = vars; stack_size = 0; global_size = size }
41
42
43 let find x env =
44 try Env.find x env.vars
45 with Not_found ->
46 failwith ("Compile: cannot find " ^ (Ident.to_string x))
47
48 let find_slot x env =
49 match find x env with
50 | Ext (_,slot) -> slot
51 | _ -> assert false
52
53
54 let from_comp_unit = ref (fun cu -> assert false)
55
56 let find_ext cu x =
57 let env = !from_comp_unit cu in
58 find x env
59
60
61 let rec compile env tail e = compile_aux env tail e.Typed.exp_descr
62 and compile_aux env tail = function
63 | Typed.Forget (e,_) -> compile env tail e
64 | Typed.Check (t0,e,t) -> Check (!t0, compile env false e, t)
65 | Typed.Var x -> Var (find x env)
66 | Typed.ExtVar (cu,x,_) -> Var (find_ext cu x)
67 | Typed.Apply (e1,e2) -> Apply (tail, compile env false e1, compile env tail e2)
68 | Typed.Abstraction a -> compile_abstr env a
69 | Typed.Cst c -> Const c
70 | Typed.Pair (e1,e2) -> Pair(compile env false e1, compile env tail e2)
71 | Typed.Xml (e1, { Typed.exp_descr = Typed.Pair (e2,e3) }) ->
72 Xml (compile env false e1, compile env false e2, compile env tail e3)
73 | Typed.Xml (_,_) -> assert false
74 | Typed.RecordLitt r -> Record (LabelMap.map (compile env false) r)
75 | Typed.String (i,j,s,q) -> String (i,j,s,compile env tail q)
76 | Typed.Match (e,brs) -> Match (compile env false e, compile_branches env tail brs)
77 | Typed.Map (e,brs) -> Map (compile env false e, compile_branches env false brs)
78 | Typed.Transform (e,brs) -> Transform
79 (compile env false e, compile_branches env false brs)
80 | Typed.Xtrans (e,brs) -> Xtrans (compile env false e, compile_branches env false brs)
81 | Typed.Validate (e,sch,t) -> Validate (compile env tail e, sch, t)
82 | Typed.RemoveField (e,l) -> RemoveField (compile env tail e,l)
83 | Typed.Dot (e,l) -> Dot (compile env tail e, l)
84 | Typed.Try (e,brs) -> Try (compile env false e, compile_branches env tail brs)
85 | Typed.Ref (e,t) -> Ref (compile env tail e, t)
86 | Typed.External (t,i) ->
87 (match env.cu with
88 | Some cu -> Var (External (cu,i))
89 | None -> failwith "Cannot compile externals in the toplevel")
90 | Typed.Op (op,_,args) ->
91 let rec aux = function
92 | [arg] -> [ compile env tail arg ]
93 | arg::l -> (compile env false arg) :: (aux l)
94 | [] -> [] in
95 Op (op, aux args)
96 | Typed.NsTable (ns,e) ->
97 NsTable (ns, compile_aux env tail e)
98
99 and compile_abstr env a =
100 let fun_env =
101 match a.Typed.fun_name with
102 | Some x -> Env.add x (Env 0) Env.empty
103 | None -> Env.empty in
104
105 let (slots,nb_slots,fun_env) =
106 List.fold_left
107 (fun (slots,nb_slots,fun_env) x ->
108 match find x env with
109 | (Stack _ | Env _) as p ->
110 p::slots,
111 succ nb_slots,
112 Env.add x (Env nb_slots) fun_env;
113 | Global _ | Ext _ | External _ as p ->
114 slots,
115 nb_slots,
116 Env.add x p fun_env
117 | Dummy -> assert false
118 )
119 ([Dummy],1,fun_env) (IdSet.get a.Typed.fun_fv) in
120
121
122 let slots = Array.of_list (List.rev slots) in
123 let env = { env with vars = fun_env; stack_size = 0 } in
124 let body = compile_branches env true a.Typed.fun_body in
125 Abstraction (slots, a.Typed.fun_iface, body)
126
127 and compile_branches env tail (brs : Typed.branches) =
128 (* Don't compile unused branches, because they have not been
129 type checked. *)
130 let used = List.filter (fun br -> br.Typed.br_used) brs.Typed.br_branches in
131 {
132 brs = List.map (compile_branch env tail) used;
133 brs_tail = tail;
134 brs_accept_chars = not (Types.Char.is_empty brs.Typed.br_accept);
135 brs_input = brs.Typed.br_typ;
136 brs_compiled = None; brs_compiled2 = None
137 }
138
139 and compile_branch env tail br =
140 let env =
141 List.fold_left
142 (fun env x ->
143 { env with
144 vars = Env.add x (Stack env.stack_size) env.vars;
145 stack_size = env.stack_size + 1 }
146
147 ) env (Patterns.fv br.Typed.br_pat) in
148 (br.Typed.br_pat, compile env tail br.Typed.br_body)
149
150
151 let enter_globals env n =
152 match env.cu with
153 | None ->
154 let env =
155 List.fold_left
156 (fun env x ->
157 { env with
158 vars = Env.add x (Global env.stack_size) env.vars;
159 stack_size = env.stack_size + 1 })
160 env n in
161 (env,[])
162 | Some cu ->
163 List.fold_left
164 (fun (env,code) x ->
165 let code = SetGlobal (cu, env.global_size) :: code in
166 let env =
167 { env with
168 vars = Env.add x (Ext (cu, env.global_size)) env.vars;
169 global_size = env.global_size + 1 } in
170 (env,code)
171 )
172 (env,[])
173 n
174
175 let compile_expr env = compile env false
176
177 let compile_eval env e = [ Push (compile_expr env e); Pop ]
178
179 let compile_let_decl env decl =
180 let pat = decl.Typed.let_pat in
181 let e = compile_expr env decl.Typed.let_body in
182 let (env,code) = enter_globals env (Patterns.fv pat) in
183 (env, (Push e) :: (Split pat) :: code)
184
185 let compile_rec_funs env funs =
186 let fun_name = function
187 | { Typed.exp_descr=Typed.Abstraction{Typed.fun_name = Some x}} -> x
188 | _ -> assert false in
189 let fun_a env = function
190 | { Typed.exp_descr=Typed.Abstraction a } ->
191 Push (compile_abstr env a)
192 | _ -> assert false in
193 let names = List.map fun_name funs in
194 let (env,code) = enter_globals env names in
195 let exprs = List.map (fun_a env) funs in
196 (env, exprs @ code)
197
198
199 (****************************************)
200
201 open Location
202
203 let eval ~run ~show (tenv,cenv,codes) e =
204 let (e,t) = Typer.type_expr tenv e in
205 let expr = compile_expr cenv e in
206 if run then
207 let v = Eval.expr expr in
208 show None t (Some v)
209 else
210 show None t None;
211 (tenv,cenv, Pop :: Push expr ::codes)
212
213 let run_show ~run ~show tenv cenv codes ids =
214 if run then
215 let () = Eval.code_items codes in
216 List.iter
217 (fun (id,_) -> show (Some id)
218 (Typer.find_value id tenv)
219 (Some (Eval.var (find id cenv)))) ids
220 else
221 List.iter
222 (fun (id,_) -> show (Some id)
223 (Typer.find_value id tenv)
224 None) ids
225
226 let let_decl ~run ~show (tenv,cenv,codes) p e =
227 let (tenv,decl,ids) = Typer.type_let_decl tenv p e in
228 let (cenv,code) = compile_let_decl cenv decl in
229 run_show ~run ~show tenv cenv code ids;
230 (tenv,cenv,List.rev_append code codes)
231
232 let let_funs ~run ~show (tenv,cenv,codes) funs =
233 let (tenv,funs,ids) = Typer.type_let_funs tenv funs in
234 let (cenv,code) = compile_rec_funs cenv funs in
235 run_show ~run ~show tenv cenv code ids;
236 (tenv,cenv,List.rev_append code codes)
237
238 let type_defs (tenv,cenv,codes) typs =
239 let tenv = Typer.enter_types (Typer.type_defs tenv typs) tenv in
240 (tenv,cenv,codes)
241
242 let namespace (tenv,cenv,codes) pr ns =
243 let tenv = Typer.enter_ns pr ns tenv in
244 (tenv,cenv,codes)
245
246 let schema (tenv,cenv,codes) x sch prefix =
247 let tenv = Typer.enter_schema ?prefix x sch tenv in
248 (tenv,cenv,codes)
249
250 let find_cu (tenv,_,_) cu =
251 Typer.find_cu cu tenv
252
253 let using (tenv,cenv,codes) x cu =
254 let tenv = Typer.enter_cu x cu tenv in
255 (tenv,cenv,codes)
256
257 let rec collect_funs accu = function
258 | { descr = Ast.FunDecl e } :: rest -> collect_funs (e::accu) rest
259 | rest -> (accu,rest)
260
261 let rec collect_types accu = function
262 | { descr = Ast.TypeDecl ((loc,x),t) } :: rest ->
263 collect_types ((loc,x,t) :: accu) rest
264 | rest -> (accu,rest)
265
266 let rec phrases ~run ~show ~loading ~directive =
267 let rec loop accu phs =
268 match phs with
269 | { descr = Ast.FunDecl _ } :: _ ->
270 let (funs,rest) = collect_funs [] phs in
271 loop (let_funs ~run ~show accu funs) rest
272 | { descr = Ast.TypeDecl (_,_) } :: _ ->
273 let (typs,rest) = collect_types [] phs in
274 loop (type_defs accu typs) rest
275 | { descr = Ast.SchemaDecl (name, uri, p) } :: rest ->
276 loop (schema accu name uri p) rest
277 | { descr = Ast.Namespace (pr,ns) } :: rest ->
278 loop (namespace accu pr ns) rest
279 | { descr = Ast.Using (x,cu) } :: rest ->
280 let cu = find_cu accu cu in
281 loading cu;
282 loop (using accu x cu) rest
283 | { descr = Ast.EvalStatement e } :: rest ->
284 loop (eval ~run ~show accu e) rest
285 | { descr = Ast.LetDecl (p,e) } :: rest ->
286 loop (let_decl ~run ~show accu p e) rest
287 | { descr = Ast.Directive d } :: rest ->
288 let (tenv,cenv,_) = accu in
289 directive tenv cenv d;
290 loop accu rest
291 | [] ->
292 accu
293 in
294 loop
295
296 let comp_unit ?(run=false)
297 ?(show=fun _ _ _ -> ())
298 ?(loading=fun _ -> ())
299 ?(directive=fun _ _ _ -> ()) tenv cenv phs =
300 let (tenv,cenv,codes) = phrases ~run ~show ~loading ~directive (tenv,cenv,[]) phs in
301 (tenv,cenv,List.rev codes)

CVS Admin">CVS Admin
ViewVC Help
Powered by ViewVC 1.1.5