Browse Source

Allow TermObjects to evaluate to AmlValues, add type 1 & 2 opcode parsers

Currently they're empty - we can add opcodes as we need to parse them. We
also need to do some work to correctly propagate results upwards, as well
as some specialist work to allow DefReturn to work
Isaac Woods 5 years ago
parent
commit
d7829a7286

+ 2 - 0
aml_parser/src/lib.rs

@@ -47,6 +47,8 @@ pub(crate) mod opcode;
 pub(crate) mod parser;
 pub(crate) mod pkg_length;
 pub(crate) mod term_object;
+pub(crate) mod type1;
+pub(crate) mod type2;
 pub mod value;
 
 pub use crate::{name_object::AmlName, value::AmlValue};

+ 4 - 0
aml_parser/src/parser.rs

@@ -403,6 +403,10 @@ where
 /// Takes a number of parsers, and tries to apply each one to the input in order. Returns the
 /// result of the first one that succeeds, or fails if all of them fail.
 pub(crate) macro choice {
+    () => {
+        emit_no_parsers_could_parse()
+    },
+
     ($first_parser: expr) => {
         $first_parser
         .or(emit_no_parsers_could_parse())

+ 15 - 3
aml_parser/src/term_object.rs

@@ -15,6 +15,8 @@ use crate::{
         Parser,
     },
     pkg_length::{pkg_length, PkgLength},
+    type1::type1_opcode,
+    type2::type2_opcode,
     value::{AmlValue, FieldFlags, MethodFlags, RegionSpace},
     AmlContext,
     AmlError,
@@ -33,7 +35,9 @@ where
      */
     move |mut input: &'a [u8], mut context: &'c mut AmlContext| {
         while list_length.still_parsing(input) {
-            let (new_input, new_context, ()) = term_object().parse(input, context)?;
+            // TODO: currently, we ignore the value of the expression. We may need to propagate
+            // this.
+            let (new_input, new_context, _) = term_object().parse(input, context)?;
             input = new_input;
             context = new_context;
         }
@@ -42,14 +46,22 @@ where
     }
 }
 
-pub fn term_object<'a, 'c>() -> impl Parser<'a, 'c, ()>
+pub fn term_object<'a, 'c>() -> impl Parser<'a, 'c, Option<AmlValue>>
 where
     'c: 'a,
 {
     /*
      * TermObj := NamespaceModifierObj | NamedObj | Type1Opcode | Type2Opcode
      */
-    comment_scope_verbose("TermObj", choice!(namespace_modifier(), named_obj()))
+    comment_scope_verbose(
+        "TermObj",
+        choice!(
+            namespace_modifier().map(|()| Ok(None)),
+            named_obj().map(|()| Ok(None)),
+            type1_opcode().map(|()| Ok(None)),
+            type2_opcode().map(|value| Ok(Some(value)))
+        ),
+    )
 }
 
 pub fn namespace_modifier<'a, 'c>() -> impl Parser<'a, 'c, ()>

+ 14 - 0
aml_parser/src/type1.rs

@@ -0,0 +1,14 @@
+use crate::parser::{choice, comment_scope_verbose, Parser};
+
+/// Type 1 opcodes return a value and so can be used in expressions.
+pub fn type1_opcode<'a, 'c>() -> impl Parser<'a, 'c, ()>
+where
+    'c: 'a,
+{
+    /*
+     * Type1Opcode := DefBreak | DefBreakPoint | DefContinue | DefFatal | DefIfElse | DefLoad | DefNoop |
+     *                DefNotify | DefRelease | DefReset | DefReturn | DefSignal | DefSleep | DefStall |
+     *                DefWhile
+     */
+    comment_scope_verbose("Type1Opcode", choice!())
+}

+ 24 - 0
aml_parser/src/type2.rs

@@ -0,0 +1,24 @@
+use crate::{
+    parser::{choice, comment_scope_verbose, Parser},
+    value::AmlValue,
+};
+
+/// Type 2 opcodes return a value and so can be used in expressions.
+pub fn type2_opcode<'a, 'c>() -> impl Parser<'a, 'c, AmlValue>
+where
+    'c: 'a,
+{
+    /*
+     * Type2Opcode := DefAquire | DefAdd | DefAnd | DefBuffer | DefConcat | DefConcatRes |
+     *                DefCondRefOf | DefCopyObject | DefDecrement | DefDerefOf | DefDivide |
+     *                DefFindSetLeftBit | DefFindSetRightBit | DefFromBCD | DefIncrement | DefIndex |
+     *                DefLAnd | DefLEqual | DefLGreater | DefLGreaterEqual | DefLLess | DefLLessEqual |
+     *                DefMid | DefLNot | DefLNotEqual | DefLoadTable | DefLOr | DefMatch | DefMod |
+     *                DefMultiply | DefNAnd | DefNOr | DefNot | DefObjectType | DefOr | DefPackage |
+     *                DefVarPackage | DefRefOf | DefShiftLeft | DefShitRight | DefSizeOf | DefStore |
+     *                DefSubtract | DefTimer | DefToBCD | DefToBuffer | DefToDecimalString |
+     *                DefToHexString | DefToInteger | DefToString | DefWait | DefXOr | MethodInvocation
+     */
+    // TODO
+    comment_scope_verbose("Type2Opcode", choice!())
+}