Skip to content

Commit

Permalink
Merge #620
Browse files Browse the repository at this point in the history
620: Feature/254 strengthen import rules r=collinc97 a=gluax

Grammar changes are a bit different than what was suggested in the original feature request #254. However, it should be logically equivalent and I think makes more sense on the rust side.

Closes #254 

Co-authored-by: gluaxspeed <jonathan.t.pavlik@gmail.com>
  • Loading branch information
bors[bot] and gluax authored Feb 11, 2021
2 parents a97d60e + f02845a commit b72b5ac
Show file tree
Hide file tree
Showing 18 changed files with 364 additions and 35 deletions.
38 changes: 26 additions & 12 deletions asg/src/program/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod function;
pub use function::*;

use crate::{AsgConvertError, ImportResolver, InnerScope, Input, Scope};
use leo_ast::{Identifier, Package, PackageAccess, Span};
use leo_ast::{Identifier, PackageAccess, PackageOrPackages, Span};

use indexmap::IndexMap;
use std::{cell::RefCell, sync::Arc};
Expand Down Expand Up @@ -74,24 +74,37 @@ enum ImportSymbol {
fn resolve_import_package(
output: &mut Vec<(Vec<String>, ImportSymbol, Span)>,
mut package_segments: Vec<String>,
package: &Package,
package_or_packages: &PackageOrPackages,
) {
package_segments.push(package.name.name.clone());

resolve_import_package_access(output, package_segments, &package.access);
match package_or_packages {
PackageOrPackages::Package(package) => {
package_segments.push(package.name.name.clone());
resolve_import_package_access(output, package_segments, &package.access);
}
PackageOrPackages::Packages(packages) => {
package_segments.push(packages.name.name.clone());
for access in packages.accesses.clone() {
resolve_import_package_access(output, package_segments.clone(), &access);
}
}
}
}

fn resolve_import_package_access(
output: &mut Vec<(Vec<String>, ImportSymbol, Span)>,
package_segments: Vec<String>,
mut package_segments: Vec<String>,
package: &PackageAccess,
) {
match package {
PackageAccess::Star(span) => {
output.push((package_segments, ImportSymbol::All, span.clone()));
}
PackageAccess::SubPackage(subpackage) => {
resolve_import_package(output, package_segments, &*subpackage);
resolve_import_package(
output,
package_segments,
&PackageOrPackages::Package(*(*subpackage).clone()),
);
}
PackageAccess::Symbol(symbol) => {
let span = symbol.symbol.span.clone();
Expand All @@ -102,8 +115,9 @@ fn resolve_import_package_access(
};
output.push((package_segments, symbol, span));
}
PackageAccess::Multiple(subaccesses) => {
for subaccess in subaccesses.iter() {
PackageAccess::Multiple(packages) => {
package_segments.push(packages.name.name.clone());
for subaccess in packages.accesses.iter() {
resolve_import_package_access(output, package_segments.clone(), &subaccess);
}
}
Expand All @@ -126,7 +140,7 @@ impl InternalProgram {
// Recursively extract imported symbols.
let mut imported_symbols: Vec<(Vec<String>, ImportSymbol, Span)> = vec![];
for import in program.imports.iter() {
resolve_import_package(&mut imported_symbols, vec![], &import.package);
resolve_import_package(&mut imported_symbols, vec![], &import.package_or_packages);
}

// Create package list.
Expand Down Expand Up @@ -383,11 +397,11 @@ pub fn reform_ast(program: &Program) -> leo_ast::Program {
imports: core_programs
.iter()
.map(|(module, _)| leo_ast::ImportStatement {
package: leo_ast::Package {
package_or_packages: leo_ast::PackageOrPackages::Package(leo_ast::Package {
name: Identifier::new(module.clone()),
access: leo_ast::PackageAccess::Star(Span::default()),
span: Default::default(),
},
}),
span: Span::default(),
})
.collect(),
Expand Down
4 changes: 4 additions & 0 deletions asg/tests/pass/import/imports/bar/src/baz.leo
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
circuit Baz {
z: u32
}

circuit Bazzar {
a: u32
}
3 changes: 2 additions & 1 deletion asg/tests/pass/import/many_import.leo
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import test-import.( // local import

import bar.( // imports directory import
Bar,
baz.Baz,
baz.(Baz, Bazzar),
bat.bat.Bat,
);

Expand All @@ -17,6 +17,7 @@ function main() {

const bar = Bar { r: 1u32 };
const baz = Baz { z: 1u32 };
const bazzar = Bazzar { a: 1u32 };
const bat = Bat { t: 1u32 };

const car = Car { c: 1u32 };
Expand Down
13 changes: 8 additions & 5 deletions ast/src/imports/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.

use crate::{Package, Span};
use crate::{PackageOrPackages, Span};
use leo_grammar::imports::Import as GrammarImport;

use serde::{Deserialize, Serialize};
Expand All @@ -23,7 +23,7 @@ use std::fmt;
/// Represents an import statement in a Leo program.
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct ImportStatement {
pub package: Package,
pub package_or_packages: PackageOrPackages,
pub span: Span,
}

Expand All @@ -32,22 +32,25 @@ impl ImportStatement {
/// Returns the the package file name of the self import statement.
///
pub fn get_file_name(&self) -> &str {
&self.package.name.name
match self.package_or_packages {
PackageOrPackages::Package(ref package) => &package.name.name,
PackageOrPackages::Packages(ref packages) => &packages.name.name,
}
}
}

impl<'ast> From<GrammarImport<'ast>> for ImportStatement {
fn from(import: GrammarImport<'ast>) -> Self {
ImportStatement {
package: Package::from(import.package),
package_or_packages: PackageOrPackages::from(import.package_or_packages),
span: Span::from(import.span),
}
}
}

impl ImportStatement {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "import {};", self.package)
write!(f, "import {};", self.package_or_packages)
}
}

Expand Down
6 changes: 6 additions & 0 deletions ast/src/imports/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,11 @@ pub use import_symbol::*;
pub mod package;
pub use package::*;

pub mod packages;
pub use packages::*;

pub mod package_or_packages;
pub use package_or_packages::*;

pub mod package_access;
pub use package_access::*;
14 changes: 6 additions & 8 deletions ast/src/imports/package_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.

use crate::{ImportSymbol, Package, Span};
use crate::{ImportSymbol, Package, Packages, Span};
use leo_grammar::imports::PackageAccess as GrammarPackageAccess;

use serde::{Deserialize, Serialize};
Expand All @@ -25,7 +25,7 @@ pub enum PackageAccess {
Star(Span),
SubPackage(Box<Package>),
Symbol(ImportSymbol),
Multiple(Vec<PackageAccess>),
Multiple(Packages),
}

impl<'ast> From<GrammarPackageAccess<'ast>> for PackageAccess {
Expand All @@ -34,9 +34,7 @@ impl<'ast> From<GrammarPackageAccess<'ast>> for PackageAccess {
GrammarPackageAccess::Star(star) => PackageAccess::Star(Span::from(star.span)),
GrammarPackageAccess::SubPackage(package) => PackageAccess::SubPackage(Box::new(Package::from(*package))),
GrammarPackageAccess::Symbol(symbol) => PackageAccess::Symbol(ImportSymbol::from(symbol)),
GrammarPackageAccess::Multiple(accesses) => {
PackageAccess::Multiple(accesses.into_iter().map(PackageAccess::from).collect())
}
GrammarPackageAccess::Multiple(packages) => PackageAccess::Multiple(Packages::from(packages)),
}
}
}
Expand All @@ -47,11 +45,11 @@ impl PackageAccess {
PackageAccess::Star(ref _span) => write!(f, "*"),
PackageAccess::SubPackage(ref package) => write!(f, "{}", package),
PackageAccess::Symbol(ref symbol) => write!(f, "{}", symbol),
PackageAccess::Multiple(ref accesses) => {
PackageAccess::Multiple(ref packages) => {
write!(f, "(")?;
for (i, access) in accesses.iter().enumerate() {
for (i, access) in packages.accesses.iter().enumerate() {
write!(f, "{}", access)?;
if i < accesses.len() - 1 {
if i < packages.accesses.len() - 1 {
write!(f, ", ")?;
}
}
Expand Down
66 changes: 66 additions & 0 deletions ast/src/imports/package_or_packages.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.

// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.

use crate::{Package, Packages};
use leo_grammar::imports::PackageOrPackages as GrammarPackageOrPackages;

use serde::{Deserialize, Serialize};
use std::fmt;

#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum PackageOrPackages {
Package(Package),
Packages(Packages),
}

impl<'ast> From<GrammarPackageOrPackages<'ast>> for PackageOrPackages {
fn from(package_or_packages: GrammarPackageOrPackages<'ast>) -> Self {
match package_or_packages {
GrammarPackageOrPackages::Package(package) => PackageOrPackages::Package(Package::from(package)),
GrammarPackageOrPackages::Packages(packages) => PackageOrPackages::Packages(Packages::from(packages)),
}
}
}

impl PackageOrPackages {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
PackageOrPackages::Package(ref package) => write!(f, "{}", package),
PackageOrPackages::Packages(ref packages) => {
write!(f, "(")?;
for (i, access) in packages.accesses.iter().enumerate() {
write!(f, "{}", access)?;
if i < packages.accesses.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, ")")
}
}
}
}

impl fmt::Debug for PackageOrPackages {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}

impl fmt::Display for PackageOrPackages {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}
63 changes: 63 additions & 0 deletions ast/src/imports/packages.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.

// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.

use crate::{common::Identifier, PackageAccess, Span};
use leo_grammar::imports::Packages as GrammarPackages;

use serde::{Deserialize, Serialize};
use std::fmt;

#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Packages {
pub name: Identifier,
pub accesses: Vec<PackageAccess>,
pub span: Span,
}

impl<'ast> From<GrammarPackages<'ast>> for Packages {
fn from(packages: GrammarPackages<'ast>) -> Self {
Packages {
name: Identifier::from(packages.name),
accesses: packages.accesses.into_iter().map(PackageAccess::from).collect(),
span: Span::from(packages.span),
}
}
}

impl Packages {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}.(", self.name)?;
for (i, access) in self.accesses.iter().enumerate() {
write!(f, "{}", access)?;
if i < self.accesses.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, ")")
}
}

impl fmt::Display for Packages {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}

impl fmt::Debug for Packages {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}
4 changes: 4 additions & 0 deletions compiler/tests/import/imports/bar/src/baz.leo
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
circuit Baz {
z: u32
}

circuit Bazzar {
a: u32
}
3 changes: 2 additions & 1 deletion compiler/tests/import/many_import.leo
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import test-import.( // local import

import bar.( // imports directory import
Bar,
baz.Baz,
baz.(Baz, Bazzar),
bat.bat.Bat,
);

Expand All @@ -17,6 +17,7 @@ function main() {

const bar = Bar { r: 1u32 };
const baz = Baz { z: 1u32 };
const bazzar = Bazzar { a: 1u32 };
const bat = Bat { t: 1u32 };

const car = Car { c: 1u32 };
Expand Down
2 changes: 1 addition & 1 deletion examples/pedersen-hash/src/main.leo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ circuit PedersenHash {
}

function hash(self, bits: [bool; 256]) -> group {
let mut digest: group = 0;
let mut digest: group = 0group;
for i in 0..256 {
if bits[i] {
digest += self.parameters[i];
Expand Down
Loading

0 comments on commit b72b5ac

Please sign in to comment.