]> git.lizzy.rs Git - rust.git/blob - src/comp/metadata/tyencode.rs
Remove proto_sugar and 'lambda' as keyword, commit to fn@.
[rust.git] / src / comp / metadata / tyencode.rs
1 // Type encoding
2
3 import core::{int, uint};
4 import std::io;
5 import std::map::hashmap;
6 import option::{some, none};
7 import syntax::ast::*;
8 import middle::ty;
9 import syntax::print::pprust::*;
10
11 export ctxt;
12 export ty_abbrev;
13 export ac_no_abbrevs;
14 export ac_use_abbrevs;
15 export enc_ty;
16 export enc_bounds;
17
18 type ctxt =
19     // Def -> str Callback:
20     // The type context.
21     {ds: fn(def_id) -> str, tcx: ty::ctxt, abbrevs: abbrev_ctxt};
22
23 // Compact string representation for ty.t values. API ty_str & parse_from_str.
24 // Extra parameters are for converting to/from def_ids in the string rep.
25 // Whatever format you choose should not contain pipe characters.
26 type ty_abbrev = {pos: uint, len: uint, s: @str};
27
28 tag abbrev_ctxt { ac_no_abbrevs; ac_use_abbrevs(hashmap<ty::t, ty_abbrev>); }
29
30 fn cx_uses_abbrevs(cx: @ctxt) -> bool {
31     alt cx.abbrevs {
32       ac_no_abbrevs. { ret false; }
33       ac_use_abbrevs(_) { ret true; }
34     }
35 }
36
37 fn enc_ty(w: io::writer, cx: @ctxt, t: ty::t) {
38     alt cx.abbrevs {
39       ac_no_abbrevs. {
40         let result_str: @str;
41         alt cx.tcx.short_names_cache.find(t) {
42           some(s) { result_str = s; }
43           none. {
44             let sw = io::string_writer();
45             enc_sty(sw.get_writer(), cx, ty::struct(cx.tcx, t));
46             result_str = @sw.get_str();
47             cx.tcx.short_names_cache.insert(t, result_str);
48           }
49         }
50         w.write_str(*result_str);
51       }
52       ac_use_abbrevs(abbrevs) {
53         alt abbrevs.find(t) {
54           some(a) { w.write_str(*a.s); ret; }
55           none. {
56             let pos = w.get_buf_writer().tell();
57             enc_sty(w, cx, ty::struct(cx.tcx, t));
58             let end = w.get_buf_writer().tell();
59             let len = end - pos;
60             fn estimate_sz(u: uint) -> uint {
61                 let n = u;
62                 let len = 0u;
63                 while n != 0u { len += 1u; n = n >> 4u; }
64                 ret len;
65             }
66             let abbrev_len = 3u + estimate_sz(pos) + estimate_sz(len);
67             if abbrev_len < len {
68                 // I.e. it's actually an abbreviation.
69                 let s = "#" + uint::to_str(pos, 16u) + ":" +
70                     uint::to_str(len, 16u) + "#";
71                 let a = {pos: pos, len: len, s: @s};
72                 abbrevs.insert(t, a);
73             }
74             ret;
75           }
76         }
77       }
78     }
79 }
80 fn enc_mt(w: io::writer, cx: @ctxt, mt: ty::mt) {
81     alt mt.mut {
82       imm. { }
83       mut. { w.write_char('m'); }
84       maybe_mut. { w.write_char('?'); }
85     }
86     enc_ty(w, cx, mt.ty);
87 }
88 fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
89     alt st {
90       ty::ty_nil. { w.write_char('n'); }
91       ty::ty_bot. { w.write_char('z'); }
92       ty::ty_bool. { w.write_char('b'); }
93       ty::ty_int(t) {
94         alt t {
95           ty_i. { w.write_char('i'); }
96           ty_char. { w.write_char('c'); }
97           ty_i8. { w.write_str("MB"); }
98           ty_i16. { w.write_str("MW"); }
99           ty_i32. { w.write_str("ML"); }
100           ty_i64. { w.write_str("MD"); }
101         }
102       }
103       ty::ty_uint(t) {
104         alt t {
105           ty_u. { w.write_char('u'); }
106           ty_u8. { w.write_str("Mb"); }
107           ty_u16. { w.write_str("Mw"); }
108           ty_u32. { w.write_str("Ml"); }
109           ty_u64. { w.write_str("Md"); }
110         }
111       }
112       ty::ty_float(t) {
113         alt t {
114           ty_f. { w.write_char('l'); }
115           ty_f32. { w.write_str("Mf"); }
116           ty_f64. { w.write_str("MF"); }
117         }
118       }
119       ty::ty_str. { w.write_char('S'); }
120       ty::ty_tag(def, tys) {
121         w.write_str("t[");
122         w.write_str(cx.ds(def));
123         w.write_char('|');
124         for t: ty::t in tys { enc_ty(w, cx, t); }
125         w.write_char(']');
126       }
127       ty::ty_iface(def, tys) {
128         w.write_str("x[");
129         w.write_str(cx.ds(def));
130         w.write_char('|');
131         for t: ty::t in tys { enc_ty(w, cx, t); }
132         w.write_char(']');
133       }
134       ty::ty_tup(ts) {
135         w.write_str("T[");
136         for t in ts { enc_ty(w, cx, t); }
137         w.write_char(']');
138       }
139       ty::ty_box(mt) { w.write_char('@'); enc_mt(w, cx, mt); }
140       ty::ty_uniq(mt) { w.write_char('~'); enc_mt(w, cx, mt); }
141       ty::ty_ptr(mt) { w.write_char('*'); enc_mt(w, cx, mt); }
142       ty::ty_vec(mt) { w.write_char('I'); enc_mt(w, cx, mt); }
143       ty::ty_rec(fields) {
144         w.write_str("R[");
145         for field: ty::field in fields {
146             w.write_str(field.ident);
147             w.write_char('=');
148             enc_mt(w, cx, field.mt);
149         }
150         w.write_char(']');
151       }
152       ty::ty_fn(f) {
153         enc_proto(w, f.proto);
154         enc_ty_fn(w, cx, f);
155       }
156       ty::ty_native_fn(args, out) {
157         w.write_char('N');
158         enc_ty_fn(w, cx, {proto: proto_bare, inputs: args, output: out,
159                           ret_style: return_val, constraints: []});
160       }
161       ty::ty_obj(methods) {
162         w.write_str("O[");
163         for m: ty::method in methods {
164             enc_proto(w, m.fty.proto);
165             w.write_str(m.ident);
166             enc_ty_fn(w, cx, m.fty);
167         }
168         w.write_char(']');
169       }
170       ty::ty_res(def, ty, tps) {
171         w.write_str("r[");
172         w.write_str(cx.ds(def));
173         w.write_char('|');
174         enc_ty(w, cx, ty);
175         for t: ty::t in tps { enc_ty(w, cx, t); }
176         w.write_char(']');
177       }
178       ty::ty_var(id) { w.write_char('X'); w.write_str(int::str(id)); }
179       ty::ty_native(def) {
180         w.write_char('E');
181         w.write_str(cx.ds(def));
182         w.write_char('|');
183       }
184       ty::ty_param(id, did) {
185         w.write_char('p');
186         w.write_str(cx.ds(did));
187         w.write_char('|');
188         w.write_str(uint::str(id));
189       }
190       ty::ty_type. { w.write_char('Y'); }
191       ty::ty_send_type. { w.write_char('y'); }
192       ty::ty_opaque_closure_ptr(ty::closure_block.) { w.write_str("C&"); }
193       ty::ty_opaque_closure_ptr(ty::closure_shared.) { w.write_str("C@"); }
194       ty::ty_opaque_closure_ptr(ty::closure_send.) { w.write_str("C~"); }
195       ty::ty_constr(ty, cs) {
196         w.write_str("A[");
197         enc_ty(w, cx, ty);
198         for tc: @ty::type_constr in cs { enc_ty_constr(w, cx, tc); }
199         w.write_char(']');
200       }
201     }
202 }
203 fn enc_proto(w: io::writer, proto: proto) {
204     alt proto {
205       proto_send. { w.write_char('s'); }
206       proto_shared. { w.write_char('F'); }
207       proto_block. { w.write_char('B'); }
208       proto_bare. { w.write_char('f'); }
209     }
210 }
211
212 fn enc_ty_fn(w: io::writer, cx: @ctxt, ft: ty::fn_ty) {
213     w.write_char('[');
214     for arg: ty::arg in ft.inputs {
215         alt arg.mode {
216           by_mut_ref. { w.write_char('&'); }
217           by_move. { w.write_char('-'); }
218           by_copy. { w.write_char('+'); }
219           by_ref. { w.write_char('='); }
220           by_val. { w.write_char('#'); }
221         }
222         enc_ty(w, cx, arg.ty);
223     }
224     w.write_char(']');
225     let colon = true;
226     for c: @ty::constr in ft.constraints {
227         if colon {
228             w.write_char(':');
229             colon = false;
230         } else { w.write_char(';'); }
231         enc_constr(w, cx, c);
232     }
233     alt ft.ret_style {
234       noreturn. { w.write_char('!'); }
235       _ { enc_ty(w, cx, ft.output); }
236     }
237 }
238
239 // FIXME less copy-and-paste
240 fn enc_constr(w: io::writer, cx: @ctxt, c: @ty::constr) {
241     w.write_str(path_to_str(c.node.path));
242     w.write_char('(');
243     w.write_str(cx.ds(c.node.id));
244     w.write_char('|');
245     let semi = false;
246     for a: @constr_arg in c.node.args {
247         if semi { w.write_char(';'); } else { semi = true; }
248         alt a.node {
249           carg_base. { w.write_char('*'); }
250           carg_ident(i) { w.write_uint(i); }
251           carg_lit(l) { w.write_str(lit_to_str(l)); }
252         }
253     }
254     w.write_char(')');
255 }
256
257 fn enc_ty_constr(w: io::writer, cx: @ctxt, c: @ty::type_constr) {
258     w.write_str(path_to_str(c.node.path));
259     w.write_char('(');
260     w.write_str(cx.ds(c.node.id));
261     w.write_char('|');
262     let semi = false;
263     for a: @ty::ty_constr_arg in c.node.args {
264         if semi { w.write_char(';'); } else { semi = true; }
265         alt a.node {
266           carg_base. { w.write_char('*'); }
267           carg_ident(p) { w.write_str(path_to_str(p)); }
268           carg_lit(l) { w.write_str(lit_to_str(l)); }
269         }
270     }
271     w.write_char(')');
272 }
273
274 fn enc_bounds(w: io::writer, cx: @ctxt, bs: @[ty::param_bound]) {
275     for bound in *bs {
276         alt bound {
277           ty::bound_send. { w.write_char('S'); }
278           ty::bound_copy. { w.write_char('C'); }
279           ty::bound_iface(tp) {
280             w.write_char('I');
281             enc_ty(w, cx, tp);
282           }
283         }
284     }
285     w.write_char('.');
286 }
287
288 //
289 // Local Variables:
290 // mode: rust
291 // fill-column: 78;
292 // indent-tabs-mode: nil
293 // c-basic-offset: 4
294 // buffer-file-coding-system: utf-8-unix
295 // End:
296 //