Browse Source

Reduce debug output slightly and map_with_context combinator

`map_with_context` provides you with the result of the parse so far, and
a `&mut AmlContext`. It allows you to query and insert stuff into the
namespace, change the current scope, and access the state of the interpreter
at any point during the parse.
Isaac Woods 5 years ago
parent
commit
7066dac206
2 changed files with 37 additions and 8 deletions
  1. 4 7
      aml_parser/src/lib.rs
  2. 33 1
      aml_parser/src/parser.rs

+ 4 - 7
aml_parser/src/lib.rs

@@ -37,7 +37,7 @@ pub enum AmlError {
 
 #[derive(Debug)]
 pub struct AmlContext {
-    namespace: BTreeMap<String, AmlValue>,
+    pub namespace: BTreeMap<String, AmlValue>,
 }
 
 impl AmlContext {
@@ -50,15 +50,12 @@ impl AmlContext {
             return Err(AmlError::UnexpectedEndOfStream);
         }
 
-        match term_object::term_list(
-            PkgLength::from_raw_length(stream, stream.len() as u32) as PkgLength
-        )
-        .parse(stream, self)
-        {
+
+        let table_length = PkgLength::from_raw_length(stream, stream.len() as u32) as PkgLength;
+        match term_object::term_list(table_length).parse(stream, self) {
             Ok(_) => Ok(()),
             Err((remaining, _context, err)) => {
                 error!("Failed to parse AML stream. Err = {:?}", err);
-                trace!("Remaining AML: {:02x?}", remaining);
                 Err(err)
             }
         }

+ 33 - 1
aml_parser/src/parser.rs

@@ -19,6 +19,13 @@ where
         Map { parser: self, map_fn, _phantom: PhantomData }
     }
 
+    fn map_with_context<F, A>(self, map_fn: F) -> MapWithContext<'a, 'c, Self, F, R, A>
+    where
+        F: Fn(R, &'c mut AmlContext) -> (A, &'c mut AmlContext),
+    {
+        MapWithContext { parser: self, map_fn, _phantom: PhantomData }
+    }
+
     fn discard_result(self) -> DiscardResult<'a, 'c, Self, R> {
         DiscardResult { parser: self, _phantom: PhantomData }
     }
@@ -243,7 +250,32 @@ where
     fn parse(&self, input: &'a [u8], context: &'c mut AmlContext) -> ParseResult<'a, 'c, A> {
         self.parser
             .parse(input, context)
-            .map(|(new_input, new_context, result)| (new_input, new_context, (self.map_fn)(result)))
+            .map(|(new_input, context, result)| (new_input, context, (self.map_fn)(result)))
+    }
+}
+
+pub struct MapWithContext<'a, 'c, P, F, R, A>
+where
+    'c: 'a,
+    P: Parser<'a, 'c, R>,
+    F: Fn(R, &'c mut AmlContext) -> (A, &'c mut AmlContext),
+{
+    parser: P,
+    map_fn: F,
+    _phantom: PhantomData<(&'a (R, A), &'c ())>,
+}
+
+impl<'a, 'c, P, F, R, A> Parser<'a, 'c, A> for MapWithContext<'a, 'c, P, F, R, A>
+where
+    'c: 'a,
+    P: Parser<'a, 'c, R>,
+    F: Fn(R, &'c mut AmlContext) -> (A, &'c mut AmlContext),
+{
+    fn parse(&self, input: &'a [u8], context: &'c mut AmlContext) -> ParseResult<'a, 'c, A> {
+        self.parser.parse(input, context).map(|(new_input, context, result)| {
+            let (mapped_result, context) = (self.map_fn)(result, context);
+            (new_input, context, mapped_result)
+        })
     }
 }