Skip to content

Commit

Permalink
Merge pull request #1102 from 0xPolygonMiden/dominik_serialize_progra…
Browse files Browse the repository at this point in the history
…mast

Writing `ProgramAst` into files
  • Loading branch information
bobbinth authored Oct 11, 2023
2 parents cf698d6 + c63d9cc commit 7e65588
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 28 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## 0.7.0 (TBD)
## 0.7.0 (2023-10-11)

#### Assembly
- Added ability to attach doc comments to re-exported procedures (#994).
Expand All @@ -12,6 +12,9 @@
- Added `debug` decorator (#1069).
- Refactored `push` instruction so now it parses long hex string in little-endian (#1076).

#### CLI
- Implemented ability to output compiled `.masb` files to disk (#1102).

#### VM Internals
- Simplified range checker and removed 1 main and 1 auxiliary trace column (#949).
- Migrated range checker lookups to use LogUp and reduced the number of trace columns to 2 main and
Expand All @@ -23,9 +26,11 @@
- Added `TraceLenSummary` struct which holds information about traces lengths to the `ExecutionTrace` (#1029).
- Imposed the 2^32 limit for the memory addresses used in the memory chiplet (#1049).
- Supported `PartialMerkleTree` as a secret input in `.input` file (#1072).
- [BREAKING] Refactored `AdviceProvider` interface into [Host] interface (#1082).

#### Stdlib
- Completed `std::collections::smt` module by implementing `insert` and `set` procedures (#1036, #1038, #1046).
- Added new module `std::crypto::dsa::rpo_falcon512` to support Falcon signature verification (#1000, #1094)

## 0.6.1 (2023-06-29)

Expand Down
14 changes: 12 additions & 2 deletions assembly/src/assembler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,19 @@ impl Assembler {
let source = source.as_ref();
let program = ProgramAst::parse(source)?;

// compile the program and return
self.compile_ast(&program)
}

/// Compiles the provided abstract syntax tree into a [Program]. The resulting program can be
/// executed on Miden VM.
///
/// # Errors
/// Returns an error if the compilation of the specified program fails.
pub fn compile_ast(&self, program: &ProgramAst) -> Result<Program, AssemblyError> {
// compile the program
let mut context = AssemblyContext::for_program(Some(&program));
let program_root = self.compile_in_context(&program, &mut context)?;
let mut context = AssemblyContext::for_program(Some(program));
let program_root = self.compile_in_context(program, &mut context)?;

// convert the context into a call block table for the program
let cb_table = context.into_cb_table(&self.proc_cache.borrow())?;
Expand Down
22 changes: 22 additions & 0 deletions assembly/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use super::{
MAX_LABEL_LEN,
};
use core::{fmt, iter, str::from_utf8};
#[cfg(feature = "std")]
use std::{fs, io, path::Path};
use vm_core::utils::bound_into_included_u64;

pub use super::tokens::SourceLocation;
Expand Down Expand Up @@ -336,6 +338,26 @@ impl ProgramAst {
pub fn clear_imports(&mut self) {
self.import_info = None;
}

// WRITE TO FILE
// --------------------------------------------------------------------------------------------

/// Writes ProgramAst to provided file path
#[cfg(feature = "std")]
pub fn write_to_file<P>(&self, file_path: P) -> io::Result<()>
where
P: AsRef<Path>,
{
let path = file_path.as_ref();
if let Some(dir) = path.parent() {
fs::create_dir_all(dir)?;
}

let bytes = self.to_bytes(AstSerdeOptions {
serialize_imports: true,
});
fs::write(path, bytes)
}
}

impl fmt::Display for ProgramAst {
Expand Down
15 changes: 11 additions & 4 deletions miden/src/cli/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ pub struct CompileCmd {
/// Paths to .masl library files
#[clap(short = 'l', long = "libraries", value_parser)]
library_paths: Vec<PathBuf>,
/// Path to output file
#[clap(short = 'o', long = "output", value_parser)]
output_file: Option<PathBuf>,
}

impl CompileCmd {
Expand All @@ -20,16 +23,20 @@ impl CompileCmd {
println!("Compile program");
println!("============================================================");

// load the program from file and parse it
let program = ProgramFile::read(&self.assembly_file)?;

// load libraries from files
let libraries = Libraries::new(&self.library_paths)?;

// load program from file and compile
let program = ProgramFile::read(&self.assembly_file, &Debug::Off, libraries.libraries)?;
// compile the program
let compiled_program = program.compile(&Debug::Off, libraries.libraries)?;

// report program hash to user
let program_hash: [u8; 32] = program.hash().into();
let program_hash: [u8; 32] = compiled_program.hash().into();
println!("program hash is {}", hex::encode(program_hash));

Ok(())
// write the compiled file
program.write(self.output_file.clone())
}
}
59 changes: 46 additions & 13 deletions miden/src/cli/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use miden::{
crypto::{MerkleStore, MerkleTree, NodeIndex, PartialMerkleTree, RpoDigest, SimpleSmt},
math::Felt,
utils::{Deserializable, SliceReader},
AdviceInputs, Assembler, Digest, ExecutionProof, MemAdviceProvider, Program, StackInputs,
StackOutputs, Word,
AdviceInputs, Assembler, Digest, ExecutionProof, MemAdviceProvider, Program, ProgramAst,
StackInputs, StackOutputs, Word,
};
use serde_derive::{Deserialize, Serialize};
use std::{
Expand Down Expand Up @@ -69,7 +69,7 @@ pub enum MerkleData {
pub struct InputFile {
/// String representation of the initial operand stack, composed of chained field elements.
pub operand_stack: Vec<String>,
/// Opitonal string representation of the initial advice stack, composed of chained field
/// Optional string representation of the initial advice stack, composed of chained field
/// elements.
pub advice_stack: Option<Vec<String>>,
/// Optional map of 32 byte hex strings to vectors of u64s representing the initial advice map.
Expand Down Expand Up @@ -371,21 +371,40 @@ impl OutputFile {
// PROGRAM FILE
// ================================================================================================

pub struct ProgramFile;
pub struct ProgramFile {
ast: ProgramAst,
path: PathBuf,
}

/// Helper methods to interact with masm program file
/// Helper methods to interact with masm program file.
impl ProgramFile {
pub fn read<I, L>(path: &PathBuf, debug: &Debug, libraries: I) -> Result<Program, String>
/// Reads the masm file at the specified path and parses it into a [ProgramAst].
pub fn read(path: &PathBuf) -> Result<Self, String> {
// read program file to string
println!("Reading program file `{}`", path.display());
let source = fs::read_to_string(&path)
.map_err(|err| format!("Failed to open program file `{}` - {}", path.display(), err))?;

// parse the program into an AST
print!("Parsing program... ");
let now = Instant::now();
let ast = ProgramAst::parse(&source).map_err(|err| {
format!("Failed to parse program file `{}` - {}", path.display(), err)
})?;
println!("done ({} ms)", now.elapsed().as_millis());

Ok(Self {
ast,
path: path.clone(),
})
}

/// Compiles this program file into a [Program].
pub fn compile<I, L>(&self, debug: &Debug, libraries: I) -> Result<Program, String>
where
I: IntoIterator<Item = L>,
L: Library,
{
println!("Reading program file `{}`", path.display());

// read program file to string
let program_file = fs::read_to_string(&path)
.map_err(|err| format!("Failed to open program file `{}` - {}", path.display(), err))?;

print!("Compiling program... ");
let now = Instant::now();

Expand All @@ -400,13 +419,27 @@ impl ProgramFile {
.map_err(|err| format!("Failed to load libraries `{}`", err))?;

let program = assembler
.compile(&program_file)
.compile_ast(&self.ast)
.map_err(|err| format!("Failed to compile program - {}", err))?;

println!("done ({} ms)", now.elapsed().as_millis());

Ok(program)
}

/// Writes this file into the specified path, if one is provided. If the path is not provided,
/// writes the file into the same directory as the source file, but with `.masb` extension.
pub fn write(&self, out_path: Option<PathBuf>) -> Result<(), String> {
let out_path = out_path.unwrap_or_else(|| {
let mut out_file = self.path.clone();
out_file.set_extension("masb");
out_file
});

self.ast
.write_to_file(out_path)
.map_err(|err| format!("Failed to write the compiled file: {err}"))
}
}

// PROOF FILE
Expand Down
3 changes: 2 additions & 1 deletion miden/src/cli/debug/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ impl DebugCmd {
let libraries = Libraries::new(&self.library_paths)?;

// load program from file and compile
let program = ProgramFile::read(&self.assembly_file, &Debug::On, libraries.libraries)?;
let program =
ProgramFile::read(&self.assembly_file)?.compile(&Debug::On, libraries.libraries)?;

let program_hash: [u8; 32] = program.hash().into();
println!("Debugging program with hash {}... ", hex::encode(program_hash));
Expand Down
3 changes: 2 additions & 1 deletion miden/src/cli/prove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ impl ProveCmd {
let libraries = Libraries::new(&self.library_paths)?;

// load program from file and compile
let program = ProgramFile::read(&self.assembly_file, &Debug::Off, libraries.libraries)?;
let program =
ProgramFile::read(&self.assembly_file)?.compile(&Debug::Off, libraries.libraries)?;

// load input data from file
let input_data = InputFile::read(&self.input_file, &self.assembly_file)?;
Expand Down
3 changes: 2 additions & 1 deletion miden/src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ impl RunCmd {
let libraries = Libraries::new(&self.library_paths)?;

// load program from file and compile
let program = ProgramFile::read(&self.assembly_file, &Debug::Off, libraries.libraries)?;
let program =
ProgramFile::read(&self.assembly_file)?.compile(&Debug::Off, libraries.libraries)?;

// load input data from file
let input_data = InputFile::read(&self.input_file, &self.assembly_file)?;
Expand Down
13 changes: 8 additions & 5 deletions miden/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
// EXPORTS
// ================================================================================================

pub use assembly::{Assembler, AssemblyError, ParsingError};
pub use assembly::{
ast::{ModuleAst, ProgramAst},
Assembler, AssemblyError, ParsingError,
};
pub use processor::{
crypto, execute, execute_iter, utils, AdviceInputs, AdviceProvider, AsmOpInfo, DefaultHost,
ExecutionError, ExecutionTrace, Host, Kernel, MemAdviceProvider, Operation, ProgramInfo,
StackInputs, VmState, VmStateIterator, ZERO,
ExecutionError, ExecutionTrace, Host, Kernel, MemAdviceProvider, Operation, Program,
ProgramInfo, StackInputs, VmState, VmStateIterator, ZERO,
};
pub use prover::{
math, prove, Digest, ExecutionProof, FieldExtension, HashFunction, InputError, Program,
ProvingOptions, StackOutputs, StarkProof, Word,
math, prove, Digest, ExecutionProof, FieldExtension, HashFunction, InputError, ProvingOptions,
StackOutputs, StarkProof, Word,
};
pub use verifier::{verify, VerificationError};

0 comments on commit 7e65588

Please sign in to comment.