summaryrefslogtreecommitdiffstats
path: root/src/test/ui/macros/html-literals.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/macros/html-literals.rs')
-rw-r--r--src/test/ui/macros/html-literals.rs95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/test/ui/macros/html-literals.rs b/src/test/ui/macros/html-literals.rs
new file mode 100644
index 000000000..26f00fed9
--- /dev/null
+++ b/src/test/ui/macros/html-literals.rs
@@ -0,0 +1,95 @@
+// run-pass
+
+#![allow(non_camel_case_types)]
+// A test of the macro system. Can we do HTML literals?
+
+/*
+
+This is an HTML parser written as a macro. It's all CPS, and we have
+to carry around a bunch of state. The arguments to macros all look like this:
+
+{ tag_stack* # expr* # tokens }
+
+The stack keeps track of where we are in the tree. The expr is a list
+of children of the current node. The tokens are everything that's
+left.
+
+*/
+use HTMLFragment::{tag, text};
+
+macro_rules! html {
+ ( $($body:tt)* ) => (
+ parse_node!( []; []; $($body)* )
+ )
+}
+
+macro_rules! parse_node {
+ (
+ [:$head:ident ($(:$head_nodes:expr),*)
+ $(:$tags:ident ($(:$tag_nodes:expr),*))*];
+ [$(:$nodes:expr),*];
+ </$tag:ident> $($rest:tt)*
+ ) => (
+ parse_node!(
+ [$(: $tags ($(:$tag_nodes),*))*];
+ [$(:$head_nodes,)* :tag(stringify!($head).to_string(),
+ vec![$($nodes),*])];
+ $($rest)*
+ )
+ );
+
+ (
+ [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
+ [$(:$nodes:expr),*];
+ <$tag:ident> $($rest:tt)*
+ ) => (
+ parse_node!(
+ [:$tag ($(:$nodes)*) $(: $tags ($(:$tag_nodes),*) )*];
+ [];
+ $($rest)*
+ )
+ );
+
+ (
+ [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
+ [$(:$nodes:expr),*];
+ . $($rest:tt)*
+ ) => (
+ parse_node!(
+ [$(: $tags ($(:$tag_nodes),*))*];
+ [$(:$nodes,)* :text(".".to_string())];
+ $($rest)*
+ )
+ );
+
+ (
+ [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
+ [$(:$nodes:expr),*];
+ $word:ident $($rest:tt)*
+ ) => (
+ parse_node!(
+ [$(: $tags ($(:$tag_nodes),*))*];
+ [$(:$nodes,)* :text(stringify!($word).to_string())];
+ $($rest)*
+ )
+ );
+
+ ( []; [:$e:expr]; ) => ( $e );
+}
+
+pub fn main() {
+ let _page = html! (
+ <html>
+ <head><title>This is the title.</title></head>
+ <body>
+ <p>This is some text</p>
+ </body>
+ </html>
+ );
+}
+
+#[allow(unused_tuple_struct_fields)]
+enum HTMLFragment {
+ tag(String, Vec<HTMLFragment> ),
+ text(String),
+}