Skip to content

Commit ebd0453

Browse files
committed
---
yaml --- r: 14832 b: refs/heads/try c: 06c8acd h: refs/heads/master v: v3
1 parent 2012b5e commit ebd0453

File tree

2 files changed

+211
-35
lines changed

2 files changed

+211
-35
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: bdd0c9387bb10e0db01c00dcd47ea3e6bc343e45
5+
refs/heads/try: 06c8acdd3167127170bc7024849d5f89bd9ac70e
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/comp/syntax/ext/auto_serialize.rs renamed to branches/try/src/rustc/syntax/ext/auto_serialize.rs

Lines changed: 210 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ deserializer `d`.
7070
7171
TODO--Hygiene. Search for "__" strings.
7272
73+
Misc notes:
74+
-----------
75+
76+
I use move mode arguments for ast nodes that will get inserted as is
77+
into the tree. This is intended to prevent us from inserting the same
78+
node twice.
79+
7380
*/
7481
import base::*;
7582
import driver::session::session;
@@ -85,12 +92,12 @@ enum ser_cx = {
8592

8693
fn expand_auto_serialize(cx: ext_ctxt,
8794
span: span,
88-
mitem: ast::meta_item,
95+
_mitem: ast::meta_item,
8996
in_items: [@ast::item]) -> [@ast::item] {
9097
vec::flat_map(in_items) {|in_item|
9198
alt in_item.node {
9299
ast::item_ty(ty, tps) {
93-
[in_item, ty_module(cx, in_item.ident, ty, tps)]
100+
[in_item, ty_module(cx, in_item.ident, copy ty, tps)]
94101
}
95102

96103
ast::item_enum(variants, tps) {
@@ -107,9 +114,7 @@ fn expand_auto_serialize(cx: ext_ctxt,
107114
}
108115
}
109116

110-
impl helpers for ser_cx {
111-
fn session() -> session { self.ext_cx.session() }
112-
117+
impl helpers for ext_ctxt {
113118
fn next_id() -> ast::node_id { self.session().next_node_id() }
114119

115120
fn path(span: span, strs: [str]) -> @ast::path {
@@ -119,14 +124,25 @@ impl helpers for ser_cx {
119124
span: span}
120125
}
121126

122-
fn expr(span: span, node: ast::expr_) -> @ast::expr {
123-
@{id: self.next_id(), node: node, span: span}
124-
}
125-
126127
fn ty_path(span: span, strs: [str]) -> @ast::ty {
127128
@{node: ast::ty_path(self.path(span, strs), self.next_id()),
128129
span: span}
129130
}
131+
}
132+
133+
impl helpers for ser_cx {
134+
fn session() -> session { self.ext_cx.session() }
135+
fn next_id() -> ast::node_id { self.ext_cx.next_id() }
136+
fn path(span: span, strs: [str]) -> @ast::path {
137+
self.ext_cx.path(span, strs)
138+
}
139+
fn ty_path(span: span, strs: [str]) -> @ast::ty {
140+
self.ext_cx.ty_path(span, strs)
141+
}
142+
143+
fn expr(span: span, node: ast::expr_) -> @ast::expr {
144+
@{id: self.next_id(), node: node, span: span}
145+
}
130146

131147
fn var_ref(span: span, name: str) -> @ast::expr {
132148
self.expr(span, ast::expr_path(self.path(span, [name])))
@@ -163,6 +179,27 @@ impl helpers for ser_cx {
163179
ast::expr_alt(v, arms, ast::alt_exhaustive)))
164180
}
165181

182+
fn lit_str(span: span, s: str) -> @ast::expr {
183+
self.expr(
184+
span,
185+
ast::expr_lit(
186+
@{node: ast::lit_str(s),
187+
span: span}))
188+
}
189+
190+
fn lit_uint(span: span, i: uint) -> @ast::expr {
191+
self.expr(
192+
span,
193+
ast::expr_lit(
194+
@{node: ast::lit_uint(i as u64, ast::ty_u),
195+
span: span}))
196+
}
197+
198+
fn lambda(-blk: @ast::blk) -> @ast::expr {
199+
let blk_e = cx.expr(blk.span, expr_block(blk));
200+
#ast(expr){{|| $(blk_e) }}
201+
}
202+
166203
fn clone(v: @ast::expr) -> @ast::expr {
167204
let fld = fold::make_fold({
168205
new_id: {|_id| self.next_id()}
@@ -197,7 +234,8 @@ impl helpers for ser_cx {
197234
}
198235
}
199236

200-
fn serialize_path(cx: ser_cx, path: @ast::path, -s: @ast::expr, -v: @ast::expr)
237+
fn serialize_path(cx: ser_cx, path: @ast::path,
238+
-s: @ast::expr, -v: @ast::expr)
201239
-> [@ast::stmt] {
202240
let ext_cx = cx.ext_cx;
203241

@@ -225,17 +263,28 @@ fn serialize_variant(cx: ser_cx,
225263
tys: [@ast::ty],
226264
span: span,
227265
-s: @ast::expr,
228-
pfn: fn([@ast::pat]) -> ast::pat_) -> ast::arm {
266+
pfn: fn([@ast::pat]) -> ast::pat_,
267+
bodyfn: fn(-@ast::expr, @ast::blk) -> @ast::expr,
268+
argfn: fn(-@ast::expr, uint, @ast::blk) -> @ast::expr)
269+
-> ast::arm {
229270
let vnames = vec::init_fn(vec::len(tys)) {|i| #fmt["__v%u", i]};
230271
let pats = vec::init_fn(vec::len(tys)) {|i|
231272
cx.binder_pat(tys[i].span, vnames[i])
232273
};
233274
let pat: @ast::pat = @{id: cx.next_id(), node: pfn(pats), span: span};
234275
let stmts = vec::init_fn(vec::len(tys)) {|i|
235276
let v = cx.var_ref(span, vnames[i]);
236-
serialize_ty(cx, tys[i], cx.clone(s), v)
277+
let arg_blk =
278+
cx.blk(
279+
span,
280+
serialize_ty(cx, tys[i], cx.clone(s), v));
281+
cx.stmt(argfn(cx.clone(s), i, arg_blk))
237282
};
238-
{pats: [pat], guard: none, body: cx.blk(span, vec::concat(stmts))}
283+
284+
let body_blk = cx.blk(span, vec::concat(stmts));
285+
let body = cx.blk(span, [cx.stmt(bodyfn(s, body_blk))]);
286+
287+
{pats: [pat], guard: none, body: body}
239288
}
240289

241290
fn serialize_ty(cx: ser_cx, ty: @ast::ty, -s: @ast::expr, -v: @ast::expr)
@@ -278,8 +327,30 @@ fn serialize_ty(cx: ser_cx, ty: @ast::ty, -s: @ast::expr, -v: @ast::expr)
278327
// };
279328

280329
let arms = [
281-
serialize_variant(cx, tys, ty.span, s,
282-
{|pats| ast::pat_tup(pats)})
330+
serialize_variant(
331+
332+
cx, tys, ty.span, s,
333+
334+
// Generate pattern (v1, v2, v3)
335+
{|pats| ast::pat_tup(pats)},
336+
337+
// Generate body s.emit_tup(3, {|| blk })
338+
{|-s, -blk|
339+
let sz = cx.lit_uint(ty.span, vec::len(tys));
340+
let body = cx.lambda(blk);
341+
#ast[expr]{
342+
$(s).emit_tup($(sz), $(body))
343+
}
344+
},
345+
346+
// Generate s.emit_tup_elt(i, {|| blk })
347+
{|-s, i, -blk|
348+
let idx = cx.lit_uint(ty.span, i);
349+
let body = cx.lambda(blk);
350+
#ast[expr]{
351+
$(s).emit_tup_elt($(idx), $(body))
352+
}
353+
})
283354
];
284355
[cx.alt_stmt(arms, ty.span, v)]
285356
}
@@ -318,7 +389,7 @@ fn serialize_ty(cx: ser_cx, ty: @ast::ty, -s: @ast::expr, -v: @ast::expr)
318389
let ser_e =
319390
cx.expr(
320391
ty.span,
321-
expr_block(
392+
ast::expr_block(
322393
cx.blk(
323394
ty.span,
324395
serialize_ty(
@@ -327,46 +398,71 @@ fn serialize_ty(cx: ser_cx, ty: @ast::ty, -s: @ast::expr, -v: @ast::expr)
327398
cx.at(
328399
ty.span,
329400
#ast(expr){__e})))));
330-
[#ast(stmt){ $(s).emit_from_vec($(v), {|__e| $(ser_e) }) }]
401+
402+
[cx.stmt(
403+
cx.expr(
404+
ty.span,
405+
ast::expr_call(
406+
#ast(expr){$(s).emit_from_vec},
407+
[#ast(expr){{|__e| $(ser_e)}}],
408+
false)))]
331409
}
332410
}
333411
}
334412

335-
fn ty_module(ext_cx: ext_ctxt, name: str, -ty: @ast::ty, tps: [ast::ty_param])
413+
fn mk_ser_fn(ext_cx: ext_ctxt, span: span,
414+
-v_ty: @ast::ty, tps: [ast::ty_param],
415+
f: fn(ser_cx, @ast::ty, -@ast::expr, -@ast::expr) -> [@ast::stmt])
336416
-> @ast::item {
337417

338418
let cx = ser_cx({ext_cx: ext_cx, tps: map::new_str_hash()});
339419

420+
let tp_inputs =
421+
vec::map(tps, {|tp|
422+
{mode: ast::expl(ast::by_ref),
423+
ty: cx.ty_path(span, [tp.ident]),
424+
ident: "__s" + tp.ident,
425+
id: cx.next_id()}});
426+
340427
let ser_inputs: [ast::arg] =
341428
[{mode: ast::expl(ast::by_ref),
342-
ty: cx.ty_path(ty.span, ["__S"]),
429+
ty: cx.ty_path(span, ["__S"]),
343430
ident: "__s",
344431
id: cx.next_id()},
345432
{mode: ast::expl(ast::by_ref),
346-
ty: ty,
433+
ty: v_ty,
347434
ident: "__v",
348-
id: cx.next_id()}] +
349-
vec::map(tps, {|tp|
350-
{mode: ast::expl(ast::by_ref),
351-
ty: cx.ty_path(ty.span, [tp.ident]),
352-
ident: "__v",
353-
id: cx.next_id()}});
435+
id: cx.next_id()}]
436+
+ tp_inputs;
437+
438+
vec::iter2(tps, ser_inputs) {|tp, arg|
439+
let arg_ident = arg.ident;
440+
cx.tps.insert(
441+
tp.ident,
442+
fn@(v: @ast::expr) -> [@ast::stmt] {
443+
let f = cx.var_ref(span, arg_ident);
444+
[cx.stmt(
445+
cx.expr(
446+
span,
447+
ast::expr_call(f, [v], false)))]
448+
});
449+
}
354450

355-
let ser_bnds = @[ast::bound_iface(cx.ty_path(ty.span,
451+
let ser_bnds = @[ast::bound_iface(cx.ty_path(span,
356452
["__std", "serialization",
357453
"serializer"]))];
454+
358455
let ser_tps: [ast::ty_param] =
359456
[{ident: "__S",
360457
id: cx.next_id(),
361458
bounds: ser_bnds}] +
362459
vec::map(tps) {|tp| cx.clone_ty_param(tp) };
363460

364461
let ser_output: @ast::ty = @{node: ast::ty_nil,
365-
span: ty.span};
462+
span: span};
366463

367-
let ser_blk = cx.blk(ty.span,
368-
serialize_ty(cx, ty,
369-
#ast(expr){"__s"}, #ast(expr){"__v"}));
464+
let ser_blk = cx.blk(span,
465+
f(cx, v_ty, #ast(expr){"__s"}, #ast(expr){"__v"}));
370466

371467
@{ident: "serialize",
372468
attrs: [],
@@ -378,11 +474,91 @@ fn ty_module(ext_cx: ext_ctxt, name: str, -ty: @ast::ty, tps: [ast::ty_param])
378474
constraints: []},
379475
ser_tps,
380476
ser_blk),
381-
span: ty.span}
477+
span: span}
478+
}
479+
480+
fn ty_module(ext_cx: ext_ctxt, name: str, -ty: @ast::ty, tps: [ast::ty_param])
481+
-> @ast::item {
482+
483+
let span = ty.span;
484+
let ser_fn = mk_ser_fn(ext_cx, span, ty, tps, serialize_ty);
485+
486+
// Return a module containing the serialization and deserialization
487+
// functions:
488+
@{ident: name,
489+
attrs: [],
490+
id: ext_cx.session().next_node_id(),
491+
node: ast::item_mod({view_items: [],
492+
items: [ser_fn]}),
493+
span: span}
382494
}
383495

384-
fn enum_module(cx: ext_ctxt, name: str,
496+
fn enum_module(ext_cx: ext_ctxt, name: str, span: span,
385497
variants: [ast::variant], tps: [ast::ty_param])
386498
-> @ast::item {
387499

388-
}
500+
let span = ty.span;
501+
let ty = ext_cx.ty_path(span, [name]);
502+
let ser_fn = mk_ser_fn(ext_cx, span, ty, tps) {|cx, ty, s, v|
503+
let arms = vec::init_fn(vec::len(variants)) {|vidx|
504+
let variant = variants[vidx];
505+
506+
if vec::is_empty(variant.args) {
507+
// degenerate case.
508+
let pat = {id: cx.next_id(),
509+
node: ast::pat_ident(cx.path(variant.ident), none),
510+
Span: variant.span};
511+
//#ast(expr){
512+
// $(s).emit_enum_variant(X, Y, SZ) {||
513+
// };
514+
//}
515+
}
516+
517+
let variant_tys = vec::map(variant.args) {|a| a.ty };
518+
519+
serialize_variant(
520+
cx, variant_tys, variant.span, cx.clone(s),
521+
522+
// Generate pattern var(v1, v2, v3)
523+
{|pats|
524+
let pat = {id: cx.next_id(),
525+
node: ast::pat_enum(cx.path(variant.ident)),
526+
span: variant.span};
527+
528+
{id: cx.next_id(),
529+
node: expr_call(s, [v_name,
530+
v_id,
531+
sz,
532+
f], false),
533+
span: variant.span}
534+
},
535+
536+
// Generate body s.emit_enum_variant("foo", 0u, 3u, {|| blk })
537+
{|-s, -blk|
538+
let v_name = cx.lit_str(variant.span, variant.ident);
539+
let v_id = cx.lit_uint(variant.span, vidx);
540+
let sz = cx.lit_uint(variant.span, vec::len(variant_tys));
541+
let body = cx.lambda(blk);
542+
#ast[expr]{
543+
$(s).emit_enum_variant($(v_name), $(v_id), $(sz), $(body))
544+
}
545+
},
546+
547+
// Generate s.emit_enum_variant_arg(i, {|| blk })
548+
{|-s, i, -blk|
549+
let idx = cx.lit_uint(i);
550+
let body = cx.lambda(blk);
551+
#ast[expr]{
552+
$(s).emit_enum_variant_arg($(idx), $(body))
553+
}
554+
})
555+
};
556+
};
557+
558+
@{ident: name,
559+
attrs: [],
560+
id: ext_cx.session().next_node_id(),
561+
node: ast::item_mod({view_items: [],
562+
items: [ser_fn]}),
563+
span: span}
564+
}

0 commit comments

Comments
 (0)