pub(super) mod apply_to_arguments;
pub(super) mod utils;
use super::ExecutionCtx;
use super::ExecutionResult;
use super::TraceHandler;
use crate::execution_step::Joinable;
use crate::execution_step::ValueAggregate;
use crate::joinable;
use crate::log_instruction;
use crate::trace_to_exec_err;
use crate::JValue;
use apply_to_arguments::apply_to_arg;
use utils::*;
use air_parser::ast;
use air_parser::ast::Ap;
use air_trace_handler::merger::MergerApResult;
impl<'i> super::ExecutableInstruction<'i> for Ap<'i> {
#[tracing::instrument(level = "debug", skip(exec_ctx, trace_ctx))]
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> {
log_instruction!(ap, exec_ctx, trace_ctx);
let should_touch_trace = should_touch_trace(self);
let result = joinable!(
apply_to_arg(&self.argument, exec_ctx, trace_ctx, should_touch_trace),
exec_ctx,
()
)?;
let merger_ap_result = to_merger_ap_result(self, trace_ctx)?;
populate_context(&self.result, &merger_ap_result, result, exec_ctx)?;
maybe_update_trace(should_touch_trace, trace_ctx);
Ok(())
}
}
fn should_touch_trace(ap: &Ap<'_>) -> bool {
matches!(ap.result, ast::ApResult::Stream(_))
}
fn to_merger_ap_result(instr: &Ap<'_>, trace_ctx: &mut TraceHandler) -> ExecutionResult<MergerApResult> {
match instr.result {
ast::ApResult::Scalar(_) => Ok(MergerApResult::NotMet),
ast::ApResult::Stream(_) => {
let merger_ap_result = trace_to_exec_err!(trace_ctx.meet_ap_start(), instr)?;
Ok(merger_ap_result)
}
}
}
fn populate_context<'ctx>(
ap_result: &ast::ApResult<'ctx>,
merger_ap_result: &MergerApResult,
result: ValueAggregate,
exec_ctx: &mut ExecutionCtx<'ctx>,
) -> ExecutionResult<()> {
match ap_result {
ast::ApResult::Scalar(scalar) => exec_ctx.scalars.set_scalar_value(scalar.name, result).map(|_| ()),
ast::ApResult::Stream(stream) => {
let value_descriptor = generate_value_descriptor(result, stream, merger_ap_result);
exec_ctx.streams.add_stream_value(value_descriptor)
}
}
}
fn maybe_update_trace(should_touch_trace: bool, trace_ctx: &mut TraceHandler) {
use air_interpreter_data::ApResult;
if should_touch_trace {
trace_ctx.meet_ap_end(ApResult::stub());
}
}