syntax: More tweaks to make alt arrows parse and print correctly

This commit is contained in:
Brian Anderson 2012-07-31 13:43:20 -07:00
parent c206d024eb
commit 567f881fdf
6 changed files with 67 additions and 49 deletions

View File

@ -761,33 +761,11 @@ class parser {
// which affects expr_is_complete().
ret self.mk_pexpr(lo, hi, expr_tup(es));
} else if self.token == token::LBRACE {
self.bump();
if self.is_keyword(~"mut") ||
is_plain_ident(self.token)
&& self.look_ahead(1u) == token::COLON {
let mut fields = ~[self.parse_field(token::COLON)];
let mut base = none;
while self.token != token::RBRACE {
// optional comma before "with"
if self.token == token::COMMA
&& self.token_is_keyword(~"with",
self.look_ahead(1u)) {
self.bump();
}
if self.eat_keyword(~"with") {
base = some(self.parse_expr()); break;
}
self.expect(token::COMMA);
if self.token == token::RBRACE {
// record ends by an optional trailing comma
break;
}
vec::push(fields, self.parse_field(token::COLON));
}
if self.looking_at_record_literal() {
ex = self.parse_record_literal();
hi = self.span.hi;
self.expect(token::RBRACE);
ex = expr_rec(fields, base);
} else {
self.bump();
let blk = self.parse_block_tail(lo, default_blk);
ret self.mk_pexpr(blk.span.lo, blk.span.hi, expr_block(blk));
}
@ -897,25 +875,18 @@ class parser {
ret pexpr(self.mk_mac_expr(lo, hi, mac_invoc_tt(pth, tts)));
} else if self.token == token::LBRACE {
// This might be a struct literal.
let lookahead = self.look_ahead(1);
if self.token_is_keyword(~"mut", lookahead) ||
(is_plain_ident(lookahead) &&
self.look_ahead(2) == token::COLON) {
if self.looking_at_record_literal() {
// It's a struct literal.
self.bump();
let mut fields = ~[];
if self.is_keyword(~"mut") || is_plain_ident(self.token)
&& self.look_ahead(1) == token::COLON {
vec::push(fields, self.parse_field(token::COLON));
while self.token != token::RBRACE {
self.expect(token::COMMA);
if self.token == token::RBRACE {
// Accept an optional trailing comma.
break;
}
vec::push(fields, self.parse_field(token::COLON));
vec::push(fields, self.parse_field(token::COLON));
while self.token != token::RBRACE {
self.expect(token::COMMA);
if self.token == token::RBRACE {
// Accept an optional trailing comma.
break;
}
vec::push(fields, self.parse_field(token::COLON));
}
hi = pth.span.hi;
@ -1500,6 +1471,39 @@ class parser {
ret self.mk_expr(lo, hi, expr_loop(body));
}
// For distingishing between record literals and blocks
fn looking_at_record_literal() -> bool {
let lookahead = self.look_ahead(1);
self.token_is_keyword(~"mut", lookahead) ||
(is_plain_ident(lookahead) &&
self.look_ahead(2) == token::COLON)
}
fn parse_record_literal() -> expr_ {
self.expect(token::LBRACE);
let mut fields = ~[self.parse_field(token::COLON)];
let mut base = none;
while self.token != token::RBRACE {
// optional comma before "with"
if self.token == token::COMMA
&& self.token_is_keyword(~"with",
self.look_ahead(1u)) {
self.bump();
}
if self.eat_keyword(~"with") {
base = some(self.parse_expr()); break;
}
self.expect(token::COMMA);
if self.token == token::RBRACE {
// record ends by an optional trailing comma
break;
}
vec::push(fields, self.parse_field(token::COLON));
}
self.expect(token::RBRACE);
ret expr_rec(fields, base);
}
fn parse_alt_expr() -> @expr {
let lo = self.last_span.lo;
let mode = if self.eat_keyword(~"check") { alt_check }
@ -1515,7 +1519,8 @@ class parser {
self.parse_block()
} else {
self.bump();
if self.token == token::LBRACE {
if self.token == token::LBRACE
&& !self.looking_at_record_literal() {
self.parse_block()
} else {
let expr = self.parse_expr();

View File

@ -1056,7 +1056,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
some(expr) => {
end(s); // close the ibox for the pattern
print_expr(s, expr);
if i < len - 1 { word_space(s, ~","); }
if i < len - 1 { word(s.s, ~","); }
end(s); // close enclosing cbox
}
none => {

View File

@ -8,10 +8,9 @@ fn main() {
let y =
alt x {
some(_) =>
"some" + "very" + "very" + "very" + "very" + "very" + "very" +
"very" + "very" + "long" + "string",
none => "none"
~"some" + ~"very" + ~"very" + ~"very" + ~"very" + ~"very" +
~"very" + ~"very" + ~"very" + ~"long" + ~"string",
none => ~"none"
};
assert y == "some(_)";
assert y == ~"some(_)";
}

View File

@ -2,6 +2,6 @@
fn main() {
let x = some(3);
let y = alt x { some(_) => "some(_)", none => "none" };
assert y == "some(_)";
let y = alt x { some(_) => ~"some(_)", none => ~"none" };
assert y == ~"some(_)";
}

View File

@ -0,0 +1,7 @@
fn main() {
let x = alt 0 {
_ => {
x: 0
}.x
};
}

View File

@ -0,0 +1,7 @@
fn main() {
let x = alt 0 {
_ => {
x: 0
}
};
}