use core::ops::Range;
use miden_assembly_syntax::{
Felt,
ast::Immediate,
debuginfo::{SourceSpan, Spanned},
diagnostics::Report,
parser::{ParsingError, WordValue},
};
use miden_core::operations::Operation::*;
use super::{BasicBlockBuilder, mem_ops::local_to_absolute_addr, push_felt};
use crate::ProcedureContext;
pub fn push_one<T>(imm: T, block_builder: &mut BasicBlockBuilder)
where
T: Into<Felt>,
{
push_felt(block_builder, imm.into());
}
pub fn push_many<T>(imms: &[T], block_builder: &mut BasicBlockBuilder)
where
T: Into<Felt> + Copy,
{
imms.iter().for_each(|imm| push_felt(block_builder, (*imm).into()));
}
pub fn push_word(word: &[Felt; 4], block_builder: &mut BasicBlockBuilder) {
for felt in word.iter().rev() {
push_felt(block_builder, *felt);
}
}
pub fn push_word_slice(
imm: &Immediate<WordValue>,
range: &Range<usize>,
block_builder: &mut BasicBlockBuilder,
) -> Result<(), Report> {
let v = imm.expect_value();
match v.0.get(range.clone()) {
None => {
return Err(Report::new(ParsingError::InvalidRange {
span: imm.span(),
range: range.clone(),
}));
},
Some([]) => {
return Err(Report::new(ParsingError::EmptySlice {
span: imm.span(),
range: range.clone(),
}));
},
Some(values) => {
for felt in values.iter().rev() {
push_felt(block_builder, *felt);
}
},
}
Ok(())
}
pub fn locaddr(
block_builder: &mut BasicBlockBuilder,
index: u16,
proc_ctx: &ProcedureContext,
instr_span: SourceSpan,
) -> Result<(), Report> {
local_to_absolute_addr(block_builder, proc_ctx, index, proc_ctx.num_locals(), true, instr_span)
}
pub fn caller(block_builder: &mut BasicBlockBuilder) {
block_builder.push_op(Caller);
}