about summary refs log tree commit diff
path: root/src/libsyntax/ext/bytes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/ext/bytes.rs')
-rw-r--r--src/libsyntax/ext/bytes.rs55
1 files changed, 50 insertions, 5 deletions
diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs
index 03020f26a93..7c2f27ada3b 100644
--- a/src/libsyntax/ext/bytes.rs
+++ b/src/libsyntax/ext/bytes.rs
@@ -16,13 +16,58 @@ use ext::base::*;
 use ext::base;
 use ext::build::{mk_u8, mk_slice_vec_e};
 
-pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
-    -> base::MacResult {
-    let var = get_single_str_from_tts(cx, sp, tts, "bytes!");
+pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> base::MacResult {
+    // Gather all argument expressions
+    let exprs = get_exprs_from_tts(cx, tts);
     let mut bytes = ~[];
-    for var.each |byte| {
-        bytes.push(mk_u8(cx, sp, byte));
+
+    for exprs.each |expr| {
+        match expr.node {
+            // expression is a literal
+            ast::expr_lit(lit) => match lit.node {
+                // string literal, push each byte to vector expression
+                ast::lit_str(s) => {
+                    for s.each |byte| {
+                        bytes.push(mk_u8(cx, sp, byte));
+                    }
+                }
+
+                // u8 literal, push to vector expression
+                ast::lit_uint(v, ast::ty_u8) => {
+                    if v > 0xFF {
+                        cx.span_err(sp, "Too large u8 literal in bytes!")
+                    } else {
+                        bytes.push(mk_u8(cx, sp, v as u8));
+                    }
+                }
+
+                // integer literal, push to vector expression
+                ast::lit_int_unsuffixed(v) => {
+                    if v > 0xFF {
+                        cx.span_err(sp, "Too large integer literal in bytes!")
+                    } else if v < 0 {
+                        cx.span_err(sp, "Negative integer literal in bytes!")
+                    } else {
+                        bytes.push(mk_u8(cx, sp, v as u8));
+                    }
+                }
+
+                // char literal, push to vector expression
+                ast::lit_int(v, ast::ty_char) => {
+                    if (v as char).is_ascii() {
+                        bytes.push(mk_u8(cx, sp, v as u8));
+                    } else {
+                        cx.span_err(sp, "Non-ascii char literal in bytes!")
+                    }
+                }
+
+                _ => cx.span_err(sp, "Unsupported literal in bytes!")
+            },
+
+            _ => cx.span_err(sp, "Non-literal in bytes!")
+        }
     }
+
     let e = mk_slice_vec_e(cx, sp, bytes);
     MRExpr(e)
 }