Skip to content

Commit

Permalink
Merge pull request #121 from maticnetwork/stdlib
Browse files Browse the repository at this point in the history
Implement stdlib structure
  • Loading branch information
bobbinth committed Feb 23, 2022
2 parents be96cb6 + 97291f0 commit e9bddec
Show file tree
Hide file tree
Showing 21 changed files with 1,258 additions and 114 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
#"examples",
#"miden",
"processor",
"stdlib",
#"verifier"
]

Expand Down
1 change: 1 addition & 0 deletions assembly/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ std = ["vm-core/std", "winter-utils/std"]

[dependencies]
vm-core = { package = "miden-core", path = "../core", version = "0.2", default-features = false }
vm-stdlib = { package = "miden-stdlib", path = "../stdlib", version = "0.1", default-features = false }
winter-utils = { package = "winter-utils", version = "0.3", default-features = false }
94 changes: 94 additions & 0 deletions assembly/src/context/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use super::{CodeBlock, ProcMap, Procedure, MODULE_PATH_DELIM};
use winter_utils::collections::BTreeMap;

// ASSEMBLY CONTEXT
// ================================================================================================

/// Context for a compilation of a given script or module.
///
/// An assembly context contains a set of procedures which can be called from the parsed code.
/// The procedures are divided into local and imported procedures. Local procedures are procedures
/// parsed from the body or a script or a module, while imported procedures are imported from
/// other modules.
///
/// Local procedures are owned by the context, while imported procedures are stored by reference.
pub struct AssemblyContext<'a> {
local_procs: ProcMap,
imported_procs: BTreeMap<String, &'a Procedure>,
}

impl<'a> AssemblyContext<'a> {
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
/// Returns a new empty [AssemblyContext].
pub fn new() -> Self {
Self {
local_procs: BTreeMap::new(),
imported_procs: BTreeMap::new(),
}
}

// STATE ACCESSORS
// --------------------------------------------------------------------------------------------

/// Returns true if a procedure with the specified label exists in this context.
pub fn contains_proc(&self, label: &str) -> bool {
self.local_procs.contains_key(label) || self.imported_procs.contains_key(label)
}

/// Returns a code root of a procedure for the specified label from this context.
pub fn get_proc_code(&self, label: &str) -> Option<&CodeBlock> {
// `expect()`'s are OK here because we first check if a given map contains the key
if self.imported_procs.contains_key(label) {
let proc = *self
.imported_procs
.get(label)
.expect("no procedure after contains");
Some(proc.code_root())
} else if self.local_procs.contains_key(label) {
let proc = self
.local_procs
.get(label)
.expect("no procedure after contains");
Some(proc.code_root())
} else {
None
}
}

// STATE MUTATORS
// --------------------------------------------------------------------------------------------

/// Adds a local procedure to this context.
///
/// A label for a local procedure is set simply `proc.label`.
///
/// # Panics
/// Panics if a procedure with the specified label already exists in this context.
pub fn add_local_proc(&mut self, proc: Procedure) {
let label = proc.label();
assert!(!self.contains_proc(label), "duplicate procedure: {}", label);
self.local_procs.insert(label.to_string(), proc);
}

/// Adds an imported procedure to this context.
///
/// A label for an imported procedure is set to `prefix::proc.label`.
///
/// # Panics
/// Panics if a procedure with the specified label already exists in this context.
pub fn add_imported_proc(&mut self, prefix: &str, proc: &'a Procedure) {
let label = format!("{}{}{}", prefix, MODULE_PATH_DELIM, proc.label());
assert!(
!self.contains_proc(&label),
"duplicate procedure: {}",
label
);
self.imported_procs.insert(label, proc);
}

/// Extracts local procedures from this context.
pub fn into_local_procs(self) -> ProcMap {
self.local_procs
}
}
46 changes: 46 additions & 0 deletions assembly/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,52 @@ impl AssemblyError {
}
}

pub fn prc_export_not_allowed(token: &Token, label: &str) -> Self {
AssemblyError {
message: format!("exported procedures not allowed in this context: {}", label),
step: token.pos(),
op: token.to_string(),
}
}

// IMPORTS AND MODULES
// --------------------------------------------------------------------------------------------

pub fn missing_import_source(token: &Token, module_path: &str) -> Self {
AssemblyError {
message: format!("module source not found: {}", module_path),
step: token.pos(),
op: token.to_string(),
}
}

pub fn dangling_ops_after_module(token: &Token, module_path: &str) -> Self {
AssemblyError {
message: format!("dangling instructions after module end at {}", module_path),
step: token.pos(),
op: token.to_string(),
}
}

pub fn circular_module_dependency(token: &Token, module_chain: &[String]) -> Self {
AssemblyError {
message: format!(
"circular module dependency in the following chain: {:?}",
module_chain
),
step: token.pos(),
op: token.to_string(),
}
}

pub fn invalid_module_path(token: &Token, module_path: &str) -> Self {
AssemblyError {
message: format!("invalid module import path: {}", module_path),
step: token.pos(),
op: token.to_string(),
}
}

// PUBLIC ACCESSORS
// --------------------------------------------------------------------------------------------
pub fn message(&self) -> &String {
Expand Down

0 comments on commit e9bddec

Please sign in to comment.