diff options
Diffstat (limited to 'src/libsyntax/ext/bytes.rs')
| -rw-r--r-- | src/libsyntax/ext/bytes.rs | 55 | 
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) } | 
