aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/xixanta/src/assembler.rs26
1 files changed, 21 insertions, 5 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs
index bf7b5a0..2f09295 100644
--- a/lib/xixanta/src/assembler.rs
+++ b/lib/xixanta/src/assembler.rs
@@ -100,13 +100,20 @@ impl Assembler {
// where scopes start/end, evaluating values for variables, labels, etc.
self.eval_context(&parser.nodes)?;
- // Finally convert the relevant nodes into binary bundles which can be
- // used by the caller.
+ // Convert the relevant nodes into binary bundles which can be used by
+ // the caller. This is done for most nodes, even if some of them will
+ // have to be marked as pending, since they depend on knowing the exact
+ // size for a given segment.
self.stage = Stage::Bundling;
self.bundle(&parser.nodes)?;
+ // Now we know how much each segment spans, and we can resolve (crunch)
+ // the nodes marked as pending.
self.stage = Stage::Crunching;
- self.crunch_and_resolve_pending()
+ self.crunch()?;
+
+ // All set, fill the vector of bundles to be returned.
+ self.fill()
}
pub fn eval_context(&mut self, nodes: &[PNode]) -> Result<(), Vec<Error>> {
@@ -281,8 +288,7 @@ impl Assembler {
}
}
- // TODO: maybe split?
- pub fn crunch_and_resolve_pending(&mut self) -> Result<Vec<Bundle>, Vec<Error>> {
+ fn crunch(&mut self) -> Result<(), Vec<Error>> {
let mut errors = vec![];
for pn in self.pending.clone() {
@@ -310,6 +316,16 @@ impl Assembler {
self.context.force_context_pop();
}
+ if errors.is_empty() {
+ Ok(())
+ } else {
+ Err(errors)
+ }
+ }
+
+ fn fill(&mut self) -> Result<Vec<Bundle>, Vec<Error>> {
+ let mut errors = vec![];
+
// Validate the mappings that have been evaluated before spitting it
// out.
if let Err(e) = crate::mapping::validate(&self.mappings) {