diff options
-rw-r--r-- | tvix/eval/src/chunk.rs | 2 | ||||
-rw-r--r-- | tvix/eval/src/disassembler.rs | 31 | ||||
-rw-r--r-- | tvix/eval/src/eval.rs | 4 |
3 files changed, 35 insertions, 2 deletions
diff --git a/tvix/eval/src/chunk.rs b/tvix/eval/src/chunk.rs index e0b584fb1f98..03071b3008de 100644 --- a/tvix/eval/src/chunk.rs +++ b/tvix/eval/src/chunk.rs @@ -4,7 +4,7 @@ use crate::value::Value; #[derive(Debug, Default)] pub struct Chunk { pub code: Vec<OpCode>, - constants: Vec<Value>, + pub constants: Vec<Value>, } impl Chunk { diff --git a/tvix/eval/src/disassembler.rs b/tvix/eval/src/disassembler.rs index 98a6dac9afc4..e5f6df525ad4 100644 --- a/tvix/eval/src/disassembler.rs +++ b/tvix/eval/src/disassembler.rs @@ -4,6 +4,7 @@ use std::io::{Stderr, Write}; use tabwriter::TabWriter; +use crate::chunk::Chunk; use crate::opcode::OpCode; use crate::value::Value; @@ -35,3 +36,33 @@ impl Drop for Tracer { self.0.flush().ok(); } } + +fn disassemble_op(tw: &mut TabWriter<Stderr>, chunk: &Chunk, offset: usize) { + let code_width = format!("{}", chunk.code.len()).len(); + write!(tw, "{:0width$}\t ", width = code_width).ok(); + + match chunk.code[offset] { + OpCode::OpConstant(idx) => write!(tw, "OpConstant({})\n", chunk.constant(idx)).ok(), + + op => write!(tw, "{:?}\n", op).ok(), + }; +} + +/// Disassemble a chunk of code, printing out the operations in a +/// reasonable, human-readable format. +pub fn disassemble_chunk(chunk: &Chunk) { + let mut tw = TabWriter::new(std::io::stderr()); + + write!( + &mut tw, + "=== compiled bytecode ({} operations) ===\n", + chunk.code.len() + ) + .ok(); + + for (idx, _) in chunk.code.iter().enumerate() { + disassemble_op(&mut tw, chunk, idx); + } + + tw.flush().ok(); +} diff --git a/tvix/eval/src/eval.rs b/tvix/eval/src/eval.rs index 903708f108b3..456f2575cab7 100644 --- a/tvix/eval/src/eval.rs +++ b/tvix/eval/src/eval.rs @@ -17,7 +17,9 @@ pub fn interpret(code: &str, location: Option<PathBuf>) -> EvalResult<Value> { } let result = crate::compiler::compile(ast, location)?; - println!("code: {:?}", result.chunk); + + #[cfg(feature = "disassembler")] + crate::disassembler::disassemble_chunk(&result.chunk); for warning in result.warnings { eprintln!( |