Skip to content

Commit f26e770

Browse files
committed
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.
1 parent c7eee8f commit f26e770

File tree

4 files changed

+82
-34
lines changed

4 files changed

+82
-34
lines changed

src/comp/syntax/parse/lexer.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,43 @@ fn gather_comments_and_literals(cm: codemap::codemap, path: str,
754754
}
755755
ret {cmnts: comments, lits: literals};
756756
}
757+
758+
// This is a stopgap fix. We will have to do better eventually (issue #954)
759+
fn maybe_untangle_minus_from_lit(r: reader, t: token::token)
760+
-> option::t<token::token> {
761+
fn check_str(r: reader, i: uint) -> option::t<uint> {
762+
let it = r.get_interner(), s = interner::get(*it, i);
763+
if s[0] == '-' as u8 {
764+
some(interner::intern(*it, str::slice(s, 1u, str::byte_len(s))))
765+
} else { none }
766+
}
767+
alt t {
768+
token::LIT_INT(v) {
769+
if v < 0 { ret some(token::LIT_INT(-v)); }
770+
}
771+
token::LIT_UINT(v) {
772+
if v > 0x7fffffffu { ret some(token::LIT_UINT(-(v as int) as uint)); }
773+
}
774+
token::LIT_MACH_INT(m, v) {
775+
if v < 0 { ret some(token::LIT_MACH_INT(m, -v)); }
776+
}
777+
token::LIT_FLOAT(s) {
778+
alt check_str(r, s) {
779+
some(s) { ret some(token::LIT_FLOAT(s)); }
780+
_ {}
781+
}
782+
}
783+
token::LIT_MACH_FLOAT(m, s) {
784+
alt check_str(r, s) {
785+
some(s) { ret some(token::LIT_MACH_FLOAT(m, s)); }
786+
_ {}
787+
}
788+
}
789+
_ {}
790+
}
791+
none
792+
}
793+
757794
//
758795
// Local Variables:
759796
// mode: rust

src/comp/syntax/parse/parser.rs

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -678,40 +678,31 @@ fn parse_seq<@T>(bra: token::token, ket: token::token,
678678
ret spanned(lo, hi, result);
679679
}
680680

681+
fn lit_from_token(p: parser, tok: token::token) -> ast::lit_ {
682+
alt tok {
683+
token::LIT_INT(i) { ast::lit_int(i) }
684+
token::LIT_UINT(u) { ast::lit_uint(u) }
685+
token::LIT_FLOAT(s) { ast::lit_float(p.get_str(s)) }
686+
token::LIT_MACH_INT(tm, i) { ast::lit_mach_int(tm, i) }
687+
token::LIT_MACH_FLOAT(tm, s) { ast::lit_mach_float(tm, p.get_str(s)) }
688+
token::LIT_CHAR(c) { ast::lit_char(c) }
689+
token::LIT_STR(s) { ast::lit_str(p.get_str(s)) }
690+
token::LPAREN. { expect(p, token::RPAREN); ast::lit_nil }
691+
_ { unexpected(p, tok); }
692+
}
693+
}
681694

682695
fn parse_lit(p: parser) -> ast::lit {
683696
let sp = p.get_span();
684-
let lit: ast::lit_ = ast::lit_nil;
685-
if eat_word(p, "true") {
686-
lit = ast::lit_bool(true);
697+
let lit = if eat_word(p, "true") {
698+
ast::lit_bool(true)
687699
} else if eat_word(p, "false") {
688-
lit = ast::lit_bool(false);
700+
ast::lit_bool(false)
689701
} else {
690-
alt p.peek() {
691-
token::LIT_INT(i) { p.bump(); lit = ast::lit_int(i); }
692-
token::LIT_UINT(u) { p.bump(); lit = ast::lit_uint(u); }
693-
token::LIT_FLOAT(s) {
694-
p.bump();
695-
lit = ast::lit_float(p.get_str(s));
696-
}
697-
token::LIT_MACH_INT(tm, i) {
698-
p.bump();
699-
lit = ast::lit_mach_int(tm, i);
700-
}
701-
token::LIT_MACH_FLOAT(tm, s) {
702-
p.bump();
703-
lit = ast::lit_mach_float(tm, p.get_str(s));
704-
}
705-
token::LIT_CHAR(c) { p.bump(); lit = ast::lit_char(c); }
706-
token::LIT_STR(s) { p.bump(); lit = ast::lit_str(p.get_str(s)); }
707-
token::LPAREN. {
708-
p.bump();
709-
expect(p, token::RPAREN);
710-
lit = ast::lit_nil;
711-
}
712-
t { unexpected(p, t); }
713-
}
714-
}
702+
let tok = p.peek();
703+
p.bump();
704+
lit_from_token(p, tok)
705+
};
715706
ret {node: lit, span: sp};
716707
}
717708

@@ -1200,13 +1191,25 @@ fn parse_more_binops(p: parser, lhs: @ast::expr, min_prec: int) ->
12001191
@ast::expr {
12011192
if !expr_has_value(lhs) { ret lhs; }
12021193
let peeked = p.peek();
1194+
let lit_after = alt lexer::maybe_untangle_minus_from_lit(p.get_reader(),
1195+
peeked) {
1196+
some(tok) {
1197+
peeked = token::BINOP(token::MINUS);
1198+
let lit = @{node: lit_from_token(p, tok), span: p.get_span()};
1199+
some(mk_expr(p, p.get_lo_pos(), p.get_hi_pos(), ast::expr_lit(lit)))
1200+
}
1201+
none. { none }
1202+
};
12031203
for cur: op_spec in *p.get_prec_table() {
12041204
if cur.prec > min_prec && cur.tok == peeked {
12051205
p.bump();
1206-
let rhs = parse_more_binops(p, parse_prefix_expr(p), cur.prec);
1207-
let bin =
1208-
mk_expr(p, lhs.span.lo, rhs.span.hi,
1209-
ast::expr_binary(cur.op, lhs, rhs));
1206+
let expr = alt lit_after {
1207+
some(ex) { ex }
1208+
_ { parse_prefix_expr(p) }
1209+
};
1210+
let rhs = parse_more_binops(p, expr, cur.prec);
1211+
let bin = mk_expr(p, lhs.span.lo, rhs.span.hi,
1212+
ast::expr_binary(cur.op, lhs, rhs));
12101213
ret parse_more_binops(p, bin, min_prec);
12111214
}
12121215
}

src/comp/syntax/parse/token.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import ast::ty_mach;
33
import ast_util::ty_mach_to_str;
44
import std::map::new_str_hash;
55
import util::interner;
6-
import std::{int, uint, str};
6+
import std::{int, uint, str, option};
7+
import option::{some, none};
78

89
type str_num = uint;
910

@@ -211,6 +212,7 @@ pure fn can_begin_expr(t: token) -> bool {
211212
_ { false }
212213
}
213214
}
215+
214216
// Local Variables:
215217
// fill-column: 78;
216218
// indent-tabs-mode: nil
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Check that issue #954 stays fixed
2+
3+
fn main() {
4+
alt -1 { -1 {} }
5+
assert 1-1 == 0;
6+
}

0 commit comments

Comments
 (0)