Make 1-1 parse again
Issue #954 This is not a very elegant fix -- we should probably do something with constant folding to handle negative-int alt patterns in the future.
This commit is contained in:
parent
c7eee8fb05
commit
f26e770745
4 changed files with 82 additions and 34 deletions
|
|
@ -754,6 +754,43 @@ fn gather_comments_and_literals(cm: codemap::codemap, path: str,
|
|||
}
|
||||
ret {cmnts: comments, lits: literals};
|
||||
}
|
||||
|
||||
// This is a stopgap fix. We will have to do better eventually (issue #954)
|
||||
fn maybe_untangle_minus_from_lit(r: reader, t: token::token)
|
||||
-> option::t<token::token> {
|
||||
fn check_str(r: reader, i: uint) -> option::t<uint> {
|
||||
let it = r.get_interner(), s = interner::get(*it, i);
|
||||
if s[0] == '-' as u8 {
|
||||
some(interner::intern(*it, str::slice(s, 1u, str::byte_len(s))))
|
||||
} else { none }
|
||||
}
|
||||
alt t {
|
||||
token::LIT_INT(v) {
|
||||
if v < 0 { ret some(token::LIT_INT(-v)); }
|
||||
}
|
||||
token::LIT_UINT(v) {
|
||||
if v > 0x7fffffffu { ret some(token::LIT_UINT(-(v as int) as uint)); }
|
||||
}
|
||||
token::LIT_MACH_INT(m, v) {
|
||||
if v < 0 { ret some(token::LIT_MACH_INT(m, -v)); }
|
||||
}
|
||||
token::LIT_FLOAT(s) {
|
||||
alt check_str(r, s) {
|
||||
some(s) { ret some(token::LIT_FLOAT(s)); }
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
token::LIT_MACH_FLOAT(m, s) {
|
||||
alt check_str(r, s) {
|
||||
some(s) { ret some(token::LIT_MACH_FLOAT(m, s)); }
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
none
|
||||
}
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
|
|
|
|||
|
|
@ -678,40 +678,31 @@ fn parse_seq<@T>(bra: token::token, ket: token::token,
|
|||
ret spanned(lo, hi, result);
|
||||
}
|
||||
|
||||
fn lit_from_token(p: parser, tok: token::token) -> ast::lit_ {
|
||||
alt tok {
|
||||
token::LIT_INT(i) { ast::lit_int(i) }
|
||||
token::LIT_UINT(u) { ast::lit_uint(u) }
|
||||
token::LIT_FLOAT(s) { ast::lit_float(p.get_str(s)) }
|
||||
token::LIT_MACH_INT(tm, i) { ast::lit_mach_int(tm, i) }
|
||||
token::LIT_MACH_FLOAT(tm, s) { ast::lit_mach_float(tm, p.get_str(s)) }
|
||||
token::LIT_CHAR(c) { ast::lit_char(c) }
|
||||
token::LIT_STR(s) { ast::lit_str(p.get_str(s)) }
|
||||
token::LPAREN. { expect(p, token::RPAREN); ast::lit_nil }
|
||||
_ { unexpected(p, tok); }
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_lit(p: parser) -> ast::lit {
|
||||
let sp = p.get_span();
|
||||
let lit: ast::lit_ = ast::lit_nil;
|
||||
if eat_word(p, "true") {
|
||||
lit = ast::lit_bool(true);
|
||||
let lit = if eat_word(p, "true") {
|
||||
ast::lit_bool(true)
|
||||
} else if eat_word(p, "false") {
|
||||
lit = ast::lit_bool(false);
|
||||
ast::lit_bool(false)
|
||||
} else {
|
||||
alt p.peek() {
|
||||
token::LIT_INT(i) { p.bump(); lit = ast::lit_int(i); }
|
||||
token::LIT_UINT(u) { p.bump(); lit = ast::lit_uint(u); }
|
||||
token::LIT_FLOAT(s) {
|
||||
p.bump();
|
||||
lit = ast::lit_float(p.get_str(s));
|
||||
}
|
||||
token::LIT_MACH_INT(tm, i) {
|
||||
p.bump();
|
||||
lit = ast::lit_mach_int(tm, i);
|
||||
}
|
||||
token::LIT_MACH_FLOAT(tm, s) {
|
||||
p.bump();
|
||||
lit = ast::lit_mach_float(tm, p.get_str(s));
|
||||
}
|
||||
token::LIT_CHAR(c) { p.bump(); lit = ast::lit_char(c); }
|
||||
token::LIT_STR(s) { p.bump(); lit = ast::lit_str(p.get_str(s)); }
|
||||
token::LPAREN. {
|
||||
p.bump();
|
||||
expect(p, token::RPAREN);
|
||||
lit = ast::lit_nil;
|
||||
}
|
||||
t { unexpected(p, t); }
|
||||
}
|
||||
}
|
||||
let tok = p.peek();
|
||||
p.bump();
|
||||
lit_from_token(p, tok)
|
||||
};
|
||||
ret {node: lit, span: sp};
|
||||
}
|
||||
|
||||
|
|
@ -1200,13 +1191,25 @@ fn parse_more_binops(p: parser, lhs: @ast::expr, min_prec: int) ->
|
|||
@ast::expr {
|
||||
if !expr_has_value(lhs) { ret lhs; }
|
||||
let peeked = p.peek();
|
||||
let lit_after = alt lexer::maybe_untangle_minus_from_lit(p.get_reader(),
|
||||
peeked) {
|
||||
some(tok) {
|
||||
peeked = token::BINOP(token::MINUS);
|
||||
let lit = @{node: lit_from_token(p, tok), span: p.get_span()};
|
||||
some(mk_expr(p, p.get_lo_pos(), p.get_hi_pos(), ast::expr_lit(lit)))
|
||||
}
|
||||
none. { none }
|
||||
};
|
||||
for cur: op_spec in *p.get_prec_table() {
|
||||
if cur.prec > min_prec && cur.tok == peeked {
|
||||
p.bump();
|
||||
let rhs = parse_more_binops(p, parse_prefix_expr(p), cur.prec);
|
||||
let bin =
|
||||
mk_expr(p, lhs.span.lo, rhs.span.hi,
|
||||
ast::expr_binary(cur.op, lhs, rhs));
|
||||
let expr = alt lit_after {
|
||||
some(ex) { ex }
|
||||
_ { parse_prefix_expr(p) }
|
||||
};
|
||||
let rhs = parse_more_binops(p, expr, cur.prec);
|
||||
let bin = mk_expr(p, lhs.span.lo, rhs.span.hi,
|
||||
ast::expr_binary(cur.op, lhs, rhs));
|
||||
ret parse_more_binops(p, bin, min_prec);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ import ast::ty_mach;
|
|||
import ast_util::ty_mach_to_str;
|
||||
import std::map::new_str_hash;
|
||||
import util::interner;
|
||||
import std::{int, uint, str};
|
||||
import std::{int, uint, str, option};
|
||||
import option::{some, none};
|
||||
|
||||
type str_num = uint;
|
||||
|
||||
|
|
@ -211,6 +212,7 @@ pure fn can_begin_expr(t: token) -> bool {
|
|||
_ { false }
|
||||
}
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
|
|
|
|||
6
src/test/run-pass/binary-minus-without-space.rs
Normal file
6
src/test/run-pass/binary-minus-without-space.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// Check that issue #954 stays fixed
|
||||
|
||||
fn main() {
|
||||
alt -1 { -1 {} }
|
||||
assert 1-1 == 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue