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

Contents of /compile/compile.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1727 - (hide annotations)
Tue Jul 10 19:17:31 2007 UTC (5 years, 10 months ago) by abate
File size: 9710 byte(s)
[r2005-06-17 14:55:43 by afrisch] New representation for integer maps (used for dispatcher on atoms and
for record values

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

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