diff --git a/src/Makefile b/src/Makefile index db21cab17b6..83a3df32046 100644 --- a/src/Makefile +++ b/src/Makefile @@ -529,10 +529,15 @@ TEST_XFAILS_SELF := $(filter-out \ fact.rs \ hello.rs \ int.rs \ + i32-sub.rs \ + i8-incr.rs \ item-name-overload.rs \ lazy-init.rs \ multiline-comment.rs \ return-nil.rs \ + u32-decr.rs \ + u8-incr.rs \ + u8-incr-decr.rs \ uint.rs \ unit.rs \ while-and-do-while.rs \ diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 3a67d2f273c..ddd02a03125 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -4,6 +4,7 @@ import std.option; import middle.typeck; import util.common.span; import util.common.spanned; +import util.common.ty_mach; type ident = str; @@ -116,6 +117,7 @@ tag lit_ { lit_char(char); lit_int(int); lit_uint(uint); + lit_mach_int(ty_mach, int); lit_nil; lit_bool(bool); } diff --git a/src/comp/front/lexer.rs b/src/comp/front/lexer.rs index 38e9367f5a2..0506ce6c360 100644 --- a/src/comp/front/lexer.rs +++ b/src/comp/front/lexer.rs @@ -302,9 +302,102 @@ impure fn consume_block_comment(reader rdr) { be consume_any_whitespace(rdr); } +impure fn scan_number(mutable char c, reader rdr) -> token.token { + auto accum_int = 0; + auto n = rdr.next(); + + if (c == '0' && n == 'x') { + rdr.bump(); + rdr.bump(); + c = rdr.curr(); + while (is_hex_digit(c) || c == '_') { + if (c != '_') { + accum_int *= 16; + accum_int += hex_digit_val(c); + } + rdr.bump(); + c = rdr.curr(); + } + } + + if (c == '0' && n == 'b') { + rdr.bump(); + rdr.bump(); + c = rdr.curr(); + while (is_bin_digit(c) || c == '_') { + if (c != '_') { + accum_int *= 2; + accum_int += bin_digit_value(c); + } + rdr.bump(); + c = rdr.curr(); + } + } + + while (is_dec_digit(c) || c == '_') { + if (c != '_') { + accum_int *= 10; + accum_int += dec_digit_val(c); + } + rdr.bump(); + c = rdr.curr(); + } + + if (c == 'u' || c == 'i') { + let bool signed = (c == 'i'); + rdr.bump(); + c = rdr.curr(); + if (c == '8') { + rdr.bump(); + if (signed) { + ret token.LIT_MACH_INT(common.ty_i8, accum_int); + } else { + ret token.LIT_MACH_INT(common.ty_u8, accum_int); + } + } + + n = rdr.next(); + if (c == '1' && n == '6') { + rdr.bump(); + rdr.bump(); + if (signed) { + ret token.LIT_MACH_INT(common.ty_i16, accum_int); + } else { + ret token.LIT_MACH_INT(common.ty_u16, accum_int); + } + } + if (c == '3' && n == '2') { + rdr.bump(); + rdr.bump(); + if (signed) { + ret token.LIT_MACH_INT(common.ty_i32, accum_int); + } else { + ret token.LIT_MACH_INT(common.ty_u32, accum_int); + } + } + + if (c == '6' && n == '4') { + rdr.bump(); + rdr.bump(); + if (signed) { + ret token.LIT_MACH_INT(common.ty_i64, accum_int); + } else { + ret token.LIT_MACH_INT(common.ty_u64, accum_int); + } + } + + if (signed) { + ret token.LIT_INT(accum_int); + } else { + // FIXME: should cast in the target bit-width. + ret token.LIT_UINT(accum_int as uint); + } + } + ret token.LIT_INT(accum_int); +} + impure fn next_token(reader rdr) -> token.token { auto accum_str = ""; - auto accum_int = 0; consume_any_whitespace(rdr); @@ -328,39 +421,7 @@ impure fn next_token(reader rdr) -> token.token { } if (is_dec_digit(c)) { - auto n = rdr.next(); - if (c == '0' && n == 'x') { - rdr.bump(); - rdr.bump(); - c = rdr.curr(); - while (is_hex_digit(c) || c == '_') { - accum_int *= 16; - accum_int += hex_digit_val(c); - rdr.bump(); - c = rdr.curr(); - } - } - - if (c == '0' && n == 'b') { - rdr.bump(); - rdr.bump(); - c = rdr.curr(); - while (is_bin_digit(c) || c == '_') { - accum_int *= 2; - accum_int += bin_digit_value(c); - rdr.bump(); - c = rdr.curr(); - } - } - - while (is_dec_digit(c) || c == '_') { - accum_int *= 10; - accum_int += dec_digit_val(c); - rdr.bump(); - c = rdr.curr(); - } - - ret token.LIT_INT(accum_int); + ret scan_number(c, rdr); } impure fn binop(reader rdr, token.binop op) -> token.token { diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 8e47cf77720..732e5b170ae 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -287,6 +287,10 @@ impure fn parse_lit(parser p) -> option.t[ast.lit] { p.bump(); lit = ast.lit_uint(u); } + case (token.LIT_MACH_INT(?tm, ?i)) { + p.bump(); + lit = ast.lit_mach_int(tm, i); + } case (token.LIT_CHAR(?c)) { p.bump(); lit = ast.lit_char(c); diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 9bc1f19ce92..f7ee82f6715 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -529,6 +529,27 @@ impure fn trans_lit(@block_ctxt cx, &ast.lit lit) -> result { case (ast.lit_uint(?u)) { ret res(cx, C_int(u as int)); } + case (ast.lit_mach_int(?tm, ?i)) { + // FIXME: the entire handling of mach types falls apart + // if target int width is larger than host, at the moment; + // re-do the mach-int types using 'big' when that works. + auto t = T_int(); + alt (tm) { + case (common.ty_u8) { t = T_i8(); } + case (common.ty_u16) { t = T_i16(); } + case (common.ty_u32) { t = T_i32(); } + case (common.ty_u64) { t = T_i64(); } + + case (common.ty_i8) { t = T_i8(); } + case (common.ty_i16) { t = T_i16(); } + case (common.ty_i32) { t = T_i32(); } + case (common.ty_i64) { t = T_i64(); } + case (_) { + cx.fcx.ccx.sess.bug("bad mach int literal type"); + } + } + ret res(cx, C_integral(i, t)); + } case (ast.lit_char(?c)) { ret res(cx, C_integral(c as int, T_char())); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index e8ae94faaa2..4bbf3cf495b 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -944,6 +944,9 @@ fn check_lit(@ast.lit lit) -> @ty { case (ast.lit_char(_)) { sty = ty_char; } case (ast.lit_int(_)) { sty = ty_int; } case (ast.lit_uint(_)) { sty = ty_uint; } + case (ast.lit_mach_int(?tm, _)) { + sty = ty_machine(tm); + } case (ast.lit_nil) { sty = ty_nil; } case (ast.lit_bool(_)) { sty = ty_bool; } }