about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorBenjamin Herr <ben@0x539.de>2013-10-08 02:49:10 +0200
committerBenjamin Herr <ben@0x539.de>2013-10-08 03:43:28 +0200
commit9d7b13004192b8eef1f68501035d05c85dee8c47 (patch)
treec96d00a2f583c825b91836764219440f5b9cb7b6 /src/libsyntax
parent97878725532c4d1dd1af07e88175462178d78cdb (diff)
downloadrust-9d7b13004192b8eef1f68501035d05c85dee8c47.tar.gz
rust-9d7b13004192b8eef1f68501035d05c85dee8c47.zip
add new enum ast::StrStyle as field to ast::lit_str
For the benefit of the pretty printer we want to keep track of how
string literals in the ast were originally represented in the source
code.

This commit changes parser functions so they don't extract strings from
the token stream without at least also returning what style of string
literal it was. This is stored in the resulting ast node for string
literals, obviously, for the package id in `extern mod = r"package id"`
view items, for the inline asm in `asm!()` invocations.

For `asm!()`'s other arguments or for `extern "Rust" fn()` items, I just
the style of string, because it seemed disproportionally cumbersome to
thread that information through the string processing that happens with
those string literals, given the limited advantage raw string literals
would provide in these positions.

The other syntax extensions don't seem to store passed string literals
in the ast, so they also discard the style of strings they parse.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs11
-rw-r--r--src/libsyntax/attr.rs6
-rw-r--r--src/libsyntax/ext/asm.rs18
-rw-r--r--src/libsyntax/ext/base.rs4
-rw-r--r--src/libsyntax/ext/build.rs2
-rw-r--r--src/libsyntax/ext/bytes.rs2
-rw-r--r--src/libsyntax/ext/deriving/generic.rs2
-rw-r--r--src/libsyntax/ext/env.rs7
-rw-r--r--src/libsyntax/ext/fmt.rs2
-rw-r--r--src/libsyntax/ext/format.rs4
-rw-r--r--src/libsyntax/ext/quote.rs2
-rw-r--r--src/libsyntax/parse/parser.rs44
-rw-r--r--src/libsyntax/print/pprust.rs25
13 files changed, 74 insertions, 55 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 5a3c3a86fed..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)
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 59d55933fa3..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()
         }
     }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index c8689db417c..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,8 +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_RAW(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); }
         }
@@ -2158,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)
@@ -2182,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)
             };
@@ -2195,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)
             };
@@ -2707,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 {
@@ -2735,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 {
@@ -2764,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,
@@ -4373,15 +4374,15 @@ impl Parser {
                                      abi::all_names().connect(", "),
                                      word));
                         }
-                    }
-                }
+                     }
+                 }
                 Some(abis)
             }
 
             _ => {
                 None
-            }
-        }
+             }
+         }
     }
 
     // parse one of the items or view items allowed by the
@@ -4932,18 +4933,17 @@ impl Parser {
         }
     }
 
-    pub fn parse_optional_str(&self) -> Option<@str> {
-        match *self.token {
-            token::LIT_STR(s)
-            | token::LIT_STR_RAW(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/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 08466aea548..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,11 +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, "=");
                 space(s.s);
-                print_string(s, *p);
+                print_string(s, *p, style);
             }
             if !mta.is_empty() {
                 popen(s);
@@ -2060,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| {
@@ -2180,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 {