Skip to content

Use assembler instead of source manager when building libraries #1445

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

Merged
merged 8 commits into from
Aug 13, 2024
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
# Changelog

## 0.10.1 (2024-08-10)
## 0.10.3 (2024-08-11)

#### Enhancements

- Added `with-debug-info` feature to `miden-stdlib` (#1445).
- Added `Assembler::add_modules_from_dir()` method (#1445).
- [BREAKING] Implemented building of multi-module kernels (#1445).

#### Changes

- [BREAKING] Replaced `SourceManager` parameter with `Assembler` in `Library::from_dir` (#1445).
- [BREAKING] Moved `Library` and `KernelLibrary` exports to the root of the `miden-assembly` crate. (#1445).

## 0.10.2 (2024-08-10)

#### Enhancements

Expand Down
9 changes: 4 additions & 5 deletions assembly/src/assembler/instruction/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use core::ops::RangeBounds;

use miette::miette;
use vm_core::{mast::MastNodeId, Decorator, ONE, ZERO};

use super::{
ast::InvokeKind, mast_forest_builder::MastForestBuilder, Assembler, BasicBlockBuilder, Felt,
Operation, ProcedureContext,
};
use crate::{
ast::Instruction, diagnostics::Report, utils::bound_into_included_u64, AssemblyError, Span,
};
use crate::{ast::Instruction, utils::bound_into_included_u64, AssemblyError, Span};

mod adv_ops;
mod crypto_ops;
Expand Down Expand Up @@ -480,10 +479,10 @@ where
let min = bound_into_included_u64(range.start_bound(), true);
let max = bound_into_included_u64(range.end_bound(), false);
AssemblyError::Other(
Report::msg(format!(
miette!(
"parameter value must be greater than or equal to {min} and \
less than or equal to {max}, but was {value}",
))
)
.into(),
)
})
Expand Down
31 changes: 31 additions & 0 deletions assembly/src/assembler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,30 @@ impl Assembler {
Ok(())
}

/// Adds all modules (defined by ".masm" files) from the specified directory to the module
/// of this assembler graph.
///
/// The modules will be added under the specified namespace, but otherwise preserving the
/// structure of the directory. Any module named `mod.masm` will be added using parent
/// directory path For example, if `namespace` = "ns", modules from the ~/masm directory
/// will be added as follows:
///
/// - ~/masm/foo.masm -> "ns::foo"
/// - ~/masm/bar/mod.masm -> "ns::bar"
/// - ~/masm/bar/baz.masm -> "ns::bar::baz"
#[cfg(feature = "std")]
pub fn add_modules_from_dir(
&mut self,
namespace: crate::LibraryNamespace,
dir: &std::path::Path,
) -> Result<(), Report> {
for module in crate::parser::read_modules_from_dir(namespace, dir, &self.source_manager)? {
self.module_graph.add_ast_module(module)?;
}

Ok(())
}

/// Adds the compiled library to provide modules for the compilation.
pub fn add_library(&mut self, library: impl AsRef<Library>) -> Result<(), Report> {
self.module_graph
Expand Down Expand Up @@ -211,6 +235,11 @@ impl Assembler {
self.module_graph.kernel()
}

/// Returns a link to the source manager used by this assembler.
pub fn source_manager(&self) -> Arc<dyn SourceManager> {
self.source_manager.clone()
}

#[cfg(any(test, feature = "testing"))]
#[doc(hidden)]
pub fn module_graph(&self) -> &ModuleGraph {
Expand Down Expand Up @@ -425,6 +454,7 @@ impl Assembler {
procedure_gid,
name,
proc.visibility(),
module.is_kernel(),
self.source_manager.clone(),
)
.with_num_locals(num_locals)
Expand All @@ -447,6 +477,7 @@ impl Assembler {
procedure_gid,
name,
ast::Visibility::Public,
module.is_kernel(),
self.source_manager.clone(),
)
.with_span(proc_alias.span());
Expand Down
6 changes: 5 additions & 1 deletion assembly/src/assembler/procedure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub struct ProcedureContext {
span: SourceSpan,
name: QualifiedProcedureName,
visibility: Visibility,
is_kernel: bool,
num_locals: u16,
callset: CallSet,
}
Expand All @@ -32,6 +33,7 @@ impl ProcedureContext {
gid: GlobalProcedureIndex,
name: QualifiedProcedureName,
visibility: Visibility,
is_kernel: bool,
source_manager: Arc<dyn SourceManager>,
) -> Self {
Self {
Expand All @@ -40,6 +42,7 @@ impl ProcedureContext {
span: name.span(),
name,
visibility,
is_kernel,
num_locals: 0,
callset: Default::default(),
}
Expand Down Expand Up @@ -76,8 +79,9 @@ impl ProcedureContext {
&self.name.module
}

/// Returns true if the procedure is being assembled for a kernel.
pub fn is_kernel(&self) -> bool {
self.visibility.is_syscall()
self.is_kernel
}

#[inline(always)]
Expand Down
12 changes: 12 additions & 0 deletions assembly/src/ast/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,18 @@ pub struct Module {
pub(crate) procedures: Vec<Export>,
}

/// Constants
impl Module {
/// File extension for a Assembly Module.
pub const FILE_EXTENSION: &'static str = "masm";

/// Name of the root module.
pub const ROOT: &'static str = "mod";

/// File name of the root module.
pub const ROOT_FILENAME: &'static str = "mod.masm";
}

/// Construction
impl Module {
/// Creates a new [Module] with the specified `kind` and fully-qualified path, e.g.
Expand Down
6 changes: 4 additions & 2 deletions assembly/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use alloc::{
vec::Vec,
};

use miette::miette;

use crate::{
ast::{Module, ModuleKind},
diagnostics::{
Expand Down Expand Up @@ -152,10 +154,10 @@ impl Compile for Box<Module> {
}
Ok(self)
} else {
Err(Report::msg(format!(
Err(miette!(
"compilation failed: expected a {} module, but got a {actual} module",
options.kind
)))
))
}
}
}
Expand Down
7 changes: 0 additions & 7 deletions assembly/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,3 @@ impl From<Report> for AssemblyError {
Self::Other(RelatedError::new(report))
}
}

#[derive(Debug, thiserror::Error, Diagnostic)]
pub enum CompiledLibraryError {
#[error("Invalid exports: MAST forest has {roots_len} procedure roots, but exports have {exports_len}")]
#[diagnostic()]
InvalidExports { exports_len: usize, roots_len: usize },
}
13 changes: 9 additions & 4 deletions assembly/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@ pub mod ast;
mod compile;
pub mod diagnostics;
mod errors;
pub mod library;
mod library;
mod parser;
mod sema;
#[cfg(any(test, feature = "testing"))]
pub mod testing;
#[cfg(test)]
mod tests;

/// Re-exported for downstream crates
// Re-exported for downstream crates

/// Merkelized abstract syntax tree (MAST) components defining Miden VM programs.
pub use vm_core::mast;
pub use vm_core::utils;

Expand All @@ -40,8 +42,11 @@ pub use self::{
DefaultSourceManager, Report, SourceFile, SourceId, SourceManager, SourceSpan, Span,
Spanned,
},
errors::{AssemblyError, CompiledLibraryError},
library::{LibraryError, LibraryNamespace, LibraryPath, PathError, Version},
errors::AssemblyError,
library::{
KernelLibrary, Library, LibraryError, LibraryNamespace, LibraryPath, LibraryPathComponent,
PathError, Version, VersionError,
},
parser::ModuleParser,
};

Expand Down
12 changes: 1 addition & 11 deletions assembly/src/library/error.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
use vm_core::errors::KernelError;

use crate::{ast::QualifiedProcedureName, diagnostics::Diagnostic, LibraryNamespace, LibraryPath};
use crate::{ast::QualifiedProcedureName, diagnostics::Diagnostic};

#[derive(Debug, thiserror::Error, Diagnostic)]
pub enum LibraryError {
#[error("kernel library must contain at least one exported procedure")]
#[diagnostic()]
EmptyKernel,
#[error("duplicate module '{0}'")]
#[diagnostic()]
DuplicateModulePath(LibraryPath),
#[error("invalid export in kernel library: {procedure_path}")]
InvalidKernelExport { procedure_path: QualifiedProcedureName },
#[error(transparent)]
Kernel(#[from] KernelError),
#[error("library '{name}' contains {count} modules, but the max is {max}")]
#[diagnostic()]
TooManyModulesInLibrary {
name: LibraryNamespace,
count: usize,
max: usize,
},
}
98 changes: 0 additions & 98 deletions assembly/src/library/masl.rs

This file was deleted.

Loading
Loading