Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
d0cd committed Nov 26, 2024
1 parent caa4366 commit 7ea23ca
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 57 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ workspace = true
[dependencies.leo-compiler]
workspace = true

[dependencies.leo-disassembler]
workspace = true

[dependencies.leo-errors]
workspace = true

Expand Down
2 changes: 2 additions & 0 deletions compiler/ast/src/program/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ pub struct Program {
pub stubs: IndexMap<Symbol, Stub>,
/// A map from program names to program scopes.
pub program_scopes: IndexMap<Symbol, ProgramScope>,
/// The program tests.
pub tests: Vec<Test>,

Check failure on line 42 in compiler/ast/src/program/mod.rs

View workflow job for this annotation

GitHub Actions / Code Coverage

cannot find type `Test` in this scope
}

impl fmt::Display for Program {
Expand Down
18 changes: 0 additions & 18 deletions compiler/compiler/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ pub struct Compiler<'a, N: Network> {
output_directory: PathBuf,
/// The program name,
pub program_name: String,
/// The network name,
pub network: String,
/// The AST for the program.
pub ast: Ast,
/// Options configuring compilation.
Expand All @@ -66,7 +64,6 @@ impl<'a, N: Network> Compiler<'a, N> {
/// Returns a new Leo compiler.
pub fn new(
program_name: String,
network: String,
handler: &'a Handler,
main_file_path: PathBuf,
output_directory: PathBuf,
Expand All @@ -81,7 +78,6 @@ impl<'a, N: Network> Compiler<'a, N> {
main_file_path,
output_directory,
program_name,
network,
ast: Ast::new(Program::default()),
compiler_options: compiler_options.unwrap_or_default(),
node_builder,
Expand Down Expand Up @@ -114,20 +110,6 @@ impl<'a, N: Network> Compiler<'a, N> {
// Use the parser to construct the abstract syntax tree (ast).
self.ast = leo_parser::parse_ast::<N>(self.handler, &self.node_builder, &prg_sf.src, prg_sf.start_pos)?;

// If the program is imported, then check that the name of its program scope matches the file name.
// Note that parsing enforces that there is exactly one program scope in a file.
// TODO: Clean up check.
let program_scope = self.ast.ast.program_scopes.values().next().unwrap();
let program_scope_name = format!("{}", program_scope.program_id.name);
if program_scope_name != self.program_name {
return Err(CompilerError::program_scope_name_does_not_match(
program_scope_name,
self.program_name.clone(),
program_scope.program_id.name.span,
)
.into());
}

if self.compiler_options.output.initial_ast {
self.write_ast_to_json("initial_ast.json")?;
}
Expand Down
1 change: 0 additions & 1 deletion compiler/compiler/tests/integration/utilities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ pub fn new_compiler(

Compiler::new(
program_name,
String::from("aleo"),
handler,
main_file_path,
output_dir,
Expand Down
46 changes: 44 additions & 2 deletions leo/cli/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use std::{
path::{Path, PathBuf},
str::FromStr,
};
use leo_package::tst::TestDirectory;

impl From<BuildOptions> for CompilerOptions {
fn from(options: BuildOptions) -> Self {
Expand Down Expand Up @@ -142,11 +143,18 @@ fn handle_build<N: Network>(command: &LeoBuild, context: Context) -> Result<<Leo
// Recursive build will recursively compile all local dependencies. Can disable to save compile time.
let recursive_build = !command.options.non_recursive;

// Store all stubs for the main program.
let mut main_stubs = Default::default();

// Loop through all local dependencies and compile them in order
for dependency in local_dependencies.into_iter() {
if recursive_build || dependency == main_sym {
// Get path to the local project
let (local_path, stubs) = retriever.prepare_local(dependency)?;
// If the dependency is the main program, store the stubs for later use.
if dependency == main_sym {
main_stubs = stubs.clone();
}

// Create the outputs directory.
let local_outputs_directory = OutputsDirectory::create(&local_path)?;
Expand Down Expand Up @@ -180,7 +188,22 @@ fn handle_build<N: Network>(command: &LeoBuild, context: Context) -> Result<<Leo
}

// `Package::open` checks that the build directory and that `main.aleo` and all imported files are well-formed.
Package::<N>::open(&build_directory).map_err(CliError::failed_to_execute_build)?;
let package = Package::<N>::open(&build_directory).map_err(CliError::failed_to_execute_build)?;

// Add the main program as a stub.
main_stubs.insert(main_sym, leo_disassembler::disassemble(package.program()));

// If the `build_tests` flag is set, compile the tests.
if command.options.build_tests {
// Compile the tests.
compile_tests(
&package_path,
&program_id,
&handler,
command.options.clone(),
main_stubs.clone(),
)?;
}

Ok(())
}
Expand All @@ -206,7 +229,6 @@ fn compile_leo_file<N: Network>(
// Create a new instance of the Leo compiler.
let mut compiler = Compiler::<N>::new(
program_name.clone(),
program_id.network().to_string(),
handler,
file_path.clone(),
outputs.to_path_buf(),
Expand All @@ -226,3 +248,23 @@ fn compile_leo_file<N: Network>(
tracing::info!("✅ Compiled '{program_name}.aleo' into Aleo instructions");
Ok(())
}

/// Compiles test files in the `tests/` directory.
#[allow(clippy::too_many_arguments)]
fn compile_tests<N: Network>(
package_path: &Path,
program_id: &ProgramID<N>,
handler: &Handler,
options: BuildOptions,
stubs: IndexMap<Symbol, Stub>,
) -> Result<()> {
// Get the files in `/tests` directory.
let test_dir = TestDirectory::files(package_path)?;

for test_file in test_dir {
// Compile the test file.

}
Ok(())
}

1 change: 0 additions & 1 deletion tests/test-framework/benches/leo_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ struct Sample {
fn new_compiler(handler: &Handler) -> Compiler<'_, CurrentNetwork> {
Compiler::new(
String::from("test"),
String::from("aleo"),
handler,
PathBuf::from(String::new()),
PathBuf::from(String::new()),
Expand Down
8 changes: 4 additions & 4 deletions utils/disassembler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ use snarkvm::{
use std::str::FromStr;

pub fn disassemble<N: Network, Instruction: InstructionTrait<N>, Command: CommandTrait<N>>(
program: ProgramCore<N, Instruction, Command>,
program: &ProgramCore<N, Instruction, Command>,
) -> Stub {
let program_id = ProgramId::from(program.id());
Stub {
imports: program.imports().into_iter().map(|(id, _)| ProgramId::from(id)).collect(),
imports: program.imports().iter().map(|(id, _)| ProgramId::from(id)).collect(),
stub_id: program_id,
consts: Vec::new(),
structs: [
Expand All @@ -48,7 +48,7 @@ pub fn disassemble<N: Network, Instruction: InstructionTrait<N>, Command: Comman
.concat(),
mappings: program
.mappings()
.into_iter()
.iter()
.map(|(id, m)| (Identifier::from(id).name, Mapping::from_snarkvm(m)))
.collect(),
functions: [
Expand Down Expand Up @@ -88,7 +88,7 @@ pub fn disassemble<N: Network, Instruction: InstructionTrait<N>, Command: Comman

pub fn disassemble_from_str<N: Network>(name: &str, program: &str) -> Result<Stub, UtilError> {
match Program::<N>::from_str(program) {
Ok(p) => Ok(disassemble(p)),
Ok(p) => Ok(disassemble(&p)),
Err(_) => Err(UtilError::snarkvm_parsing_error(name, Default::default())),
}
}
Expand Down
56 changes: 25 additions & 31 deletions utils/retriever/src/retriever/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,40 +291,34 @@ impl<N: Network> Retriever<N> {
// Creates the stub of the program, caches it, and writes the local `leo.lock` file
pub fn process_local(&mut self, name: Symbol, recursive: bool) -> Result<(), UtilError> {
let cur_context = self.contexts.get_mut(&name).unwrap();
// Don't need to disassemble the main file
if name != self.name {
// Disassemble the program
let compiled_path = cur_context.compiled_file_path();
if !compiled_path.exists() {
return Err(UtilError::build_file_does_not_exist(compiled_path.to_str().unwrap(), Default::default()));
}
let mut file = File::open(compiled_path).unwrap_or_else(|_| {
panic!("Failed to open file {}", cur_context.compiled_file_path().to_str().unwrap())
});
let mut content = String::new();
file.read_to_string(&mut content).map_err(|err| {
UtilError::util_file_io_error(
format!("Could not read {}", cur_context.compiled_file_path().to_str().unwrap()),
err,
Default::default(),
)
})?;
// Disassemble the program
let compiled_path = cur_context.compiled_file_path();
if !compiled_path.exists() {
return Err(UtilError::build_file_does_not_exist(compiled_path.to_str().unwrap(), Default::default()));
}
let mut file = File::open(compiled_path).unwrap_or_else(|_| {
panic!("Failed to open file {}", cur_context.compiled_file_path().to_str().unwrap())
});
let mut content = String::new();
file.read_to_string(&mut content).map_err(|err| {
UtilError::util_file_io_error(
format!("Could not read {}", cur_context.compiled_file_path().to_str().unwrap()),
err,
Default::default(),
)
})?;

// Cache the disassembled stub
let stub: Stub = disassemble_from_str::<N>(&name.to_string(), &content)?;
if cur_context.add_stub(stub.clone()) {
Err(UtilError::duplicate_dependency_name_error(stub.stub_id.name.name, Default::default()))?;
}
// Cache the disassembled stub
let stub: Stub = disassemble_from_str::<N>(&name.to_string(), &content)?;
if cur_context.add_stub(stub.clone()) {
Err(UtilError::duplicate_dependency_name_error(stub.stub_id.name.name, Default::default()))?;
}

// Cache the hash
cur_context.add_checksum();
// Cache the hash
cur_context.add_checksum();

// Only write lock file when recursive building
if recursive {
self.write_lock_file(&name)?;
}
} else {
// Write lock file
// Only write lock file when recursive building or when building the top-level program.
if recursive || name == self.name {
self.write_lock_file(&name)?;
}

Expand Down

0 comments on commit 7ea23ca

Please sign in to comment.