diff --git a/lib/reader/src/lib.rs b/lib/reader/src/lib.rs index 25aa25aa98..61473afe38 100644 --- a/lib/reader/src/lib.rs +++ b/lib/reader/src/lib.rs @@ -10,7 +10,7 @@ extern crate cretonne; pub use error::{Location, Result, Error}; pub use parser::{parse_functions, parse_test}; pub use testcommand::{TestCommand, TestOption}; -pub use testfile::{TestFile, Details}; +pub use testfile::{TestFile, Details, Comment}; pub use isaspec::IsaSpec; pub use sourcemap::SourceMap; diff --git a/lib/reader/src/parser.rs b/lib/reader/src/parser.rs index 7b16abe272..c513e1a86a 100644 --- a/lib/reader/src/parser.rs +++ b/lib/reader/src/parser.rs @@ -38,9 +38,12 @@ pub fn parse_functions(text: &str) -> Result> { /// The returned `TestFile` contains direct references to substrings of `text`. pub fn parse_test<'a>(text: &'a str) -> Result> { let mut parser = Parser::new(text); + // Gather the preamble comments as 'Function'. + parser.gather_comments(AnyEntity::Function); Ok(TestFile { commands: parser.parse_test_commands(), isa_spec: try!(parser.parse_isa_specs()), + preamble_comments: parser.take_comments(), functions: try!(parser.parse_function_list()), }) } @@ -273,6 +276,11 @@ impl<'a> Parser<'a> { self.comment_entity = Some(entity.into()); } + // Get the comments gathered so far, clearing out the internal list. + fn take_comments(&mut self) -> Vec> { + mem::replace(&mut self.comments, Vec::new()) + } + // Rewrite the entity of the last added comments from `old` to `new`. // Also switch to collecting future comments for `new`. fn rewrite_last_comment_entities>(&mut self, old: E, new: E) { @@ -561,7 +569,7 @@ impl<'a> Parser<'a> { let details = Details { location: location, - comments: mem::replace(&mut self.comments, Vec::new()), + comments: self.take_comments(), map: ctx.map, }; @@ -1482,6 +1490,7 @@ mod tests { test cfg option=5 test verify set enable_float=false + ; still preamble function comment() {}") .unwrap(); assert_eq!(tf.commands.len(), 2); @@ -1491,6 +1500,9 @@ mod tests { IsaSpec::None(s) => assert!(!s.enable_float()), _ => panic!("unexpected ISAs"), } + assert_eq!(tf.preamble_comments.len(), 2); + assert_eq!(tf.preamble_comments[0].text, "; before"); + assert_eq!(tf.preamble_comments[1].text, "; still preamble"); assert_eq!(tf.functions.len(), 1); assert_eq!(tf.functions[0].0.name.to_string(), "comment"); } diff --git a/lib/reader/src/testfile.rs b/lib/reader/src/testfile.rs index deeaf04e5a..fcb11590e8 100644 --- a/lib/reader/src/testfile.rs +++ b/lib/reader/src/testfile.rs @@ -20,6 +20,9 @@ pub struct TestFile<'a> { pub commands: Vec>, /// `isa bar ...` lines. pub isa_spec: IsaSpec, + /// Comments appearing before the first function. + /// These are all tagged as 'Function' scope for lack of a better entity. + pub preamble_comments: Vec>, /// Parsed functions and additional details about each function. pub functions: Vec<(Function, Details<'a>)>, } @@ -47,6 +50,9 @@ pub struct Details<'a> { /// after the function are tagged as `AnyEntity::Function`. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Comment<'a> { + /// The entity this comment is attached to. + /// Comments always follow their entity. pub entity: AnyEntity, + /// Text of the comment, including the leading `;`. pub text: &'a str, }