Skip to content

Commit

Permalink
Code reorg.
Browse files Browse the repository at this point in the history
  • Loading branch information
gzanitti committed Nov 9, 2023
1 parent 8296d16 commit f9bc8cc
Showing 1 changed file with 97 additions and 97 deletions.
194 changes: 97 additions & 97 deletions etk-asm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,89 +223,21 @@ impl Assembler {
Self::default()
}

/// Backpatch dynamic operations and emit the assembled program.
/// Feed instructions into the `Assembler`.
///
/// Errors if there are any undeclared labels.
fn backpatch_and_emit(&mut self) -> Result<Vec<u8>, Error> {
if !self.undeclared_labels.is_empty() {
return error::UndeclaredLabels {
labels: self
.undeclared_labels
.iter()
.map(|l| l.to_owned())
.collect::<Vec<String>>(),
}
.fail();
}
let mut output = Vec::new();
for op in self.ready.iter() {
if let RawOp::Op(ref op) = op {
match op
.clone()
.concretize((&self.declared_labels, &self.declared_macros).into())
{
Ok(mut cop) => {
if let AbstractOp::Push(imm) = op {
let exp = imm.tree.eval_with_context(
(&self.declared_labels, &self.declared_macros).into(),
);

let labels: HashSet<String> = imm
.tree
.labels(&self.declared_macros)
.unwrap()
.into_iter()
.collect();
if !labels.is_empty() {
if let Ok(val) = exp {
let extra = val.to_usize().unwrap() / 256;
if extra > 0 {
self.concrete_len += extra;

for label in labels {
if let Some(position) =
self.declared_labels.get_mut(&label)
{
*position = position.map(|v| v + 1);
}
}
}
}
}

cop = op
.clone()
.concretize((&self.declared_labels, &self.declared_macros).into())
.unwrap();
}
cop.assemble(&mut output)
}
Err(ops::Error::ContextIncomplete {
source: UnknownLabel { .. },
}) => {
return error::UndeclaredLabels {
labels: self.undeclared_labels.to_vec(),
}
.fail();
}
Err(ops::Error::ContextIncomplete {
source: UnknownMacro { name, .. },
}) => {
return error::UndeclaredInstructionMacro { name }.fail();
}
Err(ops::Error::ContextIncomplete {
source: UndefinedVariable { name, .. },
}) => {
return error::UndeclaredVariableMacro { var: name }.fail();
}
/// Returns the code of the assembled program.
pub fn assemble<O>(&mut self, ops: &[O]) -> Result<Vec<u8>, Error>
where
O: Into<RawOp> + Clone,
{
self.declare_macros(ops)?;

Err(_) => unreachable!("all ops should be concretizable"),
}
} else if let RawOp::Raw(raw) = op {
output.extend(raw);
}
for op in ops {
self.push(op.clone().into())?;
}

let output = self.backpatch_and_emit()?;
self.ready.clear();
Ok(output)
}

Expand Down Expand Up @@ -333,24 +265,6 @@ impl Assembler {
Ok(())
}

/// Feed instructions into the `Assembler`.
///
/// Returns the code of the assembled program.
pub fn assemble<O>(&mut self, ops: &[O]) -> Result<Vec<u8>, Error>
where
O: Into<RawOp> + Clone,
{
self.declare_macros(ops)?;

for op in ops {
self.push(op.clone().into())?;
}

let output = self.backpatch_and_emit()?;
self.ready.clear();
Ok(output)
}

/// Feed a single instruction into the `Assembler`.
fn push<O>(&mut self, rop: O) -> Result<usize, Error>
where
Expand Down Expand Up @@ -432,6 +346,92 @@ impl Assembler {
Ok(self.concrete_len)
}

/// Backpatch dynamic operations and emit the assembled program.
///
/// Errors if there are any undeclared labels.
fn backpatch_and_emit(&mut self) -> Result<Vec<u8>, Error> {
if !self.undeclared_labels.is_empty() {
return error::UndeclaredLabels {
labels: self
.undeclared_labels
.iter()
.map(|l| l.to_owned())
.collect::<Vec<String>>(),
}
.fail();
}
let mut output = Vec::new();
for op in self.ready.iter() {
if let RawOp::Op(ref op) = op {
match op
.clone()
.concretize((&self.declared_labels, &self.declared_macros).into())
{
Ok(mut cop) => {
if let AbstractOp::Push(imm) = op {
let exp = imm.tree.eval_with_context(
(&self.declared_labels, &self.declared_macros).into(),
);

let labels: HashSet<String> = imm
.tree
.labels(&self.declared_macros)
.unwrap()
.into_iter()
.collect();
if !labels.is_empty() {
if let Ok(val) = exp {
let extra = val.to_usize().unwrap() / 256;
if extra > 0 {
self.concrete_len += extra;

for label in labels {
if let Some(position) =
self.declared_labels.get_mut(&label)
{
*position = position.map(|v| v + 1);
}
}
}
}
}

cop = op
.clone()
.concretize((&self.declared_labels, &self.declared_macros).into())
.unwrap();
}
cop.assemble(&mut output)
}
Err(ops::Error::ContextIncomplete {
source: UnknownLabel { .. },
}) => {
return error::UndeclaredLabels {
labels: self.undeclared_labels.to_vec(),
}
.fail();
}
Err(ops::Error::ContextIncomplete {
source: UnknownMacro { name, .. },
}) => {
return error::UndeclaredInstructionMacro { name }.fail();
}
Err(ops::Error::ContextIncomplete {
source: UndefinedVariable { name, .. },
}) => {
return error::UndeclaredVariableMacro { var: name }.fail();
}

Err(_) => unreachable!("all ops should be concretizable"),
}
} else if let RawOp::Raw(raw) = op {
output.extend(raw);
}
}

Ok(output)
}

fn declare_label(&mut self, rop: &RawOp) -> Result<(), Error> {
if let RawOp::Op(AbstractOp::Label(label)) = rop {
if self.declared_labels.contains_key(label) {
Expand Down

0 comments on commit f9bc8cc

Please sign in to comment.