Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Writing ProgramAst into files #1102

Merged
merged 2 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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};
Dominik1999 marked this conversation as resolved.
Show resolved Hide resolved
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};