Skip to content

Commit 7a3b290

Browse files
committed
Add vstore/evec/estr to compiler.
1 parent 0c94cd5 commit 7a3b290

File tree

19 files changed

+605
-107
lines changed

19 files changed

+605
-107
lines changed

src/librustsyntax/ast.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,14 @@ enum proto {
169169
proto_block, // fn&
170170
}
171171

172+
#[auto_serialize]
173+
enum vstore {
174+
vstore_fixed(option<uint>), // [1,2,3,4]/_ or 4 FIXME: uint -> @expr
175+
vstore_uniq, // [1,2,3,4]/~
176+
vstore_box, // [1,2,3,4]/@
177+
vstore_slice(region) // [1,2,3,4]/&(foo)?
178+
}
179+
172180
pure fn is_blockish(p: ast::proto) -> bool {
173181
alt p {
174182
proto_any | proto_block { true }
@@ -278,6 +286,7 @@ enum alt_mode { alt_check, alt_exhaustive, }
278286

279287
#[auto_serialize]
280288
enum expr_ {
289+
expr_vstore(@expr, vstore),
281290
expr_vec([@expr], mutability),
282291
expr_rec([field], option<@expr>),
283292
expr_call(@expr, [@expr], bool),
@@ -459,6 +468,7 @@ enum ty_ {
459468
ty_tup([@ty]),
460469
ty_path(@path, node_id),
461470
ty_constr(@ty, [@ty_constr]),
471+
ty_vstore(@ty, vstore),
462472
ty_mac(mac),
463473
// ty_infer means the type should be inferred instead of it having been
464474
// specified. This should only appear at the "top level" of a type and not

src/librustsyntax/ext/auto_serialize.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,7 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map,
367367
}
368368

369369
ast::ty_ptr(_) | ast::ty_rptr(_, _) {
370-
cx.span_err(
371-
ty.span, #fmt["Cannot serialize pointer types"]);
370+
cx.span_err(ty.span, "cannot serialize pointer types");
372371
[]
373372
}
374373

@@ -390,8 +389,7 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map,
390389
}
391390

392391
ast::ty_fn(_, _) {
393-
cx.span_err(
394-
ty.span, #fmt["Cannot serialize function types"]);
392+
cx.span_err(ty.span, "cannot serialize function types");
395393
[]
396394
}
397395

@@ -448,17 +446,19 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map,
448446
}
449447

450448
ast::ty_mac(_) {
451-
cx.span_err(
452-
ty.span, #fmt["Cannot serialize macro types"]);
449+
cx.span_err(ty.span, "cannot serialize macro types");
453450
[]
454451
}
455452

456453
ast::ty_infer {
457-
cx.span_err(
458-
ty.span, #fmt["Cannot serialize inferred types"]);
454+
cx.span_err(ty.span, "cannot serialize inferred types");
459455
[]
460456
}
461457

458+
ast::ty_vstore(_, _) {
459+
cx.span_unimpl(ty.span, "serialization for vstore types");
460+
}
461+
462462
ast::ty_vec(mt) {
463463
let ser_e =
464464
cx.expr(
@@ -675,6 +675,10 @@ fn deser_ty(cx: ext_ctxt, tps: deser_tps_map,
675675
#ast{ fail }
676676
}
677677

678+
ast::ty_vstore(_, _) {
679+
cx.span_unimpl(ty.span, "deserialization for vstore types");
680+
}
681+
678682
ast::ty_vec(mt) {
679683
let l = deser_lambda(cx, tps, mt.ty, cx.clone(d));
680684
#ast{ std::serialization::read_to_vec($(d), $(l)) }

src/librustsyntax/fold.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,9 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
389389
fld.new_id(i),
390390
fld.fold_expr(v))
391391
}
392+
expr_vstore(e, v) {
393+
expr_vstore(fld.fold_expr(e), v)
394+
}
392395
expr_vec(exprs, mutt) {
393396
expr_vec(fld.map_exprs(fld.fold_expr, exprs), mutt)
394397
}
@@ -497,6 +500,7 @@ fn noop_fold_ty(t: ty_, fld: ast_fold) -> ty_ {
497500
ty_path(path, id) {ty_path(fld.fold_path(path), fld.new_id(id))}
498501
// FIXME: constrs likely needs to be folded...
499502
ty_constr(ty, constrs) {ty_constr(fld.fold_ty(ty), constrs)}
503+
ty_vstore(t, vs) {ty_vstore(fld.fold_ty(t), vs)}
500504
ty_mac(mac) {ty_mac(fold_mac(mac))}
501505
ty_infer {t}
502506
}

src/librustsyntax/parse/parser.rs

Lines changed: 113 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -382,15 +382,32 @@ fn parse_type_constraints(p: parser) -> [@ast::ty_constr] {
382382

383383
fn parse_ty_postfix(orig_t: ast::ty_, p: parser, colons_before_params: bool,
384384
lo: uint) -> @ast::ty {
385+
386+
387+
fn mk_ty(p: parser, t: ast::ty_, lo: uint, hi: uint) -> @ast::ty {
388+
@{id: p.get_id(),
389+
node: t,
390+
span: ast_util::mk_sp(lo, hi)}
391+
}
392+
393+
if p.token == token::BINOP(token::SLASH) {
394+
let orig_hi = p.last_span.hi;
395+
alt parse_maybe_vstore(p) {
396+
none { }
397+
some(v) {
398+
let t = ast::ty_vstore(mk_ty(p, orig_t, lo, orig_hi), v);
399+
ret mk_ty(p, t, lo, p.last_span.hi);
400+
}
401+
}
402+
}
403+
385404
if colons_before_params && p.token == token::MOD_SEP {
386405
p.bump();
387406
expect(p, token::LT);
388407
} else if !colons_before_params && p.token == token::LT {
389408
p.bump();
390409
} else {
391-
ret @{id: p.get_id(),
392-
node: orig_t,
393-
span: ast_util::mk_sp(lo, p.last_span.hi)};
410+
ret mk_ty(p, orig_t, lo, p.last_span.hi);
394411
}
395412

396413
// If we're here, we have explicit type parameter instantiation.
@@ -399,12 +416,11 @@ fn parse_ty_postfix(orig_t: ast::ty_, p: parser, colons_before_params: bool,
399416

400417
alt orig_t {
401418
ast::ty_path(pth, ann) {
402-
ret @{id: p.get_id(),
403-
node: ast::ty_path(@spanned(lo, p.last_span.hi,
404-
{global: pth.node.global,
405-
idents: pth.node.idents,
406-
types: seq}), ann),
407-
span: ast_util::mk_sp(lo, p.last_span.hi)};
419+
ret mk_ty(p, ast::ty_path(@spanned(lo, p.last_span.hi,
420+
{global: pth.node.global,
421+
idents: pth.node.idents,
422+
types: seq}), ann),
423+
lo, p.last_span.hi);
408424
}
409425
_ { p.fatal("type parameter instantiation only allowed for paths"); }
410426
}
@@ -428,22 +444,33 @@ fn parse_ret_ty(p: parser) -> (ast::ret_style, @ast::ty) {
428444
}
429445
}
430446

431-
fn parse_region(p: parser) -> ast::region {
432-
let region_ = alt p.token {
433-
token::IDENT(sid, _) if p.look_ahead(1u) == token::DOT {
434-
let string = p.get_str(sid);
435-
p.bump(); p.bump();
436-
if string == "self" {
437-
ast::re_self
438-
} else if string == "static" {
439-
ast::re_static
440-
} else {
441-
ast::re_named(string)
442-
}
447+
fn region_from_name(p: parser, s: option<str>) -> ast::region {
448+
let r = alt s {
449+
some (string) {
450+
if string == "self" {
451+
ast::re_self
452+
} else if string == "static" {
453+
ast::re_static
454+
} else {
455+
ast::re_named(string)
443456
}
444-
_ { ast::re_inferred }
457+
}
458+
none { ast::re_inferred }
445459
};
446-
ret {id: p.get_id(), node: region_};
460+
461+
{id: p.get_id(), node: r}
462+
}
463+
464+
fn parse_region(p: parser) -> ast::region {
465+
let name =
466+
alt p.token {
467+
token::IDENT(sid, _) if p.look_ahead(1u) == token::DOT {
468+
p.bump(); p.bump();
469+
some(p.get_str(sid))
470+
}
471+
_ { none }
472+
};
473+
region_from_name(p, name)
447474
}
448475

449476
fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty {
@@ -666,6 +693,44 @@ fn have_dollar(p: parser) -> option<ast::mac_> {
666693
}
667694
}
668695

696+
fn parse_maybe_vstore(p: parser) -> option<ast::vstore> {
697+
if p.token == token::BINOP(token::SLASH) {
698+
p.bump();
699+
alt p.token {
700+
token::AT {
701+
p.bump(); some(ast::vstore_box)
702+
}
703+
token::TILDE {
704+
p.bump(); some(ast::vstore_uniq)
705+
}
706+
token::UNDERSCORE {
707+
p.bump(); some(ast::vstore_fixed(none))
708+
}
709+
token::LIT_INT(i, ast::ty_i) if i >= 0 {
710+
p.bump(); some(ast::vstore_fixed(some(i as uint)))
711+
}
712+
token::BINOP(token::AND) {
713+
p.bump();
714+
alt p.token {
715+
token::IDENT(sid, _) {
716+
p.bump();
717+
let n = p.get_str(sid);
718+
some(ast::vstore_slice(region_from_name(p, some(n))))
719+
}
720+
_ {
721+
some(ast::vstore_slice(region_from_name(p, none)))
722+
}
723+
}
724+
}
725+
_ {
726+
none
727+
}
728+
}
729+
} else {
730+
none
731+
}
732+
}
733+
669734
fn lit_from_token(p: parser, tok: token::token) -> ast::lit_ {
670735
alt tok {
671736
token::LIT_INT(i, it) { ast::lit_int(i, it) }
@@ -678,7 +743,7 @@ fn lit_from_token(p: parser, tok: token::token) -> ast::lit_ {
678743
}
679744

680745
fn parse_lit(p: parser) -> ast::lit {
681-
let sp = p.span;
746+
let lo = p.span.lo;
682747
let lit = if eat_word(p, "true") {
683748
ast::lit_bool(true)
684749
} else if eat_word(p, "false") {
@@ -688,7 +753,7 @@ fn parse_lit(p: parser) -> ast::lit {
688753
p.bump();
689754
lit_from_token(p, tok)
690755
};
691-
ret {node: lit, span: sp};
756+
ret {node: lit, span: ast_util::mk_sp(lo, p.last_span.hi)};
692757
}
693758

694759
fn is_ident(t: token::token) -> bool {
@@ -891,6 +956,7 @@ fn parse_bottom_expr(p: parser) -> pexpr {
891956
let es =
892957
parse_seq_to_end(token::RBRACKET, seq_sep(token::COMMA),
893958
parse_expr, p);
959+
hi = p.span.hi;
894960
ex = ast::expr_vec(es, mutbl);
895961
} else if p.token == token::POUND_LT {
896962
p.bump();
@@ -988,6 +1054,23 @@ fn parse_bottom_expr(p: parser) -> pexpr {
9881054
hi = lit.span.hi;
9891055
ex = ast::expr_lit(@lit);
9901056
}
1057+
1058+
// Vstore is legal following expr_lit(lit_str(...)) and expr_vec(...)
1059+
// only.
1060+
alt ex {
1061+
ast::expr_lit(@{node: ast::lit_str(_), span: _}) |
1062+
ast::expr_vec(_, _) {
1063+
alt parse_maybe_vstore(p) {
1064+
none { }
1065+
some(v) {
1066+
hi = p.span.hi;
1067+
ex = ast::expr_vstore(mk_expr(p, lo, hi, ex), v);
1068+
}
1069+
}
1070+
}
1071+
_ { }
1072+
}
1073+
9911074
ret mk_pexpr(p, lo, hi, ex);
9921075
}
9931076

@@ -1194,10 +1277,10 @@ type op_spec = {tok: token::token, op: ast::binop, prec: int};
11941277

11951278
// FIXME make this a const, don't store it in parser state
11961279
fn prec_table() -> @[op_spec] {
1197-
ret @[// 'as' sits between here with 12
1198-
{tok: token::BINOP(token::STAR), op: ast::mul, prec: 11},
1199-
{tok: token::BINOP(token::SLASH), op: ast::div, prec: 11},
1200-
{tok: token::BINOP(token::PERCENT), op: ast::rem, prec: 11},
1280+
ret @[{tok: token::BINOP(token::STAR), op: ast::mul, prec: 12},
1281+
{tok: token::BINOP(token::SLASH), op: ast::div, prec: 12},
1282+
{tok: token::BINOP(token::PERCENT), op: ast::rem, prec: 12},
1283+
// 'as' sits between here with 11
12011284
{tok: token::BINOP(token::PLUS), op: ast::add, prec: 10},
12021285
{tok: token::BINOP(token::MINUS), op: ast::subtract, prec: 10},
12031286
{tok: token::BINOP(token::LSL), op: ast::lsl, prec: 9},
@@ -1222,7 +1305,7 @@ fn parse_binops(p: parser) -> @ast::expr {
12221305

12231306
const unop_prec: int = 100;
12241307

1225-
const as_prec: int = 12;
1308+
const as_prec: int = 11;
12261309

12271310
fn parse_more_binops(p: parser, plhs: pexpr, min_prec: int) ->
12281311
@ast::expr {

src/librustsyntax/print/pprust.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,10 @@ fn print_type(s: ps, &&ty: @ast::ty) {
378378
space(s.s);
379379
word(s.s, constrs_str(cs, ty_constr_to_str));
380380
}
381+
ast::ty_vstore(t, v) {
382+
print_type(s, t);
383+
print_vstore(s, v);
384+
}
381385
ast::ty_mac(_) {
382386
fail "print_type doesn't know how to print a ty_mac";
383387
}
@@ -810,12 +814,36 @@ fn print_mac(s: ps, m: ast::mac) {
810814
}
811815
}
812816

817+
fn print_vstore(s: ps, t: ast::vstore) {
818+
alt t {
819+
ast::vstore_fixed(some(i)) { word_space(s, #fmt("/%u", i)); }
820+
ast::vstore_fixed(none) { word_space(s, "/_"); }
821+
ast::vstore_uniq { word_space(s, "/~"); }
822+
ast::vstore_box { word_space(s, "/@"); }
823+
ast::vstore_slice(r) {
824+
alt r.node {
825+
ast::re_inferred { word_space(s, "/&"); }
826+
ast::re_self { word_space(s, "/&self"); }
827+
ast::re_static { word_space(s, "/&static"); }
828+
ast::re_named(name) {
829+
word(s.s, "/&");
830+
word_space(s, name);
831+
}
832+
}
833+
}
834+
}
835+
}
836+
813837
fn print_expr(s: ps, &&expr: @ast::expr) {
814838
maybe_print_comment(s, expr.span.lo);
815839
ibox(s, indent_unit);
816840
let ann_node = node_expr(s, expr);
817841
s.ann.pre(ann_node);
818842
alt expr.node {
843+
ast::expr_vstore(e, v) {
844+
print_expr(s, e);
845+
print_vstore(s, v);
846+
}
819847
ast::expr_vec(exprs, mutbl) {
820848
ibox(s, indent_unit);
821849
word(s.s, "[");

0 commit comments

Comments
 (0)