Skip to content

Commit 1950778

Browse files
committed
Add support for bracey record types and literals
type foo = {mutable x: int, y: int}; auto myfoo = {mutable x: 10, y: 20u}; The old syntax is also still supported.
1 parent cce1b46 commit 1950778

File tree

1 file changed

+46
-8
lines changed

1 file changed

+46
-8
lines changed

src/comp/syntax/parse/parser.rs

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ fn new_parser(parse_sess sess, ast::crate_cfg cfg, lexer::reader rdr,
102102
fn look_ahead(uint distance) -> token::token {
103103
while ivec::len(buffer) < distance {
104104
auto next = lexer::next_token(rdr);
105-
buffer =
106-
~[tup(next._0, rec(lo=next._1, hi=rdr.get_chpos()))] + buffer;
105+
auto sp = rec(lo=next._1, hi=rdr.get_chpos());
106+
buffer = ~[tup(next._0, sp)] + buffer;
107107
}
108108
ret buffer.(distance-1u)._0;
109109
}
@@ -344,6 +344,15 @@ fn parse_ty_field(&parser p) -> ast::ty_field {
344344
ret spanned(lo, mt.ty.span.hi, rec(ident=id, mt=mt));
345345
}
346346

347+
// FIXME rename to parse_ty_field once the other one is dropped
348+
fn parse_ty_field_modern(&parser p) -> ast::ty_field {
349+
auto lo = p.get_lo_pos();
350+
auto mut = parse_mutability(p);
351+
auto id = parse_ident(p);
352+
expect(p, token::COLON);
353+
auto ty = parse_ty(p);
354+
ret spanned(lo, ty.span.hi, rec(ident=id, mt=rec(ty=ty, mut=mut)));
355+
}
347356

348357
// if i is the jth ident in args, return j
349358
// otherwise, fail
@@ -540,6 +549,16 @@ fn parse_ty(&parser p) -> @ast::ty {
540549
auto mt = parse_mt(p);
541550
hi = mt.ty.span.hi;
542551
t = ast::ty_ptr(mt);
552+
} else if (p.peek() == token::LBRACE) {
553+
auto elems = parse_seq(token::LBRACE, token::RBRACE,
554+
some(token::COMMA), parse_ty_field_modern, p);
555+
hi = elems.span.hi;
556+
t = ast::ty_rec(elems.node);
557+
if (p.peek() == token::COLON) {
558+
p.bump();
559+
t = ast::ty_constr(@spanned(lo, hi, t),
560+
parse_type_constraints(p));
561+
}
543562
} else if (eat_word(p, "vec")) {
544563
expect(p, token::LBRACKET);
545564
t = ast::ty_vec(parse_mt(p));
@@ -738,11 +757,11 @@ fn parse_mutability(&parser p) -> ast::mutability {
738757
ret ast::imm;
739758
}
740759

741-
fn parse_field(&parser p) -> ast::field {
760+
fn parse_field(&parser p, &token::token sep) -> ast::field {
742761
auto lo = p.get_lo_pos();
743762
auto m = parse_mutability(p);
744763
auto i = parse_ident(p);
745-
expect(p, token::EQ);
764+
expect(p, sep);
746765
auto e = parse_expr(p);
747766
ret spanned(lo, e.span.hi, rec(mut=m, ident=i, expr=e));
748767
}
@@ -783,8 +802,27 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
783802
expect(p, token::RPAREN);
784803
ret mk_expr(p, lo, hi, e.node);
785804
} else if (p.peek() == token::LBRACE) {
786-
auto blk = parse_block(p);
787-
ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk));
805+
p.bump();
806+
if (is_word(p, "mutable") ||
807+
alt p.peek() { token::IDENT(_, false) { true } _ { false } } &&
808+
p.look_ahead(1u) == token::COLON) {
809+
auto fields = ~[parse_field(p, token::COLON)];
810+
auto base = none;
811+
while p.peek() != token::RBRACE {
812+
if eat_word(p, "with") {
813+
base = some(parse_expr(p));
814+
break;
815+
}
816+
expect(p, token::COMMA);
817+
fields += ~[parse_field(p, token::COLON)];
818+
}
819+
hi = p.get_hi_pos();
820+
expect(p, token::RBRACE);
821+
ex = ast::expr_rec(fields, base);
822+
} else {
823+
auto blk = parse_block_tail(p);
824+
ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk));
825+
}
788826
} else if (eat_word(p, "if")) {
789827
ret parse_if_expr(p);
790828
} else if (eat_word(p, "for")) {
@@ -883,7 +921,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
883921
ex = ast::expr_anon_obj(ob);
884922
} else if (eat_word(p, "rec")) {
885923
expect(p, token::LPAREN);
886-
auto fields = ~[parse_field(p)];
924+
auto fields = ~[parse_field(p, token::EQ)];
887925
auto more = true;
888926
auto base = none;
889927
while (more) {
@@ -898,7 +936,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
898936
more = false;
899937
} else if (p.peek() == token::COMMA) {
900938
p.bump();
901-
fields += ~[parse_field(p)];
939+
fields += ~[parse_field(p, token::EQ)];
902940
} else { unexpected(p, p.peek()); }
903941
}
904942
ex = ast::expr_rec(fields, base);

0 commit comments

Comments
 (0)