]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ext/bytes.rs
libsyntax: Fix errors arising from the automated `~[T]` conversion
[rust.git] / src / libsyntax / ext / bytes.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /* The compiler code necessary to support the bytes! extension. */
12
13 use ast;
14 use codemap::Span;
15 use ext::base::*;
16 use ext::base;
17 use ext::build::AstBuilder;
18
19 use std::char;
20 use std::vec_ng::Vec;
21
22 pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult {
23     // Gather all argument expressions
24     let exprs = match get_exprs_from_tts(cx, sp, tts) {
25         None => return MacResult::dummy_expr(sp),
26         Some(e) => e,
27     };
28     let mut bytes = Vec::new();
29
30     for expr in exprs.iter() {
31         match expr.node {
32             // expression is a literal
33             ast::ExprLit(lit) => match lit.node {
34                 // string literal, push each byte to vector expression
35                 ast::LitStr(ref s, _) => {
36                     for byte in s.get().bytes() {
37                         bytes.push(cx.expr_u8(expr.span, byte));
38                     }
39                 }
40
41                 // u8 literal, push to vector expression
42                 ast::LitUint(v, ast::TyU8) => {
43                     if v > 0xFF {
44                         cx.span_err(expr.span, "too large u8 literal in bytes!")
45                     } else {
46                         bytes.push(cx.expr_u8(expr.span, v as u8));
47                     }
48                 }
49
50                 // integer literal, push to vector expression
51                 ast::LitIntUnsuffixed(v) => {
52                     if v > 0xFF {
53                         cx.span_err(expr.span, "too large integer literal in bytes!")
54                     } else if v < 0 {
55                         cx.span_err(expr.span, "negative integer literal in bytes!")
56                     } else {
57                         bytes.push(cx.expr_u8(expr.span, v as u8));
58                     }
59                 }
60
61                 // char literal, push to vector expression
62                 ast::LitChar(v) => {
63                     if char::from_u32(v).unwrap().is_ascii() {
64                         bytes.push(cx.expr_u8(expr.span, v as u8));
65                     } else {
66                         cx.span_err(expr.span, "non-ascii char literal in bytes!")
67                     }
68                 }
69
70                 _ => cx.span_err(expr.span, "unsupported literal in bytes!")
71             },
72
73             _ => cx.span_err(expr.span, "non-literal in bytes!")
74         }
75     }
76
77     let e = cx.expr_vec_slice(sp, bytes);
78     MRExpr(e)
79 }