tamer: ir::asg::section: Provide iterators for major section groups
These groups happen to correspond with the sections of the xmle file, which suggests again that this lives in the wrong place. But I should really have my focus elsewhere right now, so I don't know if I'll go any further right now. I guess we'll see as the writer is reimplemented.main
parent
1fa9614698
commit
ab093046e9
|
@ -205,7 +205,7 @@ pub use object::{
|
|||
FragmentText, IdentObject, IdentObjectData, IdentObjectState, Source,
|
||||
TransitionError, TransitionResult, UnresolvedError,
|
||||
};
|
||||
pub use section::{Section, SectionIter, Sections};
|
||||
pub use section::{Section, SectionIter, Sections, SectionsIter};
|
||||
|
||||
/// Default concrete ASG implementation.
|
||||
pub type DefaultAsg<O, Ix> = base::BaseAsg<O, Ix>;
|
||||
|
|
|
@ -107,6 +107,7 @@ impl<'a, T> Iterator for SectionIter<'a, T> {
|
|||
///
|
||||
/// These sections may not necessarily correspond directly to sections of an
|
||||
/// [object file](crate::obj).
|
||||
// TODO: Remove pub
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
pub struct Sections<'a, T> {
|
||||
pub map: Section<'a, T>,
|
||||
|
@ -147,7 +148,7 @@ impl<'a, T> Sections<'a, T> {
|
|||
/// they are chained in the same order in which they are defined
|
||||
/// on the [`Sections`] struct.
|
||||
pub fn iter_all(&self) -> SectionsIter<T> {
|
||||
SectionsIter(
|
||||
SectionsIter(SectionsIterType::All(
|
||||
self.map
|
||||
.iter()
|
||||
.chain(self.retmap.iter())
|
||||
|
@ -158,7 +159,44 @@ impl<'a, T> Sections<'a, T> {
|
|||
.chain(self.funcs.iter())
|
||||
.chain(self.consts.iter())
|
||||
.chain(self.rater.iter()),
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
/// Construct an iterator over the static sections in arbitrary order.
|
||||
///
|
||||
/// These sections contain fragments that do not depend on any external
|
||||
/// inputs and can therefore be executed a single time when the
|
||||
/// program is loaded into memory.
|
||||
///
|
||||
/// Each individual section is ordered as stated in [`Section::iter`],
|
||||
/// but you should not rely on the order that the sections themselves
|
||||
/// appear in;
|
||||
/// they may change or be combined in the future.
|
||||
pub fn iter_static(&self) -> SectionsIter<T> {
|
||||
SectionsIter(SectionsIterType::Static(
|
||||
self.meta
|
||||
.iter()
|
||||
.chain(self.worksheet.iter())
|
||||
.chain(self.params.iter())
|
||||
.chain(self.types.iter())
|
||||
.chain(self.funcs.iter())
|
||||
.chain(self.consts.iter()),
|
||||
))
|
||||
}
|
||||
|
||||
/// Construct an iterator over the map section.
|
||||
pub fn iter_map(&self) -> SectionsIter<T> {
|
||||
SectionsIter(SectionsIterType::Single(self.map.iter()))
|
||||
}
|
||||
|
||||
/// Construct an iterator over the return map section.
|
||||
pub fn iter_retmap(&self) -> SectionsIter<T> {
|
||||
SectionsIter(SectionsIterType::Single(self.retmap.iter()))
|
||||
}
|
||||
|
||||
/// Construct an iterator over the executable `rater` section.
|
||||
pub fn iter_exec(&self) -> SectionsIter<T> {
|
||||
SectionsIter(SectionsIterType::Single(self.rater.iter()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,20 +208,33 @@ type CSIter1<'a, T, L> = Chain<L, SIter<'a, T>>;
|
|||
type CSIter2<'a, T, L> = CSIter1<'a, T, CSIter1<'a, T, L>>;
|
||||
type CSIter4<'a, T, L> = CSIter2<'a, T, CSIter2<'a, T, L>>;
|
||||
type CSIter8<'a, T, L> = CSIter4<'a, T, CSIter4<'a, T, L>>;
|
||||
|
||||
type SIter6<'a, T> = CSIter4<'a, T, CSIter1<'a, T, SIter<'a, T>>>;
|
||||
type SIter9<'a, T> = CSIter8<'a, T, SIter<'a, T>>;
|
||||
|
||||
/// Types of iterators encapsulated by [`SectionsIter`].
|
||||
enum SectionsIterType<'a, T> {
|
||||
All(SIter9<'a, T>),
|
||||
Static(SIter6<'a, T>),
|
||||
Single(SIter<'a, T>),
|
||||
}
|
||||
|
||||
/// Iterator over each of the sections.
|
||||
///
|
||||
/// This iterator should be created with [`Sections::iter_all`].
|
||||
///
|
||||
/// This hides the complex iterator type from callers.
|
||||
pub struct SectionsIter<'a, T>(SIter9<'a, T>);
|
||||
pub struct SectionsIter<'a, T>(SectionsIterType<'a, T>);
|
||||
|
||||
impl<'a, T> Iterator for SectionsIter<'a, T> {
|
||||
type Item = &'a T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.0.next()
|
||||
match &mut self.0 {
|
||||
SectionsIterType::All(inner) => inner.next(),
|
||||
SectionsIterType::Static(inner) => inner.next(),
|
||||
SectionsIterType::Single(inner) => inner.next(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
use super::writer::{Result, WriterError};
|
||||
use crate::global;
|
||||
use crate::ir::asg::{
|
||||
IdentKind, IdentObject, IdentObjectData, SectionIter, Sections,
|
||||
IdentKind, IdentObject, IdentObjectData, Sections, SectionsIter,
|
||||
};
|
||||
use crate::sym::{GlobalSymbolResolve, ProgSymbolId, SymbolId};
|
||||
use fxhash::FxHashSet;
|
||||
|
@ -108,22 +108,16 @@ impl<W: Write> XmleWriter<W> {
|
|||
writer.write_froms(§ions)
|
||||
})?
|
||||
.write_element(b"l:map-exec", |writer| {
|
||||
writer.write_section(sections.map.iter())
|
||||
writer.write_section(sections.iter_map())
|
||||
})?
|
||||
.write_element(b"l:retmap-exec", |writer| {
|
||||
writer.write_section(sections.retmap.iter())
|
||||
writer.write_section(sections.iter_retmap())
|
||||
})?
|
||||
.write_element(b"l:static", |writer| {
|
||||
writer
|
||||
.write_section(sections.meta.iter())?
|
||||
.write_section(sections.worksheet.iter())?
|
||||
.write_section(sections.params.iter())?
|
||||
.write_section(sections.types.iter())?
|
||||
.write_section(sections.funcs.iter())?
|
||||
.write_section(sections.consts.iter())
|
||||
writer.write_section(sections.iter_static())
|
||||
})?
|
||||
.write_element(b"l:exec", |writer| {
|
||||
writer.write_section(sections.rater.iter())
|
||||
writer.write_section(sections.iter_exec())
|
||||
})?
|
||||
.write_end_tag(b"package")?;
|
||||
|
||||
|
@ -313,7 +307,7 @@ impl<W: Write> XmleWriter<W> {
|
|||
) -> Result<&mut XmleWriter<W>> {
|
||||
let mut map_froms: FxHashSet<ProgSymbolId> = Default::default();
|
||||
|
||||
let map_iter = sections.map.iter();
|
||||
let map_iter = sections.iter_map();
|
||||
|
||||
for map_ident in map_iter {
|
||||
let src = map_ident.src().expect("internal error: missing map src");
|
||||
|
@ -343,7 +337,7 @@ impl<W: Write> XmleWriter<W> {
|
|||
/// `writer`'s 'write_event`.
|
||||
fn write_section<T: IdentObjectData<Ix>>(
|
||||
&mut self,
|
||||
idents: SectionIter<T>,
|
||||
idents: SectionsIter<T>,
|
||||
) -> Result<&mut XmleWriter<W>> {
|
||||
for obj in idents {
|
||||
let ident = obj
|
||||
|
@ -420,7 +414,7 @@ mod mock {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::ir::asg::{Dim, FragmentText, Section, Source};
|
||||
use crate::ir::asg::{Dim, FragmentText, Source};
|
||||
use crate::ir::legacyir::SymAttrs;
|
||||
use crate::sym::GlobalSymbolIntern;
|
||||
use std::str;
|
||||
|
@ -517,9 +511,9 @@ mod test {
|
|||
FragmentText::from(""),
|
||||
);
|
||||
|
||||
let mut section = Section::new();
|
||||
section.push_body(&obj);
|
||||
sut.write_section(section.iter())?;
|
||||
let mut sections = Sections::new();
|
||||
sections.rater.push_body(&obj);
|
||||
sut.write_section(sections.iter_all())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -537,9 +531,9 @@ mod test {
|
|||
Source::default(),
|
||||
);
|
||||
|
||||
let mut section = Section::new();
|
||||
section.push_body(&obj);
|
||||
sut.write_section(section.iter())?;
|
||||
let mut sections = Sections::new();
|
||||
sections.rater.push_body(&obj);
|
||||
sut.write_section(sections.iter_all())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -553,9 +547,9 @@ mod test {
|
|||
|
||||
let obj = IdentObject::Missing("missing".intern());
|
||||
|
||||
let mut section = Section::new();
|
||||
section.push_body(&obj);
|
||||
let result = sut.write_section(section.iter());
|
||||
let mut sections = Sections::new();
|
||||
sections.rater.push_body(&obj);
|
||||
let result = sut.write_section(sections.iter_all());
|
||||
|
||||
match result {
|
||||
Err(WriterError::ExpectedFragment(_)) => {}
|
||||
|
|
Loading…
Reference in New Issue