diff options
| author | bors <bors@rust-lang.org> | 2013-10-07 23:01:39 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-10-07 23:01:39 -0700 |
| commit | c9196290af3934481bd413e11057725f248fd104 (patch) | |
| tree | 64e4d5fed93cfedb791ac3abddb9cc703d337f75 /src/libsyntax | |
| parent | 6ddd011ce8875c6c5b119e5a8957a51d524a95da (diff) | |
| parent | d7dfe0ae34eb9a818dcbdb5646e21e721ffb3c33 (diff) | |
| download | rust-c9196290af3934481bd413e11057725f248fd104.tar.gz rust-c9196290af3934481bd413e11057725f248fd104.zip | |
auto merge of #9674 : ben0x539/rust/raw-str, r=alexcrichton
This branch parses raw string literals as in #9411.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/attr.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/asm.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/bytes.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/env.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/ext/fmt.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/format.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/quote.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer.rs | 68 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 45 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 27 |
15 files changed, 160 insertions, 57 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 6de3b7aa0b0..63c2f0e5191 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -680,11 +680,17 @@ pub enum mac_ { mac_invoc_tt(Path,~[token_tree],SyntaxContext), // new macro-invocation } +#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] +pub enum StrStyle { + CookedStr, + RawStr(uint) +} + pub type lit = Spanned<lit_>; #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub enum lit_ { - lit_str(@str), + lit_str(@str, StrStyle), lit_char(u32), lit_int(i64, int_ty), lit_uint(u64, uint_ty), @@ -862,6 +868,7 @@ pub enum asm_dialect { #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub struct inline_asm { asm: @str, + asm_str_style: StrStyle, clobbers: @str, inputs: ~[(@str, @Expr)], outputs: ~[(@str, @Expr)], @@ -1027,7 +1034,7 @@ pub enum view_item_ { // optional @str: if present, this is a location (containing // arbitrary characters) from which to fetch the crate sources // For example, extern mod whatever = "github.com/mozilla/rust" - view_item_extern_mod(Ident, Option<@str>, ~[@MetaItem], NodeId), + view_item_extern_mod(Ident, Option<(@str, StrStyle)>, ~[@MetaItem], NodeId), view_item_use(~[@view_path]), } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index df31fece5ea..d9a23f6eb35 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -67,7 +67,7 @@ impl AttrMetaMethods for MetaItem { match self.node { MetaNameValue(_, ref v) => { match v.node { - ast::lit_str(s) => Some(s), + ast::lit_str(s, _) => Some(s), _ => None, } }, @@ -127,7 +127,7 @@ impl AttributeMethods for Attribute { /* Constructors */ pub fn mk_name_value_item_str(name: @str, value: @str) -> @MetaItem { - let value_lit = dummy_spanned(ast::lit_str(value)); + let value_lit = dummy_spanned(ast::lit_str(value, ast::CookedStr)); mk_name_value_item(name, value_lit) } @@ -153,7 +153,7 @@ pub fn mk_attr(item: @MetaItem) -> Attribute { pub fn mk_sugared_doc_attr(text: @str, lo: BytePos, hi: BytePos) -> Attribute { let style = doc_comment_style(text); - let lit = spanned(lo, hi, ast::lit_str(text)); + let lit = spanned(lo, hi, ast::lit_str(text, ast::CookedStr)); let attr = Attribute_ { style: style, value: @spanned(lo, hi, MetaNameValue(@"doc", lit)), diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index 9241e8c4fbc..e836367555a 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -44,6 +44,7 @@ pub fn expand_asm(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) tts.to_owned()); let mut asm = @""; + let mut asm_str_style = None; let mut outputs = ~[]; let mut inputs = ~[]; let mut cons = ~""; @@ -58,8 +59,11 @@ pub fn expand_asm(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) while continue_ { match state { Asm => { - asm = expr_to_str(cx, p.parse_expr(), - "inline assembly must be a string literal."); + let (s, style) = + expr_to_str(cx, p.parse_expr(), + "inline assembly must be a string literal."); + asm = s; + asm_str_style = Some(style); } Outputs => { while *p.token != token::EOF && @@ -70,7 +74,7 @@ pub fn expand_asm(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) p.eat(&token::COMMA); } - let constraint = p.parse_str(); + let (constraint, _str_style) = p.parse_str(); p.expect(&token::LPAREN); let out = p.parse_expr(); p.expect(&token::RPAREN); @@ -93,7 +97,7 @@ pub fn expand_asm(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) p.eat(&token::COMMA); } - let constraint = p.parse_str(); + let (constraint, _str_style) = p.parse_str(); p.expect(&token::LPAREN); let input = p.parse_expr(); p.expect(&token::RPAREN); @@ -111,14 +115,15 @@ pub fn expand_asm(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) p.eat(&token::COMMA); } - let clob = format!("~\\{{}\\}", p.parse_str()); + let (s, _str_style) = p.parse_str(); + let clob = format!("~\\{{}\\}", s); clobs.push(clob); } cons = clobs.connect(","); } Options => { - let option = p.parse_str(); + let (option, _str_style) = p.parse_str(); if "volatile" == option { volatile = true; @@ -175,6 +180,7 @@ pub fn expand_asm(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) id: ast::DUMMY_NODE_ID, node: ast::ExprInlineAsm(ast::inline_asm { asm: asm, + asm_str_style: asm_str_style.unwrap(), clobbers: cons.to_managed(), inputs: inputs, outputs: outputs, diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 3b4be1de3e8..7f89271927c 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -410,10 +410,10 @@ impl ExtCtxt { } } -pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::Expr, err_msg: &str) -> @str { +pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::Expr, err_msg: &str) -> (@str, ast::StrStyle) { match expr.node { ast::ExprLit(l) => match l.node { - ast::lit_str(s) => s, + ast::lit_str(s, style) => (s, style), _ => cx.span_fatal(l.span, err_msg) }, _ => cx.span_fatal(expr.span, err_msg) @@ -437,7 +437,8 @@ pub fn get_single_str_from_tts(cx: @ExtCtxt, } match tts[0] { - ast::tt_tok(_, token::LIT_STR(ident)) => cx.str_of(ident), + ast::tt_tok(_, token::LIT_STR(ident)) + | ast::tt_tok(_, token::LIT_STR_RAW(ident, _)) => cx.str_of(ident), _ => cx.span_fatal(sp, format!("{} requires a string.", name)), } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 65a6572fa5e..a5336187200 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -562,7 +562,7 @@ impl AstBuilder for @ExtCtxt { self.expr_vstore(sp, self.expr_vec(sp, exprs), ast::ExprVstoreSlice) } fn expr_str(&self, sp: Span, s: @str) -> @ast::Expr { - self.expr_lit(sp, ast::lit_str(s)) + self.expr_lit(sp, ast::lit_str(s, ast::CookedStr)) } fn expr_str_uniq(&self, sp: Span, s: @str) -> @ast::Expr { self.expr_vstore(sp, self.expr_str(sp, s), ast::ExprVstoreUniq) diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs index b27fcb6c9b9..5ebaea2ce44 100644 --- a/src/libsyntax/ext/bytes.rs +++ b/src/libsyntax/ext/bytes.rs @@ -28,7 +28,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) -> bas // expression is a literal ast::ExprLit(lit) => match lit.node { // string literal, push each byte to vector expression - ast::lit_str(s) => { + ast::lit_str(s, _) => { for byte in s.byte_iter() { bytes.push(cx.expr_u8(expr.span, byte)); } diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index b3fd4f920d8..c31c609d4e7 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -361,7 +361,7 @@ impl<'self> TraitDef<'self> { span, cx.meta_name_value(span, @"doc", - ast::lit_str(@"Automatically derived."))); + ast::lit_str(@"Automatically derived.", ast::CookedStr))); cx.item( span, ::parse::token::special_idents::clownshoes_extensions, diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs index 63a45b06e16..15630e37ead 100644 --- a/src/libsyntax/ext/env.rs +++ b/src/libsyntax/ext/env.rs @@ -41,10 +41,13 @@ pub fn expand_env(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) cx.span_fatal(sp, "env! takes 1 or 2 arguments"); } - let var = expr_to_str(cx, exprs[0], "expected string literal"); + let (var, _var_str_style) = expr_to_str(cx, exprs[0], "expected string literal"); let msg = match exprs.len() { 1 => format!("Environment variable {} not defined", var).to_managed(), - 2 => expr_to_str(cx, exprs[1], "expected string literal"), + 2 => { + let (s, _style) = expr_to_str(cx, exprs[1], "expected string literal"); + s + } _ => cx.span_fatal(sp, "env! takes 1 or 2 arguments") }; diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index cd364e7ad64..8258048a04d 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -30,7 +30,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) if args.len() == 0 { cx.span_fatal(sp, "fmt! takes at least 1 argument."); } - let fmt = + let (fmt, _fmt_str_style) = expr_to_str(cx, args[0], "first argument to fmt! must be a string literal."); let fmtspan = args[0].span; diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 8d327de6d61..171748e9b2e 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -722,8 +722,8 @@ pub fn expand_args(ecx: @ExtCtxt, sp: Span, (_, None) => { return MRExpr(ecx.expr_uint(sp, 2)); } }; cx.fmtsp = efmt.span; - let fmt = expr_to_str(ecx, efmt, - "format argument must be a string literal."); + let (fmt, _fmt_str_style) = expr_to_str(ecx, efmt, + "format argument must be a string literal."); let mut err = false; do parse::parse_error::cond.trap(|m| { diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index bfd1e9cc994..4bef9601855 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -118,7 +118,7 @@ pub mod rt { impl<'self> ToSource for &'self str { fn to_source(&self) -> @str { - let lit = dummy_spanned(ast::lit_str(self.to_managed())); + let lit = dummy_spanned(ast::lit_str(self.to_managed(), ast::CookedStr)); pprust::lit_to_str(@lit).to_managed() } } @@ -464,6 +464,13 @@ fn mk_token(cx: @ExtCtxt, sp: Span, tok: &token::Token) -> @ast::Expr { ~[mk_ident(cx, sp, ident)]); } + LIT_STR_RAW(ident, n) => { + return cx.expr_call_ident(sp, + id_ext("LIT_STR_RAW"), + ~[mk_ident(cx, sp, ident), + cx.expr_uint(sp, n)]); + } + IDENT(ident, b) => { return cx.expr_call_ident(sp, id_ext("IDENT"), diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 79c330c4737..a43e018cf49 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -213,10 +213,22 @@ fn byte_offset(rdr: &StringReader, pos: BytePos) -> BytePos { (pos - rdr.filemap.start_pos) } +/// Calls `f` with a string slice of the source text spanning from `start` +/// up to but excluding `rdr.last_pos`, meaning the slice does not include +/// the character `rdr.curr`. pub fn with_str_from<T>(rdr: @mut StringReader, start: BytePos, f: &fn(s: &str) -> T) -> T { + with_str_from_to(rdr, start, rdr.last_pos, f) +} + +/// Calls `f` with astring slice of the source text spanning from `start` +/// up to but excluding `end`. +fn with_str_from_to<T>(rdr: @mut StringReader, + start: BytePos, + end: BytePos, + f: &fn(s: &str) -> T) -> T { f(rdr.src.slice( byte_offset(rdr, start).to_uint(), - byte_offset(rdr, rdr.last_pos).to_uint())) + byte_offset(rdr, end).to_uint())) } // EFFECT: advance the StringReader by one character. If a newline is @@ -612,7 +624,10 @@ fn ident_continue(c: char) -> bool { // EFFECT: updates the interner fn next_token_inner(rdr: @mut StringReader) -> token::Token { let c = rdr.curr; - if ident_start(c) { + if ident_start(c) && nextch(rdr) != '"' && nextch(rdr) != '#' { + // Note: r as in r" or r#" is part of a raw string literal, + // not an identifier, and is handled further down. + let start = rdr.last_pos; while ident_continue(rdr.curr) { bump(rdr); @@ -829,6 +844,47 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { bump(rdr); return token::LIT_STR(str_to_ident(accum_str)); } + 'r' => { + let start_bpos = rdr.last_pos; + bump(rdr); + let mut hash_count = 0u; + while rdr.curr == '#' { + bump(rdr); + hash_count += 1; + } + if rdr.curr != '"' { + fatal_span_char(rdr, start_bpos, rdr.last_pos, + ~"only `#` is allowed in raw string delimitation; \ + found illegal character", + rdr.curr); + } + bump(rdr); + let content_start_bpos = rdr.last_pos; + let mut content_end_bpos; + 'outer: loop { + if is_eof(rdr) { + fatal_span(rdr, start_bpos, rdr.last_pos, + ~"unterminated raw string"); + } + if rdr.curr == '"' { + content_end_bpos = rdr.last_pos; + for _ in range(0, hash_count) { + bump(rdr); + if rdr.curr != '#' { + continue 'outer; + } + } + break; + } + bump(rdr); + } + bump(rdr); + let str_content = with_str_from_to(rdr, + content_start_bpos, + content_end_bpos, + str_to_ident); + return token::LIT_STR_RAW(str_content, hash_count); + } '-' => { if nextch(rdr) == '>' { bump(rdr); @@ -987,6 +1043,14 @@ mod test { assert_eq!(tok, token::LIFETIME(id)); } + #[test] fn raw_string() { + let env = setup(@"r###\"\"#a\\b\x00c\"\"###"); + let TokenAndSpan {tok, sp: _} = + env.string_reader.next_token(); + let id = token::str_to_ident("\"#a\\b\x00c\""); + assert_eq!(tok, token::LIT_STR_RAW(id, 3)); + } + #[test] fn line_doc_comments() { assert!(!is_line_non_doc_comment("///")); assert!(!is_line_non_doc_comment("/// blah")); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cad19543608..ffebe7980bf 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -48,6 +48,7 @@ use ast::{BiRem, required}; use ast::{ret_style, return_val, BiShl, BiShr, Stmt, StmtDecl}; use ast::{StmtExpr, StmtSemi, StmtMac, struct_def, struct_field}; use ast::{struct_variant_kind, BiSub}; +use ast::StrStyle; use ast::{sty_box, sty_region, sty_static, sty_uniq, sty_value}; use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok}; use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box}; @@ -1282,7 +1283,8 @@ impl Parser { token::LIT_FLOAT(s, ft) => lit_float(self.id_to_str(s), ft), token::LIT_FLOAT_UNSUFFIXED(s) => lit_float_unsuffixed(self.id_to_str(s)), - token::LIT_STR(s) => lit_str(self.id_to_str(s)), + token::LIT_STR(s) => lit_str(self.id_to_str(s), ast::CookedStr), + token::LIT_STR_RAW(s, n) => lit_str(self.id_to_str(s), ast::RawStr(n)), token::LPAREN => { self.expect(&token::RPAREN); lit_nil }, _ => { self.unexpected_last(tok); } } @@ -2157,7 +2159,7 @@ impl Parser { // HACK: turn &[...] into a &-evec ex = match e.node { ExprVec(*) | ExprLit(@codemap::Spanned { - node: lit_str(_), span: _ + node: lit_str(*), span: _ }) if m == MutImmutable => { ExprVstore(e, ExprVstoreSlice) @@ -2181,7 +2183,7 @@ impl Parser { ExprVec(*) | ExprRepeat(*) if m == MutMutable => ExprVstore(e, ExprVstoreMutBox), ExprVec(*) | - ExprLit(@codemap::Spanned { node: lit_str(_), span: _}) | + ExprLit(@codemap::Spanned { node: lit_str(*), span: _}) | ExprRepeat(*) if m == MutImmutable => ExprVstore(e, ExprVstoreBox), _ => self.mk_unary(UnBox(m), e) }; @@ -2194,7 +2196,7 @@ impl Parser { // HACK: turn ~[...] into a ~-evec ex = match e.node { ExprVec(*) | - ExprLit(@codemap::Spanned { node: lit_str(_), span: _}) | + ExprLit(@codemap::Spanned { node: lit_str(*), span: _}) | ExprRepeat(*) => ExprVstore(e, ExprVstoreUniq), _ => self.mk_unary(UnUniq, e) }; @@ -2706,7 +2708,7 @@ impl Parser { pat = match sub.node { PatLit(e@@Expr { node: ExprLit(@codemap::Spanned { - node: lit_str(_), + node: lit_str(*), span: _}), _ }) => { let vst = @Expr { @@ -2734,7 +2736,7 @@ impl Parser { pat = match sub.node { PatLit(e@@Expr { node: ExprLit(@codemap::Spanned { - node: lit_str(_), + node: lit_str(*), span: _}), _ }) => { let vst = @Expr { @@ -2763,7 +2765,7 @@ impl Parser { pat = match sub.node { PatLit(e@@Expr { node: ExprLit(@codemap::Spanned { - node: lit_str(_), span: _}), _ + node: lit_str(*), span: _}), _ }) => { let vst = @Expr { id: ast::DUMMY_NODE_ID, @@ -4345,7 +4347,8 @@ impl Parser { // parse a string as an ABI spec on an extern type or module fn parse_opt_abis(&self) -> Option<AbiSet> { match *self.token { - token::LIT_STR(s) => { + token::LIT_STR(s) + | token::LIT_STR_RAW(s, _) => { self.bump(); let the_string = ident_to_str(&s); let mut abis = AbiSet::empty(); @@ -4371,15 +4374,15 @@ impl Parser { abi::all_names().connect(", "), word)); } - } - } + } + } Some(abis) } _ => { None - } - } + } + } } // parse one of the items or view items allowed by the @@ -4930,17 +4933,17 @@ impl Parser { } } - pub fn parse_optional_str(&self) -> Option<@str> { - match *self.token { - token::LIT_STR(s) => { - self.bump(); - Some(ident_to_str(&s)) - } - _ => None - } + pub fn parse_optional_str(&self) -> Option<(@str, ast::StrStyle)> { + let (s, style) = match *self.token { + token::LIT_STR(s) => (s, ast::CookedStr), + token::LIT_STR_RAW(s, n) => (s, ast::RawStr(n)), + _ => return None + }; + self.bump(); + Some((ident_to_str(&s), style)) } - pub fn parse_str(&self) -> @str { + pub fn parse_str(&self) -> (@str, StrStyle) { match self.parse_optional_str() { Some(s) => { s } _ => self.fatal("expected string literal") diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index d0faf917688..ba4c2637d10 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -79,6 +79,7 @@ pub enum Token { LIT_FLOAT(ast::Ident, ast::float_ty), LIT_FLOAT_UNSUFFIXED(ast::Ident), LIT_STR(ast::Ident), + LIT_STR_RAW(ast::Ident, uint), /* raw str delimited by n hash symbols */ /* Name components */ // an identifier contains an "is_mod_name" boolean, @@ -194,6 +195,10 @@ pub fn to_str(input: @ident_interner, t: &Token) -> ~str { body } LIT_STR(ref s) => { format!("\"{}\"", ident_to_str(s).escape_default()) } + LIT_STR_RAW(ref s, n) => { + format!("r{delim}\"{string}\"{delim}", + delim="#".repeat(n), string=ident_to_str(s)) + } /* Name components */ IDENT(s, _) => input.get(s.name).to_owned(), @@ -243,6 +248,7 @@ pub fn can_begin_expr(t: &Token) -> bool { LIT_FLOAT(_, _) => true, LIT_FLOAT_UNSUFFIXED(_) => true, LIT_STR(_) => true, + LIT_STR_RAW(_, _) => true, POUND => true, AT => true, NOT => true, @@ -284,6 +290,7 @@ pub fn is_lit(t: &Token) -> bool { LIT_FLOAT(_, _) => true, LIT_FLOAT_UNSUFFIXED(_) => true, LIT_STR(_) => true, + LIT_STR_RAW(_, _) => true, _ => false } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 2a3add059ce..7091a2d5518 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1433,10 +1433,10 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { word(s.s, "asm!"); } popen(s); - print_string(s, a.asm); + print_string(s, a.asm, a.asm_str_style); word_space(s, ":"); for &(co, o) in a.outputs.iter() { - print_string(s, co); + print_string(s, co, ast::CookedStr); popen(s); print_expr(s, o); pclose(s); @@ -1444,14 +1444,14 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { } word_space(s, ":"); for &(co, o) in a.inputs.iter() { - print_string(s, co); + print_string(s, co, ast::CookedStr); popen(s); print_expr(s, o); pclose(s); word_space(s, ","); } word_space(s, ":"); - print_string(s, a.clobbers); + print_string(s, a.clobbers, ast::CookedStr); pclose(s); } ast::ExprMac(ref m) => print_mac(s, m), @@ -1894,9 +1894,11 @@ pub fn print_view_item(s: @ps, item: &ast::view_item) { ast::view_item_extern_mod(id, ref optional_path, ref mta, _) => { head(s, "extern mod"); print_ident(s, id); - for p in optional_path.iter() { + for &(ref p, style) in optional_path.iter() { + space(s.s); word(s.s, "="); - print_string(s, *p); + space(s.s); + print_string(s, *p, style); } if !mta.is_empty() { popen(s); @@ -2058,7 +2060,7 @@ pub fn print_literal(s: @ps, lit: &ast::lit) { _ => () } match lit.node { - ast::lit_str(st) => print_string(s, st), + ast::lit_str(st, style) => print_string(s, st, style), ast::lit_char(ch) => { let mut res = ~"'"; do char::from_u32(ch).unwrap().escape_default |c| { @@ -2178,10 +2180,13 @@ pub fn print_comment(s: @ps, cmnt: &comments::cmnt) { } } -pub fn print_string(s: @ps, st: &str) { - word(s.s, "\""); - word(s.s, st.escape_default()); - word(s.s, "\""); +pub fn print_string(s: @ps, st: &str, style: ast::StrStyle) { + let st = match style { + ast::CookedStr => format!("\"{}\"", st.escape_default()), + ast::RawStr(n) => format!("r{delim}\"{string}\"{delim}", + delim="#".repeat(n), string=st) + }; + word(s.s, st); } pub fn to_str<T>(t: &T, f: &fn(@ps, &T), intr: @ident_interner) -> ~str { |
