-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #114 from Amjad50/aml_display
Improve displaying AML code using `fmt::Display` and Added more AML parsing
- Loading branch information
Showing
9 changed files
with
2,540 additions
and
775 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
use core::{ | ||
cell::RefCell, | ||
fmt::{self, Write}, | ||
}; | ||
|
||
#[derive(Default)] | ||
struct PadAdapterState { | ||
on_newline: bool, | ||
} | ||
|
||
struct PadAdapter<'buf, 'state> { | ||
buf: &'buf mut (dyn fmt::Write + 'buf), | ||
state: &'state mut PadAdapterState, | ||
} | ||
|
||
impl<'buf, 'state> PadAdapter<'buf, 'state> { | ||
pub fn wrap(buf: &'buf mut dyn fmt::Write, state: &'state mut PadAdapterState) -> Self { | ||
Self { buf, state } | ||
} | ||
} | ||
|
||
impl fmt::Write for PadAdapter<'_, '_> { | ||
fn write_str(&mut self, s: &str) -> fmt::Result { | ||
for s in s.split_inclusive('\n') { | ||
if self.state.on_newline { | ||
self.buf.write_str(" ")?; | ||
} | ||
|
||
self.state.on_newline = s.ends_with('\n'); | ||
self.buf.write_str(s)?; | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
fn write_char(&mut self, c: char) -> fmt::Result { | ||
if self.state.on_newline { | ||
self.buf.write_str(" ")?; | ||
} | ||
self.state.on_newline = c == '\n'; | ||
self.buf.write_char(c) | ||
} | ||
} | ||
|
||
struct FmtHolder<F> | ||
where | ||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, | ||
{ | ||
f: RefCell<Option<F>>, | ||
} | ||
|
||
impl<F> FmtHolder<F> | ||
where | ||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, | ||
{ | ||
fn new(value_fmt: F) -> Self { | ||
Self { | ||
f: RefCell::new(Some(value_fmt)), | ||
} | ||
} | ||
} | ||
|
||
impl<F> fmt::Display for FmtHolder<F> | ||
where | ||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, | ||
{ | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
(self.f.borrow_mut().take().unwrap())(f) | ||
} | ||
} | ||
|
||
pub struct AmlDisplayer<'a, 'b: 'a> { | ||
fmt: &'a mut fmt::Formatter<'b>, | ||
result: fmt::Result, | ||
in_paren_arg: bool, | ||
already_in_paren_arg: bool, | ||
already_in_body: bool, | ||
in_body: bool, | ||
is_list: bool, | ||
} | ||
|
||
impl<'a, 'b: 'a> AmlDisplayer<'a, 'b> { | ||
pub fn start(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> Self { | ||
let result = fmt.write_str(name); | ||
Self { | ||
fmt, | ||
result, | ||
in_paren_arg: false, | ||
already_in_paren_arg: false, | ||
in_body: false, | ||
is_list: false, | ||
already_in_body: false, | ||
} | ||
} | ||
|
||
pub fn set_list(&mut self, value: bool) -> &mut Self { | ||
self.is_list = value; | ||
self | ||
} | ||
|
||
pub fn paren_arg<F>(&mut self, value_fmt: F) -> &mut Self | ||
where | ||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, | ||
{ | ||
if !self.in_paren_arg && self.already_in_paren_arg { | ||
self.result = Err(fmt::Error); | ||
} | ||
|
||
self.result = self.result.and_then(|_| { | ||
let prefix = if self.in_paren_arg { ", " } else { " (" }; | ||
|
||
self.fmt.write_str(prefix)?; | ||
value_fmt(self.fmt) | ||
}); | ||
|
||
self.in_paren_arg = true; | ||
self.already_in_paren_arg = true; | ||
|
||
self | ||
} | ||
|
||
pub fn finish_paren_arg(&mut self) -> &mut Self { | ||
if self.in_paren_arg { | ||
self.result = self.result.and_then(|_| self.fmt.write_str(")")); | ||
self.in_paren_arg = false; | ||
} | ||
self | ||
} | ||
|
||
pub fn body_field<F>(&mut self, value_fmt: F) -> &mut Self | ||
where | ||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, | ||
{ | ||
self.finish_paren_arg(); | ||
|
||
self.result = self.result.and_then(|_| { | ||
if self.fmt.alternate() { | ||
if !self.in_body { | ||
self.fmt.write_str(" {\n")?; | ||
} else { | ||
self.fmt | ||
.write_str(if self.is_list { ",\n" } else { "\n" })?; | ||
} | ||
|
||
let mut state = PadAdapterState { on_newline: true }; | ||
let mut writer = PadAdapter::wrap(self.fmt, &mut state); | ||
let fmt_holder = FmtHolder::new(value_fmt); | ||
|
||
writer.write_fmt(format_args!("{:#}", fmt_holder)) | ||
} else { | ||
let prefix = if self.in_body { | ||
if self.is_list { | ||
", " | ||
} else { | ||
"; " | ||
} | ||
} else { | ||
" { " | ||
}; | ||
|
||
self.fmt.write_str(prefix)?; | ||
value_fmt(self.fmt) | ||
} | ||
}); | ||
|
||
self.in_body = true; | ||
self.already_in_body = true; | ||
|
||
self | ||
} | ||
|
||
pub fn at_least_empty_paren_arg(&mut self) -> &mut Self { | ||
if !self.in_paren_arg && !self.already_in_paren_arg { | ||
self.result = self.result.and_then(|_| self.fmt.write_str(" ()")); | ||
} | ||
self | ||
} | ||
|
||
pub fn at_least_empty_body(&mut self) -> &mut Self { | ||
if !self.in_body && !self.already_in_body { | ||
self.result = self.result.and_then(|_| self.fmt.write_str("{ }")); | ||
} | ||
self | ||
} | ||
|
||
pub fn finish(&mut self) -> fmt::Result { | ||
self.finish_paren_arg(); | ||
|
||
if self.in_body { | ||
self.result = self.result.and_then(|_| { | ||
if !self.fmt.alternate() { | ||
self.fmt.write_str(" }") | ||
} else { | ||
self.fmt.write_str("\n}") | ||
} | ||
}); | ||
self.in_body = false; | ||
} | ||
|
||
self.result | ||
} | ||
} | ||
|
||
pub struct HexHolder<'a, T: fmt::UpperHex>(pub &'a T); | ||
|
||
impl<T: fmt::UpperHex> fmt::Display for HexHolder<'_, T> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
write!(f, "{:#X}", self.0) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
mod display; | ||
pub mod execution; | ||
mod parser; | ||
mod structured; | ||
|
Oops, something went wrong.