mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-23 23:23:50 +03:00
impl importing from package lib, file, directory, and star
This commit is contained in:
parent
24cf5a0181
commit
d905ffd569
@ -299,7 +299,7 @@ package_access = {
|
||||
| import_symbol
|
||||
}
|
||||
|
||||
multiple_package_access = _{ "(" ~ NEWLINE* ~ package_access ~ ("," ~ NEWLINE* ~ package_access)* ~ NEWLINE* ~ ")"}
|
||||
multiple_package_access = _{ "(" ~ NEWLINE* ~ package_access ~ ("," ~ NEWLINE* ~ package_access)* ~ ","? ~ NEWLINE* ~ ")"}
|
||||
|
||||
// Declared in imports/star.rs
|
||||
star = {"*"}
|
||||
|
@ -8,7 +8,10 @@ use leo_ast::LeoParser;
|
||||
use leo_types::{ImportSymbol, Program, Span};
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use std::fs::DirEntry;
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
fs::{read_dir, DirEntry},
|
||||
};
|
||||
|
||||
static LIBRARY_FILE: &str = "src/lib.leo";
|
||||
|
||||
@ -27,7 +30,10 @@ fn parse_import_file(entry: &DirEntry, span: &Span) -> Result<Program, ImportErr
|
||||
file_path.push(LIBRARY_FILE);
|
||||
|
||||
if !file_path.exists() {
|
||||
return Err(ImportError::expected_file(file_name, span.clone()));
|
||||
return Err(ImportError::expected_lib_file(
|
||||
format!("{:?}", file_path.as_path()),
|
||||
span.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,13 +47,35 @@ fn parse_import_file(entry: &DirEntry, span: &Span) -> Result<Program, ImportErr
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn enforce_import_star(&mut self, scope: String, entry: &DirEntry, span: Span) -> Result<(), ImportError> {
|
||||
let mut program = parse_import_file(entry, &span)?;
|
||||
// import star from a file
|
||||
if entry.path().is_file() {
|
||||
// only parse `.leo` files
|
||||
if let Some(extension) = entry.path().extension() {
|
||||
if extension.eq(&OsString::from("leo")) {
|
||||
let mut program = parse_import_file(entry, &span)?;
|
||||
|
||||
// Use same namespace as calling function for imported symbols
|
||||
program = program.name(scope);
|
||||
// Use same namespace as calling function for imported symbols
|
||||
program = program.name(scope);
|
||||
|
||||
// * -> import all imports, circuits, functions in the current scope
|
||||
self.resolve_definitions(program)
|
||||
// * -> import all imports, circuits, functions in the current scope
|
||||
self.resolve_definitions(program)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
// import star for every file in the directory
|
||||
for entry in read_dir(entry.path()).map_err(|error| ImportError::directory_error(error, span.clone()))? {
|
||||
match entry {
|
||||
Ok(entry) => self.enforce_import_star(scope.clone(), &entry, span.clone())?,
|
||||
Err(error) => return Err(ImportError::directory_error(error, span.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enforce_import_symbol(
|
||||
|
@ -31,14 +31,23 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enforce_package(&mut self, scope: String, path: PathBuf, package: Package) -> Result<(), ImportError> {
|
||||
pub fn enforce_package(&mut self, scope: String, mut path: PathBuf, package: Package) -> Result<(), ImportError> {
|
||||
let package_name = package.name;
|
||||
|
||||
// search for package name in local src directory
|
||||
// search for package name in local directory
|
||||
let mut source_directory = path.clone();
|
||||
source_directory.push(SOURCE_DIRECTORY_NAME);
|
||||
|
||||
let entries = fs::read_dir(source_directory)
|
||||
// search for package name in `imports` directory
|
||||
let mut imports_directory = path.clone();
|
||||
imports_directory.push(IMPORTS_DIRECTORY_NAME);
|
||||
|
||||
// read from local `src` directory or the current path
|
||||
if source_directory.exists() {
|
||||
path = source_directory
|
||||
}
|
||||
|
||||
let entries = fs::read_dir(path)
|
||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone()))?
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<_>, std::io::Error>>()
|
||||
@ -53,10 +62,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
.eq(&package_name.name)
|
||||
});
|
||||
|
||||
// search for package name in imports directory
|
||||
let mut imports_directory = path.clone();
|
||||
imports_directory.push(IMPORTS_DIRECTORY_NAME);
|
||||
|
||||
if imports_directory.exists() {
|
||||
let entries = fs::read_dir(imports_directory)
|
||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone()))?
|
||||
|
@ -35,8 +35,11 @@ impl ImportError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn expected_file(entry: String, span: Span) -> Self {
|
||||
let message = format!("cannot import symbol `{}` from directory `{}`", span.text, entry);
|
||||
pub fn expected_lib_file(entry: String, span: Span) -> Self {
|
||||
let message = format!(
|
||||
"expected library file`{}` when looking for symbol `{}`",
|
||||
entry, span.text
|
||||
);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
1
compiler/tests/import/imports/bar/.gitignore
vendored
Executable file
1
compiler/tests/import/imports/bar/.gitignore
vendored
Executable file
@ -0,0 +1 @@
|
||||
outputs/
|
3
compiler/tests/import/imports/bar/Leo.toml
Executable file
3
compiler/tests/import/imports/bar/Leo.toml
Executable file
@ -0,0 +1,3 @@
|
||||
[package]
|
||||
name = "bar"
|
||||
version = "0.1.0"
|
3
compiler/tests/import/imports/bar/src/bat/bat.leo
Executable file
3
compiler/tests/import/imports/bar/src/bat/bat.leo
Executable file
@ -0,0 +1,3 @@
|
||||
circuit Bat {
|
||||
t: u32
|
||||
}
|
3
compiler/tests/import/imports/bar/src/baz.leo
Executable file
3
compiler/tests/import/imports/bar/src/baz.leo
Executable file
@ -0,0 +1,3 @@
|
||||
circuit Baz {
|
||||
z: u32
|
||||
}
|
3
compiler/tests/import/imports/bar/src/lib.leo
Executable file
3
compiler/tests/import/imports/bar/src/lib.leo
Executable file
@ -0,0 +1,3 @@
|
||||
circuit Bar {
|
||||
r: u32
|
||||
}
|
1
compiler/tests/import/imports/car/.gitignore
vendored
Executable file
1
compiler/tests/import/imports/car/.gitignore
vendored
Executable file
@ -0,0 +1 @@
|
||||
outputs/
|
3
compiler/tests/import/imports/car/Leo.toml
Executable file
3
compiler/tests/import/imports/car/Leo.toml
Executable file
@ -0,0 +1,3 @@
|
||||
[package]
|
||||
name = "car"
|
||||
version = "0.1.0"
|
3
compiler/tests/import/imports/car/src/lib.leo
Executable file
3
compiler/tests/import/imports/car/src/lib.leo
Executable file
@ -0,0 +1,3 @@
|
||||
circuit Car {
|
||||
c: u32
|
||||
}
|
25
compiler/tests/import/many_import.leo
Normal file
25
compiler/tests/import/many_import.leo
Normal file
@ -0,0 +1,25 @@
|
||||
import test_import.( // local import
|
||||
Point,
|
||||
foo,
|
||||
);
|
||||
|
||||
import bar.( // imports directory import
|
||||
Bar,
|
||||
baz.Baz,
|
||||
bat.bat.Bat,
|
||||
);
|
||||
|
||||
import car.Car; // imports directory import
|
||||
|
||||
function main() -> u32 {
|
||||
// const point = Point { x: 1u32, y: 1u32 };
|
||||
// const foo = foo();
|
||||
|
||||
const bar = Bar { r: 1u32 };
|
||||
const bat = Bat { t: 1u32 };
|
||||
const baz = Baz { z: 1u32 };
|
||||
|
||||
const car = Car { c: 1u32 };
|
||||
|
||||
return car.c
|
||||
}
|
16
compiler/tests/import/many_import_star.leo
Normal file
16
compiler/tests/import/many_import_star.leo
Normal file
@ -0,0 +1,16 @@
|
||||
import test_import.*; // local import
|
||||
import bar.*; // imports directory import
|
||||
import car.*; // imports directory import
|
||||
|
||||
function main() -> u32 {
|
||||
const point = Point { x: 1u32, y: 1u32 };
|
||||
const foo = foo();
|
||||
|
||||
const bar = Bar { r: 1u32 };
|
||||
const bat = Bat { t: 1u32 };
|
||||
const baz = Baz { z: 1u32 };
|
||||
|
||||
const car = Car { c: 1u32 };
|
||||
|
||||
return car.c
|
||||
}
|
@ -56,3 +56,26 @@ fn test_alias() {
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
// more complex tests
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_many_import() {
|
||||
let bytes = include_bytes!("many_import.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
set_local_dir();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_many_import_star() {
|
||||
let bytes = include_bytes!("many_import_star.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
set_local_dir();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
@ -46,8 +46,8 @@ impl LibFile {
|
||||
fn template(&self) -> String {
|
||||
format!(
|
||||
r#"// The '{}' lib function.
|
||||
circuit Circ {{
|
||||
c: field
|
||||
circuit Foo {{
|
||||
a: field
|
||||
}}
|
||||
"#,
|
||||
self.package_name
|
||||
|
Loading…
Reference in New Issue
Block a user