add import parsing to first pass of static check

This commit is contained in:
collin 2020-10-26 15:51:46 -07:00
parent d5bc0d2b7f
commit 09d86576ea
17 changed files with 407 additions and 176 deletions

View File

@ -165,7 +165,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
self.imported_programs = ImportParser::parse(&self.program)?;
// Run static check on program.
let symbol_table = StaticCheck::run(&self.program, &self.program_input, &self.imported_programs)?;
let symbol_table = StaticCheck::run_with_input(&self.program, &self.imported_programs, &self.program_input)?;
// Run dynamic check on program.
DynamicCheck::run(&self.program, symbol_table)?;

View File

@ -14,9 +14,10 @@
// 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::{errors::ImportError, imported_symbols::ImportedSymbols, ConstrainedProgram, GroupType};
use crate::{errors::ImportError, ConstrainedProgram, GroupType};
use leo_imports::ImportParser;
use leo_typed::Import;
use leo_static_check::imported_symbols::ImportedSymbols;
use leo_typed::ImportStatement;
use snarkos_models::curves::{Field, PrimeField};
@ -24,7 +25,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
pub(crate) fn store_import(
&mut self,
scope: String,
import: &Import,
import: &ImportStatement,
imported_programs: &ImportParser,
) -> Result<(), ImportError> {
// Fetch core packages

View File

@ -1,55 +1,55 @@
// Copyright (C) 2019-2020 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 leo_typed::{Import, ImportSymbol, Package, PackageAccess};
/// Stores the the package file name and imported symbol from an import statement
#[derive(Debug)]
pub(crate) struct ImportedSymbols {
pub symbols: Vec<(String, ImportSymbol)>,
}
impl ImportedSymbols {
fn new() -> Self {
Self { symbols: vec![] }
}
pub(crate) fn from(import: &Import) -> Self {
let mut symbols = Self::new();
symbols.from_package(&import.package);
symbols
}
fn from_package(&mut self, package: &Package) {
self.from_package_access(package.name.name.clone(), &package.access);
}
fn from_package_access(&mut self, package: String, access: &PackageAccess) {
match access {
PackageAccess::SubPackage(package) => self.from_package(package),
PackageAccess::Star(span) => {
let star = ImportSymbol::star(span);
self.symbols.push((package, star));
}
PackageAccess::Symbol(symbol) => self.symbols.push((package, symbol.clone())),
PackageAccess::Multiple(packages) => packages
.iter()
.for_each(|access| self.from_package_access(package.clone(), access)),
}
}
}
// // Copyright (C) 2019-2020 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 leo_typed::{ImportStatement, ImportSymbol, Package, PackageAccess};
//
// /// Stores the the package file name and imported symbol from an import statement
// #[derive(Debug)]
// pub(crate) struct ImportedSymbols {
// pub symbols: Vec<(String, ImportSymbol)>,
// }
//
// impl ImportedSymbols {
// fn new() -> Self {
// Self { symbols: vec![] }
// }
//
// pub(crate) fn from(import: &ImportStatement) -> Self {
// let mut symbols = Self::new();
//
// symbols.from_package(&import.package);
//
// symbols
// }
//
// fn from_package(&mut self, package: &Package) {
// self.from_package_access(package.name.name.clone(), &package.access);
// }
//
// fn from_package_access(&mut self, package: String, access: &PackageAccess) {
// match access {
// PackageAccess::SubPackage(package) => self.from_package(package),
// PackageAccess::Star(span) => {
// let star = ImportSymbol::star(span);
// self.symbols.push((package, star));
// }
// PackageAccess::Symbol(symbol) => self.symbols.push((package, symbol.clone())),
// PackageAccess::Multiple(packages) => packages
// .iter()
// .for_each(|access| self.from_package_access(package.clone(), access)),
// }
// }
// }

View File

@ -21,7 +21,7 @@ pub use self::core_package::*;
pub mod import;
pub use self::import::*;
pub mod imported_symbols;
// pub mod imported_symbols;
pub mod symbol;
pub use self::symbol::*;

View File

@ -45,7 +45,7 @@ impl TestDynamicCheck {
let program = typed.into_repr();
// Create static check.
let symbol_table = StaticCheck::run(&program).unwrap();
let symbol_table = StaticCheck::run_with_input(&program).unwrap();
// Create dynamic check
let dynamic_check = DynamicCheck::new(&program, symbol_table).unwrap();

View File

@ -15,7 +15,7 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::errors::ImportParserError;
use leo_typed::{Package, Program, Span};
use leo_typed::{Package, Program};
use std::{collections::HashMap, env::current_dir};
@ -43,25 +43,12 @@ impl ImportParser {
///
/// Inserts a (file name -> program) pair into the `ImportParser`.
///
/// If the map did not have this file name present, `Ok()` is returned.
/// It is okay if the imported program is already present since importing multiple symbols from
/// the same file is allowed.
///
/// If the map did have this file name present, a duplicate import error is thrown.
///
pub(crate) fn insert_import(
&mut self,
file_name: String,
program: Program,
span: &Span,
) -> Result<(), ImportParserError> {
pub(crate) fn insert_import(&mut self, file_name: String, program: Program) {
// Insert the imported program.
let duplicate = self.imports.insert(file_name.clone(), program);
// Check for duplicate import name.
if duplicate.is_some() {
return Err(ImportParserError::duplicate_import(file_name, span.clone()));
}
Ok(())
let _program = self.imports.insert(file_name.clone(), program);
}
///
@ -86,7 +73,7 @@ impl ImportParser {
///
/// Returns a reference to the program corresponding to the file name.
///
pub fn get_import(&self, file_name: &String) -> Option<&Program> {
pub fn get_import(&self, file_name: &str) -> Option<&Program> {
self.imports.get(file_name)
}

View File

@ -107,7 +107,7 @@ impl ImportParser {
.unwrap(); // the file exists so these will not fail
// Attempt to insert the typed syntax tree for the imported package.
self.insert_import(file_name, program, span)?;
self.insert_import(file_name, program);
Ok(())
} else {
@ -140,7 +140,7 @@ impl ImportParser {
.unwrap(); // the file exists so these will not fail
// Attempt to insert the typed syntax tree for the imported package.
self.insert_import(file_name, program, &symbol.span)?;
self.insert_import(file_name, program);
Ok(())
}

View File

@ -14,9 +14,9 @@
// 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::TypeError;
use crate::{ParameterType, TypeError};
use leo_core::{CorePackageListError, LeoCoreError};
use leo_typed::{Error as FormattedError, Identifier, Span};
use leo_typed::{Error as FormattedError, ImportSymbol, Program, Span};
use std::path::PathBuf;
@ -59,18 +59,42 @@ impl SymbolTableError {
///
/// Two circuits have been defined with the same name.
///
pub fn duplicate_circuit(identifier: Identifier, span: Span) -> Self {
let message = format!("Duplicate circuit definition found for `{}`", identifier);
pub fn duplicate_circuit(variable: ParameterType) -> Self {
let message = format!("Duplicate circuit definition found for `{}`", variable.identifier);
Self::new_from_span(message, span)
Self::new_from_span(message, variable.identifier.span)
}
///
/// Two functions have been defined with the same name.
///
pub fn duplicate_function(identifier: Identifier, span: Span) -> Self {
let message = format!("Duplicate function definition found for `{}`", identifier);
pub fn duplicate_function(variable: ParameterType) -> Self {
let message = format!("Duplicate function definition found for `{}`", variable.identifier);
Self::new_from_span(message, span)
Self::new_from_span(message, variable.identifier.span)
}
///
/// Attempted to access a package name that is not defined.
///
pub fn unknown_package(name: &str, span: &Span) -> Self {
let message = format!(
"Cannot find imported package `{}` in source files or import directory",
name
);
Self::new_from_span(message, span.to_owned())
}
///
/// Attempted to import a name that is not defined in the current file.
///
pub fn unknown_symbol(symbol: &ImportSymbol, program: &Program) -> Self {
let message = format!(
"Cannot find imported symbol `{}` in imported file `{}`",
symbol, program.name
);
Self::new_from_span(message, symbol.span.to_owned())
}
}

View File

@ -0,0 +1,55 @@
// Copyright (C) 2019-2020 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 leo_typed::{ImportStatement, ImportSymbol, Package, PackageAccess};
/// Stores the the package file name and imported symbol from an import statement
#[derive(Debug)]
pub struct ImportedSymbols {
pub symbols: Vec<(String, ImportSymbol)>,
}
impl ImportedSymbols {
fn new() -> Self {
Self { symbols: vec![] }
}
pub fn from(import: &ImportStatement) -> Self {
let mut symbols = Self::new();
symbols.from_package(&import.package);
symbols
}
fn from_package(&mut self, package: &Package) {
self.from_package_access(package.name.name.clone(), &package.access);
}
fn from_package_access(&mut self, package: String, access: &PackageAccess) {
match access {
PackageAccess::SubPackage(package) => self.from_package(package),
PackageAccess::Star(span) => {
let star = ImportSymbol::star(span);
self.symbols.push((package, star));
}
PackageAccess::Symbol(symbol) => self.symbols.push((package, symbol.clone())),
PackageAccess::Multiple(packages) => packages
.iter()
.for_each(|access| self.from_package_access(package.clone(), access)),
}
}
}

View File

@ -0,0 +1,18 @@
// Copyright (C) 2019-2020 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/>.
pub mod imported_symbols;
pub use self::imported_symbols::*;

View File

@ -23,6 +23,9 @@ pub use self::attributes::*;
pub mod errors;
pub use self::errors::*;
pub mod imports;
pub use self::imports::*;
pub mod static_check;
pub use self::static_check::*;

View File

@ -34,30 +34,47 @@ impl StaticCheck {
}
///
/// Returns a new `SymbolTable` from a given program.
/// Returns a new `SymbolTable` from a given program and import parser.
///
pub fn run(
pub fn run(program: &Program, import_parser: &ImportParser) -> Result<SymbolTable, StaticCheckError> {
let mut check = Self::new();
// Run checks on program and imports.
check.check(program, import_parser)?;
Ok(check.table)
}
///
/// Returns a new `SymbolTable` from a given program, input, and import parser.
///
pub fn run_with_input(
program: &Program,
input: &Input,
import_parser: &ImportParser,
input: &Input,
) -> Result<SymbolTable, StaticCheckError> {
let mut check = Self::new();
// Load program input types.
check.insert_input(input)?;
// // Load the program imports into the symbol table.
// check.insert_imports()?;
// Run pass one checks
check.pass_one(program, import_parser)?;
// Run pass two checks
check.pass_two(program)?;
// Run checks on program and imports.
check.check(program, import_parser)?;
Ok(check.table)
}
///
/// Computes pass one and pass two checks on self.
///
pub fn check(&mut self, program: &Program, import_parser: &ImportParser) -> Result<(), StaticCheckError> {
// Run pass one checks.
self.pass_one(program, import_parser)?;
// Run pass two checks.
self.pass_two(program)
}
///
/// Inserts the program input types into the symbol table.
///
@ -67,11 +84,6 @@ impl StaticCheck {
.map_err(|err| StaticCheckError::SymbolTableError(err))
}
// ///
// /// Inserts the program imports into the symbol table.
// ///
// pub fn insert_imports(&mut self, imports: &ImportParser) -> Result<(), StaticCheckError> {}
///
/// Checks for duplicate circuit and function names given an unresolved program.
///
@ -79,16 +91,9 @@ impl StaticCheck {
/// Variables defined later in the unresolved program cannot have the same name.
///
pub fn pass_one(&mut self, program: &Program, import_parser: &ImportParser) -> Result<(), StaticCheckError> {
// Check unresolved program import names.
self.table.check_imports(&program.imports, import_parser)?;
// Check unresolved program circuit names.
self.table.check_duplicate_circuits(&program.circuits)?;
// Check unresolved program function names.
self.table.check_duplicate_functions(&program.functions)?;
Ok(())
self.table
.check_duplicate_program(program, import_parser)
.map_err(|err| StaticCheckError::SymbolTableError(err))
}
///

View File

@ -14,10 +14,10 @@
// 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::{CircuitType, CircuitVariableType, FunctionType, ParameterType, SymbolTableError};
use crate::{CircuitType, CircuitVariableType, FunctionType, ImportedSymbols, ParameterType, SymbolTableError};
use leo_core::CorePackageList;
use leo_imports::ImportParser;
use leo_typed::{Circuit, Function, Identifier, Import, Input, Package};
use leo_typed::{Circuit, Function, Identifier, ImportStatement, ImportSymbol, Input, Package, Program};
use std::collections::HashMap;
@ -69,9 +69,36 @@ impl SymbolTable {
/// variable type is returned.
///
pub fn insert_name(&mut self, name: String, variable_type: ParameterType) -> Option<ParameterType> {
println!("name: {}", name);
self.names.insert(name, variable_type)
}
///
/// Insert a circuit name into the symbol table from a given name and variable type.
///
/// Returns an error if the circuit name is a duplicate.
///
pub fn insert_circuit_name(&mut self, name: String, variable_type: ParameterType) -> Result<(), SymbolTableError> {
// Check that the circuit name is unique.
match self.insert_name(name, variable_type) {
Some(duplicate) => Err(SymbolTableError::duplicate_circuit(duplicate)),
None => Ok(()),
}
}
///
/// Insert a function name into the symbol table from a given name and variable type.
///
/// Returns an error if the function name is a duplicate.
///
pub fn insert_function_name(&mut self, name: String, variable_type: ParameterType) -> Result<(), SymbolTableError> {
// Check that the circuit name is unique.
match self.insert_name(name, variable_type) {
Some(duplicate) => Err(SymbolTableError::duplicate_function(duplicate)),
None => Ok(()),
}
}
///
/// Insert a circuit definition into the symbol table from a given circuit identifier and
/// circuit type.
@ -153,7 +180,7 @@ impl SymbolTable {
/// Inserts function input types into symbol table.
///
/// Creates a new `CircuitType` to represent the input values.
/// The type contains register, record, state, and state leaf circuit variables.
/// The new type contains register, record, state, and state leaf circuit variables.
/// This allows easy access to input types using dot syntax: `input.register.r0`.
///
pub fn insert_input(&mut self, input: &Input) -> Result<(), SymbolTableError> {
@ -195,17 +222,92 @@ impl SymbolTable {
}
///
/// Inserts all imported identifiers for a given list of imported programs.
/// Inserts the imported symbol into the symbol table if it is present in the given program.
///
pub fn insert_import_symbol(&mut self, symbol: ImportSymbol, program: &Program) -> Result<(), SymbolTableError> {
// Check for import *.
if symbol.is_star() {
// Insert all program circuits.
self.check_duplicate_circuits(&program.circuits)?;
// Insert all program functions.
self.check_duplicate_functions(&program.functions)
} else {
// Check for a symbol alias.
let identifier = symbol.alias.to_owned().unwrap_or(symbol.symbol.to_owned());
// Check if the imported symbol is a circuit
let matched_circuit = program
.circuits
.iter()
.find(|(circuit_name, _circuit_def)| symbol.symbol == **circuit_name);
match matched_circuit {
Some((_circuit_name, circuit)) => {
// Insert imported circuit.
self.insert_circuit_name(identifier.to_string(), ParameterType::from(circuit.to_owned()))
}
None => {
// Check if the imported symbol is a function.
let matched_function = program
.functions
.iter()
.find(|(function_name, _function)| symbol.symbol == **function_name);
match matched_function {
Some((_function_name, function)) => {
// Insert the imported function.
self.insert_function_name(identifier.to_string(), ParameterType::from(function.to_owned()))
}
None => Err(SymbolTableError::unknown_symbol(&symbol, program)),
}
}
}
}
}
///
/// Inserts one or more imported symbols for a given import statement.
///
/// No type resolution performed at this step.
///
// pub fn insert_imports(&mut self, imports: ImportParser) -> Result<(), SymbolTableError> {
// // Iterate over each imported program.
//
// // Store separate symbol table for each program.
//
// //
// }
pub fn insert_import(
&mut self,
import: &ImportStatement,
import_parser: &ImportParser,
) -> Result<(), SymbolTableError> {
// Get imported symbols from statement.
let imported_symbols = ImportedSymbols::from(import);
// Import all symbols from an imported file for now.
// Keep track of which import files have already been checked.
let mut checked = Vec::new();
// Iterate over each imported symbol.
for (name, symbol) in imported_symbols.symbols {
// Skip the imported symbol if we have already checked the file.
if checked.contains(&name) {
continue;
};
// Find the imported program.
let program = import_parser
.get_import(&name)
.ok_or_else(|| SymbolTableError::unknown_package(&name, &symbol.span))?;
// Check the imported program.
self.check_duplicate_program(program, import_parser)?;
// Push the imported file's name to checked import files.
checked.push(name);
// Store the imported symbol.
// self.insert_import_symbol(symbol, program)?; // TODO (collinc97) uncomment this line when public/private import scopes are implemented.
}
Ok(())
}
///
/// Inserts core package name and type information into the symbol table.
@ -220,7 +322,7 @@ impl SymbolTable {
// Insert name and type information for each core package symbol.
for (name, circuit) in symbol_list.symbols() {
// Store name of symbol.
self.insert_name(name, ParameterType::from(circuit.clone()));
self.insert_circuit_name(name, ParameterType::from(circuit.clone()))?;
// Create new circuit type for symbol.
let circuit_type = CircuitType::new(&self, circuit)?;
@ -232,6 +334,41 @@ impl SymbolTable {
Ok(())
}
///
/// Checks that a given import statement contains imported names that exist in the list of
/// imported programs.
///
/// Additionally checks for duplicate imported names in the given vector of imports.
/// Types defined later in the program cannot have the same name.
///
pub fn check_import(
&mut self,
import: &ImportStatement,
import_parser: &ImportParser,
) -> Result<(), SymbolTableError> {
// Check if the import name exists as core package.
let core_package = import_parser.get_core_package(&import.package);
// If the core package exists, then attempt to insert the import into the symbol table.
if let Some(package) = core_package {
return self.insert_core_package(package);
}
// // Get the import file name from the import statement.
// let import_file_name = import.get_file_name();
//
// // Check if the import file name exists in the import parser.
// let program = import_parser
// .get_import(&import_file_name)
// .ok_or_else(|| SymbolTableError::unknown_package(import_file_name, &import.span))?;
//
// // Check the imported file.
// self.check_duplicate_program(program, import_parser)?;
// Attempt to insert the imported names into the symbol table.
self.insert_import(import, import_parser)
}
///
/// Checks that all given imported names exist in the list of imported programs.
///
@ -240,31 +377,40 @@ impl SymbolTable {
///
pub fn check_imports(
&mut self,
imports: &Vec<Import>,
imports: &Vec<ImportStatement>,
import_parser: &ImportParser,
) -> Result<(), SymbolTableError> {
// Iterate over imported names.
for import in imports.iter() {
// Check if the import name exists as core package.
let core_package = import_parser.get_core_package(&import.package);
// If the core package exists, then attempt to insert the import into the symbol table.
match core_package {
Some(package) => self.insert_core_package(package)?,
None => {
// Check if the import name exists in the import parser.
// Attempt to insert the imported name into the symbol table.
// Check that the imported name is unique.
unimplemented!("normal imports not supported yet")
}
}
self.check_import(import, import_parser)?;
}
Ok(())
}
///
/// Checks for duplicate import, circuit, and function names given a program.
///
/// If a circuit or function name has no duplicates, then it is inserted into the symbol table.
/// Variables defined later in the unresolved program cannot have the same name.
///
pub fn check_duplicate_program(
&mut self,
program: &Program,
import_parser: &ImportParser,
) -> Result<(), SymbolTableError> {
// Check unresolved program import names.
self.check_imports(&program.imports, import_parser)?;
// Check unresolved program circuit names.
self.check_duplicate_circuits(&program.circuits)?;
// Check unresolved program function names.
self.check_duplicate_functions(&program.functions)?;
Ok(())
}
///
/// Checks for duplicate circuit names given a hashmap of circuits.
///
@ -278,15 +424,7 @@ impl SymbolTable {
// Iterate over circuit names and definitions.
for (identifier, circuit) in circuits.iter() {
// Attempt to insert the circuit name into the symbol table.
let duplicate = self.insert_name(identifier.to_string(), ParameterType::from(circuit.clone()));
// Check that the circuit name is unique.
if duplicate.is_some() {
return Err(SymbolTableError::duplicate_circuit(
identifier.clone(),
circuit.circuit_name.span.clone(),
));
}
self.insert_circuit_name(identifier.to_string(), ParameterType::from(circuit.clone()))?;
}
Ok(())
@ -305,15 +443,7 @@ impl SymbolTable {
// Iterate over function names and definitions.
for (identifier, function) in functions.iter() {
// Attempt to insert the function name into the symbol table.
let duplicate = self.insert_name(identifier.to_string(), ParameterType::from(function.clone()));
// Check that the function name is unique.
if duplicate.is_some() {
return Err(SymbolTableError::duplicate_function(
identifier.clone(),
function.identifier.span.clone(),
));
}
self.insert_function_name(identifier.to_string(), ParameterType::from(function.clone()))?;
}
Ok(())

View File

@ -59,7 +59,7 @@ impl TestStaticCheck {
let program = self.typed.into_repr();
// Create new symbol table.
let _symbol_table = StaticCheck::run(&program).unwrap();
let _symbol_table = StaticCheck::run_with_input(&program).unwrap();
}
///

View File

@ -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::{Circuit, Function, FunctionInput, Identifier, Import, TestFunction};
use crate::{Circuit, Function, FunctionInput, Identifier, ImportStatement, TestFunction};
use leo_ast::{
annotations::{Annotation, AnnotationArguments, AnnotationName},
definitions::{AnnotatedDefinition, Definition},
@ -24,7 +24,7 @@ use std::collections::HashMap;
pub fn load_annotation(
annotated_definition: AnnotatedDefinition,
_imports: &mut Vec<Import>,
_imports: &mut Vec<ImportStatement>,
_circuits: &mut HashMap<Identifier, Circuit>,
_functions: &mut HashMap<Identifier, Function>,
tests: &mut HashMap<Identifier, TestFunction>,

View File

@ -14,42 +14,50 @@
// 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/>.
//! The import type for a Leo program.
use crate::{Package, Span};
use leo_ast::imports::Import as AstImport;
use serde::{Deserialize, Serialize};
use std::fmt;
/// Represents an import statement in a Leo program.
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Import {
pub struct ImportStatement {
pub package: Package,
pub span: Span,
}
impl<'ast> From<AstImport<'ast>> for Import {
impl ImportStatement {
///
/// Returns the the package file name of the self import statement.
///
pub fn get_file_name(&self) -> &str {
&self.package.name.name
}
}
impl<'ast> From<AstImport<'ast>> for ImportStatement {
fn from(import: AstImport<'ast>) -> Self {
Import {
ImportStatement {
package: Package::from(import.package),
span: Span::from(import.span),
}
}
}
impl Import {
impl ImportStatement {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "import {};", self.package)
}
}
impl fmt::Display for Import {
impl fmt::Display for ImportStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}
impl fmt::Debug for Import {
impl fmt::Debug for ImportStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}

View File

@ -17,7 +17,7 @@
//! A typed Leo program consists of import, circuit, and function definitions.
//! Each defined type consists of typed statements and expressions.
use crate::{load_annotation, Circuit, Function, FunctionInput, Identifier, Import, TestFunction};
use crate::{load_annotation, Circuit, Function, FunctionInput, Identifier, ImportStatement, TestFunction};
use leo_ast::{definitions::Definition, files::File};
use serde::{Deserialize, Serialize};
@ -28,7 +28,7 @@ use std::collections::HashMap;
pub struct Program {
pub name: String,
pub expected_input: Vec<FunctionInput>,
pub imports: Vec<Import>,
pub imports: Vec<ImportStatement>,
pub circuits: HashMap<Identifier, Circuit>,
pub functions: HashMap<Identifier, Function>,
pub tests: HashMap<Identifier, TestFunction>,
@ -50,7 +50,7 @@ impl<'ast> Program {
.to_owned()
.into_iter()
.for_each(|definition| match definition {
Definition::Import(import) => imports.push(Import::from(import)),
Definition::Import(import) => imports.push(ImportStatement::from(import)),
Definition::Circuit(circuit) => {
circuits.insert(Identifier::from(circuit.identifier.clone()), Circuit::from(circuit));
}