about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2010-11-22 17:41:26 -0800
committerGraydon Hoare <graydon@mozilla.com>2010-11-22 17:41:32 -0800
commite05d7c3ac1e72edff337719fe58da69e959c4cf4 (patch)
treeb040d23dac019f8caf1157b385e4b6f915696815
parent3e01b2d529a81ac7b2d7ba3deb5d1f116efc7b34 (diff)
Support mach types in rustc, enable 5 more tests.
-rw-r--r--src/Makefile5
-rw-r--r--src/comp/front/ast.rs2
-rw-r--r--src/comp/front/lexer.rs129
-rw-r--r--src/comp/front/parser.rs4
-rw-r--r--src/comp/middle/trans.rs21
-rw-r--r--src/comp/middle/typeck.rs3
6 files changed, 130 insertions, 34 deletions
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; }
     }