(index<- )        ./libsyntax/ext/bytes.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
  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  
 20  pub fn expand_syntax_ext(cx: &mut ExtCtxt, spSpan, tts: &[ast::TokenTree])
 21                           -> Box<base::MacResult> {
 22      // Gather all argument expressions
 23      let exprs = match get_exprs_from_tts(cx, sp, tts) {
 24          None => return DummyResult::expr(sp),
 25          Some(e) => e,
 26      };
 27      let mut bytes = Vec::new();
 28  
 29      for expr in exprs.iter() {
 30          match expr.node {
 31              // expression is a literal
 32              ast::ExprLit(lit) => match lit.node {
 33                  // string literal, push each byte to vector expression
 34                  ast::LitStr(ref s, _) => {
 35                      for byte in s.get().bytes() {
 36                          bytes.push(cx.expr_u8(expr.span, byte));
 37                      }
 38                  }
 39  
 40                  // u8 literal, push to vector expression
 41                  ast::LitUint(v, ast::TyU8) => {
 42                      if v > 0xFF {
 43                          cx.span_err(expr.span, "too large u8 literal in bytes!")
 44                      } else {
 45                          bytes.push(cx.expr_u8(expr.span, v as u8));
 46                      }
 47                  }
 48  
 49                  // integer literal, push to vector expression
 50                  ast::LitIntUnsuffixed(v) => {
 51                      if v > 0xFF {
 52                          cx.span_err(expr.span, "too large integer literal in bytes!")
 53                      } else if v < 0 {
 54                          cx.span_err(expr.span, "negative integer literal in bytes!")
 55                      } else {
 56                          bytes.push(cx.expr_u8(expr.span, v as u8));
 57                      }
 58                  }
 59  
 60                  // char literal, push to vector expression
 61                  ast::LitChar(v) => {
 62                      if v.is_ascii() {
 63                          bytes.push(cx.expr_u8(expr.span, v as u8));
 64                      } else {
 65                          cx.span_err(expr.span, "non-ascii char literal in bytes!")
 66                      }
 67                  }
 68  
 69                  _ => cx.span_err(expr.span, "unsupported literal in bytes!")
 70              },
 71  
 72              _ => cx.span_err(expr.span, "non-literal in bytes!")
 73          }
 74      }
 75  
 76      let e = cx.expr_vec_slice(sp, bytes);
 77      MacExpr::new(e)
 78  }