Skip to content

Commit f6fe07d

Browse files
committed
Add support for negative literals.
1 parent c0ffd2e commit f6fe07d

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

src/comp/syntax/parse/lexer.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,15 @@ fn consume_block_comment(rdr: reader) {
158158
be consume_whitespace_and_comments(rdr);
159159
}
160160

161-
fn digits_to_string(s: str) -> int {
161+
fn string_to_int(s: str) -> int {
162+
let negative = false;
163+
if str::char_at(s, 0u) == '-' {
164+
negative = true;
165+
s = str::substr(s, 1u, str::byte_len(s) - 1u);
166+
}
162167
let accum_int: int = 0;
163168
for c: u8 in s { accum_int *= 10; accum_int += dec_digit_val(c as char); }
164-
ret accum_int;
169+
ret if negative { -accum_int } else { accum_int };
165170
}
166171

167172
fn scan_exponent(rdr: reader) -> option::t<str> {
@@ -182,6 +187,17 @@ fn scan_exponent(rdr: reader) -> option::t<str> {
182187
} else { ret none::<str>; }
183188
}
184189

190+
fn scan_dec_digits_with_prefix(rdr: reader) -> str {
191+
let negative = false;
192+
if rdr.curr() == '-' {
193+
negative = true;
194+
rdr.bump();
195+
}
196+
let digits = scan_dec_digits(rdr);
197+
if negative { str::unshift_char(digits, '-') }
198+
ret digits;
199+
}
200+
185201
fn scan_dec_digits(rdr: reader) -> str {
186202
let c = rdr.curr();
187203
let rslt: str = "";
@@ -196,7 +212,6 @@ fn scan_dec_digits(rdr: reader) -> str {
196212
fn scan_number(c: char, rdr: reader) -> token::token {
197213
let accum_int = 0;
198214
let num_str: str = "";
199-
let is_dec_integer: bool = false;
200215
let n = rdr.next();
201216
if c == '0' && n == 'x' {
202217
rdr.bump();
@@ -216,8 +231,10 @@ fn scan_number(c: char, rdr: reader) -> token::token {
216231
rdr.bump();
217232
c = rdr.curr();
218233
}
219-
} else { num_str = scan_dec_digits(rdr); is_dec_integer = true; }
220-
if is_dec_integer { accum_int = digits_to_string(num_str); }
234+
} else {
235+
num_str = scan_dec_digits_with_prefix(rdr);
236+
accum_int = string_to_int(num_str);
237+
}
221238
c = rdr.curr();
222239
n = rdr.next();
223240
if c == 'u' || c == 'i' {
@@ -341,7 +358,9 @@ fn next_token_inner(rdr: reader) -> token::token {
341358
ret token::IDENT(interner::intern::<str>(*rdr.get_interner(),
342359
accum_str), is_mod_name);
343360
}
344-
if is_dec_digit(c) { ret scan_number(c, rdr); }
361+
if is_dec_digit(c) || (c == '-' && is_dec_digit(rdr.next())) {
362+
ret scan_number(c, rdr);
363+
}
345364
fn binop(rdr: reader, op: token::binop) -> token::token {
346365
rdr.bump();
347366
if rdr.curr() == '=' {

src/test/run-pass/negative.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
alt -5 {
3+
-5 {}
4+
_ { fail }
5+
}
6+
}

0 commit comments

Comments
 (0)