Skip to content

Commit

Permalink
Attempting to implement input and output.
Browse files Browse the repository at this point in the history
  • Loading branch information
lvella authored and Leo Alt committed Oct 18, 2023
1 parent da82563 commit cd23c52
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 deletions.
2 changes: 1 addition & 1 deletion powdr_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ fn handle_riscv_asm<F: FieldElement>(
just_execute: bool,
) -> Result<(), Vec<String>> {
if just_execute {
riscv_executor::execute::<F>(contents);
riscv_executor::execute::<F>(contents, &inputs);
} else {
compile_asm_string(
file_name,
Expand Down
55 changes: 41 additions & 14 deletions riscv_executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
//! TODO: perform determinism verification for each instruction independently
//! from execution.
use std::collections::HashMap;
use std::{
collections::HashMap,
io::{self, Write},
};

use ast::{
asm_analysis::{AnalysisASMFile, CallableSymbol, FunctionStatement, LabelStatement, Machine},
Expand Down Expand Up @@ -273,18 +276,16 @@ fn preprocess_main_function<T: FieldElement>(
(statements, label_map, batch_to_line_map)
}

struct Executor<'a, 'b> {
struct Executor<'a, 'b, F: FieldElement> {
proc: TraceBuilder<'a, 'b>,
mem: MemoryBuilder,
label_map: HashMap<&'a str, Elem>,
inputs: &'b [F],
stdout: io::Stdout,
}

impl<'a, 'b> Executor<'a, 'b> {
fn exec_instruction<F: FieldElement>(
&mut self,
name: &str,
args: &[Expression<F>],
) -> Vec<Elem> {
impl<'a, 'b, F: FieldElement> Executor<'a, 'b, F> {
fn exec_instruction(&mut self, name: &str, args: &[Expression<F>]) -> Vec<Elem> {
let args = args
.iter()
.map(|expr| self.eval_expression(expr)[0])
Expand Down Expand Up @@ -577,7 +578,7 @@ impl<'a, 'b> Executor<'a, 'b> {
}
}

fn eval_expression<T: FieldElement>(&mut self, expression: &Expression<T>) -> Vec<Elem> {
fn eval_expression(&mut self, expression: &Expression<F>) -> Vec<Elem> {
match expression {
Expression::Reference(r) => {
// an identifier looks like this:
Expand Down Expand Up @@ -649,20 +650,46 @@ impl<'a, 'b> Executor<'a, 'b> {
vec![result.into()]
}
Expression::FunctionCall(f) => self.exec_instruction(&f.id, &f.arguments),
Expression::FreeInput(_) => todo!(),
Expression::FreeInput(expr) => 'input: {
if let Expression::Tuple(t) = &**expr {
if let Expression::String(name) = &t[0] {
let val = self.eval_expression(&t[1])[0];
break 'input vec![match name.as_str() {
"input" => {
let idx = val.u() as usize;
to_u32(&self.inputs[idx]).unwrap().into()
}
"print_char" => {
self.stdout.write(&[val.u() as u8]).unwrap();
// what is print_char supposed to return?
Elem::zero()
}
unk => {
panic!("unknown IO command: {unk}");
}
}];
}
};
panic!("does not matched IO pattern")
}
Expression::MatchExpression(_, _) => todo!(),
}
}
}

pub fn execute_ast<T: FieldElement>(program: &AnalysisASMFile<T>) -> ExecutionTrace {
pub fn execute_ast<'a, T: FieldElement>(
program: &'a AnalysisASMFile<T>,
inputs: &[T],
) -> ExecutionTrace<'a> {
let main_machine = get_main_machine(program);
let (statements, label_map, batch_to_line_map) = preprocess_main_function(main_machine);

let mut e = Executor {
proc: TraceBuilder::new(main_machine, &batch_to_line_map),
mem: MemoryBuilder::new(),
label_map,
inputs,
stdout: io::stdout(),
};

let mut curr_pc = 0u32;
Expand Down Expand Up @@ -700,7 +727,7 @@ pub fn execute_ast<T: FieldElement>(program: &AnalysisASMFile<T>) -> ExecutionTr
///
/// The FieldElement is just used by the parser, before everything is converted
/// to i64, so it is probably not very important.
pub fn execute<F: FieldElement>(asm_source: &str) {
pub fn execute<F: FieldElement>(asm_source: &str, inputs: &[F]) {
log::info!("Parsing...");
let parsed = parser::parse_asm::<F>(None, asm_source).unwrap();
log::info!("Resolving imports...");
Expand All @@ -709,7 +736,7 @@ pub fn execute<F: FieldElement>(asm_source: &str) {
let analyzed = analysis::analyze(resolved, &mut ast::DiffMonitor::default()).unwrap();

log::info!("Executing...");
execute_ast(&analyzed);
execute_ast(&analyzed, inputs);
}

fn to_u32<F: FieldElement>(val: &F) -> Option<u32> {
Expand Down Expand Up @@ -744,6 +771,6 @@ mod test {
println!("Validating UTF-8...");
let asm_str = std::str::from_utf8(&asm).unwrap();

execute::<GoldilocksField>(asm_str);
execute::<GoldilocksField>(asm_str, &[]);
}
}

0 comments on commit cd23c52

Please sign in to comment.