From 22422c1b5545dc24393614e331a01d9fc53b0ed9 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 18 Sep 2020 12:04:10 -0700 Subject: [PATCH 001/139] create separate module for imports --- Cargo.lock | 11 +++- Cargo.toml | 5 ++ compiler/Cargo.toml | 2 +- core/Cargo.toml | 2 +- imports/Cargo.toml | 25 +++++++ imports/src/core_package.rs | 28 ++++++++ imports/src/import_parser.rs | 70 ++++++++++++++++++++ imports/src/lib.rs | 28 ++++++++ imports/src/parse_package.rs | 115 ++++++++++++++++++++++++++++++++ imports/src/parse_symbol.rs | 124 +++++++++++++++++++++++++++++++++++ 10 files changed, 407 insertions(+), 3 deletions(-) create mode 100644 imports/Cargo.toml create mode 100644 imports/src/core_package.rs create mode 100644 imports/src/import_parser.rs create mode 100644 imports/src/lib.rs create mode 100644 imports/src/parse_package.rs create mode 100644 imports/src/parse_symbol.rs diff --git a/Cargo.lock b/Cargo.lock index cece206388..0c92b96fea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1261,7 +1261,7 @@ dependencies = [ [[package]] name = "leo-core" -version = "1.0.1" +version = "1.0.3" dependencies = [ "leo-gadgets", "leo-typed", @@ -1287,6 +1287,14 @@ dependencies = [ "thiserror", ] +[[package]] +name = "leo-imports" +version = "1.0.3" +dependencies = [ + "leo-typed", + "thiserror", +] + [[package]] name = "leo-input" version = "1.0.3" @@ -1319,6 +1327,7 @@ dependencies = [ "leo-compiler", "leo-core", "leo-gadgets", + "leo-imports", "leo-input", "leo-package", "leo-state", diff --git a/Cargo.toml b/Cargo.toml index 618495c59a..d15e9019e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ members = [ "compiler", "core", "gadgets", + "imports", "input", "linter", "package", @@ -49,6 +50,10 @@ version = "1.0.1" path = "./gadgets" version = "1.0.3" +[dependencies.leo-imports] +path = "./imports" +version = "1.0.3" + [dependencies.leo-input] path = "./input" version = "1.0.3" diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 80b22634d2..58041b4253 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -23,7 +23,7 @@ version = "1.0.3" [dependencies.leo-core] path = "../core" -version = "1.0.1" +version = "1.0.3" [dependencies.leo-gadgets] path = "../gadgets" diff --git a/core/Cargo.toml b/core/Cargo.toml index 111ce74559..aa59743d09 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-core" -version = "1.0.1" +version = "1.0.3" authors = [ "The Aleo Team " ] description = "Core package dependencies of the Leo programming language" homepage = "https://aleo.org" diff --git a/imports/Cargo.toml b/imports/Cargo.toml new file mode 100644 index 0000000000..2c0c98154a --- /dev/null +++ b/imports/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "leo-imports" +version = "1.0.3" +authors = [ "The Aleo Team "] +description = "Import parser for Leo program package dependencies" +homepage = "https://aleo.org" +respository = "https://github.com/AleoHQ/leo" +keywords = [ + "aleo", + "cryptography", + "leo", + "programming-language", + "zero-knowledge" +] +categories = [ "cryptography::cryptocurrencies", "web-programming" ] +include = ["Cargo.toml", "src", "README.md", "LICENSE.md" ] +license = "GPL-3.0" +edition = "2018" + +[dependencies.leo-typed] +path = "../typed" +version = "1.0.3" + +[dependencies.thiserror] +version = "1.0" \ No newline at end of file diff --git a/imports/src/core_package.rs b/imports/src/core_package.rs new file mode 100644 index 0000000000..2873eb4346 --- /dev/null +++ b/imports/src/core_package.rs @@ -0,0 +1,28 @@ +// 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 . + +use crate::{errors::ImportError, ImportParser}; +use leo_typed::Package; + +pub static CORE_PACKAGE_NAME: &str = "core"; + +impl ImportParser { + // import a core package into scope + pub fn parse_core_package(&mut self, package: &Package) -> Result<(), ImportError> { + self.insert_core_package(package); + Ok(()) + } +} diff --git a/imports/src/import_parser.rs b/imports/src/import_parser.rs new file mode 100644 index 0000000000..c870f8670f --- /dev/null +++ b/imports/src/import_parser.rs @@ -0,0 +1,70 @@ +// 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 . + +use crate::errors::ImportError; +use leo_typed::{Package, Program}; + +use std::{collections::HashMap, env::current_dir}; + +/// Parses all relevant import files for a program. +/// Stores compiled program structs. +#[derive(Clone)] +pub struct ImportParser { + imports: HashMap, + core_packages: Vec, +} + +impl ImportParser { + pub fn new() -> Self { + Self { + imports: HashMap::new(), + core_packages: vec![], + } + } + + pub(crate) fn insert_import(&mut self, file_name: String, program: Program) { + // todo: handle conflicting versions for duplicate imports here + let _res = self.imports.insert(file_name, program); + } + + pub(crate) fn insert_core_package(&mut self, package: &Package) { + let _res = self.core_packages.push(package.clone()); + } + + pub fn get_import(&self, file_name: &String) -> Option<&Program> { + self.imports.get(file_name) + } + + pub fn core_packages(&self) -> &Vec { + &self.core_packages + } + + pub fn parse(program: &Program) -> Result { + let mut imports = Self::new(); + + // Find all imports relative to current directory + let path = current_dir().map_err(|error| ImportError::current_directory_error(error))?; + + // Parse each imported file + program + .imports + .iter() + .map(|import| imports.parse_package(path.clone(), &import.package)) + .collect::, ImportError>>()?; + + Ok(imports) + } +} diff --git a/imports/src/lib.rs b/imports/src/lib.rs new file mode 100644 index 0000000000..4cc48bcdc2 --- /dev/null +++ b/imports/src/lib.rs @@ -0,0 +1,28 @@ +// 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 . + +/// The import parser creates a hashmap of import program names -> import program structs +pub mod core_package; +pub use self::core_package::*; + +pub mod parse_symbol; +pub use self::parse_symbol::*; + +pub mod import_parser; +pub use self::import_parser::*; + +pub mod parse_package; +pub use self::parse_package::*; diff --git a/imports/src/parse_package.rs b/imports/src/parse_package.rs new file mode 100644 index 0000000000..3247cb5c29 --- /dev/null +++ b/imports/src/parse_package.rs @@ -0,0 +1,115 @@ +// 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 . + +use crate::{errors::ImportError, ImportParser, CORE_PACKAGE_NAME}; +use leo_typed::{Package, PackageAccess}; + +use std::{fs, fs::DirEntry, path::PathBuf}; + +static SOURCE_FILE_EXTENSION: &str = ".leo"; +static SOURCE_DIRECTORY_NAME: &str = "src/"; +static IMPORTS_DIRECTORY_NAME: &str = "imports/"; + +impl ImportParser { + // bring one or more import symbols into scope for the current constrained program + // we will recursively traverse sub packages here until we find the desired symbol + pub fn parse_package_access(&mut self, entry: &DirEntry, access: &PackageAccess) -> Result<(), ImportError> { + tracing::debug!("import {:?}", entry.path()); + + match access { + PackageAccess::Star(span) => self.parse_import_star(entry, span), + PackageAccess::Symbol(symbol) => self.parse_import_symbol(entry, symbol), + PackageAccess::SubPackage(package) => self.parse_package(entry.path(), package), + PackageAccess::Multiple(accesses) => { + for access in accesses { + self.parse_package_access(entry, access)?; + } + + Ok(()) + } + } + } + + pub fn parse_package(&mut self, mut path: PathBuf, package: &Package) -> Result<(), ImportError> { + let error_path = path.clone(); + let package_name = package.name.clone(); + + // Fetch a core package + let core_package = package_name.name.eq(CORE_PACKAGE_NAME); + + // Trim path if importing from another file + if path.is_file() { + path.pop(); + } + + // Search for package name in local directory + let mut source_directory = path.clone(); + source_directory.push(SOURCE_DIRECTORY_NAME); + + // 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(), error_path.clone()))? + .into_iter() + .collect::, std::io::Error>>() + .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?; + + let matched_source_entry = entries.into_iter().find(|entry| { + entry + .file_name() + .to_os_string() + .into_string() + .unwrap() + .trim_end_matches(SOURCE_FILE_EXTENSION) + .eq(&package_name.name) + }); + + if core_package { + // Enforce core library package access + self.parse_core_package(&package) + } else if imports_directory.exists() { + let entries = fs::read_dir(imports_directory) + .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))? + .into_iter() + .collect::, std::io::Error>>() + .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?; + + let matched_import_entry = entries + .into_iter() + .find(|entry| entry.file_name().into_string().unwrap().eq(&package_name.name)); + + match (matched_source_entry, matched_import_entry) { + (Some(_), Some(_)) => Err(ImportError::conflicting_imports(package_name)), + (Some(source_entry), None) => self.parse_package_access(&source_entry, &package.access), + (None, Some(import_entry)) => self.parse_package_access(&import_entry, &package.access), + (None, None) => Err(ImportError::unknown_package(package_name)), + } + } else { + // Enforce local package access with no found imports directory + match matched_source_entry { + Some(source_entry) => self.parse_package_access(&source_entry, &package.access), + None => Err(ImportError::unknown_package(package_name)), + } + } + } +} diff --git a/imports/src/parse_symbol.rs b/imports/src/parse_symbol.rs new file mode 100644 index 0000000000..0d8f869b4f --- /dev/null +++ b/imports/src/parse_symbol.rs @@ -0,0 +1,124 @@ +// 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 . + +use crate::{errors::ImportError, ImportParser}; +use leo_ast::LeoAst; +use leo_typed::{ImportSymbol, Program, Span}; + +use std::{ffi::OsString, fs::DirEntry, path::PathBuf}; + +static LIBRARY_FILE: &str = "src/lib.leo"; +static FILE_EXTENSION: &str = "leo"; + +fn parse_import_file(entry: &DirEntry, span: &Span) -> Result { + // make sure the given entry is file + let file_type = entry + .file_type() + .map_err(|error| ImportError::directory_error(error, span.clone(), entry.path()))?; + let file_name = entry + .file_name() + .to_os_string() + .into_string() + .map_err(|_| ImportError::convert_os_string(span.clone()))?; + + let mut file_path = entry.path().to_path_buf(); + if file_type.is_dir() { + file_path.push(LIBRARY_FILE); + + if !file_path.exists() { + return Err(ImportError::expected_lib_file( + format!("{:?}", file_path.as_path()), + span.clone(), + )); + } + } + + // Builds the abstract syntax tree. + let program_string = &LeoAst::load_file(&file_path)?; + let ast = &LeoAst::new(&file_path, &program_string)?; + + // Generates the Leo program from file. + Ok(Program::from(&file_name, ast.as_repr())) +} + +impl ImportParser { + pub fn parse_import_star(&mut self, entry: &DirEntry, span: &Span) -> Result<(), ImportError> { + let path = entry.path(); + let is_dir = path.is_dir(); + let is_leo_file = path + .extension() + .map_or(false, |ext| ext.eq(&OsString::from(FILE_EXTENSION))); + + let mut package_path = path.to_path_buf(); + package_path.push(LIBRARY_FILE); + + let is_package = is_dir && package_path.exists(); + + // import * can only be invoked on a package with a library file or a leo file + if is_package || is_leo_file { + // Generate aleo program from file + let program = parse_import_file(entry, &span)?; + + // Store program's imports in imports hashmap + program + .imports + .iter() + .map(|import| self.parse_package(entry.path(), &import.package)) + .collect::, ImportError>>()?; + + // Store program in imports hashmap + let file_name_path = PathBuf::from(entry.file_name()); + let file_name = file_name_path + .file_stem() + .unwrap() + .to_os_string() + .into_string() + .unwrap(); // the file exists so these will not fail + + self.insert_import(file_name, program); + + Ok(()) + } else { + // importing * from a directory or non-leo file in `package/src/` is illegal + Err(ImportError::star(entry.path().to_path_buf(), span.clone())) + } + } + + pub fn parse_import_symbol(&mut self, entry: &DirEntry, symbol: &ImportSymbol) -> Result<(), ImportError> { + // Generate aleo program from file + let program = parse_import_file(entry, &symbol.span)?; + + // Store program's imports in imports hashmap + program + .imports + .iter() + .map(|import| self.parse_package(entry.path(), &import.package)) + .collect::, ImportError>>()?; + + // Store program in imports hashmap + let file_name_path = PathBuf::from(entry.file_name()); + let file_name = file_name_path + .file_stem() + .unwrap() + .to_os_string() + .into_string() + .unwrap(); // the file exists so these will not fail + + self.insert_import(file_name, program); + + Ok(()) + } +} From d54749145bc335a9cd5fcd3741e88456ea896bc7 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 18 Sep 2020 12:26:51 -0700 Subject: [PATCH 002/139] use import parser errors in compiler --- Cargo.lock | 3 + compiler/Cargo.toml | 4 + compiler/src/compiler.rs | 2 +- compiler/src/constraints/constraints.rs | 6 +- compiler/src/definition/definitions.rs | 2 +- compiler/src/errors/compiler.rs | 4 + compiler/src/import/store/import.rs | 3 +- imports/Cargo.toml | 9 ++- imports/src/errors/import_parser.rs | 92 +++++++++++++++++++++++ imports/src/errors/mod.rs | 18 +++++ imports/src/lib.rs | 15 ++-- imports/src/{ => parser}/core_package.rs | 4 +- imports/src/{ => parser}/import_parser.rs | 8 +- imports/src/parser/mod.rs | 28 +++++++ imports/src/{ => parser}/parse_package.rs | 26 ++++--- imports/src/{ => parser}/parse_symbol.rs | 20 ++--- 16 files changed, 202 insertions(+), 42 deletions(-) create mode 100644 imports/src/errors/import_parser.rs create mode 100644 imports/src/errors/mod.rs rename imports/src/{ => parser}/core_package.rs (92%) rename imports/src/{ => parser}/import_parser.rs (88%) create mode 100644 imports/src/parser/mod.rs rename imports/src/{ => parser}/parse_package.rs (79%) rename imports/src/{ => parser}/parse_symbol.rs (86%) diff --git a/Cargo.lock b/Cargo.lock index 0c92b96fea..935396e8b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1236,6 +1236,7 @@ dependencies = [ "leo-ast", "leo-core", "leo-gadgets", + "leo-imports", "leo-input", "leo-package", "leo-state", @@ -1291,8 +1292,10 @@ dependencies = [ name = "leo-imports" version = "1.0.3" dependencies = [ + "leo-ast", "leo-typed", "thiserror", + "tracing", ] [[package]] diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 58041b4253..a3b641e65d 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -29,6 +29,10 @@ version = "1.0.3" path = "../gadgets" version = "1.0.3" +[dependencies.leo-imports] +path = "../imports" +version = "1.0.3" + [dependencies.leo-input] path = "../input" version = "1.0.3" diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 62b36d2dce..0abf3ec47b 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -20,11 +20,11 @@ use crate::{ constraints::{generate_constraints, generate_test_constraints}, errors::CompilerError, GroupType, - ImportParser, OutputBytes, OutputFile, }; use leo_ast::LeoAst; +use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; use leo_state::verify_local_data_commitment; diff --git a/compiler/src/constraints/constraints.rs b/compiler/src/constraints/constraints.rs index 42583f0ed2..7065e816b1 100644 --- a/compiler/src/constraints/constraints.rs +++ b/compiler/src/constraints/constraints.rs @@ -22,14 +22,14 @@ use crate::{ ConstrainedProgram, ConstrainedValue, GroupType, - ImportParser, OutputBytes, OutputFile, }; -use leo_typed::{Input, Program}; - +use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; +use leo_typed::{Input, Program}; + use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::{ConstraintSystem, TestConstraintSystem}, diff --git a/compiler/src/definition/definitions.rs b/compiler/src/definition/definitions.rs index 6ff9778977..53d44dcbe5 100644 --- a/compiler/src/definition/definitions.rs +++ b/compiler/src/definition/definitions.rs @@ -21,8 +21,8 @@ use crate::{ program::{new_scope, ConstrainedProgram}, value::ConstrainedValue, GroupType, - ImportParser, }; +use leo_imports::ImportParser; use leo_typed::Program; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index 0f1bc30a7f..576b1218a9 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -16,6 +16,7 @@ use crate::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError}; use leo_ast::ParserError; +use leo_imports::ImportParserError; use leo_input::InputParserError; use leo_state::LocalDataVerificationError; @@ -27,6 +28,9 @@ pub enum CompilerError { #[error("{}", _0)] ImportError(#[from] ImportError), + #[error("{}", _0)] + ImportParserError(#[from] ImportParserError), + #[error("{}", _0)] InputParserError(#[from] InputParserError), diff --git a/compiler/src/import/store/import.rs b/compiler/src/import/store/import.rs index a9aec1f1c7..833e60c98e 100644 --- a/compiler/src/import/store/import.rs +++ b/compiler/src/import/store/import.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{errors::ImportError, imported_symbols::ImportedSymbols, ConstrainedProgram, GroupType, ImportParser}; +use crate::{errors::ImportError, imported_symbols::ImportedSymbols, ConstrainedProgram, GroupType}; +use leo_imports::ImportParser; use leo_typed::Import; use snarkos_models::curves::{Field, PrimeField}; diff --git a/imports/Cargo.toml b/imports/Cargo.toml index 2c0c98154a..51bca2a856 100644 --- a/imports/Cargo.toml +++ b/imports/Cargo.toml @@ -17,9 +17,16 @@ include = ["Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" +[dependencies.leo-ast] +path = "../ast" +version = "1.0.3" + [dependencies.leo-typed] path = "../typed" version = "1.0.3" [dependencies.thiserror] -version = "1.0" \ No newline at end of file +version = "1.0" + +[dependencies.tracing] +version = "0.1" \ No newline at end of file diff --git a/imports/src/errors/import_parser.rs b/imports/src/errors/import_parser.rs new file mode 100644 index 0000000000..caa450b347 --- /dev/null +++ b/imports/src/errors/import_parser.rs @@ -0,0 +1,92 @@ +// 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 . +use leo_ast::ParserError; +use leo_typed::{Error as FormattedError, Identifier, Span}; + +use std::{io, path::PathBuf}; + +#[derive(Debug, Error)] +pub enum ImportParserError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + ParserError(#[from] ParserError), +} + +impl ImportParserError { + fn new_from_span(message: String, span: Span) -> Self { + ImportParserError::Error(FormattedError::new_from_span(message, span)) + } + + fn new_from_span_with_path(message: String, span: Span, path: PathBuf) -> Self { + ImportParserError::Error(FormattedError::new_from_span_with_path(message, span, path)) + } + + pub fn conflicting_imports(identifier: Identifier) -> Self { + let message = format!("conflicting imports found for `{}`", identifier.name); + + Self::new_from_span(message, identifier.span) + } + + pub fn convert_os_string(span: Span) -> Self { + let message = format!("failed to convert file string name, maybe an illegal character?"); + + Self::new_from_span(message, span) + } + + pub fn current_directory_error(error: io::Error) -> Self { + let span = Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0, + }; + let message = format!("compilation failed trying to find current directory - {:?}", error); + + Self::new_from_span(message, span) + } + + pub fn directory_error(error: io::Error, span: Span, path: PathBuf) -> Self { + let message = format!("compilation failed due to directory error - {:?}", error); + + Self::new_from_span_with_path(message, span, path) + } + + pub fn star(path: PathBuf, span: Span) -> Self { + let message = format!("cannot import `*` from path `{:?}`", path); + + Self::new_from_span(message, span) + } + + 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) + } + + pub fn unknown_package(identifier: Identifier) -> Self { + let message = format!( + "cannot find imported package `{}` in source files or import directory", + identifier.name + ); + + Self::new_from_span(message, identifier.span) + } +} diff --git a/imports/src/errors/mod.rs b/imports/src/errors/mod.rs new file mode 100644 index 0000000000..8cd075bde1 --- /dev/null +++ b/imports/src/errors/mod.rs @@ -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 . + +pub mod import_parser; +pub use self::import_parser::*; diff --git a/imports/src/lib.rs b/imports/src/lib.rs index 4cc48bcdc2..674047771e 100644 --- a/imports/src/lib.rs +++ b/imports/src/lib.rs @@ -15,14 +15,11 @@ // along with the Leo library. If not, see . /// The import parser creates a hashmap of import program names -> import program structs -pub mod core_package; -pub use self::core_package::*; +#[macro_use] +extern crate thiserror; -pub mod parse_symbol; -pub use self::parse_symbol::*; +pub mod errors; +pub use self::errors::*; -pub mod import_parser; -pub use self::import_parser::*; - -pub mod parse_package; -pub use self::parse_package::*; +pub mod parser; +pub use self::parser::*; diff --git a/imports/src/core_package.rs b/imports/src/parser/core_package.rs similarity index 92% rename from imports/src/core_package.rs rename to imports/src/parser/core_package.rs index 2873eb4346..e13387e1a5 100644 --- a/imports/src/core_package.rs +++ b/imports/src/parser/core_package.rs @@ -14,14 +14,14 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{errors::ImportError, ImportParser}; +use crate::{errors::ImportParserError, ImportParser}; use leo_typed::Package; pub static CORE_PACKAGE_NAME: &str = "core"; impl ImportParser { // import a core package into scope - pub fn parse_core_package(&mut self, package: &Package) -> Result<(), ImportError> { + pub fn parse_core_package(&mut self, package: &Package) -> Result<(), ImportParserError> { self.insert_core_package(package); Ok(()) } diff --git a/imports/src/import_parser.rs b/imports/src/parser/import_parser.rs similarity index 88% rename from imports/src/import_parser.rs rename to imports/src/parser/import_parser.rs index c870f8670f..2287efbc9f 100644 --- a/imports/src/import_parser.rs +++ b/imports/src/parser/import_parser.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::errors::ImportError; +use crate::errors::ImportParserError; use leo_typed::{Package, Program}; use std::{collections::HashMap, env::current_dir}; @@ -52,18 +52,18 @@ impl ImportParser { &self.core_packages } - pub fn parse(program: &Program) -> Result { + pub fn parse(program: &Program) -> Result { let mut imports = Self::new(); // Find all imports relative to current directory - let path = current_dir().map_err(|error| ImportError::current_directory_error(error))?; + let path = current_dir().map_err(|error| ImportParserError::current_directory_error(error))?; // Parse each imported file program .imports .iter() .map(|import| imports.parse_package(path.clone(), &import.package)) - .collect::, ImportError>>()?; + .collect::, ImportParserError>>()?; Ok(imports) } diff --git a/imports/src/parser/mod.rs b/imports/src/parser/mod.rs new file mode 100644 index 0000000000..4cc48bcdc2 --- /dev/null +++ b/imports/src/parser/mod.rs @@ -0,0 +1,28 @@ +// 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 . + +/// The import parser creates a hashmap of import program names -> import program structs +pub mod core_package; +pub use self::core_package::*; + +pub mod parse_symbol; +pub use self::parse_symbol::*; + +pub mod import_parser; +pub use self::import_parser::*; + +pub mod parse_package; +pub use self::parse_package::*; diff --git a/imports/src/parse_package.rs b/imports/src/parser/parse_package.rs similarity index 79% rename from imports/src/parse_package.rs rename to imports/src/parser/parse_package.rs index 3247cb5c29..09c9220c8a 100644 --- a/imports/src/parse_package.rs +++ b/imports/src/parser/parse_package.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{errors::ImportError, ImportParser, CORE_PACKAGE_NAME}; +use crate::{errors::ImportParserError, ImportParser, CORE_PACKAGE_NAME}; use leo_typed::{Package, PackageAccess}; use std::{fs, fs::DirEntry, path::PathBuf}; @@ -26,7 +26,7 @@ static IMPORTS_DIRECTORY_NAME: &str = "imports/"; impl ImportParser { // bring one or more import symbols into scope for the current constrained program // we will recursively traverse sub packages here until we find the desired symbol - pub fn parse_package_access(&mut self, entry: &DirEntry, access: &PackageAccess) -> Result<(), ImportError> { + pub fn parse_package_access(&mut self, entry: &DirEntry, access: &PackageAccess) -> Result<(), ImportParserError> { tracing::debug!("import {:?}", entry.path()); match access { @@ -43,7 +43,7 @@ impl ImportParser { } } - pub fn parse_package(&mut self, mut path: PathBuf, package: &Package) -> Result<(), ImportError> { + pub fn parse_package(&mut self, mut path: PathBuf, package: &Package) -> Result<(), ImportParserError> { let error_path = path.clone(); let package_name = package.name.clone(); @@ -69,10 +69,12 @@ impl ImportParser { } let entries = fs::read_dir(path) - .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))? + .map_err(|error| ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone()))? .into_iter() .collect::, std::io::Error>>() - .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?; + .map_err(|error| { + ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone()) + })?; let matched_source_entry = entries.into_iter().find(|entry| { entry @@ -89,26 +91,30 @@ impl ImportParser { self.parse_core_package(&package) } else if imports_directory.exists() { let entries = fs::read_dir(imports_directory) - .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))? + .map_err(|error| { + ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone()) + })? .into_iter() .collect::, std::io::Error>>() - .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?; + .map_err(|error| { + ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone()) + })?; let matched_import_entry = entries .into_iter() .find(|entry| entry.file_name().into_string().unwrap().eq(&package_name.name)); match (matched_source_entry, matched_import_entry) { - (Some(_), Some(_)) => Err(ImportError::conflicting_imports(package_name)), + (Some(_), Some(_)) => Err(ImportParserError::conflicting_imports(package_name)), (Some(source_entry), None) => self.parse_package_access(&source_entry, &package.access), (None, Some(import_entry)) => self.parse_package_access(&import_entry, &package.access), - (None, None) => Err(ImportError::unknown_package(package_name)), + (None, None) => Err(ImportParserError::unknown_package(package_name)), } } else { // Enforce local package access with no found imports directory match matched_source_entry { Some(source_entry) => self.parse_package_access(&source_entry, &package.access), - None => Err(ImportError::unknown_package(package_name)), + None => Err(ImportParserError::unknown_package(package_name)), } } } diff --git a/imports/src/parse_symbol.rs b/imports/src/parser/parse_symbol.rs similarity index 86% rename from imports/src/parse_symbol.rs rename to imports/src/parser/parse_symbol.rs index 0d8f869b4f..9e47432744 100644 --- a/imports/src/parse_symbol.rs +++ b/imports/src/parser/parse_symbol.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{errors::ImportError, ImportParser}; +use crate::{errors::ImportParserError, ImportParser}; use leo_ast::LeoAst; use leo_typed::{ImportSymbol, Program, Span}; @@ -23,23 +23,23 @@ use std::{ffi::OsString, fs::DirEntry, path::PathBuf}; static LIBRARY_FILE: &str = "src/lib.leo"; static FILE_EXTENSION: &str = "leo"; -fn parse_import_file(entry: &DirEntry, span: &Span) -> Result { +fn parse_import_file(entry: &DirEntry, span: &Span) -> Result { // make sure the given entry is file let file_type = entry .file_type() - .map_err(|error| ImportError::directory_error(error, span.clone(), entry.path()))?; + .map_err(|error| ImportParserError::directory_error(error, span.clone(), entry.path()))?; let file_name = entry .file_name() .to_os_string() .into_string() - .map_err(|_| ImportError::convert_os_string(span.clone()))?; + .map_err(|_| ImportParserError::convert_os_string(span.clone()))?; let mut file_path = entry.path().to_path_buf(); if file_type.is_dir() { file_path.push(LIBRARY_FILE); if !file_path.exists() { - return Err(ImportError::expected_lib_file( + return Err(ImportParserError::expected_lib_file( format!("{:?}", file_path.as_path()), span.clone(), )); @@ -55,7 +55,7 @@ fn parse_import_file(entry: &DirEntry, span: &Span) -> Result Result<(), ImportError> { + pub fn parse_import_star(&mut self, entry: &DirEntry, span: &Span) -> Result<(), ImportParserError> { let path = entry.path(); let is_dir = path.is_dir(); let is_leo_file = path @@ -77,7 +77,7 @@ impl ImportParser { .imports .iter() .map(|import| self.parse_package(entry.path(), &import.package)) - .collect::, ImportError>>()?; + .collect::, ImportParserError>>()?; // Store program in imports hashmap let file_name_path = PathBuf::from(entry.file_name()); @@ -93,11 +93,11 @@ impl ImportParser { Ok(()) } else { // importing * from a directory or non-leo file in `package/src/` is illegal - Err(ImportError::star(entry.path().to_path_buf(), span.clone())) + Err(ImportParserError::star(entry.path().to_path_buf(), span.clone())) } } - pub fn parse_import_symbol(&mut self, entry: &DirEntry, symbol: &ImportSymbol) -> Result<(), ImportError> { + pub fn parse_import_symbol(&mut self, entry: &DirEntry, symbol: &ImportSymbol) -> Result<(), ImportParserError> { // Generate aleo program from file let program = parse_import_file(entry, &symbol.span)?; @@ -106,7 +106,7 @@ impl ImportParser { .imports .iter() .map(|import| self.parse_package(entry.path(), &import.package)) - .collect::, ImportError>>()?; + .collect::, ImportParserError>>()?; // Store program in imports hashmap let file_name_path = PathBuf::from(entry.file_name()); From 557fccd9dab77381aca6c4e1d88d218df1835688 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 18 Sep 2020 12:35:27 -0700 Subject: [PATCH 003/139] remove old import parser code from compiler --- compiler/src/errors/import.rs | 57 +-------- compiler/src/import/mod.rs | 7 -- compiler/src/import/parser/core_package.rs | 28 ----- compiler/src/import/parser/import_parser.rs | 70 ----------- compiler/src/import/parser/mod.rs | 28 ----- compiler/src/import/parser/parse_package.rs | 115 ------------------ compiler/src/import/parser/parse_symbol.rs | 124 -------------------- 7 files changed, 1 insertion(+), 428 deletions(-) delete mode 100644 compiler/src/import/parser/core_package.rs delete mode 100644 compiler/src/import/parser/import_parser.rs delete mode 100644 compiler/src/import/parser/mod.rs delete mode 100644 compiler/src/import/parser/parse_package.rs delete mode 100644 compiler/src/import/parser/parse_symbol.rs diff --git a/compiler/src/errors/import.rs b/compiler/src/errors/import.rs index 42c43e8420..b6a6e51180 100644 --- a/compiler/src/errors/import.rs +++ b/compiler/src/errors/import.rs @@ -14,11 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::ParserError; -use leo_typed::{Error as FormattedError, Identifier, ImportSymbol, Span}; - use leo_core::LeoCoreError; -use std::{io, path::PathBuf}; +use leo_typed::{Error as FormattedError, Identifier, ImportSymbol, Span}; #[derive(Debug, Error)] pub enum ImportError { @@ -27,9 +24,6 @@ pub enum ImportError { #[error("{}", _0)] LeoCoreError(#[from] LeoCoreError), - - #[error("{}", _0)] - ParserError(#[from] ParserError), } impl ImportError { @@ -37,55 +31,6 @@ impl ImportError { ImportError::Error(FormattedError::new_from_span(message, span)) } - fn new_from_span_with_path(message: String, span: Span, path: PathBuf) -> Self { - ImportError::Error(FormattedError::new_from_span_with_path(message, span, path)) - } - - pub fn conflicting_imports(identifier: Identifier) -> Self { - let message = format!("conflicting imports found for `{}`", identifier.name); - - Self::new_from_span(message, identifier.span) - } - - pub fn convert_os_string(span: Span) -> Self { - let message = format!("failed to convert file string name, maybe an illegal character?"); - - Self::new_from_span(message, span) - } - - pub fn current_directory_error(error: io::Error) -> Self { - let span = Span { - text: "".to_string(), - line: 0, - start: 0, - end: 0, - }; - let message = format!("compilation failed trying to find current directory - {:?}", error); - - Self::new_from_span(message, span) - } - - pub fn directory_error(error: io::Error, span: Span, path: PathBuf) -> Self { - let message = format!("compilation failed due to directory error - {:?}", error); - - Self::new_from_span_with_path(message, span, path) - } - - pub fn star(path: PathBuf, span: Span) -> Self { - let message = format!("cannot import `*` from path `{:?}`", path); - - Self::new_from_span(message, span) - } - - 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) - } - pub fn unknown_package(identifier: Identifier) -> Self { let message = format!( "cannot find imported package `{}` in source files or import directory", diff --git a/compiler/src/import/mod.rs b/compiler/src/import/mod.rs index 1e72ba4545..e4767afd6b 100644 --- a/compiler/src/import/mod.rs +++ b/compiler/src/import/mod.rs @@ -13,13 +13,6 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . - -//! Imports are split up into two parts: parsing and storing - -/// The import parser creates a hashmap of import program names -> import program structs -pub mod parser; -pub use self::parser::*; - /// The import store brings an imported symbol into the main program from an import program struct pub mod store; pub use self::store::*; diff --git a/compiler/src/import/parser/core_package.rs b/compiler/src/import/parser/core_package.rs deleted file mode 100644 index 2873eb4346..0000000000 --- a/compiler/src/import/parser/core_package.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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 . - -use crate::{errors::ImportError, ImportParser}; -use leo_typed::Package; - -pub static CORE_PACKAGE_NAME: &str = "core"; - -impl ImportParser { - // import a core package into scope - pub fn parse_core_package(&mut self, package: &Package) -> Result<(), ImportError> { - self.insert_core_package(package); - Ok(()) - } -} diff --git a/compiler/src/import/parser/import_parser.rs b/compiler/src/import/parser/import_parser.rs deleted file mode 100644 index c870f8670f..0000000000 --- a/compiler/src/import/parser/import_parser.rs +++ /dev/null @@ -1,70 +0,0 @@ -// 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 . - -use crate::errors::ImportError; -use leo_typed::{Package, Program}; - -use std::{collections::HashMap, env::current_dir}; - -/// Parses all relevant import files for a program. -/// Stores compiled program structs. -#[derive(Clone)] -pub struct ImportParser { - imports: HashMap, - core_packages: Vec, -} - -impl ImportParser { - pub fn new() -> Self { - Self { - imports: HashMap::new(), - core_packages: vec![], - } - } - - pub(crate) fn insert_import(&mut self, file_name: String, program: Program) { - // todo: handle conflicting versions for duplicate imports here - let _res = self.imports.insert(file_name, program); - } - - pub(crate) fn insert_core_package(&mut self, package: &Package) { - let _res = self.core_packages.push(package.clone()); - } - - pub fn get_import(&self, file_name: &String) -> Option<&Program> { - self.imports.get(file_name) - } - - pub fn core_packages(&self) -> &Vec { - &self.core_packages - } - - pub fn parse(program: &Program) -> Result { - let mut imports = Self::new(); - - // Find all imports relative to current directory - let path = current_dir().map_err(|error| ImportError::current_directory_error(error))?; - - // Parse each imported file - program - .imports - .iter() - .map(|import| imports.parse_package(path.clone(), &import.package)) - .collect::, ImportError>>()?; - - Ok(imports) - } -} diff --git a/compiler/src/import/parser/mod.rs b/compiler/src/import/parser/mod.rs deleted file mode 100644 index 4cc48bcdc2..0000000000 --- a/compiler/src/import/parser/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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 . - -/// The import parser creates a hashmap of import program names -> import program structs -pub mod core_package; -pub use self::core_package::*; - -pub mod parse_symbol; -pub use self::parse_symbol::*; - -pub mod import_parser; -pub use self::import_parser::*; - -pub mod parse_package; -pub use self::parse_package::*; diff --git a/compiler/src/import/parser/parse_package.rs b/compiler/src/import/parser/parse_package.rs deleted file mode 100644 index 3247cb5c29..0000000000 --- a/compiler/src/import/parser/parse_package.rs +++ /dev/null @@ -1,115 +0,0 @@ -// 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 . - -use crate::{errors::ImportError, ImportParser, CORE_PACKAGE_NAME}; -use leo_typed::{Package, PackageAccess}; - -use std::{fs, fs::DirEntry, path::PathBuf}; - -static SOURCE_FILE_EXTENSION: &str = ".leo"; -static SOURCE_DIRECTORY_NAME: &str = "src/"; -static IMPORTS_DIRECTORY_NAME: &str = "imports/"; - -impl ImportParser { - // bring one or more import symbols into scope for the current constrained program - // we will recursively traverse sub packages here until we find the desired symbol - pub fn parse_package_access(&mut self, entry: &DirEntry, access: &PackageAccess) -> Result<(), ImportError> { - tracing::debug!("import {:?}", entry.path()); - - match access { - PackageAccess::Star(span) => self.parse_import_star(entry, span), - PackageAccess::Symbol(symbol) => self.parse_import_symbol(entry, symbol), - PackageAccess::SubPackage(package) => self.parse_package(entry.path(), package), - PackageAccess::Multiple(accesses) => { - for access in accesses { - self.parse_package_access(entry, access)?; - } - - Ok(()) - } - } - } - - pub fn parse_package(&mut self, mut path: PathBuf, package: &Package) -> Result<(), ImportError> { - let error_path = path.clone(); - let package_name = package.name.clone(); - - // Fetch a core package - let core_package = package_name.name.eq(CORE_PACKAGE_NAME); - - // Trim path if importing from another file - if path.is_file() { - path.pop(); - } - - // Search for package name in local directory - let mut source_directory = path.clone(); - source_directory.push(SOURCE_DIRECTORY_NAME); - - // 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(), error_path.clone()))? - .into_iter() - .collect::, std::io::Error>>() - .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?; - - let matched_source_entry = entries.into_iter().find(|entry| { - entry - .file_name() - .to_os_string() - .into_string() - .unwrap() - .trim_end_matches(SOURCE_FILE_EXTENSION) - .eq(&package_name.name) - }); - - if core_package { - // Enforce core library package access - self.parse_core_package(&package) - } else if imports_directory.exists() { - let entries = fs::read_dir(imports_directory) - .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))? - .into_iter() - .collect::, std::io::Error>>() - .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?; - - let matched_import_entry = entries - .into_iter() - .find(|entry| entry.file_name().into_string().unwrap().eq(&package_name.name)); - - match (matched_source_entry, matched_import_entry) { - (Some(_), Some(_)) => Err(ImportError::conflicting_imports(package_name)), - (Some(source_entry), None) => self.parse_package_access(&source_entry, &package.access), - (None, Some(import_entry)) => self.parse_package_access(&import_entry, &package.access), - (None, None) => Err(ImportError::unknown_package(package_name)), - } - } else { - // Enforce local package access with no found imports directory - match matched_source_entry { - Some(source_entry) => self.parse_package_access(&source_entry, &package.access), - None => Err(ImportError::unknown_package(package_name)), - } - } - } -} diff --git a/compiler/src/import/parser/parse_symbol.rs b/compiler/src/import/parser/parse_symbol.rs deleted file mode 100644 index 0d8f869b4f..0000000000 --- a/compiler/src/import/parser/parse_symbol.rs +++ /dev/null @@ -1,124 +0,0 @@ -// 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 . - -use crate::{errors::ImportError, ImportParser}; -use leo_ast::LeoAst; -use leo_typed::{ImportSymbol, Program, Span}; - -use std::{ffi::OsString, fs::DirEntry, path::PathBuf}; - -static LIBRARY_FILE: &str = "src/lib.leo"; -static FILE_EXTENSION: &str = "leo"; - -fn parse_import_file(entry: &DirEntry, span: &Span) -> Result { - // make sure the given entry is file - let file_type = entry - .file_type() - .map_err(|error| ImportError::directory_error(error, span.clone(), entry.path()))?; - let file_name = entry - .file_name() - .to_os_string() - .into_string() - .map_err(|_| ImportError::convert_os_string(span.clone()))?; - - let mut file_path = entry.path().to_path_buf(); - if file_type.is_dir() { - file_path.push(LIBRARY_FILE); - - if !file_path.exists() { - return Err(ImportError::expected_lib_file( - format!("{:?}", file_path.as_path()), - span.clone(), - )); - } - } - - // Builds the abstract syntax tree. - let program_string = &LeoAst::load_file(&file_path)?; - let ast = &LeoAst::new(&file_path, &program_string)?; - - // Generates the Leo program from file. - Ok(Program::from(&file_name, ast.as_repr())) -} - -impl ImportParser { - pub fn parse_import_star(&mut self, entry: &DirEntry, span: &Span) -> Result<(), ImportError> { - let path = entry.path(); - let is_dir = path.is_dir(); - let is_leo_file = path - .extension() - .map_or(false, |ext| ext.eq(&OsString::from(FILE_EXTENSION))); - - let mut package_path = path.to_path_buf(); - package_path.push(LIBRARY_FILE); - - let is_package = is_dir && package_path.exists(); - - // import * can only be invoked on a package with a library file or a leo file - if is_package || is_leo_file { - // Generate aleo program from file - let program = parse_import_file(entry, &span)?; - - // Store program's imports in imports hashmap - program - .imports - .iter() - .map(|import| self.parse_package(entry.path(), &import.package)) - .collect::, ImportError>>()?; - - // Store program in imports hashmap - let file_name_path = PathBuf::from(entry.file_name()); - let file_name = file_name_path - .file_stem() - .unwrap() - .to_os_string() - .into_string() - .unwrap(); // the file exists so these will not fail - - self.insert_import(file_name, program); - - Ok(()) - } else { - // importing * from a directory or non-leo file in `package/src/` is illegal - Err(ImportError::star(entry.path().to_path_buf(), span.clone())) - } - } - - pub fn parse_import_symbol(&mut self, entry: &DirEntry, symbol: &ImportSymbol) -> Result<(), ImportError> { - // Generate aleo program from file - let program = parse_import_file(entry, &symbol.span)?; - - // Store program's imports in imports hashmap - program - .imports - .iter() - .map(|import| self.parse_package(entry.path(), &import.package)) - .collect::, ImportError>>()?; - - // Store program in imports hashmap - let file_name_path = PathBuf::from(entry.file_name()); - let file_name = file_name_path - .file_stem() - .unwrap() - .to_os_string() - .into_string() - .unwrap(); // the file exists so these will not fail - - self.insert_import(file_name, program); - - Ok(()) - } -} From 3164f6ce33808ac840b90bafe22cbb18802621c6 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 18 Sep 2020 12:41:38 -0700 Subject: [PATCH 004/139] fix import tests --- compiler/tests/import/alias.leo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/tests/import/alias.leo b/compiler/tests/import/alias.leo index 96c65282ef..f153b5a128 100644 --- a/compiler/tests/import/alias.leo +++ b/compiler/tests/import/alias.leo @@ -1,4 +1,4 @@ -import test_import.foo as bar; +import test-import.foo as bar; function main() { console.assert(bar() == 1u32); From ce8e3f497844756e1919b0f54914ecc21139338c Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 30 Sep 2020 14:06:56 -0700 Subject: [PATCH 005/139] rename variables and add docs --- imports/src/errors/import_parser.rs | 21 ++++++++ imports/src/lib.rs | 1 - imports/src/parser/core_package.rs | 8 ++- imports/src/parser/import_parser.rs | 73 ++++++++++++++++++++++++---- imports/src/parser/parse_package.rs | 35 ++++++++++---- imports/src/parser/parse_symbol.rs | 75 +++++++++++++++++++---------- 6 files changed, 165 insertions(+), 48 deletions(-) diff --git a/imports/src/errors/import_parser.rs b/imports/src/errors/import_parser.rs index caa450b347..aa97b8f72c 100644 --- a/imports/src/errors/import_parser.rs +++ b/imports/src/errors/import_parser.rs @@ -36,12 +36,33 @@ impl ImportParserError { ImportParserError::Error(FormattedError::new_from_span_with_path(message, span, path)) } + /// + /// An imported package has the same name as an imported core_package. + /// pub fn conflicting_imports(identifier: Identifier) -> Self { let message = format!("conflicting imports found for `{}`", identifier.name); Self::new_from_span(message, identifier.span) } + /// + /// A package name has been imported twice. + /// + pub fn duplicate_import(name: String, span: Span) -> Self { + let message = format!("Duplicate imports found for `{}`", name); + + Self::new_from_span(message, span) + } + + /// + /// A core package name has been imported twice. + /// + pub fn duplicate_core_package(identifier: Identifier) -> Self { + let message = format!("Duplicate core_package import `{}`", identifier.name); + + Self::new_from_span(message, identifier.span) + } + pub fn convert_os_string(span: Span) -> Self { let message = format!("failed to convert file string name, maybe an illegal character?"); diff --git a/imports/src/lib.rs b/imports/src/lib.rs index 674047771e..8807f72fca 100644 --- a/imports/src/lib.rs +++ b/imports/src/lib.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -/// The import parser creates a hashmap of import program names -> import program structs #[macro_use] extern crate thiserror; diff --git a/imports/src/parser/core_package.rs b/imports/src/parser/core_package.rs index e13387e1a5..3173257552 100644 --- a/imports/src/parser/core_package.rs +++ b/imports/src/parser/core_package.rs @@ -20,9 +20,13 @@ use leo_typed::Package; pub static CORE_PACKAGE_NAME: &str = "core"; impl ImportParser { - // import a core package into scope + /// + /// Import a core package and insert into the `ImportParser`. + /// pub fn parse_core_package(&mut self, package: &Package) -> Result<(), ImportParserError> { - self.insert_core_package(package); + // Insert a core package into the `ImportParser`. + self.insert_core_package(package)?; + Ok(()) } } diff --git a/imports/src/parser/import_parser.rs b/imports/src/parser/import_parser.rs index 2287efbc9f..05bd601bc0 100644 --- a/imports/src/parser/import_parser.rs +++ b/imports/src/parser/import_parser.rs @@ -15,12 +15,14 @@ // along with the Leo library. If not, see . use crate::errors::ImportParserError; -use leo_typed::{Package, Program}; +use leo_typed::{Package, Program, Span}; use std::{collections::HashMap, env::current_dir}; -/// Parses all relevant import files for a program. -/// Stores compiled program structs. +/// Stores imported packages. +/// +/// A program can import one or more packages. A package can be found locally in the source +/// directory, foreign in the imports directory, or part of the core package list. #[derive(Clone)] pub struct ImportParser { imports: HashMap, @@ -28,6 +30,9 @@ pub struct ImportParser { } impl ImportParser { + /// + /// Creates a new empty `ImportParser`. + /// pub fn new() -> Self { Self { imports: HashMap::new(), @@ -35,30 +40,78 @@ impl ImportParser { } } - pub(crate) fn insert_import(&mut self, file_name: String, program: Program) { - // todo: handle conflicting versions for duplicate imports here - let _res = self.imports.insert(file_name, program); + /// + /// Inserts a (file name -> program) pair into the `ImportParser`. + /// + /// If the map did not have this file name present, `Ok()` is returned. + /// + /// 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> { + // 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(()) } - pub(crate) fn insert_core_package(&mut self, package: &Package) { - let _res = self.core_packages.push(package.clone()); + /// + /// Inserts a core package into the `ImportParser`. + /// + /// If the vector did not have this file_name present, `Ok()` is returned. + /// + /// If the vector did have this file_name present, a duplicate import error is thrown. + /// + pub(crate) fn insert_core_package(&mut self, package: &Package) -> Result<(), ImportParserError> { + // Check for duplicate core package name. + if self.core_packages.contains(package) { + return Err(ImportParserError::duplicate_core_package(package.name.clone())); + } + + // Append the core package. + self.core_packages.push(package.clone()); + + Ok(()) } + /// + /// Returns a reference to the program corresponding to the file name. + /// pub fn get_import(&self, file_name: &String) -> Option<&Program> { self.imports.get(file_name) } + /// + /// Returns a reference to the vector of core packages. + /// pub fn core_packages(&self) -> &Vec { &self.core_packages } + /// + /// Returns a new `ImportParser` from a given `Program`. + /// + /// For every import statement in the program: + /// 1. Check if the imported package exists. + /// 2. Create the typed syntax tree for the imported package. + /// 3. Insert the typed syntax tree into the `ImportParser` + /// pub fn parse(program: &Program) -> Result { let mut imports = Self::new(); - // Find all imports relative to current directory + // Find all imports relative to current directory. let path = current_dir().map_err(|error| ImportParserError::current_directory_error(error))?; - // Parse each imported file + // Parse each import statement. program .imports .iter() diff --git a/imports/src/parser/parse_package.rs b/imports/src/parser/parse_package.rs index 09c9220c8a..839dc6cd1d 100644 --- a/imports/src/parser/parse_package.rs +++ b/imports/src/parser/parse_package.rs @@ -24,18 +24,25 @@ static SOURCE_DIRECTORY_NAME: &str = "src/"; static IMPORTS_DIRECTORY_NAME: &str = "imports/"; impl ImportParser { - // bring one or more import symbols into scope for the current constrained program - // we will recursively traverse sub packages here until we find the desired symbol - pub fn parse_package_access(&mut self, entry: &DirEntry, access: &PackageAccess) -> Result<(), ImportParserError> { - tracing::debug!("import {:?}", entry.path()); + /// + /// Import one or more symbols from a package. + /// + /// Will recursively traverse sub packages until the desired symbol is found. + /// + pub fn parse_package_access( + &mut self, + package: &DirEntry, + access: &PackageAccess, + ) -> Result<(), ImportParserError> { + tracing::debug!("import {:?}", package.path()); match access { - PackageAccess::Star(span) => self.parse_import_star(entry, span), - PackageAccess::Symbol(symbol) => self.parse_import_symbol(entry, symbol), - PackageAccess::SubPackage(package) => self.parse_package(entry.path(), package), + PackageAccess::Star(span) => self.parse_import_star(package, span), + PackageAccess::Symbol(symbol) => self.parse_import_symbol(package, symbol), + PackageAccess::SubPackage(package) => self.parse_package(package.path(), package), PackageAccess::Multiple(accesses) => { for access in accesses { - self.parse_package_access(entry, access)?; + self.parse_package_access(package, access)?; } Ok(()) @@ -43,6 +50,11 @@ impl ImportParser { } } + /// + /// Create the typed syntax tree for an imported package. + /// + /// Inserts the typed syntax tree into the `ImportParser`. + /// pub fn parse_package(&mut self, mut path: PathBuf, package: &Package) -> Result<(), ImportParserError> { let error_path = path.clone(); let package_name = package.name.clone(); @@ -68,6 +80,7 @@ impl ImportParser { path = source_directory } + // Get a vector of all packages in the source directory. let entries = fs::read_dir(path) .map_err(|error| ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone()))? .into_iter() @@ -76,6 +89,7 @@ impl ImportParser { ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone()) })?; + // Check if the imported package name is in the source directory. let matched_source_entry = entries.into_iter().find(|entry| { entry .file_name() @@ -87,9 +101,10 @@ impl ImportParser { }); if core_package { - // Enforce core library package access + // Enforce core package access. self.parse_core_package(&package) } else if imports_directory.exists() { + // Get a vector of all packages in the imports directory. let entries = fs::read_dir(imports_directory) .map_err(|error| { ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone()) @@ -100,10 +115,12 @@ impl ImportParser { ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone()) })?; + // Check if the imported package name is in the imports directory. let matched_import_entry = entries .into_iter() .find(|entry| entry.file_name().into_string().unwrap().eq(&package_name.name)); + // Check if the package name was found in both the source and imports directory. match (matched_source_entry, matched_import_entry) { (Some(_), Some(_)) => Err(ImportParserError::conflicting_imports(package_name)), (Some(source_entry), None) => self.parse_package_access(&source_entry, &package.access), diff --git a/imports/src/parser/parse_symbol.rs b/imports/src/parser/parse_symbol.rs index 9e47432744..c5638d00ef 100644 --- a/imports/src/parser/parse_symbol.rs +++ b/imports/src/parser/parse_symbol.rs @@ -23,18 +23,26 @@ use std::{ffi::OsString, fs::DirEntry, path::PathBuf}; static LIBRARY_FILE: &str = "src/lib.leo"; static FILE_EXTENSION: &str = "leo"; -fn parse_import_file(entry: &DirEntry, span: &Span) -> Result { - // make sure the given entry is file - let file_type = entry +/// +/// Returns a typed syntax tree from a given package. +/// +/// Builds an abstract syntax tree from the given file and then builds the typed syntax tree. +/// +fn parse_import_file(package: &DirEntry, span: &Span) -> Result { + // Get the package file type. + let file_type = package .file_type() - .map_err(|error| ImportParserError::directory_error(error, span.clone(), entry.path()))?; - let file_name = entry + .map_err(|error| ImportParserError::directory_error(error, span.clone(), package.path()))?; + + // Get the package file name. + let file_name = package .file_name() .to_os_string() .into_string() .map_err(|_| ImportParserError::convert_os_string(span.clone()))?; - let mut file_path = entry.path().to_path_buf(); + // Construct the package file path. + let mut file_path = package.path().to_path_buf(); if file_type.is_dir() { file_path.push(LIBRARY_FILE); @@ -46,41 +54,51 @@ fn parse_import_file(entry: &DirEntry, span: &Span) -> Result Result<(), ImportParserError> { - let path = entry.path(); + /// + /// Import all symbols from a given package. + /// + /// If the package is a Leo file, import all symbols from the file. + /// If the package is a directory, import all symbol from the library file. + /// + pub fn parse_import_star(&mut self, package: &DirEntry, span: &Span) -> Result<(), ImportParserError> { + let path = package.path(); let is_dir = path.is_dir(); + + // Check if the package is a Leo file. let is_leo_file = path .extension() .map_or(false, |ext| ext.eq(&OsString::from(FILE_EXTENSION))); + // Construct the library file path to use if the package is a directory. let mut package_path = path.to_path_buf(); package_path.push(LIBRARY_FILE); + // Check if the package is a directory. let is_package = is_dir && package_path.exists(); // import * can only be invoked on a package with a library file or a leo file if is_package || is_leo_file { - // Generate aleo program from file - let program = parse_import_file(entry, &span)?; + // Get the package typed syntax tree. + let program = parse_import_file(package, span)?; - // Store program's imports in imports hashmap + // Insert the package's imports into the import parser. program .imports .iter() - .map(|import| self.parse_package(entry.path(), &import.package)) + .map(|import| self.parse_package(package.path(), &import.package)) .collect::, ImportParserError>>()?; - // Store program in imports hashmap - let file_name_path = PathBuf::from(entry.file_name()); + // Get the package file name from the path. + let file_name_path = PathBuf::from(package.file_name()); let file_name = file_name_path .file_stem() .unwrap() @@ -88,28 +106,32 @@ impl ImportParser { .into_string() .unwrap(); // the file exists so these will not fail - self.insert_import(file_name, program); + // Attempt to insert the typed syntax tree for the imported package. + self.insert_import(file_name, program, span)?; Ok(()) } else { // importing * from a directory or non-leo file in `package/src/` is illegal - Err(ImportParserError::star(entry.path().to_path_buf(), span.clone())) + Err(ImportParserError::star(package.path().to_path_buf(), span.clone())) } } - pub fn parse_import_symbol(&mut self, entry: &DirEntry, symbol: &ImportSymbol) -> Result<(), ImportParserError> { - // Generate aleo program from file - let program = parse_import_file(entry, &symbol.span)?; + /// + /// Import a symbol from a given package. + /// + pub fn parse_import_symbol(&mut self, package: &DirEntry, symbol: &ImportSymbol) -> Result<(), ImportParserError> { + // Get the package typed syntax tree. + let program = parse_import_file(package, &symbol.span)?; - // Store program's imports in imports hashmap + // Insert the package's imports into the import parser. program .imports .iter() - .map(|import| self.parse_package(entry.path(), &import.package)) + .map(|import| self.parse_package(package.path(), &import.package)) .collect::, ImportParserError>>()?; - // Store program in imports hashmap - let file_name_path = PathBuf::from(entry.file_name()); + // Get the package file name from the path. + let file_name_path = PathBuf::from(package.file_name()); let file_name = file_name_path .file_stem() .unwrap() @@ -117,7 +139,8 @@ impl ImportParser { .into_string() .unwrap(); // the file exists so these will not fail - self.insert_import(file_name, program); + // Attempt to insert the typed syntax tree for the imported package. + self.insert_import(file_name, program, &symbol.span)?; Ok(()) } From 76b7c7a17f882cfc166cfa2a6a2904080d25f428 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 30 Sep 2020 16:27:17 -0700 Subject: [PATCH 006/139] add docs for errors --- imports/src/errors/import_parser.rs | 36 +++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/imports/src/errors/import_parser.rs b/imports/src/errors/import_parser.rs index aa97b8f72c..ef185a1595 100644 --- a/imports/src/errors/import_parser.rs +++ b/imports/src/errors/import_parser.rs @@ -40,7 +40,7 @@ impl ImportParserError { /// An imported package has the same name as an imported core_package. /// pub fn conflicting_imports(identifier: Identifier) -> Self { - let message = format!("conflicting imports found for `{}`", identifier.name); + let message = format!("conflicting imports found for `{}`.", identifier.name); Self::new_from_span(message, identifier.span) } @@ -49,7 +49,7 @@ impl ImportParserError { /// A package name has been imported twice. /// pub fn duplicate_import(name: String, span: Span) -> Self { - let message = format!("Duplicate imports found for `{}`", name); + let message = format!("Duplicate imports found for `{}`.", name); Self::new_from_span(message, span) } @@ -58,17 +58,23 @@ impl ImportParserError { /// A core package name has been imported twice. /// pub fn duplicate_core_package(identifier: Identifier) -> Self { - let message = format!("Duplicate core_package import `{}`", identifier.name); + let message = format!("Duplicate core_package import `{}`.", identifier.name); Self::new_from_span(message, identifier.span) } + /// + /// Failed to convert a file path into an os string. + /// pub fn convert_os_string(span: Span) -> Self { - let message = format!("failed to convert file string name, maybe an illegal character?"); + let message = format!("Failed to convert file string name, maybe an illegal character?"); Self::new_from_span(message, span) } + /// + /// Failed to find the directory of the current file. + /// pub fn current_directory_error(error: io::Error) -> Self { let span = Span { text: "".to_string(), @@ -76,35 +82,47 @@ impl ImportParserError { start: 0, end: 0, }; - let message = format!("compilation failed trying to find current directory - {:?}", error); + let message = format!("Compilation failed trying to find current directory - {:?}.", error); Self::new_from_span(message, span) } + /// + /// Failed to open or get the name of a directory. + /// pub fn directory_error(error: io::Error, span: Span, path: PathBuf) -> Self { - let message = format!("compilation failed due to directory error - {:?}", error); + let message = format!("Compilation failed due to directory error - {:?}.", error); Self::new_from_span_with_path(message, span, path) } + /// + /// Failed to import all symbols at a package path. + /// pub fn star(path: PathBuf, span: Span) -> Self { - let message = format!("cannot import `*` from path `{:?}`", path); + let message = format!("Cannot import `*` from path `{:?}`.", path); Self::new_from_span(message, span) } + /// + /// Failed to find a library file for the current package. + /// pub fn expected_lib_file(entry: String, span: Span) -> Self { let message = format!( - "expected library file`{}` when looking for symbol `{}`", + "Expected library file`{}` when looking for symbol `{}`.", entry, span.text ); Self::new_from_span(message, span) } + /// + /// Failed to import a package name. + /// pub fn unknown_package(identifier: Identifier) -> Self { let message = format!( - "cannot find imported package `{}` in source files or import directory", + "Cannot find imported package `{}` in source files or import directory.", identifier.name ); From dd703185311e5ddc2b1747c7961b0d975644329d Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 30 Sep 2020 16:39:06 -0700 Subject: [PATCH 007/139] fix naming conflict --- imports/src/parser/parse_package.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imports/src/parser/parse_package.rs b/imports/src/parser/parse_package.rs index 839dc6cd1d..ea11ecbbf0 100644 --- a/imports/src/parser/parse_package.rs +++ b/imports/src/parser/parse_package.rs @@ -39,7 +39,7 @@ impl ImportParser { match access { PackageAccess::Star(span) => self.parse_import_star(package, span), PackageAccess::Symbol(symbol) => self.parse_import_symbol(package, symbol), - PackageAccess::SubPackage(package) => self.parse_package(package.path(), package), + PackageAccess::SubPackage(sub_package) => self.parse_package(package.path(), sub_package), PackageAccess::Multiple(accesses) => { for access in accesses { self.parse_package_access(package, access)?; From d5a9cefe7cd5a0236ba7707b591df20461b5f6de Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 1 Oct 2020 20:17:47 -0700 Subject: [PATCH 008/139] impl symbol table for pass 1 + pass 2 type resolution --- Cargo.lock | 12 + Cargo.toml | 7 +- compiler/src/function/function.rs | 6 +- compiler/src/function/main_function.rs | 6 +- core/src/packages/unstable/blake2s.rs | 6 +- symbol-table/Cargo.toml | 36 +++ symbol-table/src/attributes/attribute.rs | 24 ++ symbol-table/src/attributes/mod.rs | 18 ++ symbol-table/src/errors/mod.rs | 21 ++ symbol-table/src/errors/symbol_table.rs | 67 ++++ symbol-table/src/errors/type_.rs | 141 +++++++++ symbol-table/src/lib.rs | 52 ++++ symbol-table/src/symbol_table.rs | 291 ++++++++++++++++++ symbol-table/src/types/circuits/circuit.rs | 144 +++++++++ .../src/types/circuits/circuit_function.rs | 27 ++ .../src/types/circuits/circuit_variable.rs | 30 ++ symbol-table/src/types/circuits/mod.rs | 24 ++ symbol-table/src/types/functions/function.rs | 127 ++++++++ .../src/types/functions/function_input.rs | 109 +++++++ .../functions/function_input_variable.rs | 108 +++++++ .../src/types/functions/function_output.rs | 74 +++++ symbol-table/src/types/functions/mod.rs | 27 ++ symbol-table/src/types/mod.rs | 27 ++ symbol-table/src/types/type_.rs | 221 +++++++++++++ symbol-table/src/types/variables/mod.rs | 18 ++ symbol-table/src/types/variables/variable.rs | 79 +++++ symbol-table/tests/mod.rs | 115 +++++++ .../tests/symbol_table/duplicate_circuit.leo | 10 + .../tests/symbol_table/duplicate_function.leo | 10 + symbol-table/tests/symbol_table/mod.rs | 72 +++++ .../tests/symbol_table/self_not_available.leo | 8 + .../tests/symbol_table/undefined_circuit.leo | 10 + typed/src/annotation.rs | 4 +- typed/src/functions/function.rs | 6 +- typed/src/functions/input/function_input.rs | 12 +- typed/src/functions/input/input_variable.rs | 22 +- typed/src/program.rs | 4 +- 37 files changed, 1941 insertions(+), 34 deletions(-) create mode 100644 symbol-table/Cargo.toml create mode 100644 symbol-table/src/attributes/attribute.rs create mode 100644 symbol-table/src/attributes/mod.rs create mode 100644 symbol-table/src/errors/mod.rs create mode 100644 symbol-table/src/errors/symbol_table.rs create mode 100644 symbol-table/src/errors/type_.rs create mode 100644 symbol-table/src/lib.rs create mode 100644 symbol-table/src/symbol_table.rs create mode 100644 symbol-table/src/types/circuits/circuit.rs create mode 100644 symbol-table/src/types/circuits/circuit_function.rs create mode 100644 symbol-table/src/types/circuits/circuit_variable.rs create mode 100644 symbol-table/src/types/circuits/mod.rs create mode 100644 symbol-table/src/types/functions/function.rs create mode 100644 symbol-table/src/types/functions/function_input.rs create mode 100644 symbol-table/src/types/functions/function_input_variable.rs create mode 100644 symbol-table/src/types/functions/function_output.rs create mode 100644 symbol-table/src/types/functions/mod.rs create mode 100644 symbol-table/src/types/mod.rs create mode 100644 symbol-table/src/types/type_.rs create mode 100644 symbol-table/src/types/variables/mod.rs create mode 100644 symbol-table/src/types/variables/variable.rs create mode 100644 symbol-table/tests/mod.rs create mode 100644 symbol-table/tests/symbol_table/duplicate_circuit.leo create mode 100644 symbol-table/tests/symbol_table/duplicate_function.leo create mode 100644 symbol-table/tests/symbol_table/mod.rs create mode 100644 symbol-table/tests/symbol_table/self_not_available.leo create mode 100644 symbol-table/tests/symbol_table/undefined_circuit.leo diff --git a/Cargo.lock b/Cargo.lock index b0fede3470..6bef767a1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1334,6 +1334,7 @@ dependencies = [ "leo-input", "leo-package", "leo-state", + "leo-symbol-table", "notify", "num-bigint", "rand", @@ -1393,6 +1394,17 @@ dependencies = [ "thiserror", ] +[[package]] +name = "leo-symbol-table" +version = "1.0.3" +dependencies = [ + "leo-ast", + "leo-imports", + "leo-typed", + "serde", + "thiserror", +] + [[package]] name = "leo-typed" version = "1.0.3" diff --git a/Cargo.toml b/Cargo.toml index 9bf294db3d..e014240d55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,8 @@ members = [ "linter", "package", "typed", - "state" + "state", + "symbol-table", ] [dependencies.leo-compiler] @@ -66,6 +67,10 @@ version = "1.0.3" path = "./state" version = "1.0.3" +[dependencies.leo-symbol-table] +path = "./symbol-table" +version = "1.0.3" + [dependencies.snarkos-algorithms] version = "1.1.3" default-features = false diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index 80b58f9bbb..bca4d761e6 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -23,7 +23,7 @@ use crate::{ GroupType, }; -use leo_typed::{Expression, Function, InputVariable, Span, Type}; +use leo_typed::{Expression, Function, FunctionInput, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -57,7 +57,7 @@ impl> ConstrainedProgram { // Store input values as new variables in resolved program for (input_model, input_expression) in function.input.clone().iter().zip(input.into_iter()) { let (name, value) = match input_model { - InputVariable::InputKeyword(identifier) => { + FunctionInput::InputKeyword(identifier) => { let input_value = self.enforce_function_input( cs, scope.clone(), @@ -69,7 +69,7 @@ impl> ConstrainedProgram { (identifier.name.clone(), input_value) } - InputVariable::FunctionInput(input_model) => { + FunctionInput::Variable(input_model) => { // First evaluate input expression let mut input_value = self.enforce_function_input( cs, diff --git a/compiler/src/function/main_function.rs b/compiler/src/function/main_function.rs index 950d1cdc7d..74bd917e04 100644 --- a/compiler/src/function/main_function.rs +++ b/compiler/src/function/main_function.rs @@ -23,7 +23,7 @@ use crate::{ OutputBytes, }; -use leo_typed::{Expression, Function, Input, InputVariable}; +use leo_typed::{Expression, Function, FunctionInput, Input}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -45,12 +45,12 @@ impl> ConstrainedProgram { let mut input_variables = vec![]; for input_model in function.input.clone().into_iter() { let (identifier, value) = match input_model { - InputVariable::InputKeyword(identifier) => { + FunctionInput::InputKeyword(identifier) => { let value = self.allocate_input_keyword(cs, identifier.clone(), &input)?; (identifier, value) } - InputVariable::FunctionInput(input_model) => { + FunctionInput::Variable(input_model) => { let name = input_model.identifier.name.clone(); let input_option = input .get(&name) diff --git a/core/src/packages/unstable/blake2s.rs b/core/src/packages/unstable/blake2s.rs index 4c2a6f7426..2dfa759c88 100644 --- a/core/src/packages/unstable/blake2s.rs +++ b/core/src/packages/unstable/blake2s.rs @@ -22,8 +22,8 @@ use leo_typed::{ Expression, Function, FunctionInput, + FunctionInputVariable, Identifier, - InputVariable, IntegerType, Span, Statement, @@ -67,7 +67,7 @@ impl CoreCircuit for Blake2sCircuit { span: span.clone(), }, input: vec![ - InputVariable::FunctionInput(FunctionInput { + FunctionInput::Variable(FunctionInputVariable { identifier: Identifier { name: "seed".to_owned(), span: span.clone(), @@ -76,7 +76,7 @@ impl CoreCircuit for Blake2sCircuit { type_: Type::Array(Box::new(Type::IntegerType(IntegerType::U8)), vec![32usize]), span: span.clone(), }), - InputVariable::FunctionInput(FunctionInput { + FunctionInput::Variable(FunctionInputVariable { identifier: Identifier { name: "message".to_owned(), span: span.clone(), diff --git a/symbol-table/Cargo.toml b/symbol-table/Cargo.toml new file mode 100644 index 0000000000..3e03c9ebe2 --- /dev/null +++ b/symbol-table/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "leo-symbol-table" +version = "1.0.3" +authors = [ "The Aleo Team " ] +description = "Stores user-defined variables during type resolution" +homepage = "https://aleo.org" +respository = "https://github.com/AleoHQ/leo" +keywords = [ + "aleo", + "cryptography", + "leo", + "programming-language", + "zero-knowledge" +] +categories = [ "cryptography::croptocurrencies", "web-programming" ] +include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] +license = "GPL-3.0" +edition = "2018" + +[dependencies.leo-ast] +path = "../ast" +version = "1.0.3" + +[dependencies.leo-imports] +path = "../imports" +version = "1.0.3" + +[dependencies.leo-typed] +path = "../typed" +version = "1.0.3" + +[dependencies.serde] +version = "1.0" + +[dependencies.thiserror] +version = "1.0" \ No newline at end of file diff --git a/symbol-table/src/attributes/attribute.rs b/symbol-table/src/attributes/attribute.rs new file mode 100644 index 0000000000..0fa7153b69 --- /dev/null +++ b/symbol-table/src/attributes/attribute.rs @@ -0,0 +1,24 @@ +// 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 . + +use serde::{Deserialize, Serialize}; + +/// Indicates that a program variable has additional functionality. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum Attribute { + Mutable, + Static, +} diff --git a/symbol-table/src/attributes/mod.rs b/symbol-table/src/attributes/mod.rs new file mode 100644 index 0000000000..f8d19f5a62 --- /dev/null +++ b/symbol-table/src/attributes/mod.rs @@ -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 . + +pub mod attribute; +pub use self::attribute::*; diff --git a/symbol-table/src/errors/mod.rs b/symbol-table/src/errors/mod.rs new file mode 100644 index 0000000000..107ac193f8 --- /dev/null +++ b/symbol-table/src/errors/mod.rs @@ -0,0 +1,21 @@ +// 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 . + +pub mod symbol_table; +pub use self::symbol_table::*; + +pub mod type_; +pub use self::type_::*; diff --git a/symbol-table/src/errors/symbol_table.rs b/symbol-table/src/errors/symbol_table.rs new file mode 100644 index 0000000000..deca39c4a1 --- /dev/null +++ b/symbol-table/src/errors/symbol_table.rs @@ -0,0 +1,67 @@ +// 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 . + +use crate::TypeError; +use leo_typed::{Error as FormattedError, Identifier, Span}; + +use std::path::PathBuf; + +/// Errors encountered when tracking variable, function, and circuit names in a program +#[derive(Debug, Error)] +pub enum SymbolTableError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + TypeError(#[from] TypeError), +} + +impl SymbolTableError { + /// + /// Set the filepath for the error stacktrace + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + SymbolTableError::Error(error) => error.set_path(path), + SymbolTableError::TypeError(error) => error.set_path(path), + } + } + + /// + /// Return a new formatted error with a given message and span information + /// + fn new_from_span(message: String, span: Span) -> Self { + SymbolTableError::Error(FormattedError::new_from_span(message, span)) + } + + /// + /// 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); + + Self::new_from_span(message, 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); + + Self::new_from_span(message, span) + } +} diff --git a/symbol-table/src/errors/type_.rs b/symbol-table/src/errors/type_.rs new file mode 100644 index 0000000000..5ae5f8a9be --- /dev/null +++ b/symbol-table/src/errors/type_.rs @@ -0,0 +1,141 @@ +// 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 . + +use crate::Type; +use leo_typed::{Error as FormattedError, Identifier, Span}; + +use std::path::PathBuf; + +/// Errors encountered when resolving types. +#[derive(Debug, Error)] +pub enum TypeError { + #[error("{}", _0)] + Error(#[from] FormattedError), +} + +impl TypeError { + /// + /// Set the filepath for the error stacktrace. + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + TypeError::Error(error) => error.set_path(path), + } + } + + /// + /// Return a new formatted error with a given message and span information. + /// + fn new_from_span(message: String, span: Span) -> Self { + TypeError::Error(FormattedError::new_from_span(message, span)) + } + + /// + /// Expected an array type from the given expression. + /// + pub fn invalid_array(actual: &Type, span: Span) -> Self { + let message = format!("Expected array type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// + /// Expected a circuit type from the given expression. + /// + pub fn invalid_circuit(actual: &Type, span: Span) -> Self { + let message = format!("Expected circuit type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// + /// Expected a function type from the given expression. + /// + pub fn invalid_function(actual: &Type, span: Span) -> Self { + let message = format!("Expected function type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// + /// Expected an integer type from the given expression. + /// + pub fn invalid_integer(actual: &Type, span: Span) -> Self { + let message = format!("Expected integer type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// + /// Expected a tuple type from the given expression. + /// + pub fn invalid_tuple(actual: &Type, span: Span) -> Self { + let message = format!("Expected tuple type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// + /// The value of the expression does not match the given explicit type. + /// + pub fn mismatched_types(expected: &Type, actual: &Type, span: Span) -> Self { + let message = format!("Expected type `{}`, found type `{}`.", expected, actual); + + Self::new_from_span(message, span) + } + + /// + /// The `Self` keyword was used outside of a circuit. + /// + pub fn self_not_available(span: Span) -> Self { + let message = format!("Type `Self` is only available in circuit definitions and circuit functions."); + + Self::new_from_span(message, span) + } + + /// + /// Found an unknown circuit name. + /// + pub fn undefined_circuit(identifier: Identifier) -> Self { + let message = format!( + "Type circuit `{}` must be defined before it is used in an expression.", + identifier.name + ); + + Self::new_from_span(message, identifier.span) + } + + /// + /// Found an unknown circuit member name. + /// + pub fn undefined_circuit_member(identifier: Identifier) -> Self { + let message = format!("Circuit has no member `{}`.", identifier.name); + + Self::new_from_span(message, identifier.span) + } + + /// + /// Found an unknown function name. + /// + pub fn undefined_function(identifier: Identifier) -> Self { + let message = format!( + "Type function `{}` must be defined before it is used in an expression.", + identifier.name + ); + + Self::new_from_span(message, identifier.span) + } +} diff --git a/symbol-table/src/lib.rs b/symbol-table/src/lib.rs new file mode 100644 index 0000000000..f4a5aaa97a --- /dev/null +++ b/symbol-table/src/lib.rs @@ -0,0 +1,52 @@ +// 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 . + +#[macro_use] +extern crate thiserror; + +pub mod attributes; +pub use self::attributes::*; + +pub mod errors; +pub use self::errors::*; + +pub mod symbol_table; +pub use self::symbol_table::*; + +pub mod types; +pub use self::types::*; + +/// A resolved node in an abstract syntax tree (AST). +/// +/// Resolved nodes can be any function, statement, expression, type, etc. in an AST. +/// Resolved nodes should not contain any illegal types. +/// Resolved nodes should not contain any implicit types. +pub trait ResolvedNode { + /// The expected error type if the type resolution fails. + type Error; + + /// The unresolved AST node that is being resolved. + type UnresolvedNode; + + /// + /// Returns a resolved AST representation given an unresolved AST representation. + /// + /// User-defined types are looked up using the given symbol table. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result + where + Self: std::marker::Sized; +} diff --git a/symbol-table/src/symbol_table.rs b/symbol-table/src/symbol_table.rs new file mode 100644 index 0000000000..452269e8fb --- /dev/null +++ b/symbol-table/src/symbol_table.rs @@ -0,0 +1,291 @@ +// 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 . + +use crate::{CircuitType, FunctionType, ResolvedNode, SymbolTableError, VariableType}; +use leo_typed::{Circuit, Function, Identifier, Program as UnresolvedProgram}; + +use leo_imports::ImportParser; +use std::collections::HashMap; + +/// A abstract data type that tracks the current bindings of identifier +/// names to types in a Leo program. +/// +/// A symbol table has access to all function and circuit names in its +/// parent's symbol table. +/// A symbol table cannot access names in its child's symbol table. +/// Children cannot access names in another sibling's symbol table. +#[derive(Clone)] +pub struct SymbolTable { + /// Maps variable name -> variable type. + variables: HashMap, + + /// Maps circuit name -> circuit type. + circuits: HashMap, + + ///Maps function name -> function type. + functions: HashMap, + + /// The parent of this symbol table. + parent: Option>, +} + +impl SymbolTable { + /// + /// Creates a new symbol table with a given parent symbol table. + /// + pub fn new(parent: Option>) -> Self { + SymbolTable { + variables: HashMap::new(), + circuits: HashMap::new(), + functions: HashMap::new(), + parent, + } + } + + /// + /// Insert a variable into the symbol table from a given name and variable type. + /// + /// If the symbol table did not have this name present, `None` is returned. + /// If the symbol table did have this name present, the variable type is updated, and the old + /// variable type is returned. + /// + pub fn insert_variable(&mut self, name: String, variable_type: VariableType) -> Option { + self.variables.insert(name, variable_type) + } + + /// + /// Insert a circuit definition into the symbol table from a given circuit identifier and + /// circuit type. + /// + /// If the symbol table did not have this name present, `None` is returned. + /// If the symbol table did have this name present, the circuit type is updated, and the old + /// circuit type is returned. + /// + pub fn insert_circuit(&mut self, identifier: Identifier, circuit_type: CircuitType) -> Option { + self.circuits.insert(identifier.name, circuit_type) + } + + /// + /// Insert a function definition into the symbol table from a given identifier and + /// function type. + /// + /// If the symbol table did not have this name present, `None` is returned. + /// If the symbol table did have this name present, the function type is updated, and the old + /// function type is returned. + /// + pub fn insert_function(&mut self, identifier: Identifier, function_type: FunctionType) -> Option { + self.functions.insert(identifier.name, function_type) + } + + /// + /// Returns a reference to the variable type corresponding to the name. + /// + /// If the symbol table did not have this name present, then `None` is returned. + /// + pub fn get_variable(&self, name: &String) -> Option<&VariableType> { + // Lookup variable name in symbol table. + match self.variables.get(name) { + Some(variable) => Some(variable), + None => None, + } + } + + /// + /// Returns a reference to the circuit type corresponding to the name. + /// + /// If the symbol table did not have this name present, then the parent symbol table is checked. + /// If there is no parent symbol table, then `None` is returned. + /// + pub fn get_circuit(&self, name: &String) -> Option<&CircuitType> { + // Lookup name in symbol table. + match self.circuits.get(name) { + Some(circuit) => Some(circuit), + None => { + // Lookup name in parent symbol table. + match &self.parent { + Some(parent) => parent.get_circuit(name), + None => None, + } + } + } + } + + /// + /// Returns a reference to the function type corresponding to the name. + /// + /// If the symbol table did not have this name present, then the parent symbol table is checked. + /// If there is no parent symbol table, then `None` is returned. + /// + pub fn get_function(&self, key: &String) -> Option<&FunctionType> { + // Lookup name in symbol table. + match self.functions.get(key) { + Some(circuit) => Some(circuit), + None => { + // Lookup name in parent symbol table + match &self.parent { + Some(parent) => parent.get_function(key), + None => None, + } + } + } + } + + /// + /// Inserts all imported identifiers for a given list of imported programs. + /// + /// No type resolution performed at this step. + /// + pub fn insert_imports(&mut self, _imports: ImportParser) {} + + /// + /// Checks for duplicate circuit names given a hashmap of unresolved circuits. + /// + /// If a circuit 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_circuits( + &mut self, + circuits: &HashMap, + ) -> Result<(), SymbolTableError> { + // 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_variable(identifier.to_string(), VariableType::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(), + )); + } + } + + Ok(()) + } + + /// + /// Checks for duplicate function names given a hashmap of unresolved functions. + /// + /// If a 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_functions( + &mut self, + functions: &HashMap, + ) -> Result<(), SymbolTableError> { + // 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_variable(identifier.to_string(), VariableType::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(), + )); + } + } + + Ok(()) + } + + /// + /// Checks for unknown types in a circuit given a hashmap of unresolved circuits. + /// + /// If a circuit definition only contains known types, then it is inserted into the + /// symbol table. Variables defined later in the unresolved program can lookup the definition + /// and refer to its expected types + /// + pub fn check_unknown_types_circuits( + &mut self, + circuits: &HashMap, + ) -> Result<(), SymbolTableError> { + // Iterate over circuit names and definitions. + for (_, circuit) in circuits.iter() { + // Get the identifier of the unresolved circuit. + let identifier = circuit.circuit_name.clone(); + + // Resolve unknown types in the unresolved circuit definition. + let circuit_type = CircuitType::resolve(self, circuit.clone())?; + + // Attempt to insert the circuit definition into the symbol table. + self.insert_circuit(identifier, circuit_type); + } + + Ok(()) + } + + /// + /// Checks for unknown types in a function given a hashmap of unresolved functions. + /// + /// If a function definition only contains known types, then it is inserted into the + /// symbol table. Variables defined later in the unresolved program can lookup the definition + /// and refer to its expected types + /// + pub fn check_unknown_types_functions( + &mut self, + functions: &HashMap, + ) -> Result<(), SymbolTableError> { + // Iterate over function names and definitions. + for (_, function) in functions.iter() { + // Get the identifier of the unresolved function. + let identifier = function.identifier.clone(); + + // Resolve unknown types in the unresolved function definition. + let function_type = FunctionType::resolve(self, function.clone())?; + + // Attempt to insert the function definition into the symbol table. + self.insert_function(identifier, function_type); + } + + Ok(()) + } + + /// + /// Checks for duplicate circuit and function names given an unresolved 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 pass_one(&mut self, program: &UnresolvedProgram) -> Result<(), SymbolTableError> { + // 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 unknown types in circuit and function definitions given an unresolved program. + /// + /// If a circuit or function definition only contains known types, then it is inserted into the + /// symbol table. Variables defined later in the unresolved program can lookup the definition and + /// refer to its expected types. + /// + pub fn pass_two(&mut self, program: &UnresolvedProgram) -> Result<(), SymbolTableError> { + // Check unresolved program circuit definitions. + self.check_unknown_types_circuits(&program.circuits)?; + + // Check unresolved program function definitions. + self.check_unknown_types_functions(&program.functions)?; + + Ok(()) + } +} diff --git a/symbol-table/src/types/circuits/circuit.rs b/symbol-table/src/types/circuits/circuit.rs new file mode 100644 index 0000000000..8d1df94a91 --- /dev/null +++ b/symbol-table/src/types/circuits/circuit.rs @@ -0,0 +1,144 @@ +// 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 . + +use crate::{ + types::circuits::{CircuitFunctionType, CircuitVariableType}, + Attribute, + FunctionType, + ResolvedNode, + SymbolTable, + Type, + TypeError, +}; +use leo_typed::{Circuit, CircuitMember, Identifier}; + +use serde::{Deserialize, Serialize}; + +/// Stores circuit definition details. +/// +/// This type should be added to the circuit symbol table for a resolved syntax tree. +/// This is a user-defined type. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct CircuitType { + /// The name of the circuit definition. + pub identifier: Identifier, + + /// The circuit variables. + pub variables: Vec, + + /// The circuit functions. + pub functions: Vec, +} + +impl ResolvedNode for CircuitType { + type Error = TypeError; + type UnresolvedNode = Circuit; + + /// + /// Return a new `CircuitType` from a given `Circuit` definition. + /// + /// Performs a lookup in the given symbol table if the circuit definition contains + /// user-defined types. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let circuit_identifier = unresolved.circuit_name; + let mut variables = vec![]; + let mut functions = vec![]; + + // Resolve the type of every circuit member. + for member in unresolved.members { + match member { + CircuitMember::CircuitVariable(is_mutable, variable_identifier, type_) => { + // Resolve the type of the circuit member variable. + let type_ = Type::from_circuit( + table, + type_, + circuit_identifier.clone(), + circuit_identifier.span.clone(), + )?; + + // Check if the circuit member variable is mutable. + let attributes = if is_mutable { vec![Attribute::Mutable] } else { vec![] }; + + // Create a new circuit variable type. + let variable = CircuitVariableType { + identifier: variable_identifier, + type_, + attributes, + }; + + // Store the circuit variable type. + variables.push(variable); + } + CircuitMember::CircuitFunction(is_static, function) => { + // Resolve the type of the circuit member function. + let function_type = FunctionType::from_circuit(table, circuit_identifier.clone(), function)?; + + // Check if the circuit member function is static. + let attributes = if is_static { vec![Attribute::Static] } else { vec![] }; + + // Create a new circuit function type. + let function = CircuitFunctionType { + function: function_type, + attributes, + }; + + // Store the circuit function type. + functions.push(function); + } + } + } + + // Return a new circuit type. + Ok(CircuitType { + identifier: circuit_identifier.clone(), + variables, + functions, + }) + } +} + +impl CircuitType { + /// + /// Returns the type of a circuit member. + /// + /// If the member is a circuit variable, then the type of the variable is returned. + /// If the member is a circuit function, then the return type of the function is returned. + /// + pub fn member_type(&self, identifier: &Identifier) -> Result<&Type, TypeError> { + // Check if the circuit member is a circuit variable. + let matched_variable = self + .variables + .iter() + .find(|variable| variable.identifier.eq(identifier)); + + match matched_variable { + Some(variable) => Ok(&variable.type_), + None => { + // Check if the circuit member is a circuit function. + let matched_function = self + .functions + .iter() + .find(|function| function.function.identifier.eq(identifier)); + + match matched_function { + Some(function) => Ok(&function.function.output.type_), + None => Err(TypeError::undefined_circuit_member(identifier.clone())), + } + } + } + } +} diff --git a/symbol-table/src/types/circuits/circuit_function.rs b/symbol-table/src/types/circuits/circuit_function.rs new file mode 100644 index 0000000000..0eff740236 --- /dev/null +++ b/symbol-table/src/types/circuits/circuit_function.rs @@ -0,0 +1,27 @@ +// 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 . + +use crate::{types::FunctionType, Attribute}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct CircuitFunctionType { + /// The function signature of the circuit function + pub function: FunctionType, + /// The attributes of the circuit function + pub attributes: Vec, +} diff --git a/symbol-table/src/types/circuits/circuit_variable.rs b/symbol-table/src/types/circuits/circuit_variable.rs new file mode 100644 index 0000000000..55b8326b8a --- /dev/null +++ b/symbol-table/src/types/circuits/circuit_variable.rs @@ -0,0 +1,30 @@ +// 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 . + +use crate::{Attribute, Type}; +use leo_typed::Identifier; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct CircuitVariableType { + /// The name of the circuit variable + pub identifier: Identifier, + /// The type of the circuit variable + pub type_: Type, + /// The attributes of the circuit variable + pub attributes: Vec, +} diff --git a/symbol-table/src/types/circuits/mod.rs b/symbol-table/src/types/circuits/mod.rs new file mode 100644 index 0000000000..8205016c50 --- /dev/null +++ b/symbol-table/src/types/circuits/mod.rs @@ -0,0 +1,24 @@ +// 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 . + +pub mod circuit; +pub use self::circuit::*; + +pub mod circuit_function; +pub use self::circuit_function::*; + +pub mod circuit_variable; +pub use self::circuit_variable::*; diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs new file mode 100644 index 0000000000..f446ec95ec --- /dev/null +++ b/symbol-table/src/types/functions/function.rs @@ -0,0 +1,127 @@ +// 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 . + +use crate::{ + types::functions::{FunctionInputType, FunctionOutputType}, + ResolvedNode, + SymbolTable, + TypeError, +}; +use leo_typed::{Function, Identifier}; + +use serde::{Deserialize, Serialize}; + +/// Stores function definition details. +/// +/// This type should be added to the function symbol table for a resolved syntax tree. +/// This is a user-defined type. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct FunctionType { + /// The name of the function definition. + pub identifier: Identifier, + + /// The function inputs. + pub inputs: Vec, + + /// The function output. + pub output: FunctionOutputType, +} + +impl ResolvedNode for FunctionType { + type Error = TypeError; + type UnresolvedNode = Function; + + /// + /// Return a new `FunctionType` from a given `Function` definition. + /// + /// Performs a lookup in the given symbol table if the function definition contains + /// user-defined types. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let mut inputs_resolved = vec![]; + + // Type check function inputs + for input in unresolved.input { + let input = FunctionInputType::resolve(table, input)?; + inputs_resolved.push(input); + } + + // Type check function output + let output = FunctionOutputType::resolve(table, (unresolved.returns, unresolved.span))?; + + Ok(FunctionType { + identifier: unresolved.identifier, + inputs: inputs_resolved, + output, + }) + } +} + +impl FunctionType { + /// + /// Resolve a function definition and insert it into the given symbol table. + /// + pub fn insert_definition(table: &mut SymbolTable, unresolved_function: Function) -> Result<(), TypeError> { + // Get the identifier of the function. + let function_identifier = unresolved_function.identifier.clone(); + + // Resolve the function definition into a function type. + let function = Self::resolve(table, unresolved_function)?; + + // Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table. + table.insert_function(function_identifier, function); + + Ok(()) + } + + /// + /// Return a new `FunctionType` from a given `Function` definition. + /// + /// Performs a lookup in the given symbol table if the function definition contains + /// user-defined types. + /// + /// If the function definition contains the `Self` keyword, then the given circuit identifier + /// is used as the type. + /// + pub fn from_circuit( + table: &mut SymbolTable, + circuit_name: Identifier, + unresolved_function: Function, + ) -> Result { + let function_identifier = unresolved_function.identifier; + let mut inputs = vec![]; + + // Type check function inputs. + for unresolved_input in unresolved_function.input { + let input = FunctionInputType::from_circuit(table, unresolved_input, circuit_name.clone())?; + inputs.push(input); + } + + // Type check function output. + let output = FunctionOutputType::from_circuit( + table, + circuit_name.clone(), + unresolved_function.returns, + unresolved_function.span, + )?; + + Ok(FunctionType { + identifier: function_identifier.clone(), + inputs, + output, + }) + } +} diff --git a/symbol-table/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs new file mode 100644 index 0000000000..74df8ede4c --- /dev/null +++ b/symbol-table/src/types/functions/function_input.rs @@ -0,0 +1,109 @@ +// 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 . + +use crate::{FunctionInputVariableType, ResolvedNode, SymbolTable, Type, TypeError, VariableType}; +use leo_typed::{FunctionInput, Identifier}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum FunctionInputType { + InputKeyword(Identifier), + Variable(FunctionInputVariableType), +} + +impl ResolvedNode for FunctionInputType { + type Error = TypeError; + type UnresolvedNode = FunctionInput; + + /// + /// Return a new `FunctionInputType` from a given `FunctionInput`. + /// + /// Performs a lookup in the given symbol table if the function input contains + /// user-defined types. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + Ok(match unresolved { + FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), + FunctionInput::Variable(variable) => { + let variable_resolved = FunctionInputVariableType::resolve(table, variable)?; + + FunctionInputType::Variable(variable_resolved) + } + }) + } +} + +impl FunctionInputType { + /// + /// Return the `Identifier` containing name and span information about the current function input. + /// + pub fn identifier(&self) -> &Identifier { + match self { + FunctionInputType::InputKeyword(identifier) => identifier, + FunctionInputType::Variable(variable) => &variable.identifier, + } + } + + /// + /// Return the `Type` of the current function input. + /// + pub fn type_(&self) -> &Type { + match self { + FunctionInputType::InputKeyword(_) => unimplemented!("ERROR: input type not implemented"), + FunctionInputType::Variable(variable) => &variable.type_, + } + } + + /// + /// Return a new `FunctionInputType` from a given `FunctionInput`. + /// + /// Performs a lookup in the given symbol table if the function input contains + /// user-defined types. + /// + /// If the type of the function input is the `Self` keyword, then the given circuit identifier + /// is used as the type. + /// + pub fn from_circuit( + table: &mut SymbolTable, + unresolved: FunctionInput, + circuit_name: Identifier, + ) -> Result { + Ok(match unresolved { + FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), + FunctionInput::Variable(unresolved_function_input) => { + let function_input = + FunctionInputVariableType::from_circuit(table, unresolved_function_input, circuit_name)?; + + FunctionInputType::Variable(function_input) + } + }) + } + + /// + /// Insert the current function input type into the given symbol table. + /// + /// If the symbol table did not have this name present, `None` is returned. + /// + pub fn insert(&self, table: &mut SymbolTable) -> Option { + match self { + FunctionInputType::Variable(variable) => variable.insert(table), + FunctionInputType::InputKeyword(_identifier) => { + unimplemented!("uncomment when support for input types is added") + } + } + } +} diff --git a/symbol-table/src/types/functions/function_input_variable.rs b/symbol-table/src/types/functions/function_input_variable.rs new file mode 100644 index 0000000000..5987d5e78f --- /dev/null +++ b/symbol-table/src/types/functions/function_input_variable.rs @@ -0,0 +1,108 @@ +// 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 . + +use crate::{Attribute, ResolvedNode, SymbolTable, Type, TypeError, VariableType}; +use leo_typed::{FunctionInputVariable, Identifier, Span}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct FunctionInputVariableType { + /// Name of function input. + pub identifier: Identifier, + + /// Type of function input. + pub type_: Type, + + /// The attributes of the function input. + pub attributes: Vec, + + /// The span of the function input. + pub span: Span, +} + +impl ResolvedNode for FunctionInputVariableType { + type Error = TypeError; + type UnresolvedNode = FunctionInputVariable; + + /// + /// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`. + /// + /// Performs a lookup in the given symbol table if the type is user-defined. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let type_ = Type::resolve(table, (unresolved.type_, unresolved.span.clone()))?; + let attributes = if unresolved.mutable { + vec![Attribute::Mutable] + } else { + vec![] + }; + + Ok(FunctionInputVariableType { + identifier: unresolved.identifier, + type_, + attributes, + span: unresolved.span, + }) + } +} + +impl FunctionInputVariableType { + /// + /// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`. + /// + /// Performs a lookup in the given symbol table if the type is user-defined. + /// + /// If the type of the function return type is the `Self` keyword, then the given circuit + /// identifier is used as the type. + /// + pub fn from_circuit( + table: &mut SymbolTable, + unresolved_function_input: FunctionInputVariable, + circuit_name: Identifier, + ) -> Result { + let type_ = Type::from_circuit( + table, + unresolved_function_input.type_, + circuit_name, + unresolved_function_input.span.clone(), + )?; + let attributes = if unresolved_function_input.mutable { + vec![Attribute::Mutable] + } else { + vec![] + }; + + Ok(FunctionInputVariableType { + identifier: unresolved_function_input.identifier, + type_, + attributes, + span: unresolved_function_input.span, + }) + } + + /// + /// Insert the current function input variable type into the given symbol table. + /// + /// If the symbol table did not have this name present, `None` is returned. + /// + pub fn insert(&self, table: &mut SymbolTable) -> Option { + let key = self.identifier.name.clone(); + let value = VariableType::from(self.clone()); + + table.insert_variable(key, value) + } +} diff --git a/symbol-table/src/types/functions/function_output.rs b/symbol-table/src/types/functions/function_output.rs new file mode 100644 index 0000000000..0f403b6ae4 --- /dev/null +++ b/symbol-table/src/types/functions/function_output.rs @@ -0,0 +1,74 @@ +// 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 . + +use crate::{ResolvedNode, SymbolTable, Type, TypeError}; + +use leo_typed::{Identifier, Span, Type as UnresolvedType}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct FunctionOutputType { + /// Type of function output. + pub type_: Type, +} + +impl ResolvedNode for FunctionOutputType { + type Error = TypeError; + /// (optional function output, span) + type UnresolvedNode = (Option, Span); + + /// + /// Return a new `FunctionOutputType` from a given optional function return type and span. + /// + /// Performs a lookup in the given symbol table if the return type is user-defined. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let function_output = unresolved.0; + let span = unresolved.1; + + let type_ = match function_output { + None => Type::Tuple(vec![]), // functions with no return value return an empty tuple + Some(type_) => Type::resolve(table, (type_, span))?, + }; + + Ok(FunctionOutputType { type_ }) + } +} + +impl FunctionOutputType { + /// + /// Return a new `FunctionOutputType` from a given optional function return type and span. + /// + /// Performs a lookup in the given symbol table if the return type is user-defined. + /// + /// If the type of the function return type is the `Self` keyword, then the given circuit + /// identifier is used as the type. + /// + pub fn from_circuit( + table: &mut SymbolTable, + circuit_name: Identifier, + unresolved: Option, + span: Span, + ) -> Result { + let output_type = match unresolved { + None => Type::Tuple(vec![]), + Some(type_) => Type::from_circuit(table, type_, circuit_name, span)?, + }; + + Ok(FunctionOutputType { type_: output_type }) + } +} diff --git a/symbol-table/src/types/functions/mod.rs b/symbol-table/src/types/functions/mod.rs new file mode 100644 index 0000000000..fe22157837 --- /dev/null +++ b/symbol-table/src/types/functions/mod.rs @@ -0,0 +1,27 @@ +// 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 . + +pub mod function; +pub use self::function::*; + +pub mod function_input; +pub use self::function_input::*; + +pub mod function_input_variable; +pub use self::function_input_variable::*; + +pub mod function_output; +pub use self::function_output::*; diff --git a/symbol-table/src/types/mod.rs b/symbol-table/src/types/mod.rs new file mode 100644 index 0000000000..0d27661ad9 --- /dev/null +++ b/symbol-table/src/types/mod.rs @@ -0,0 +1,27 @@ +// 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 . + +pub mod circuits; +pub use self::circuits::*; + +pub mod functions; +pub use self::functions::*; + +pub mod type_; +pub use self::type_::*; + +pub mod variables; +pub use self::variables::*; diff --git a/symbol-table/src/types/type_.rs b/symbol-table/src/types/type_.rs new file mode 100644 index 0000000000..9a13e979a1 --- /dev/null +++ b/symbol-table/src/types/type_.rs @@ -0,0 +1,221 @@ +// 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 . +use crate::{ResolvedNode, SymbolTable, TypeError}; +use leo_typed::{Identifier, IntegerType, Span, Type as UnresolvedType}; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// A resolved type in a Leo program. +/// +/// This type cannot be an implicit or `Self` type. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum Type { + // Data types + Address, + Boolean, + Field, + Group, + IntegerType(IntegerType), + + // Data type wrappers + Array(Box, Vec), + Tuple(Vec), + + // User defined types + Circuit(Identifier), + Function(Identifier), +} + +impl ResolvedNode for Type { + type Error = TypeError; + type UnresolvedNode = (UnresolvedType, Span); + + /// + /// Resolves the given type. + /// + /// Cannot be an implicit or `Self` type. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let type_ = unresolved.0; + let span = unresolved.1; + + Ok(match type_ { + UnresolvedType::Address => Type::Address, + UnresolvedType::Boolean => Type::Boolean, + UnresolvedType::Field => Type::Field, + UnresolvedType::Group => Type::Group, + UnresolvedType::IntegerType(integer) => Type::IntegerType(integer), + + UnresolvedType::Array(type_, dimensions) => { + let array_type = Type::resolve(table, (*type_, span))?; + + Type::Array(Box::new(array_type), dimensions) + } + UnresolvedType::Tuple(types) => { + let tuple_types = types + .into_iter() + .map(|type_| Type::resolve(table, (type_, span.clone()))) + .collect::, _>>()?; + + Type::Tuple(tuple_types) + } + + UnresolvedType::Circuit(identifier) => { + // Lookup the circuit type in the symbol table + let circuit_type = table + .get_circuit(&identifier.name) + .ok_or(TypeError::undefined_circuit(identifier))?; + + Type::Circuit(circuit_type.identifier.clone()) + } + + UnresolvedType::SelfType => { + // Throw an error for using `Self` outside of a circuit + return Err(TypeError::self_not_available(span)); + } + }) + } +} + +impl Type { + /// + /// Resolve a type inside of a circuit definition. + /// + /// If this type is SelfType, return the circuit's type. + /// + pub fn from_circuit( + table: &mut SymbolTable, + type_: UnresolvedType, + circuit_name: Identifier, + span: Span, + ) -> Result { + Ok(match type_ { + UnresolvedType::Array(type_, dimensions) => { + let array_type = Type::from_circuit(table, *type_, circuit_name, span)?; + Type::Array(Box::new(array_type), dimensions) + } + UnresolvedType::Tuple(types) => { + let tuple_types = types + .into_iter() + .map(|type_| Type::from_circuit(table, type_, circuit_name.clone(), span.clone())) + .collect::, _>>()?; + + Type::Tuple(tuple_types) + } + UnresolvedType::SelfType => Type::Circuit(circuit_name), + // The unresolved type does not depend on the current circuit definition + unresolved => Type::resolve(table, (unresolved, span))?, + }) + } + + /// + /// Returns `Ok` if the given expected type is `Some` and expected type == actual type. + /// + pub fn check_type(expected_option: &Option, actual: &Type, span: Span) -> Result<(), TypeError> { + if let Some(expected) = expected_option { + if expected.ne(actual) { + return Err(TypeError::mismatched_types(expected, actual, span)); + } + } + Ok(()) + } + + /// + /// Returns `Ok` if self is an expected integer type `Type::IntegerType`. + /// + pub fn check_type_integer(&self, span: Span) -> Result<(), TypeError> { + match self { + Type::IntegerType(_) => Ok(()), + // Throw mismatched type error + type_ => Err(TypeError::invalid_integer(type_, span)), + } + } + + /// + /// Returns array element type and dimensions if self is an expected array type `Type::Array`. + /// + pub fn get_type_array(&self, span: Span) -> Result<(&Type, &Vec), TypeError> { + match self { + Type::Array(element_type, dimensions) => Ok((element_type, dimensions)), + // Throw mismatched type error + type_ => Err(TypeError::invalid_array(type_, span)), + } + } + + /// + /// Returns tuple element types if self is an expected tuple type `Type::Tuple`. + /// + pub fn get_type_tuple(&self, span: Span) -> Result<&Vec, TypeError> { + match self { + Type::Tuple(types) => Ok(types), + // Throw mismatched type error + type_ => Err(TypeError::invalid_tuple(type_, span)), + } + } + + /// + /// Returns circuit identifier if self is an expected circuit type `Type::Circuit`. + /// + pub fn get_type_circuit(&self, span: Span) -> Result<&Identifier, TypeError> { + match self { + Type::Circuit(identifier) => Ok(identifier), + // Throw mismatched type error + type_ => Err(TypeError::invalid_circuit(type_, span)), + } + } + + /// + /// Returns function identifier if self is an expected function type `Type::Function`. + /// + pub fn get_type_function(&self, span: Span) -> Result<&Identifier, TypeError> { + match self { + Type::Function(identifier) => Ok(identifier), + // Throw mismatched type error + type_ => Err(TypeError::invalid_function(type_, span)), + } + } +} + +impl fmt::Display for Type { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match &self { + Type::Address => write!(f, "address"), + Type::Boolean => write!(f, "bool"), + Type::Field => write!(f, "field"), + Type::Group => write!(f, "group"), + Type::IntegerType(integer_type) => write!(f, "{}", integer_type), + + Type::Array(type_, dimensions) => { + let dimensions_string = dimensions + .iter() + .map(|dimension| format!("{}", dimension)) + .collect::>() + .join(", "); + + write!(f, "[{}; ({})]", *type_, dimensions_string) + } + Type::Tuple(tuple) => { + let tuple_string = tuple.iter().map(|x| format!("{}", x)).collect::>().join(", "); + + write!(f, "({})", tuple_string) + } + + Type::Circuit(identifier) => write!(f, "circuit {}", identifier), + Type::Function(identifier) => write!(f, "function {}", identifier), + } + } +} diff --git a/symbol-table/src/types/variables/mod.rs b/symbol-table/src/types/variables/mod.rs new file mode 100644 index 0000000000..80950ed0c3 --- /dev/null +++ b/symbol-table/src/types/variables/mod.rs @@ -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 . + +pub mod variable; +pub use self::variable::*; diff --git a/symbol-table/src/types/variables/variable.rs b/symbol-table/src/types/variables/variable.rs new file mode 100644 index 0000000000..4d30977fb7 --- /dev/null +++ b/symbol-table/src/types/variables/variable.rs @@ -0,0 +1,79 @@ +// 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 . +use crate::{Attribute, Type}; +use leo_typed::{Circuit, Function, Identifier}; + +use crate::FunctionInputVariableType; +use std::fmt; + +/// Stores variable definition details. +/// +/// This type should be added to the variable symbol table for a resolved syntax tree. +#[derive(Clone, Debug, Eq, PartialEq, Hash)] +pub struct VariableType { + pub identifier: Identifier, + pub type_: Type, + pub attributes: Vec, +} + +impl VariableType { + /// + /// Returns `true` if this variable's value can be modified. + /// + pub fn is_mutable(&self) -> bool { + self.attributes.contains(&Attribute::Mutable) + } +} + +impl From for VariableType { + fn from(value: Circuit) -> Self { + let identifier = value.circuit_name; + + VariableType { + identifier: identifier.clone(), + type_: Type::Circuit(identifier), + attributes: vec![], + } + } +} + +impl From for VariableType { + fn from(value: Function) -> Self { + let identifier = value.identifier; + + VariableType { + identifier: identifier.clone(), + type_: Type::Function(identifier.clone()), + attributes: vec![], + } + } +} + +impl From for VariableType { + fn from(value: FunctionInputVariableType) -> Self { + VariableType { + identifier: value.identifier, + type_: value.type_, + attributes: value.attributes, + } + } +} + +impl fmt::Display for VariableType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.identifier) + } +} diff --git a/symbol-table/tests/mod.rs b/symbol-table/tests/mod.rs new file mode 100644 index 0000000000..1ee70d31bb --- /dev/null +++ b/symbol-table/tests/mod.rs @@ -0,0 +1,115 @@ +// 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 . + +pub mod symbol_table; + +use leo_ast::LeoAst; +use leo_symbol_table::{SymbolTable, SymbolTableError}; +use leo_typed::LeoTypedAst; + +use std::path::PathBuf; + +const TEST_PROGRAM_PATH: &str = ""; + +/// A helper struct to test a `SymbolTable`. +pub struct TestSymbolTable { + typed: LeoTypedAst, +} + +impl TestSymbolTable { + /// + /// Returns a typed syntax tree given a Leo program. + /// + pub fn new(bytes: &[u8]) -> Self { + // Get file string from bytes. + let file_string = String::from_utf8_lossy(bytes); + + // Get test file path. + let file_path = PathBuf::from(TEST_PROGRAM_PATH); + + // Get parser syntax tree + let ast = LeoAst::new(&file_path, &*file_string).unwrap(); + + // Get typed syntax tree + let typed = LeoTypedAst::new(TEST_PROGRAM_PATH, &ast); + + Self { typed } + } + + /// + /// Parse the typed syntax tree into a symbol table. + /// + /// Expect no errors during parsing. + /// + pub fn expect_success(self) { + // Get program. + let program = self.typed.into_repr(); + + // Create new symbol table. + let symbol_table = &mut SymbolTable::new(None); + + // Run the first pass to check for duplicate names. + symbol_table.pass_one(&program).unwrap(); + + // Run the second pass to check for invalid definitions. + symbol_table.pass_two(&program).unwrap(); + } + + /// + /// Parse the typed syntax tree into a symbol table. + /// + /// Expect an error involving entries in the symbol table. + /// + pub fn expect_pass_one_error(self) { + // Get program. + let program = self.typed.into_repr(); + + // Create new symbol table. + let symbol_table = &mut SymbolTable::new(None); + + // Run pass one and expect an error. + let error = symbol_table.pass_one(&program).unwrap_err(); + + match error { + SymbolTableError::Error(_) => {} // Ok + error => panic!("Expected a symbol table error found `{}`", error), + } + } + + /// + /// Parse the typed syntax tree into a symbol table. + /// + /// Expect an error involving types in the symbol table. + /// + pub fn expect_pass_two_error(self) { + // Get program. + let program = self.typed.into_repr(); + + // Create a new symbol table. + let symbol_table = &mut SymbolTable::new(None); + + // Run the pass one and expect no errors. + symbol_table.pass_one(&program).unwrap(); + + // Run the pass two and expect and error. + let error = symbol_table.pass_two(&program).unwrap_err(); + + match error { + SymbolTableError::TypeError(_) => {} //Ok + error => panic!("Expected a type error found `{}`", error), + } + } +} diff --git a/symbol-table/tests/symbol_table/duplicate_circuit.leo b/symbol-table/tests/symbol_table/duplicate_circuit.leo new file mode 100644 index 0000000000..de08c207ad --- /dev/null +++ b/symbol-table/tests/symbol_table/duplicate_circuit.leo @@ -0,0 +1,10 @@ +/// +/// Defines a circuit `Foo {}`. +/// Attempts to define a second circuit `Foo {}`. +/// +/// Expected output: SymbolTableError +/// Message: "Duplicate circuit definition found for `Foo`." +/// + +circuit Foo {} +circuit Foo {} \ No newline at end of file diff --git a/symbol-table/tests/symbol_table/duplicate_function.leo b/symbol-table/tests/symbol_table/duplicate_function.leo new file mode 100644 index 0000000000..fffbbeff5a --- /dev/null +++ b/symbol-table/tests/symbol_table/duplicate_function.leo @@ -0,0 +1,10 @@ +/// +/// Defines a function `main() {}`. +/// Attempts to define a second function `main() {}`. +/// +/// Expected output: SymbolTableError +/// Message: "Duplicate function definition found for `main`." +/// + +function main() {} +function main() {} \ No newline at end of file diff --git a/symbol-table/tests/symbol_table/mod.rs b/symbol-table/tests/symbol_table/mod.rs new file mode 100644 index 0000000000..b6d511c89c --- /dev/null +++ b/symbol-table/tests/symbol_table/mod.rs @@ -0,0 +1,72 @@ +// 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 . +use crate::TestSymbolTable; + +/// +/// Defines a circuit `Foo {}`. +/// Attempts to define a second circuit `Foo {}`. +/// +/// Expected output: SymbolTableError +/// Message: "Duplicate circuit definition found for `Foo`." +/// +#[test] +fn test_duplicate_circuit() { + let program_bytes = include_bytes!("duplicate_circuit.leo"); + let resolver = TestSymbolTable::new(program_bytes); + + resolver.expect_pass_one_error(); +} + +/// +/// Defines a function `main() {}`. +/// Attempts to define a second function `main() {}`. +/// +/// Expected output: SymbolTableError +/// Message: "Duplicate function definition found for `main`." +/// +#[test] +fn test_duplicate_function() { + let program_bytes = include_bytes!("duplicate_function.leo"); + let resolver = TestSymbolTable::new(program_bytes); + + resolver.expect_pass_one_error(); +} + +/// +/// Defines a function that returns `Self`. +/// +/// Expected output: TypeError +/// Message: "Type `Self` is only available in circuit definitions and circuit functions." +/// +#[test] +fn test_self_not_available() { + let program_bytes = include_bytes!("self_not_available.leo"); + let resolver = TestSymbolTable::new(program_bytes); + + resolver.expect_pass_two_error(); +} + +/// +/// Defines a circuit with variable whose type is `Bar`, an undefined circuit. +/// +/// Expected output: TypeError +/// Message: "Type circuit `Bar` must be defined before it is used in an expression." +/// +#[test] +fn test_undefined_circuit() { + let program_bytes = include_bytes!("undefined_circuit.leo"); + let resolver = TestSymbolTable::new(program_bytes); + + resolver.expect_pass_two_error(); +} diff --git a/symbol-table/tests/symbol_table/self_not_available.leo b/symbol-table/tests/symbol_table/self_not_available.leo new file mode 100644 index 0000000000..e34a4c5670 --- /dev/null +++ b/symbol-table/tests/symbol_table/self_not_available.leo @@ -0,0 +1,8 @@ +/// +/// Defines a function that returns `Self`. +/// +/// Expected output: TypeError +/// Message: "Type `Self` is only available in circuit definitions and circuit functions." +/// + +function main() -> Self {} \ No newline at end of file diff --git a/symbol-table/tests/symbol_table/undefined_circuit.leo b/symbol-table/tests/symbol_table/undefined_circuit.leo new file mode 100644 index 0000000000..396dcfd177 --- /dev/null +++ b/symbol-table/tests/symbol_table/undefined_circuit.leo @@ -0,0 +1,10 @@ +/// +/// Defines a circuit with variable whose type is `Bar`, an undefined circuit. +/// +/// Expected output: TypeError +/// Message: "Type circuit `Bar` must be defined before it is used in an expression." +/// + +circuit Foo { + b: Bar +} \ No newline at end of file diff --git a/typed/src/annotation.rs b/typed/src/annotation.rs index 3c1b66ee39..6ffa0fad8c 100644 --- a/typed/src/annotation.rs +++ b/typed/src/annotation.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Circuit, Function, Identifier, Import, InputVariable, TestFunction}; +use crate::{Circuit, Function, FunctionInput, Identifier, Import, TestFunction}; use leo_ast::{ annotations::{Annotation, AnnotationArguments, AnnotationName}, definitions::{AnnotatedDefinition, Definition}, @@ -28,7 +28,7 @@ pub fn load_annotation( _circuits: &mut HashMap, _functions: &mut HashMap, tests: &mut HashMap, - _expected: &mut Vec, + _expected: &mut Vec, ) { let ast_annotation = annotated_definition.annotation; let ast_definition = *annotated_definition.definition; diff --git a/typed/src/functions/function.rs b/typed/src/functions/function.rs index 4f52da175d..9d1e1d718b 100644 --- a/typed/src/functions/function.rs +++ b/typed/src/functions/function.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Identifier, InputVariable, Span, Statement, Type}; +use crate::{FunctionInput, Identifier, Span, Statement, Type}; use leo_ast::functions::Function as AstFunction; use serde::{Deserialize, Serialize}; @@ -23,7 +23,7 @@ use std::fmt; #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Function { pub identifier: Identifier, - pub input: Vec, + pub input: Vec, pub returns: Option, pub statements: Vec, pub span: Span, @@ -35,7 +35,7 @@ impl<'ast> From> for Function { let parameters = function .parameters .into_iter() - .map(|parameter| InputVariable::from(parameter)) + .map(|parameter| FunctionInput::from(parameter)) .collect(); let returns = function.returns.map(|type_| Type::from(type_)); let statements = function diff --git a/typed/src/functions/input/function_input.rs b/typed/src/functions/input/function_input.rs index ea91b1b988..5de9468f94 100644 --- a/typed/src/functions/input/function_input.rs +++ b/typed/src/functions/input/function_input.rs @@ -21,16 +21,16 @@ use serde::{Deserialize, Serialize}; use std::fmt; #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct FunctionInput { +pub struct FunctionInputVariable { pub identifier: Identifier, pub mutable: bool, pub type_: Type, pub span: Span, } -impl<'ast> From> for FunctionInput { +impl<'ast> From> for FunctionInputVariable { fn from(parameter: AstFunctionInput<'ast>) -> Self { - FunctionInput { + FunctionInputVariable { identifier: Identifier::from(parameter.identifier), mutable: parameter.mutable.is_some(), type_: Type::from(parameter.type_), @@ -39,7 +39,7 @@ impl<'ast> From> for FunctionInput { } } -impl FunctionInput { +impl FunctionInputVariable { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { // mut var: bool if self.mutable { @@ -50,13 +50,13 @@ impl FunctionInput { } } -impl fmt::Display for FunctionInput { +impl fmt::Display for FunctionInputVariable { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.format(f) } } -impl fmt::Debug for FunctionInput { +impl fmt::Debug for FunctionInputVariable { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.format(f) } diff --git a/typed/src/functions/input/input_variable.rs b/typed/src/functions/input/input_variable.rs index b3032d8b1b..01974dda8a 100644 --- a/typed/src/functions/input/input_variable.rs +++ b/typed/src/functions/input/input_variable.rs @@ -14,19 +14,19 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{FunctionInput, Identifier, Span}; +use crate::{FunctionInputVariable, Identifier, Span}; use leo_ast::functions::input::Input as AstInput; use serde::{Deserialize, Serialize}; use std::fmt; #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum InputVariable { +pub enum FunctionInput { InputKeyword(Identifier), - FunctionInput(FunctionInput), + Variable(FunctionInputVariable), } -impl<'ast> From> for InputVariable { +impl<'ast> From> for FunctionInput { fn from(input: AstInput<'ast>) -> Self { match input { AstInput::InputKeyword(input_keyword) => { @@ -35,31 +35,31 @@ impl<'ast> From> for InputVariable { span: Span::from(input_keyword.span), }; - InputVariable::InputKeyword(id) + FunctionInput::InputKeyword(id) } AstInput::FunctionInput(function_input) => { - InputVariable::FunctionInput(FunctionInput::from(function_input)) + FunctionInput::Variable(FunctionInputVariable::from(function_input)) } } } } -impl InputVariable { +impl FunctionInput { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - InputVariable::InputKeyword(id) => write!(f, "{}", id), - InputVariable::FunctionInput(function_input) => write!(f, "{}", function_input), + FunctionInput::InputKeyword(id) => write!(f, "{}", id), + FunctionInput::Variable(function_input) => write!(f, "{}", function_input), } } } -impl fmt::Display for InputVariable { +impl fmt::Display for FunctionInput { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.format(f) } } -impl fmt::Debug for InputVariable { +impl fmt::Debug for FunctionInput { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.format(f) } diff --git a/typed/src/program.rs b/typed/src/program.rs index 8cc8b4f3ad..90cfb41fc4 100644 --- a/typed/src/program.rs +++ b/typed/src/program.rs @@ -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, Identifier, Import, InputVariable, TestFunction}; +use crate::{load_annotation, Circuit, Function, FunctionInput, Identifier, Import, TestFunction}; use leo_ast::{definitions::Definition, files::File}; use serde::{Deserialize, Serialize}; @@ -27,7 +27,7 @@ use std::collections::HashMap; #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] pub struct Program { pub name: String, - pub expected_input: Vec, + pub expected_input: Vec, pub imports: Vec, pub circuits: HashMap, pub functions: HashMap, From effdfc7628f6b162d6cdc74013727768e1f6104c Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 6 Oct 2020 17:20:51 -0700 Subject: [PATCH 009/139] add leo dynamic check module --- Cargo.lock | 13 + Cargo.toml | 5 + compiler/src/function/function.rs | 4 +- core/src/packages/unstable/blake2s.rs | 2 +- dynamic-check/Cargo.toml | 40 +++ dynamic-check/src/dynamic_check.rs | 305 ++++++++++++++++++ dynamic-check/src/lib.rs | 18 ++ dynamic-check/tests/empty.leo | 0 dynamic-check/tests/mod.rs | 73 +++++ symbol-table/src/errors/type_.rs | 14 +- symbol-table/src/types/circuits/circuit.rs | 6 +- .../src/types/circuits/circuit_variable.rs | 4 +- symbol-table/src/types/functions/function.rs | 4 +- .../src/types/functions/function_input.rs | 4 +- .../functions/function_input_variable.rs | 8 +- .../src/types/functions/function_output.rs | 12 +- symbol-table/src/types/type_.rs | 78 ++--- symbol-table/src/types/variables/variable.rs | 8 +- typed/src/functions/function.rs | 6 +- 19 files changed, 529 insertions(+), 75 deletions(-) create mode 100644 dynamic-check/Cargo.toml create mode 100644 dynamic-check/src/dynamic_check.rs create mode 100644 dynamic-check/src/lib.rs create mode 100644 dynamic-check/tests/empty.leo create mode 100644 dynamic-check/tests/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 6bef767a1c..6495689c93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1276,6 +1276,18 @@ dependencies = [ "thiserror", ] +[[package]] +name = "leo-dynamic-check" +version = "1.0.3" +dependencies = [ + "leo-ast", + "leo-imports", + "leo-symbol-table", + "leo-typed", + "serde", + "thiserror", +] + [[package]] name = "leo-gadgets" version = "1.0.3" @@ -1329,6 +1341,7 @@ dependencies = [ "lazy_static", "leo-compiler", "leo-core", + "leo-dynamic-check", "leo-gadgets", "leo-imports", "leo-input", diff --git a/Cargo.toml b/Cargo.toml index e014240d55..367ce011de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ members = [ "ast", "compiler", "core", + "dynamic-check", "gadgets", "imports", "input", @@ -47,6 +48,10 @@ version = "1.0.3" path = "./core" version = "1.0.1" +[dependencies.leo-dynamic-check] +path = "./dynamic-check" +version = "1.0.3" + [dependencies.leo-gadgets] path = "./gadgets" version = "1.0.3" diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index bca4d761e6..07a8bb6894 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -103,7 +103,7 @@ impl> ConstrainedProgram { function_name.clone(), None, statement.clone(), - function.returns.clone(), + function.output.clone(), declared_circuit_reference.clone(), )?; @@ -116,7 +116,7 @@ impl> ConstrainedProgram { Self::conditionally_select_result(cs, &mut return_values, results, function.span.clone())?; if let ConstrainedValue::Tuple(ref returns) = return_values { - let return_types = match function.returns { + let return_types = match function.output { Some(Type::Tuple(types)) => types.len(), Some(_) => 1usize, None => 0usize, diff --git a/core/src/packages/unstable/blake2s.rs b/core/src/packages/unstable/blake2s.rs index 2dfa759c88..f64de3d0fb 100644 --- a/core/src/packages/unstable/blake2s.rs +++ b/core/src/packages/unstable/blake2s.rs @@ -86,7 +86,7 @@ impl CoreCircuit for Blake2sCircuit { span: span.clone(), }), ], - returns: Some(Type::Array(Box::new(Type::IntegerType(IntegerType::U8)), vec![32usize])), + output: Some(Type::Array(Box::new(Type::IntegerType(IntegerType::U8)), vec![32usize])), statements: vec![Statement::Return( Expression::CoreFunctionCall( Self::name(), diff --git a/dynamic-check/Cargo.toml b/dynamic-check/Cargo.toml new file mode 100644 index 0000000000..c00cbf8219 --- /dev/null +++ b/dynamic-check/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "leo-dynamic-check" +version = "1.0.3" +authors = [ "The Aleo Team " ] +description = "Checks that a program is correct using type inference" +homepage = "https://aleo.org" +respository = "https://github.com/AleoHQ/leo" +keywords = [ + "aleo", + "cryptography", + "leo", + "programming-language", + "zero-knowledge" +] +categories = [ "cryptography::croptocurrencies", "web-programming" ] +include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] +license = "GPL-3.0" +edition = "2018" + +[dependencies.leo-ast] +path = "../ast" +version = "1.0.3" + +[dependencies.leo-imports] +path = "../imports" +version = "1.0.3" + +[dependencies.leo-symbol-table] +path = "../symbol-table" +version = "1.0.3" + +[dependencies.leo-typed] +path = "../typed" +version = "1.0.3" + +[dependencies.serde] +version = "1.0" + +[dependencies.thiserror] +version = "1.0" \ No newline at end of file diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs new file mode 100644 index 0000000000..4a3f68fb1e --- /dev/null +++ b/dynamic-check/src/dynamic_check.rs @@ -0,0 +1,305 @@ +// 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 . + +use leo_typed::{Expression, Function, Identifier, Program, Span, Statement}; + +use leo_symbol_table::{ExtendedType, FunctionType, SymbolTable}; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; + +/// Performs a dynamic type inference check over a program. +pub struct DynamicCheck { + symbol_table: SymbolTable, + functions: Vec, +} + +impl DynamicCheck { + /// + /// Return a new `DynamicCheck` from a given program and symbol table. + /// + pub fn new(program: &Program, symbol_table: SymbolTable) -> Self { + let mut dynamic_check = Self { + symbol_table, + functions: vec![], + }; + + dynamic_check.parse_program(program); + + dynamic_check + } + + /// + /// Collects a vector of `TypeAssertion` predicates from a program. + /// + fn parse_program(&mut self, program: &Program) { + let functions = program + .functions + .iter() + .map(|(_identifier, function)| function) + .collect::>(); + + self.parse_functions(functions); + } + + /// + /// Collects a vector of `TypeAssertion` predicates from a vector of functions. + /// + fn parse_functions(&mut self, functions: Vec<&Function>) { + for function in functions { + self.parse_function(function) + } + } + + /// + /// Collects a vector of `TypeAssertion` predicates from a function. + /// + fn parse_function(&mut self, function: &Function) { + let function_body = FunctionBody::new(function.clone(), self.symbol_table.clone()); + + self.functions.push(function_body); + } + + /// + /// Return the result of evaluating all `TypeAssertion` predicates. + /// + /// Will attempt to substitute a `Type` for all `TypeVariable`s. + /// Returns `true` if all `TypeAssertion` predicates are true. + /// Returns ERROR if a `TypeAssertion` predicate is false or a solution does not exist. + /// + pub fn solve(self) -> bool { + for function_body in self.functions { + function_body.solve(); + } + + true + } +} + +/// A vector of `TypeAssertion` predicates created from a function body. +#[derive(Clone)] +pub struct FunctionBody { + function_type: FunctionType, + symbol_table: SymbolTable, + type_assertions: Vec, + type_variables: HashSet, +} + +impl FunctionBody { + /// + /// Collects a vector of `TypeAssertion` predicates from a function. + /// + pub fn new(function: Function, symbol_table: SymbolTable) -> Self { + let name = &function.identifier.name; + let function_type = symbol_table.get_function(name).unwrap().clone(); + + let mut function_body = Self { + function_type, + symbol_table, + type_assertions: vec![], + type_variables: HashSet::new(), + }; + + // Create type assertions for function statements + function_body.parse_statements(&function.statements); + + function_body + } + + /// + /// Collects a vector of `TypeAssertion` predicates from a vector of statements. + /// + fn parse_statements(&mut self, statements: &Vec) { + for statement in statements { + self.parse_statement(statement); + } + } + + /// + /// Collects a vector of `TypeAssertion` predicates from a statement. + /// + fn parse_statement(&mut self, statement: &Statement) { + match statement { + Statement::Return(expression, span) => { + self.parse_statement_return(expression, span); + } + statement => unimplemented!("statement {} not implemented", statement), + } + } + + /// + /// Collects a `TypeAssertion` predicate from a statement return. + /// + fn parse_statement_return(&mut self, expression: &Expression, _span: &Span) { + // Get the function output type. + let output_type = &self.function_type.output.type_; + + // Create the left hand side of a type assertion. + let left = TypeElement::Type(output_type.clone()); + + // Create the right hand side from the statement return expression. + let right = TypeElement::new(expression, self.symbol_table.clone()); + + // Create a new type assertion for the statement return. + let type_assertion = TypeAssertion::new(left, right); + + // Push the new type assertion to this function's list of type assertions. + self.type_assertions.push(type_assertion) + } + + /// + /// Iteratively solves all `TypeAssertions`. + /// + fn solve(self) { + let mut unsolved = self.type_assertions.clone(); + + while !unsolved.is_empty() { + // Pop type assertion from list + let type_assertion = unsolved.pop().unwrap(); + + println!("assertion: {:?}", type_assertion); + + // Get type variable and type + if let Some((type_variable, type_)) = type_assertion.get_substitute() { + // Substitute type variable for type in unsolved + for original in &mut unsolved { + original.substitute(&type_variable, &type_) + } + } + } + + // for type_assertion in unsolved.pop() { + // if let Some((type_variable, type_)) = type_assertion.get_substitute() { + // // Substitute type variable in unsolved type assertions + // for mut original in unsolved { + // original.substitute(type_variable, type_) + // } + // } + // } + } +} + +/// A predicate that evaluates equality between two `TypeElement`s. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct TypeAssertion { + left: TypeElement, + right: TypeElement, +} + +impl TypeAssertion { + /// + /// Return a `TypeAssertion` predicate from given left and right `TypeElement`s + /// + pub fn new(left: TypeElement, right: TypeElement) -> Self { + Self { left, right } + } + + /// + /// Substitute the given `TypeVariable` for each `TypeElement` in the `TypeAssertion`. + /// + pub fn substitute(&mut self, variable: &TypeVariable, type_: &TypeElement) { + self.left.substitute(variable, type_); + self.right.substitute(variable, type_); + } + + /// + /// Returns true if the left `TypeElement` is equal to the right `TypeElement`. + /// + pub fn evaluate(&self) -> bool { + self.left.eq(&self.right) + } + + pub fn get_substitute(&self) -> Option<(TypeVariable, TypeElement)> { + match (&self.left, &self.right) { + (TypeElement::Variable(variable), element) => Some((variable.clone(), element.clone())), + (TypeElement::Type(type_), TypeElement::Variable(variable)) => { + Some((variable.clone(), TypeElement::Type(type_.clone()))) + } + (TypeElement::Type(_), TypeElement::Type(_)) => None, + } + } +} + +/// A `Type` or a `TypeVariable` in a `TypeAssertion`. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum TypeElement { + Type(ExtendedType), + Variable(TypeVariable), +} + +impl TypeElement { + /// + /// Return a new `TypeElement` from the given expression and symbol table. + /// + pub fn new(expression: &Expression, _symbol_table: SymbolTable) -> Self { + match expression { + Expression::Identifier(identifier) => Self::from(identifier.clone()), + Expression::Implicit(name, _) => Self::from(name.clone()), + Expression::Boolean(_, _) => Self::boolean(), + expression => unimplemented!("expression {} not implemented", expression), + } + } + + /// + /// Return a boolean `TypeElement`. + /// + pub fn boolean() -> Self { + TypeElement::Type(ExtendedType::Boolean) + } + + /// + /// Substitute the given `TypeElement` if self is equal to the given `TypeVariable`. + /// + pub fn substitute(&mut self, variable: &TypeVariable, type_: &TypeElement) { + match self { + TypeElement::Type(_) => {} + TypeElement::Variable(original) => { + if original.eq(&variable) { + *self = type_.clone() + } + } + } + } +} + +impl From for TypeElement { + fn from(name: String) -> Self { + Self::Variable(TypeVariable::from(name)) + } +} + +impl From for TypeElement { + fn from(identifier: Identifier) -> Self { + Self::Variable(TypeVariable::from(identifier)) + } +} + +/// An unknown type in a `TypeAssertion`. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct TypeVariable { + name: String, +} + +impl From for TypeVariable { + fn from(name: String) -> Self { + Self { name } + } +} + +impl From for TypeVariable { + fn from(identifier: Identifier) -> Self { + Self::from(identifier.name) + } +} diff --git a/dynamic-check/src/lib.rs b/dynamic-check/src/lib.rs new file mode 100644 index 0000000000..ddebbdd6a7 --- /dev/null +++ b/dynamic-check/src/lib.rs @@ -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 . + +pub mod dynamic_check; +pub use self::dynamic_check::*; diff --git a/dynamic-check/tests/empty.leo b/dynamic-check/tests/empty.leo new file mode 100644 index 0000000000..e69de29bb2 diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs new file mode 100644 index 0000000000..21c3928b25 --- /dev/null +++ b/dynamic-check/tests/mod.rs @@ -0,0 +1,73 @@ +// 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 . + +use leo_ast::LeoAst; +use leo_dynamic_check::DynamicCheck; + +use leo_symbol_table::SymbolTable; +use leo_typed::LeoTypedAst; +use std::path::PathBuf; + +const TEST_PROGRAM_PATH: &str = ""; +const TEST_PROGRAM_NAME: &str = "test"; + +/// A helper struct to test a `DynamicCheck`. +pub struct TestDynamicCheck { + dynamic_check: DynamicCheck, +} + +impl TestDynamicCheck { + pub fn new(bytes: &[u8]) -> Self { + // Get file string from bytes. + let file_string = String::from_utf8_lossy(bytes); + + // Get test file path. + let file_path = PathBuf::from(TEST_PROGRAM_PATH); + + // Get parser syntax tree. + let ast = LeoAst::new(&file_path, &*file_string).unwrap(); + + // Get typed syntax tree. + let typed = LeoTypedAst::new(TEST_PROGRAM_NAME, &ast); + let program = typed.into_repr(); + + // Create symbol table. + let mut symbol_table = SymbolTable::new(None); + + // Load symbols into symbol table. + symbol_table.pass_one(&program).unwrap(); + + symbol_table.pass_two(&program).unwrap(); + + // Create dynamic check + let dynamic_check = DynamicCheck::new(&program, symbol_table); + + Self { dynamic_check } + } + + pub fn solve(self) { + self.dynamic_check.solve(); + } +} + +#[test] +fn test_new() { + let bytes = include_bytes!("empty.leo"); + + let dynamic_check = TestDynamicCheck::new(bytes); + + dynamic_check.solve() +} diff --git a/symbol-table/src/errors/type_.rs b/symbol-table/src/errors/type_.rs index 5ae5f8a9be..1b6e85c5a0 100644 --- a/symbol-table/src/errors/type_.rs +++ b/symbol-table/src/errors/type_.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::Type; +use crate::ExtendedType; use leo_typed::{Error as FormattedError, Identifier, Span}; use std::path::PathBuf; @@ -46,7 +46,7 @@ impl TypeError { /// /// Expected an array type from the given expression. /// - pub fn invalid_array(actual: &Type, span: Span) -> Self { + pub fn invalid_array(actual: &ExtendedType, span: Span) -> Self { let message = format!("Expected array type, found type `{}`.", actual); Self::new_from_span(message, span) @@ -55,7 +55,7 @@ impl TypeError { /// /// Expected a circuit type from the given expression. /// - pub fn invalid_circuit(actual: &Type, span: Span) -> Self { + pub fn invalid_circuit(actual: &ExtendedType, span: Span) -> Self { let message = format!("Expected circuit type, found type `{}`.", actual); Self::new_from_span(message, span) @@ -64,7 +64,7 @@ impl TypeError { /// /// Expected a function type from the given expression. /// - pub fn invalid_function(actual: &Type, span: Span) -> Self { + pub fn invalid_function(actual: &ExtendedType, span: Span) -> Self { let message = format!("Expected function type, found type `{}`.", actual); Self::new_from_span(message, span) @@ -73,7 +73,7 @@ impl TypeError { /// /// Expected an integer type from the given expression. /// - pub fn invalid_integer(actual: &Type, span: Span) -> Self { + pub fn invalid_integer(actual: &ExtendedType, span: Span) -> Self { let message = format!("Expected integer type, found type `{}`.", actual); Self::new_from_span(message, span) @@ -82,7 +82,7 @@ impl TypeError { /// /// Expected a tuple type from the given expression. /// - pub fn invalid_tuple(actual: &Type, span: Span) -> Self { + pub fn invalid_tuple(actual: &ExtendedType, span: Span) -> Self { let message = format!("Expected tuple type, found type `{}`.", actual); Self::new_from_span(message, span) @@ -91,7 +91,7 @@ impl TypeError { /// /// The value of the expression does not match the given explicit type. /// - pub fn mismatched_types(expected: &Type, actual: &Type, span: Span) -> Self { + pub fn mismatched_types(expected: &ExtendedType, actual: &ExtendedType, span: Span) -> Self { let message = format!("Expected type `{}`, found type `{}`.", expected, actual); Self::new_from_span(message, span) diff --git a/symbol-table/src/types/circuits/circuit.rs b/symbol-table/src/types/circuits/circuit.rs index 8d1df94a91..c60fbc736a 100644 --- a/symbol-table/src/types/circuits/circuit.rs +++ b/symbol-table/src/types/circuits/circuit.rs @@ -17,10 +17,10 @@ use crate::{ types::circuits::{CircuitFunctionType, CircuitVariableType}, Attribute, + ExtendedType, FunctionType, ResolvedNode, SymbolTable, - Type, TypeError, }; use leo_typed::{Circuit, CircuitMember, Identifier}; @@ -63,7 +63,7 @@ impl ResolvedNode for CircuitType { match member { CircuitMember::CircuitVariable(is_mutable, variable_identifier, type_) => { // Resolve the type of the circuit member variable. - let type_ = Type::from_circuit( + let type_ = ExtendedType::from_circuit( table, type_, circuit_identifier.clone(), @@ -118,7 +118,7 @@ impl CircuitType { /// If the member is a circuit variable, then the type of the variable is returned. /// If the member is a circuit function, then the return type of the function is returned. /// - pub fn member_type(&self, identifier: &Identifier) -> Result<&Type, TypeError> { + pub fn member_type(&self, identifier: &Identifier) -> Result<&ExtendedType, TypeError> { // Check if the circuit member is a circuit variable. let matched_variable = self .variables diff --git a/symbol-table/src/types/circuits/circuit_variable.rs b/symbol-table/src/types/circuits/circuit_variable.rs index 55b8326b8a..4f936d1237 100644 --- a/symbol-table/src/types/circuits/circuit_variable.rs +++ b/symbol-table/src/types/circuits/circuit_variable.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Attribute, Type}; +use crate::{Attribute, ExtendedType}; use leo_typed::Identifier; use serde::{Deserialize, Serialize}; @@ -24,7 +24,7 @@ pub struct CircuitVariableType { /// The name of the circuit variable pub identifier: Identifier, /// The type of the circuit variable - pub type_: Type, + pub type_: ExtendedType, /// The attributes of the circuit variable pub attributes: Vec, } diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs index f446ec95ec..3a3d98475a 100644 --- a/symbol-table/src/types/functions/function.rs +++ b/symbol-table/src/types/functions/function.rs @@ -60,7 +60,7 @@ impl ResolvedNode for FunctionType { } // Type check function output - let output = FunctionOutputType::resolve(table, (unresolved.returns, unresolved.span))?; + let output = FunctionOutputType::resolve(table, (unresolved.output, unresolved.span))?; Ok(FunctionType { identifier: unresolved.identifier, @@ -114,7 +114,7 @@ impl FunctionType { let output = FunctionOutputType::from_circuit( table, circuit_name.clone(), - unresolved_function.returns, + unresolved_function.output, unresolved_function.span, )?; diff --git a/symbol-table/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs index 74df8ede4c..63bf3412c4 100644 --- a/symbol-table/src/types/functions/function_input.rs +++ b/symbol-table/src/types/functions/function_input.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{FunctionInputVariableType, ResolvedNode, SymbolTable, Type, TypeError, VariableType}; +use crate::{ExtendedType, FunctionInputVariableType, ResolvedNode, SymbolTable, TypeError, VariableType}; use leo_typed::{FunctionInput, Identifier}; use serde::{Deserialize, Serialize}; @@ -61,7 +61,7 @@ impl FunctionInputType { /// /// Return the `Type` of the current function input. /// - pub fn type_(&self) -> &Type { + pub fn type_(&self) -> &ExtendedType { match self { FunctionInputType::InputKeyword(_) => unimplemented!("ERROR: input type not implemented"), FunctionInputType::Variable(variable) => &variable.type_, diff --git a/symbol-table/src/types/functions/function_input_variable.rs b/symbol-table/src/types/functions/function_input_variable.rs index 5987d5e78f..ecb8086a1b 100644 --- a/symbol-table/src/types/functions/function_input_variable.rs +++ b/symbol-table/src/types/functions/function_input_variable.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Attribute, ResolvedNode, SymbolTable, Type, TypeError, VariableType}; +use crate::{Attribute, ExtendedType, ResolvedNode, SymbolTable, TypeError, VariableType}; use leo_typed::{FunctionInputVariable, Identifier, Span}; use serde::{Deserialize, Serialize}; @@ -25,7 +25,7 @@ pub struct FunctionInputVariableType { pub identifier: Identifier, /// Type of function input. - pub type_: Type, + pub type_: ExtendedType, /// The attributes of the function input. pub attributes: Vec, @@ -44,7 +44,7 @@ impl ResolvedNode for FunctionInputVariableType { /// Performs a lookup in the given symbol table if the type is user-defined. /// fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let type_ = Type::resolve(table, (unresolved.type_, unresolved.span.clone()))?; + let type_ = ExtendedType::resolve(table, (unresolved.type_, unresolved.span.clone()))?; let attributes = if unresolved.mutable { vec![Attribute::Mutable] } else { @@ -74,7 +74,7 @@ impl FunctionInputVariableType { unresolved_function_input: FunctionInputVariable, circuit_name: Identifier, ) -> Result { - let type_ = Type::from_circuit( + let type_ = ExtendedType::from_circuit( table, unresolved_function_input.type_, circuit_name, diff --git a/symbol-table/src/types/functions/function_output.rs b/symbol-table/src/types/functions/function_output.rs index 0f403b6ae4..837d1568ab 100644 --- a/symbol-table/src/types/functions/function_output.rs +++ b/symbol-table/src/types/functions/function_output.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ResolvedNode, SymbolTable, Type, TypeError}; +use crate::{ExtendedType, ResolvedNode, SymbolTable, TypeError}; use leo_typed::{Identifier, Span, Type as UnresolvedType}; @@ -23,7 +23,7 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct FunctionOutputType { /// Type of function output. - pub type_: Type, + pub type_: ExtendedType, } impl ResolvedNode for FunctionOutputType { @@ -41,8 +41,8 @@ impl ResolvedNode for FunctionOutputType { let span = unresolved.1; let type_ = match function_output { - None => Type::Tuple(vec![]), // functions with no return value return an empty tuple - Some(type_) => Type::resolve(table, (type_, span))?, + None => ExtendedType::Tuple(vec![]), // functions with no return value return an empty tuple + Some(type_) => ExtendedType::resolve(table, (type_, span))?, }; Ok(FunctionOutputType { type_ }) @@ -65,8 +65,8 @@ impl FunctionOutputType { span: Span, ) -> Result { let output_type = match unresolved { - None => Type::Tuple(vec![]), - Some(type_) => Type::from_circuit(table, type_, circuit_name, span)?, + None => ExtendedType::Tuple(vec![]), + Some(type_) => ExtendedType::from_circuit(table, type_, circuit_name, span)?, }; Ok(FunctionOutputType { type_: output_type }) diff --git a/symbol-table/src/types/type_.rs b/symbol-table/src/types/type_.rs index 9a13e979a1..9dc6105469 100644 --- a/symbol-table/src/types/type_.rs +++ b/symbol-table/src/types/type_.rs @@ -23,7 +23,7 @@ use std::fmt; /// /// This type cannot be an implicit or `Self` type. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum Type { +pub enum ExtendedType { // Data types Address, Boolean, @@ -32,15 +32,15 @@ pub enum Type { IntegerType(IntegerType), // Data type wrappers - Array(Box, Vec), - Tuple(Vec), + Array(Box, Vec), + Tuple(Vec), // User defined types Circuit(Identifier), Function(Identifier), } -impl ResolvedNode for Type { +impl ResolvedNode for ExtendedType { type Error = TypeError; type UnresolvedNode = (UnresolvedType, Span); @@ -54,24 +54,24 @@ impl ResolvedNode for Type { let span = unresolved.1; Ok(match type_ { - UnresolvedType::Address => Type::Address, - UnresolvedType::Boolean => Type::Boolean, - UnresolvedType::Field => Type::Field, - UnresolvedType::Group => Type::Group, - UnresolvedType::IntegerType(integer) => Type::IntegerType(integer), + UnresolvedType::Address => ExtendedType::Address, + UnresolvedType::Boolean => ExtendedType::Boolean, + UnresolvedType::Field => ExtendedType::Field, + UnresolvedType::Group => ExtendedType::Group, + UnresolvedType::IntegerType(integer) => ExtendedType::IntegerType(integer), UnresolvedType::Array(type_, dimensions) => { - let array_type = Type::resolve(table, (*type_, span))?; + let array_type = ExtendedType::resolve(table, (*type_, span))?; - Type::Array(Box::new(array_type), dimensions) + ExtendedType::Array(Box::new(array_type), dimensions) } UnresolvedType::Tuple(types) => { let tuple_types = types .into_iter() - .map(|type_| Type::resolve(table, (type_, span.clone()))) + .map(|type_| ExtendedType::resolve(table, (type_, span.clone()))) .collect::, _>>()?; - Type::Tuple(tuple_types) + ExtendedType::Tuple(tuple_types) } UnresolvedType::Circuit(identifier) => { @@ -80,7 +80,7 @@ impl ResolvedNode for Type { .get_circuit(&identifier.name) .ok_or(TypeError::undefined_circuit(identifier))?; - Type::Circuit(circuit_type.identifier.clone()) + ExtendedType::Circuit(circuit_type.identifier.clone()) } UnresolvedType::SelfType => { @@ -91,7 +91,7 @@ impl ResolvedNode for Type { } } -impl Type { +impl ExtendedType { /// /// Resolve a type inside of a circuit definition. /// @@ -105,27 +105,27 @@ impl Type { ) -> Result { Ok(match type_ { UnresolvedType::Array(type_, dimensions) => { - let array_type = Type::from_circuit(table, *type_, circuit_name, span)?; - Type::Array(Box::new(array_type), dimensions) + let array_type = ExtendedType::from_circuit(table, *type_, circuit_name, span)?; + ExtendedType::Array(Box::new(array_type), dimensions) } UnresolvedType::Tuple(types) => { let tuple_types = types .into_iter() - .map(|type_| Type::from_circuit(table, type_, circuit_name.clone(), span.clone())) + .map(|type_| ExtendedType::from_circuit(table, type_, circuit_name.clone(), span.clone())) .collect::, _>>()?; - Type::Tuple(tuple_types) + ExtendedType::Tuple(tuple_types) } - UnresolvedType::SelfType => Type::Circuit(circuit_name), + UnresolvedType::SelfType => ExtendedType::Circuit(circuit_name), // The unresolved type does not depend on the current circuit definition - unresolved => Type::resolve(table, (unresolved, span))?, + unresolved => ExtendedType::resolve(table, (unresolved, span))?, }) } /// /// Returns `Ok` if the given expected type is `Some` and expected type == actual type. /// - pub fn check_type(expected_option: &Option, actual: &Type, span: Span) -> Result<(), TypeError> { + pub fn check_type(expected_option: &Option, actual: &ExtendedType, span: Span) -> Result<(), TypeError> { if let Some(expected) = expected_option { if expected.ne(actual) { return Err(TypeError::mismatched_types(expected, actual, span)); @@ -139,7 +139,7 @@ impl Type { /// pub fn check_type_integer(&self, span: Span) -> Result<(), TypeError> { match self { - Type::IntegerType(_) => Ok(()), + ExtendedType::IntegerType(_) => Ok(()), // Throw mismatched type error type_ => Err(TypeError::invalid_integer(type_, span)), } @@ -148,9 +148,9 @@ impl Type { /// /// Returns array element type and dimensions if self is an expected array type `Type::Array`. /// - pub fn get_type_array(&self, span: Span) -> Result<(&Type, &Vec), TypeError> { + pub fn get_type_array(&self, span: Span) -> Result<(&ExtendedType, &Vec), TypeError> { match self { - Type::Array(element_type, dimensions) => Ok((element_type, dimensions)), + ExtendedType::Array(element_type, dimensions) => Ok((element_type, dimensions)), // Throw mismatched type error type_ => Err(TypeError::invalid_array(type_, span)), } @@ -159,9 +159,9 @@ impl Type { /// /// Returns tuple element types if self is an expected tuple type `Type::Tuple`. /// - pub fn get_type_tuple(&self, span: Span) -> Result<&Vec, TypeError> { + pub fn get_type_tuple(&self, span: Span) -> Result<&Vec, TypeError> { match self { - Type::Tuple(types) => Ok(types), + ExtendedType::Tuple(types) => Ok(types), // Throw mismatched type error type_ => Err(TypeError::invalid_tuple(type_, span)), } @@ -172,7 +172,7 @@ impl Type { /// pub fn get_type_circuit(&self, span: Span) -> Result<&Identifier, TypeError> { match self { - Type::Circuit(identifier) => Ok(identifier), + ExtendedType::Circuit(identifier) => Ok(identifier), // Throw mismatched type error type_ => Err(TypeError::invalid_circuit(type_, span)), } @@ -183,23 +183,23 @@ impl Type { /// pub fn get_type_function(&self, span: Span) -> Result<&Identifier, TypeError> { match self { - Type::Function(identifier) => Ok(identifier), + ExtendedType::Function(identifier) => Ok(identifier), // Throw mismatched type error type_ => Err(TypeError::invalid_function(type_, span)), } } } -impl fmt::Display for Type { +impl fmt::Display for ExtendedType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match &self { - Type::Address => write!(f, "address"), - Type::Boolean => write!(f, "bool"), - Type::Field => write!(f, "field"), - Type::Group => write!(f, "group"), - Type::IntegerType(integer_type) => write!(f, "{}", integer_type), + ExtendedType::Address => write!(f, "address"), + ExtendedType::Boolean => write!(f, "bool"), + ExtendedType::Field => write!(f, "field"), + ExtendedType::Group => write!(f, "group"), + ExtendedType::IntegerType(integer_type) => write!(f, "{}", integer_type), - Type::Array(type_, dimensions) => { + ExtendedType::Array(type_, dimensions) => { let dimensions_string = dimensions .iter() .map(|dimension| format!("{}", dimension)) @@ -208,14 +208,14 @@ impl fmt::Display for Type { write!(f, "[{}; ({})]", *type_, dimensions_string) } - Type::Tuple(tuple) => { + ExtendedType::Tuple(tuple) => { let tuple_string = tuple.iter().map(|x| format!("{}", x)).collect::>().join(", "); write!(f, "({})", tuple_string) } - Type::Circuit(identifier) => write!(f, "circuit {}", identifier), - Type::Function(identifier) => write!(f, "function {}", identifier), + ExtendedType::Circuit(identifier) => write!(f, "circuit {}", identifier), + ExtendedType::Function(identifier) => write!(f, "function {}", identifier), } } } diff --git a/symbol-table/src/types/variables/variable.rs b/symbol-table/src/types/variables/variable.rs index 4d30977fb7..e5ef783d93 100644 --- a/symbol-table/src/types/variables/variable.rs +++ b/symbol-table/src/types/variables/variable.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Attribute, Type}; +use crate::{Attribute, ExtendedType}; use leo_typed::{Circuit, Function, Identifier}; use crate::FunctionInputVariableType; @@ -25,7 +25,7 @@ use std::fmt; #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct VariableType { pub identifier: Identifier, - pub type_: Type, + pub type_: ExtendedType, pub attributes: Vec, } @@ -44,7 +44,7 @@ impl From for VariableType { VariableType { identifier: identifier.clone(), - type_: Type::Circuit(identifier), + type_: ExtendedType::Circuit(identifier), attributes: vec![], } } @@ -56,7 +56,7 @@ impl From for VariableType { VariableType { identifier: identifier.clone(), - type_: Type::Function(identifier.clone()), + type_: ExtendedType::Function(identifier.clone()), attributes: vec![], } } diff --git a/typed/src/functions/function.rs b/typed/src/functions/function.rs index 9d1e1d718b..ab16d6b2ce 100644 --- a/typed/src/functions/function.rs +++ b/typed/src/functions/function.rs @@ -24,7 +24,7 @@ use std::fmt; pub struct Function { pub identifier: Identifier, pub input: Vec, - pub returns: Option, + pub output: Option, pub statements: Vec, pub span: Span, } @@ -47,7 +47,7 @@ impl<'ast> From> for Function { Function { identifier: function_name, input: parameters, - returns, + output: returns, statements, span: Span::from(function.span), } @@ -67,7 +67,7 @@ impl Function { .map(|x| format!("{}", x)) .collect::>() .join(","); - let returns = self.returns.as_ref().map(|type_| format!("{}", type_)); + let returns = self.output.as_ref().map(|type_| format!("{}", type_)); let statements = self .statements .iter() From a5975eb5fdbe8922be87cf99b0c8e4ec69cacc0c Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 9 Oct 2020 16:25:04 -0700 Subject: [PATCH 010/139] move types into separate module --- Cargo.lock | 11 + Cargo.toml | 1 + types/Cargo.toml | 36 +++ types/src/errors/mod.rs | 21 ++ types/src/errors/symbol_table.rs | 67 ++++++ types/src/errors/type_.rs | 141 ++++++++++++ types/src/lib.rs | 46 ++++ types/src/types/circuits/circuit.rs | 144 ++++++++++++ types/src/types/circuits/circuit_function.rs | 27 +++ types/src/types/circuits/circuit_variable.rs | 30 +++ types/src/types/circuits/mod.rs | 24 ++ types/src/types/functions/function.rs | 127 +++++++++++ types/src/types/functions/function_input.rs | 109 +++++++++ .../functions/function_input_variable.rs | 108 +++++++++ types/src/types/functions/function_output.rs | 74 +++++++ types/src/types/functions/mod.rs | 27 +++ types/src/types/mod.rs | 27 +++ types/src/types/type_.rs | 209 ++++++++++++++++++ types/src/types/variables/mod.rs | 18 ++ types/src/types/variables/variable.rs | 79 +++++++ 20 files changed, 1326 insertions(+) create mode 100644 types/Cargo.toml create mode 100644 types/src/errors/mod.rs create mode 100644 types/src/errors/symbol_table.rs create mode 100644 types/src/errors/type_.rs create mode 100644 types/src/lib.rs create mode 100644 types/src/types/circuits/circuit.rs create mode 100644 types/src/types/circuits/circuit_function.rs create mode 100644 types/src/types/circuits/circuit_variable.rs create mode 100644 types/src/types/circuits/mod.rs create mode 100644 types/src/types/functions/function.rs create mode 100644 types/src/types/functions/function_input.rs create mode 100644 types/src/types/functions/function_input_variable.rs create mode 100644 types/src/types/functions/function_output.rs create mode 100644 types/src/types/functions/mod.rs create mode 100644 types/src/types/mod.rs create mode 100644 types/src/types/type_.rs create mode 100644 types/src/types/variables/mod.rs create mode 100644 types/src/types/variables/variable.rs diff --git a/Cargo.lock b/Cargo.lock index 6495689c93..553a4f3faf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1432,6 +1432,17 @@ dependencies = [ "snarkos-models", ] +[[package]] +name = "leo-types" +version = "1.0.3" +dependencies = [ + "leo-ast", + "leo-imports", + "leo-typed", + "serde", + "thiserror", +] + [[package]] name = "libc" version = "0.2.76" diff --git a/Cargo.toml b/Cargo.toml index 367ce011de..45431d65d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ members = [ "linter", "package", "typed", + "types", "state", "symbol-table", ] diff --git a/types/Cargo.toml b/types/Cargo.toml new file mode 100644 index 0000000000..ed9b068232 --- /dev/null +++ b/types/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "leo-types" +version = "1.0.3" +authors = [ "The Aleo Team " ] +description = "Leo program type and type variables" +homepage = "https://aleo.org" +respository = "https://github.com/AleoHQ/leo" +keywords = [ + "aleo", + "cryptography", + "leo", + "programming-language", + "zero-knowledge" +] +categories = [ "cryptography::croptocurrencies", "web-programming" ] +include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] +license = "GPL-3.0" +edition = "2018" + +[dependencies.leo-ast] +path = "../ast" +version = "1.0.3" + +[dependencies.leo-imports] +path = "../imports" +version = "1.0.3" + +[dependencies.leo-typed] +path = "../typed" +version = "1.0.3" + +[dependencies.serde] +version = "1.0" + +[dependencies.thiserror] +version = "1.0" \ No newline at end of file diff --git a/types/src/errors/mod.rs b/types/src/errors/mod.rs new file mode 100644 index 0000000000..107ac193f8 --- /dev/null +++ b/types/src/errors/mod.rs @@ -0,0 +1,21 @@ +// 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 . + +pub mod symbol_table; +pub use self::symbol_table::*; + +pub mod type_; +pub use self::type_::*; diff --git a/types/src/errors/symbol_table.rs b/types/src/errors/symbol_table.rs new file mode 100644 index 0000000000..deca39c4a1 --- /dev/null +++ b/types/src/errors/symbol_table.rs @@ -0,0 +1,67 @@ +// 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 . + +use crate::TypeError; +use leo_typed::{Error as FormattedError, Identifier, Span}; + +use std::path::PathBuf; + +/// Errors encountered when tracking variable, function, and circuit names in a program +#[derive(Debug, Error)] +pub enum SymbolTableError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + TypeError(#[from] TypeError), +} + +impl SymbolTableError { + /// + /// Set the filepath for the error stacktrace + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + SymbolTableError::Error(error) => error.set_path(path), + SymbolTableError::TypeError(error) => error.set_path(path), + } + } + + /// + /// Return a new formatted error with a given message and span information + /// + fn new_from_span(message: String, span: Span) -> Self { + SymbolTableError::Error(FormattedError::new_from_span(message, span)) + } + + /// + /// 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); + + Self::new_from_span(message, 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); + + Self::new_from_span(message, span) + } +} diff --git a/types/src/errors/type_.rs b/types/src/errors/type_.rs new file mode 100644 index 0000000000..5ae5f8a9be --- /dev/null +++ b/types/src/errors/type_.rs @@ -0,0 +1,141 @@ +// 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 . + +use crate::Type; +use leo_typed::{Error as FormattedError, Identifier, Span}; + +use std::path::PathBuf; + +/// Errors encountered when resolving types. +#[derive(Debug, Error)] +pub enum TypeError { + #[error("{}", _0)] + Error(#[from] FormattedError), +} + +impl TypeError { + /// + /// Set the filepath for the error stacktrace. + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + TypeError::Error(error) => error.set_path(path), + } + } + + /// + /// Return a new formatted error with a given message and span information. + /// + fn new_from_span(message: String, span: Span) -> Self { + TypeError::Error(FormattedError::new_from_span(message, span)) + } + + /// + /// Expected an array type from the given expression. + /// + pub fn invalid_array(actual: &Type, span: Span) -> Self { + let message = format!("Expected array type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// + /// Expected a circuit type from the given expression. + /// + pub fn invalid_circuit(actual: &Type, span: Span) -> Self { + let message = format!("Expected circuit type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// + /// Expected a function type from the given expression. + /// + pub fn invalid_function(actual: &Type, span: Span) -> Self { + let message = format!("Expected function type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// + /// Expected an integer type from the given expression. + /// + pub fn invalid_integer(actual: &Type, span: Span) -> Self { + let message = format!("Expected integer type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// + /// Expected a tuple type from the given expression. + /// + pub fn invalid_tuple(actual: &Type, span: Span) -> Self { + let message = format!("Expected tuple type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// + /// The value of the expression does not match the given explicit type. + /// + pub fn mismatched_types(expected: &Type, actual: &Type, span: Span) -> Self { + let message = format!("Expected type `{}`, found type `{}`.", expected, actual); + + Self::new_from_span(message, span) + } + + /// + /// The `Self` keyword was used outside of a circuit. + /// + pub fn self_not_available(span: Span) -> Self { + let message = format!("Type `Self` is only available in circuit definitions and circuit functions."); + + Self::new_from_span(message, span) + } + + /// + /// Found an unknown circuit name. + /// + pub fn undefined_circuit(identifier: Identifier) -> Self { + let message = format!( + "Type circuit `{}` must be defined before it is used in an expression.", + identifier.name + ); + + Self::new_from_span(message, identifier.span) + } + + /// + /// Found an unknown circuit member name. + /// + pub fn undefined_circuit_member(identifier: Identifier) -> Self { + let message = format!("Circuit has no member `{}`.", identifier.name); + + Self::new_from_span(message, identifier.span) + } + + /// + /// Found an unknown function name. + /// + pub fn undefined_function(identifier: Identifier) -> Self { + let message = format!( + "Type function `{}` must be defined before it is used in an expression.", + identifier.name + ); + + Self::new_from_span(message, identifier.span) + } +} diff --git a/types/src/lib.rs b/types/src/lib.rs new file mode 100644 index 0000000000..28ee6ddf03 --- /dev/null +++ b/types/src/lib.rs @@ -0,0 +1,46 @@ +// 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 . + +#[macro_use] +extern crate thiserror; + +pub mod errors; +pub use self::errors::*; + +pub mod types; +pub use self::types::*; + +/// A resolved node in an abstract syntax tree (AST). +/// +/// Resolved nodes can be any function, statement, expression, type, etc. in an AST. +/// Resolved nodes should not contain any illegal types. +/// Resolved nodes should not contain any implicit types. +pub trait ResolvedNode { + /// The expected error type if the type resolution fails. + type Error; + + /// The unresolved AST node that is being resolved. + type UnresolvedNode; + + /// + /// Returns a resolved AST representation given an unresolved AST representation. + /// + /// User-defined types are looked up using the given symbol table. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result + where + Self: std::marker::Sized; +} diff --git a/types/src/types/circuits/circuit.rs b/types/src/types/circuits/circuit.rs new file mode 100644 index 0000000000..8d1df94a91 --- /dev/null +++ b/types/src/types/circuits/circuit.rs @@ -0,0 +1,144 @@ +// 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 . + +use crate::{ + types::circuits::{CircuitFunctionType, CircuitVariableType}, + Attribute, + FunctionType, + ResolvedNode, + SymbolTable, + Type, + TypeError, +}; +use leo_typed::{Circuit, CircuitMember, Identifier}; + +use serde::{Deserialize, Serialize}; + +/// Stores circuit definition details. +/// +/// This type should be added to the circuit symbol table for a resolved syntax tree. +/// This is a user-defined type. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct CircuitType { + /// The name of the circuit definition. + pub identifier: Identifier, + + /// The circuit variables. + pub variables: Vec, + + /// The circuit functions. + pub functions: Vec, +} + +impl ResolvedNode for CircuitType { + type Error = TypeError; + type UnresolvedNode = Circuit; + + /// + /// Return a new `CircuitType` from a given `Circuit` definition. + /// + /// Performs a lookup in the given symbol table if the circuit definition contains + /// user-defined types. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let circuit_identifier = unresolved.circuit_name; + let mut variables = vec![]; + let mut functions = vec![]; + + // Resolve the type of every circuit member. + for member in unresolved.members { + match member { + CircuitMember::CircuitVariable(is_mutable, variable_identifier, type_) => { + // Resolve the type of the circuit member variable. + let type_ = Type::from_circuit( + table, + type_, + circuit_identifier.clone(), + circuit_identifier.span.clone(), + )?; + + // Check if the circuit member variable is mutable. + let attributes = if is_mutable { vec![Attribute::Mutable] } else { vec![] }; + + // Create a new circuit variable type. + let variable = CircuitVariableType { + identifier: variable_identifier, + type_, + attributes, + }; + + // Store the circuit variable type. + variables.push(variable); + } + CircuitMember::CircuitFunction(is_static, function) => { + // Resolve the type of the circuit member function. + let function_type = FunctionType::from_circuit(table, circuit_identifier.clone(), function)?; + + // Check if the circuit member function is static. + let attributes = if is_static { vec![Attribute::Static] } else { vec![] }; + + // Create a new circuit function type. + let function = CircuitFunctionType { + function: function_type, + attributes, + }; + + // Store the circuit function type. + functions.push(function); + } + } + } + + // Return a new circuit type. + Ok(CircuitType { + identifier: circuit_identifier.clone(), + variables, + functions, + }) + } +} + +impl CircuitType { + /// + /// Returns the type of a circuit member. + /// + /// If the member is a circuit variable, then the type of the variable is returned. + /// If the member is a circuit function, then the return type of the function is returned. + /// + pub fn member_type(&self, identifier: &Identifier) -> Result<&Type, TypeError> { + // Check if the circuit member is a circuit variable. + let matched_variable = self + .variables + .iter() + .find(|variable| variable.identifier.eq(identifier)); + + match matched_variable { + Some(variable) => Ok(&variable.type_), + None => { + // Check if the circuit member is a circuit function. + let matched_function = self + .functions + .iter() + .find(|function| function.function.identifier.eq(identifier)); + + match matched_function { + Some(function) => Ok(&function.function.output.type_), + None => Err(TypeError::undefined_circuit_member(identifier.clone())), + } + } + } + } +} diff --git a/types/src/types/circuits/circuit_function.rs b/types/src/types/circuits/circuit_function.rs new file mode 100644 index 0000000000..0eff740236 --- /dev/null +++ b/types/src/types/circuits/circuit_function.rs @@ -0,0 +1,27 @@ +// 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 . + +use crate::{types::FunctionType, Attribute}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct CircuitFunctionType { + /// The function signature of the circuit function + pub function: FunctionType, + /// The attributes of the circuit function + pub attributes: Vec, +} diff --git a/types/src/types/circuits/circuit_variable.rs b/types/src/types/circuits/circuit_variable.rs new file mode 100644 index 0000000000..55b8326b8a --- /dev/null +++ b/types/src/types/circuits/circuit_variable.rs @@ -0,0 +1,30 @@ +// 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 . + +use crate::{Attribute, Type}; +use leo_typed::Identifier; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct CircuitVariableType { + /// The name of the circuit variable + pub identifier: Identifier, + /// The type of the circuit variable + pub type_: Type, + /// The attributes of the circuit variable + pub attributes: Vec, +} diff --git a/types/src/types/circuits/mod.rs b/types/src/types/circuits/mod.rs new file mode 100644 index 0000000000..8205016c50 --- /dev/null +++ b/types/src/types/circuits/mod.rs @@ -0,0 +1,24 @@ +// 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 . + +pub mod circuit; +pub use self::circuit::*; + +pub mod circuit_function; +pub use self::circuit_function::*; + +pub mod circuit_variable; +pub use self::circuit_variable::*; diff --git a/types/src/types/functions/function.rs b/types/src/types/functions/function.rs new file mode 100644 index 0000000000..3a3d98475a --- /dev/null +++ b/types/src/types/functions/function.rs @@ -0,0 +1,127 @@ +// 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 . + +use crate::{ + types::functions::{FunctionInputType, FunctionOutputType}, + ResolvedNode, + SymbolTable, + TypeError, +}; +use leo_typed::{Function, Identifier}; + +use serde::{Deserialize, Serialize}; + +/// Stores function definition details. +/// +/// This type should be added to the function symbol table for a resolved syntax tree. +/// This is a user-defined type. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct FunctionType { + /// The name of the function definition. + pub identifier: Identifier, + + /// The function inputs. + pub inputs: Vec, + + /// The function output. + pub output: FunctionOutputType, +} + +impl ResolvedNode for FunctionType { + type Error = TypeError; + type UnresolvedNode = Function; + + /// + /// Return a new `FunctionType` from a given `Function` definition. + /// + /// Performs a lookup in the given symbol table if the function definition contains + /// user-defined types. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let mut inputs_resolved = vec![]; + + // Type check function inputs + for input in unresolved.input { + let input = FunctionInputType::resolve(table, input)?; + inputs_resolved.push(input); + } + + // Type check function output + let output = FunctionOutputType::resolve(table, (unresolved.output, unresolved.span))?; + + Ok(FunctionType { + identifier: unresolved.identifier, + inputs: inputs_resolved, + output, + }) + } +} + +impl FunctionType { + /// + /// Resolve a function definition and insert it into the given symbol table. + /// + pub fn insert_definition(table: &mut SymbolTable, unresolved_function: Function) -> Result<(), TypeError> { + // Get the identifier of the function. + let function_identifier = unresolved_function.identifier.clone(); + + // Resolve the function definition into a function type. + let function = Self::resolve(table, unresolved_function)?; + + // Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table. + table.insert_function(function_identifier, function); + + Ok(()) + } + + /// + /// Return a new `FunctionType` from a given `Function` definition. + /// + /// Performs a lookup in the given symbol table if the function definition contains + /// user-defined types. + /// + /// If the function definition contains the `Self` keyword, then the given circuit identifier + /// is used as the type. + /// + pub fn from_circuit( + table: &mut SymbolTable, + circuit_name: Identifier, + unresolved_function: Function, + ) -> Result { + let function_identifier = unresolved_function.identifier; + let mut inputs = vec![]; + + // Type check function inputs. + for unresolved_input in unresolved_function.input { + let input = FunctionInputType::from_circuit(table, unresolved_input, circuit_name.clone())?; + inputs.push(input); + } + + // Type check function output. + let output = FunctionOutputType::from_circuit( + table, + circuit_name.clone(), + unresolved_function.output, + unresolved_function.span, + )?; + + Ok(FunctionType { + identifier: function_identifier.clone(), + inputs, + output, + }) + } +} diff --git a/types/src/types/functions/function_input.rs b/types/src/types/functions/function_input.rs new file mode 100644 index 0000000000..74df8ede4c --- /dev/null +++ b/types/src/types/functions/function_input.rs @@ -0,0 +1,109 @@ +// 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 . + +use crate::{FunctionInputVariableType, ResolvedNode, SymbolTable, Type, TypeError, VariableType}; +use leo_typed::{FunctionInput, Identifier}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum FunctionInputType { + InputKeyword(Identifier), + Variable(FunctionInputVariableType), +} + +impl ResolvedNode for FunctionInputType { + type Error = TypeError; + type UnresolvedNode = FunctionInput; + + /// + /// Return a new `FunctionInputType` from a given `FunctionInput`. + /// + /// Performs a lookup in the given symbol table if the function input contains + /// user-defined types. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + Ok(match unresolved { + FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), + FunctionInput::Variable(variable) => { + let variable_resolved = FunctionInputVariableType::resolve(table, variable)?; + + FunctionInputType::Variable(variable_resolved) + } + }) + } +} + +impl FunctionInputType { + /// + /// Return the `Identifier` containing name and span information about the current function input. + /// + pub fn identifier(&self) -> &Identifier { + match self { + FunctionInputType::InputKeyword(identifier) => identifier, + FunctionInputType::Variable(variable) => &variable.identifier, + } + } + + /// + /// Return the `Type` of the current function input. + /// + pub fn type_(&self) -> &Type { + match self { + FunctionInputType::InputKeyword(_) => unimplemented!("ERROR: input type not implemented"), + FunctionInputType::Variable(variable) => &variable.type_, + } + } + + /// + /// Return a new `FunctionInputType` from a given `FunctionInput`. + /// + /// Performs a lookup in the given symbol table if the function input contains + /// user-defined types. + /// + /// If the type of the function input is the `Self` keyword, then the given circuit identifier + /// is used as the type. + /// + pub fn from_circuit( + table: &mut SymbolTable, + unresolved: FunctionInput, + circuit_name: Identifier, + ) -> Result { + Ok(match unresolved { + FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), + FunctionInput::Variable(unresolved_function_input) => { + let function_input = + FunctionInputVariableType::from_circuit(table, unresolved_function_input, circuit_name)?; + + FunctionInputType::Variable(function_input) + } + }) + } + + /// + /// Insert the current function input type into the given symbol table. + /// + /// If the symbol table did not have this name present, `None` is returned. + /// + pub fn insert(&self, table: &mut SymbolTable) -> Option { + match self { + FunctionInputType::Variable(variable) => variable.insert(table), + FunctionInputType::InputKeyword(_identifier) => { + unimplemented!("uncomment when support for input types is added") + } + } + } +} diff --git a/types/src/types/functions/function_input_variable.rs b/types/src/types/functions/function_input_variable.rs new file mode 100644 index 0000000000..f2f0e9062a --- /dev/null +++ b/types/src/types/functions/function_input_variable.rs @@ -0,0 +1,108 @@ +// 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 . + +use crate::{Attribute, ResolvedNode, SymbolTable, Type, TypeError, VariableType}; +use leo_typed::{FunctionInputVariable, Identifier, Span}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct FunctionInputVariableType { + /// Name of function input. + pub identifier: Identifier, + + /// Type of function input. + pub type_: Type, + + /// The attributes of the function input. + pub attributes: Vec, + + /// The span of the function input. + pub span: Span, +} + +impl ResolvedNode for FunctionInputVariableType { + type Error = TypeError; + type UnresolvedNode = FunctionInputVariable; + + /// + /// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`. + /// + /// Performs a lookup in the given symbol table if the type is user-defined. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let type_ = Type::new(table, unresolved.type_, unresolved.span.clone())?; + let attributes = if unresolved.mutable { + vec![Attribute::Mutable] + } else { + vec![] + }; + + Ok(FunctionInputVariableType { + identifier: unresolved.identifier, + type_, + attributes, + span: unresolved.span, + }) + } +} + +impl FunctionInputVariableType { + /// + /// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`. + /// + /// Performs a lookup in the given symbol table if the type is user-defined. + /// + /// If the type of the function return type is the `Self` keyword, then the given circuit + /// identifier is used as the type. + /// + pub fn from_circuit( + table: &mut SymbolTable, + unresolved_function_input: FunctionInputVariable, + circuit_name: Identifier, + ) -> Result { + let type_ = Type::from_circuit( + table, + unresolved_function_input.type_, + circuit_name, + unresolved_function_input.span.clone(), + )?; + let attributes = if unresolved_function_input.mutable { + vec![Attribute::Mutable] + } else { + vec![] + }; + + Ok(FunctionInputVariableType { + identifier: unresolved_function_input.identifier, + type_, + attributes, + span: unresolved_function_input.span, + }) + } + + /// + /// Insert the current function input variable type into the given symbol table. + /// + /// If the symbol table did not have this name present, `None` is returned. + /// + pub fn insert(&self, table: &mut SymbolTable) -> Option { + let key = self.identifier.name.clone(); + let value = VariableType::from(self.clone()); + + table.insert_variable(key, value) + } +} diff --git a/types/src/types/functions/function_output.rs b/types/src/types/functions/function_output.rs new file mode 100644 index 0000000000..4ed18f9b45 --- /dev/null +++ b/types/src/types/functions/function_output.rs @@ -0,0 +1,74 @@ +// 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 . + +use crate::{ResolvedNode, SymbolTable, Type, TypeError}; + +use leo_typed::{Identifier, Span, Type as UnresolvedType}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct FunctionOutputType { + /// Type of function output. + pub type_: Type, +} + +impl ResolvedNode for FunctionOutputType { + type Error = TypeError; + /// (optional function output, span) + type UnresolvedNode = (Option, Span); + + /// + /// Return a new `FunctionOutputType` from a given optional function return type and span. + /// + /// Performs a lookup in the given symbol table if the return type is user-defined. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let function_output = unresolved.0; + let span = unresolved.1; + + let type_ = match function_output { + None => Type::Tuple(vec![]), // functions with no return value return an empty tuple + Some(type_) => Type::new(table, type_, span)?, + }; + + Ok(FunctionOutputType { type_ }) + } +} + +impl FunctionOutputType { + /// + /// Return a new `FunctionOutputType` from a given optional function return type and span. + /// + /// Performs a lookup in the given symbol table if the return type is user-defined. + /// + /// If the type of the function return type is the `Self` keyword, then the given circuit + /// identifier is used as the type. + /// + pub fn from_circuit( + table: &mut SymbolTable, + circuit_name: Identifier, + unresolved: Option, + span: Span, + ) -> Result { + let output_type = match unresolved { + None => Type::Tuple(vec![]), + Some(type_) => Type::from_circuit(table, type_, circuit_name, span)?, + }; + + Ok(FunctionOutputType { type_: output_type }) + } +} diff --git a/types/src/types/functions/mod.rs b/types/src/types/functions/mod.rs new file mode 100644 index 0000000000..fe22157837 --- /dev/null +++ b/types/src/types/functions/mod.rs @@ -0,0 +1,27 @@ +// 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 . + +pub mod function; +pub use self::function::*; + +pub mod function_input; +pub use self::function_input::*; + +pub mod function_input_variable; +pub use self::function_input_variable::*; + +pub mod function_output; +pub use self::function_output::*; diff --git a/types/src/types/mod.rs b/types/src/types/mod.rs new file mode 100644 index 0000000000..0d27661ad9 --- /dev/null +++ b/types/src/types/mod.rs @@ -0,0 +1,27 @@ +// 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 . + +pub mod circuits; +pub use self::circuits::*; + +pub mod functions; +pub use self::functions::*; + +pub mod type_; +pub use self::type_::*; + +pub mod variables; +pub use self::variables::*; diff --git a/types/src/types/type_.rs b/types/src/types/type_.rs new file mode 100644 index 0000000000..335a1eea0a --- /dev/null +++ b/types/src/types/type_.rs @@ -0,0 +1,209 @@ +// 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 . +use crate::{ResolvedNode, SymbolTable, TypeError}; +use leo_typed::{Identifier, IntegerType, Span, Type as UnresolvedType}; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// A type in a Leo program. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum Type { + // Data types + Address, + Boolean, + Field, + Group, + IntegerType(IntegerType), + + // Data type wrappers + Array(Box, Vec), + Tuple(Vec), + + // User defined types + Circuit(Identifier), + Function(Identifier), +} + +impl Type { + /// + /// Return a new type from the given unresolved type. + /// + pub fn new(table: &mut SymbolTable, type_: UnresolvedType, span: Span) -> Result { + Ok(match type_ { + UnresolvedType::Address => Type::Address, + UnresolvedType::Boolean => Type::Boolean, + UnresolvedType::Field => Type::Field, + UnresolvedType::Group => Type::Group, + UnresolvedType::IntegerType(integer) => Type::IntegerType(integer), + + UnresolvedType::Array(type_, dimensions) => { + let array_type = Type::new(table, *type_, span)?; + + Type::Array(Box::new(array_type), dimensions) + } + UnresolvedType::Tuple(types) => { + let tuple_types = types + .into_iter() + .map(|type_| Type::new(table, type_, span.clone())) + .collect::, _>>()?; + + Type::Tuple(tuple_types) + } + + UnresolvedType::Circuit(identifier) => { + // Lookup the circuit type in the symbol table + let circuit_type = table + .get_circuit(&identifier.name) + .ok_or(TypeError::undefined_circuit(identifier))?; + + Type::Circuit(circuit_type.identifier.clone()) + } + + UnresolvedType::SelfType => { + // Throw an error for using `Self` outside of a circuit + return Err(TypeError::self_not_available(span)); + } + }) + } + + /// + /// Return a new type from the given unresolved type. + /// + /// If this type is SelfType, return the circuit's type. + /// + pub fn from_circuit( + table: &mut SymbolTable, + type_: UnresolvedType, + circuit_name: Identifier, + span: Span, + ) -> Result { + Ok(match type_ { + UnresolvedType::Array(type_, dimensions) => { + let array_type = Type::from_circuit(table, *type_, circuit_name, span)?; + Type::Array(Box::new(array_type), dimensions) + } + UnresolvedType::Tuple(types) => { + let tuple_types = types + .into_iter() + .map(|type_| Type::from_circuit(table, type_, circuit_name.clone(), span.clone())) + .collect::, _>>()?; + + Type::Tuple(tuple_types) + } + UnresolvedType::SelfType => Type::Circuit(circuit_name), + // The unresolved type does not depend on the current circuit definition + unresolved => Type::new(table, unresolved, span)?, + }) + } + + /// + /// Returns `Ok` if the given expected type is `Some` and expected type == actual type. + /// + pub fn check_type(expected_option: &Option, actual: &Type, span: Span) -> Result<(), TypeError> { + if let Some(expected) = expected_option { + if expected.ne(actual) { + return Err(TypeError::mismatched_types(expected, actual, span)); + } + } + Ok(()) + } + + /// + /// Returns `Ok` if self is an expected integer type `Type::IntegerType`. + /// + pub fn check_type_integer(&self, span: Span) -> Result<(), TypeError> { + match self { + Type::IntegerType(_) => Ok(()), + // Throw mismatched type error + type_ => Err(TypeError::invalid_integer(type_, span)), + } + } + + /// + /// Returns array element type and dimensions if self is an expected array type `Type::Array`. + /// + pub fn get_type_array(&self, span: Span) -> Result<(&Type, &Vec), TypeError> { + match self { + Type::Array(element_type, dimensions) => Ok((element_type, dimensions)), + // Throw mismatched type error + type_ => Err(TypeError::invalid_array(type_, span)), + } + } + + /// + /// Returns tuple element types if self is an expected tuple type `Type::Tuple`. + /// + pub fn get_type_tuple(&self, span: Span) -> Result<&Vec, TypeError> { + match self { + Type::Tuple(types) => Ok(types), + // Throw mismatched type error + type_ => Err(TypeError::invalid_tuple(type_, span)), + } + } + + /// + /// Returns circuit identifier if self is an expected circuit type `Type::Circuit`. + /// + pub fn get_type_circuit(&self, span: Span) -> Result<&Identifier, TypeError> { + match self { + Type::Circuit(identifier) => Ok(identifier), + // Throw mismatched type error + type_ => Err(TypeError::invalid_circuit(type_, span)), + } + } + + /// + /// Returns function identifier if self is an expected function type `Type::Function`. + /// + pub fn get_type_function(&self, span: Span) -> Result<&Identifier, TypeError> { + match self { + Type::Function(identifier) => Ok(identifier), + // Throw mismatched type error + type_ => Err(TypeError::invalid_function(type_, span)), + } + } +} + +impl fmt::Display for Type { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match &self { + Type::Address => write!(f, "address"), + Type::Boolean => write!(f, "bool"), + Type::Field => write!(f, "field"), + Type::Group => write!(f, "group"), + Type::IntegerType(integer_type) => write!(f, "{}", integer_type), + + Type::Array(type_, dimensions) => { + let dimensions_string = dimensions + .iter() + .map(|dimension| format!("{}", dimension)) + .collect::>() + .join(", "); + + write!(f, "[{}; ({})]", *type_, dimensions_string) + } + Type::Tuple(tuple) => { + let tuple_string = tuple.iter().map(|x| format!("{}", x)).collect::>().join(", "); + + write!(f, "({})", tuple_string) + } + + Type::Circuit(identifier) => write!(f, "circuit {}", identifier), + Type::Function(identifier) => write!(f, "function {}", identifier), + } + } +} diff --git a/types/src/types/variables/mod.rs b/types/src/types/variables/mod.rs new file mode 100644 index 0000000000..80950ed0c3 --- /dev/null +++ b/types/src/types/variables/mod.rs @@ -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 . + +pub mod variable; +pub use self::variable::*; diff --git a/types/src/types/variables/variable.rs b/types/src/types/variables/variable.rs new file mode 100644 index 0000000000..4d30977fb7 --- /dev/null +++ b/types/src/types/variables/variable.rs @@ -0,0 +1,79 @@ +// 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 . +use crate::{Attribute, Type}; +use leo_typed::{Circuit, Function, Identifier}; + +use crate::FunctionInputVariableType; +use std::fmt; + +/// Stores variable definition details. +/// +/// This type should be added to the variable symbol table for a resolved syntax tree. +#[derive(Clone, Debug, Eq, PartialEq, Hash)] +pub struct VariableType { + pub identifier: Identifier, + pub type_: Type, + pub attributes: Vec, +} + +impl VariableType { + /// + /// Returns `true` if this variable's value can be modified. + /// + pub fn is_mutable(&self) -> bool { + self.attributes.contains(&Attribute::Mutable) + } +} + +impl From for VariableType { + fn from(value: Circuit) -> Self { + let identifier = value.circuit_name; + + VariableType { + identifier: identifier.clone(), + type_: Type::Circuit(identifier), + attributes: vec![], + } + } +} + +impl From for VariableType { + fn from(value: Function) -> Self { + let identifier = value.identifier; + + VariableType { + identifier: identifier.clone(), + type_: Type::Function(identifier.clone()), + attributes: vec![], + } + } +} + +impl From for VariableType { + fn from(value: FunctionInputVariableType) -> Self { + VariableType { + identifier: value.identifier, + type_: value.type_, + attributes: value.attributes, + } + } +} + +impl fmt::Display for VariableType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.identifier) + } +} From a66cc3afdaa574e7d5308caa01017deef77f1bfb Mon Sep 17 00:00:00 2001 From: collin Date: Sun, 11 Oct 2020 12:56:01 -0700 Subject: [PATCH 011/139] deprecate resolved node trait --- types/src/lib.rs | 22 ------------------- types/src/types/circuits/circuit.rs | 2 +- types/src/types/functions/function.rs | 19 ++++++---------- types/src/types/functions/function_input.rs | 15 +++++-------- .../functions/function_input_variable.rs | 13 ++++------- types/src/types/functions/function_output.rs | 21 +++++++----------- types/src/types/type_.rs | 6 ++--- 7 files changed, 28 insertions(+), 70 deletions(-) diff --git a/types/src/lib.rs b/types/src/lib.rs index 28ee6ddf03..2166af9a94 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -22,25 +22,3 @@ pub use self::errors::*; pub mod types; pub use self::types::*; - -/// A resolved node in an abstract syntax tree (AST). -/// -/// Resolved nodes can be any function, statement, expression, type, etc. in an AST. -/// Resolved nodes should not contain any illegal types. -/// Resolved nodes should not contain any implicit types. -pub trait ResolvedNode { - /// The expected error type if the type resolution fails. - type Error; - - /// The unresolved AST node that is being resolved. - type UnresolvedNode; - - /// - /// Returns a resolved AST representation given an unresolved AST representation. - /// - /// User-defined types are looked up using the given symbol table. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result - where - Self: std::marker::Sized; -} diff --git a/types/src/types/circuits/circuit.rs b/types/src/types/circuits/circuit.rs index 8d1df94a91..f20f9dc053 100644 --- a/types/src/types/circuits/circuit.rs +++ b/types/src/types/circuits/circuit.rs @@ -63,7 +63,7 @@ impl ResolvedNode for CircuitType { match member { CircuitMember::CircuitVariable(is_mutable, variable_identifier, type_) => { // Resolve the type of the circuit member variable. - let type_ = Type::from_circuit( + let type_ = Type::new_from_circuit( table, type_, circuit_identifier.clone(), diff --git a/types/src/types/functions/function.rs b/types/src/types/functions/function.rs index 3a3d98475a..4f2657baf8 100644 --- a/types/src/types/functions/function.rs +++ b/types/src/types/functions/function.rs @@ -40,27 +40,24 @@ pub struct FunctionType { pub output: FunctionOutputType, } -impl ResolvedNode for FunctionType { - type Error = TypeError; - type UnresolvedNode = Function; - +impl FunctionType { /// /// Return a new `FunctionType` from a given `Function` definition. /// /// Performs a lookup in the given symbol table if the function definition contains /// user-defined types. /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + pub fn new(table: &mut SymbolTable, unresolved: Function) -> Result { let mut inputs_resolved = vec![]; // Type check function inputs for input in unresolved.input { - let input = FunctionInputType::resolve(table, input)?; + let input = FunctionInputType::new(table, input)?; inputs_resolved.push(input); } // Type check function output - let output = FunctionOutputType::resolve(table, (unresolved.output, unresolved.span))?; + let output = FunctionOutputType::new(table, unresolved.output, unresolved.span)?; Ok(FunctionType { identifier: unresolved.identifier, @@ -68,9 +65,7 @@ impl ResolvedNode for FunctionType { output, }) } -} -impl FunctionType { /// /// Resolve a function definition and insert it into the given symbol table. /// @@ -79,7 +74,7 @@ impl FunctionType { let function_identifier = unresolved_function.identifier.clone(); // Resolve the function definition into a function type. - let function = Self::resolve(table, unresolved_function)?; + let function = Self::new(table, unresolved_function)?; // Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table. table.insert_function(function_identifier, function); @@ -106,12 +101,12 @@ impl FunctionType { // Type check function inputs. for unresolved_input in unresolved_function.input { - let input = FunctionInputType::from_circuit(table, unresolved_input, circuit_name.clone())?; + let input = FunctionInputType::new_from_circuit(table, unresolved_input, circuit_name.clone())?; inputs.push(input); } // Type check function output. - let output = FunctionOutputType::from_circuit( + let output = FunctionOutputType::new_from_circuit( table, circuit_name.clone(), unresolved_function.output, diff --git a/types/src/types/functions/function_input.rs b/types/src/types/functions/function_input.rs index 74df8ede4c..08657d6f06 100644 --- a/types/src/types/functions/function_input.rs +++ b/types/src/types/functions/function_input.rs @@ -25,29 +25,24 @@ pub enum FunctionInputType { Variable(FunctionInputVariableType), } -impl ResolvedNode for FunctionInputType { - type Error = TypeError; - type UnresolvedNode = FunctionInput; - +impl FunctionInputType { /// /// Return a new `FunctionInputType` from a given `FunctionInput`. /// /// Performs a lookup in the given symbol table if the function input contains /// user-defined types. /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + pub fn new(table: &mut SymbolTable, unresolved: FunctionInput) -> Result { Ok(match unresolved { FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), FunctionInput::Variable(variable) => { - let variable_resolved = FunctionInputVariableType::resolve(table, variable)?; + let variable_resolved = FunctionInputVariableType::new(table, variable)?; FunctionInputType::Variable(variable_resolved) } }) } -} -impl FunctionInputType { /// /// Return the `Identifier` containing name and span information about the current function input. /// @@ -77,7 +72,7 @@ impl FunctionInputType { /// If the type of the function input is the `Self` keyword, then the given circuit identifier /// is used as the type. /// - pub fn from_circuit( + pub fn new_from_circuit( table: &mut SymbolTable, unresolved: FunctionInput, circuit_name: Identifier, @@ -86,7 +81,7 @@ impl FunctionInputType { FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), FunctionInput::Variable(unresolved_function_input) => { let function_input = - FunctionInputVariableType::from_circuit(table, unresolved_function_input, circuit_name)?; + FunctionInputVariableType::new_from_circuit(table, unresolved_function_input, circuit_name)?; FunctionInputType::Variable(function_input) } diff --git a/types/src/types/functions/function_input_variable.rs b/types/src/types/functions/function_input_variable.rs index f2f0e9062a..0d02e8b329 100644 --- a/types/src/types/functions/function_input_variable.rs +++ b/types/src/types/functions/function_input_variable.rs @@ -34,16 +34,13 @@ pub struct FunctionInputVariableType { pub span: Span, } -impl ResolvedNode for FunctionInputVariableType { - type Error = TypeError; - type UnresolvedNode = FunctionInputVariable; - +impl FunctionInputVariableType { /// /// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`. /// /// Performs a lookup in the given symbol table if the type is user-defined. /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + pub fn new(table: &mut SymbolTable, unresolved: FunctionInputVariable) -> Result { let type_ = Type::new(table, unresolved.type_, unresolved.span.clone())?; let attributes = if unresolved.mutable { vec![Attribute::Mutable] @@ -58,9 +55,7 @@ impl ResolvedNode for FunctionInputVariableType { span: unresolved.span, }) } -} -impl FunctionInputVariableType { /// /// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`. /// @@ -69,12 +64,12 @@ impl FunctionInputVariableType { /// If the type of the function return type is the `Self` keyword, then the given circuit /// identifier is used as the type. /// - pub fn from_circuit( + pub fn new_from_circuit( table: &mut SymbolTable, unresolved_function_input: FunctionInputVariable, circuit_name: Identifier, ) -> Result { - let type_ = Type::from_circuit( + let type_ = Type::new_from_circuit( table, unresolved_function_input.type_, circuit_name, diff --git a/types/src/types/functions/function_output.rs b/types/src/types/functions/function_output.rs index 4ed18f9b45..3d06cf69ed 100644 --- a/types/src/types/functions/function_output.rs +++ b/types/src/types/functions/function_output.rs @@ -26,20 +26,17 @@ pub struct FunctionOutputType { pub type_: Type, } -impl ResolvedNode for FunctionOutputType { - type Error = TypeError; - /// (optional function output, span) - type UnresolvedNode = (Option, Span); - +impl FunctionOutputType { /// /// Return a new `FunctionOutputType` from a given optional function return type and span. /// /// Performs a lookup in the given symbol table if the return type is user-defined. /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let function_output = unresolved.0; - let span = unresolved.1; - + pub(crate) fn new( + table: &mut SymbolTable, + function_output: Option, + span: Span, + ) -> Result { let type_ = match function_output { None => Type::Tuple(vec![]), // functions with no return value return an empty tuple Some(type_) => Type::new(table, type_, span)?, @@ -47,9 +44,7 @@ impl ResolvedNode for FunctionOutputType { Ok(FunctionOutputType { type_ }) } -} -impl FunctionOutputType { /// /// Return a new `FunctionOutputType` from a given optional function return type and span. /// @@ -58,7 +53,7 @@ impl FunctionOutputType { /// If the type of the function return type is the `Self` keyword, then the given circuit /// identifier is used as the type. /// - pub fn from_circuit( + pub fn new_from_circuit( table: &mut SymbolTable, circuit_name: Identifier, unresolved: Option, @@ -66,7 +61,7 @@ impl FunctionOutputType { ) -> Result { let output_type = match unresolved { None => Type::Tuple(vec![]), - Some(type_) => Type::from_circuit(table, type_, circuit_name, span)?, + Some(type_) => Type::new_from_circuit(table, type_, circuit_name, span)?, }; Ok(FunctionOutputType { type_: output_type }) diff --git a/types/src/types/type_.rs b/types/src/types/type_.rs index 335a1eea0a..788713644b 100644 --- a/types/src/types/type_.rs +++ b/types/src/types/type_.rs @@ -85,7 +85,7 @@ impl Type { /// /// If this type is SelfType, return the circuit's type. /// - pub fn from_circuit( + pub fn new_from_circuit( table: &mut SymbolTable, type_: UnresolvedType, circuit_name: Identifier, @@ -93,13 +93,13 @@ impl Type { ) -> Result { Ok(match type_ { UnresolvedType::Array(type_, dimensions) => { - let array_type = Type::from_circuit(table, *type_, circuit_name, span)?; + let array_type = Type::new_from_circuit(table, *type_, circuit_name, span)?; Type::Array(Box::new(array_type), dimensions) } UnresolvedType::Tuple(types) => { let tuple_types = types .into_iter() - .map(|type_| Type::from_circuit(table, type_, circuit_name.clone(), span.clone())) + .map(|type_| Type::new_from_circuit(table, type_, circuit_name.clone(), span.clone())) .collect::, _>>()?; Type::Tuple(tuple_types) From e0750158f5a7b605480de003dfd6dce099518fe6 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 12 Oct 2020 11:33:42 -0700 Subject: [PATCH 012/139] add type variable --- types/src/attributes/attribute.rs | 24 +++++++++++++++ .../{types/variables => attributes}/mod.rs | 4 +-- types/src/lib.rs | 3 ++ types/src/types/functions/function_input.rs | 4 +-- .../functions/function_input_variable.rs | 6 ++-- types/src/types/mod.rs | 7 +++-- types/src/types/parameters/mod.rs | 18 +++++++++++ .../variable.rs => parameters/parameter.rs} | 18 +++++------ types/src/types/type_.rs | 6 +++- types/src/types/type_variable.rs | 30 +++++++++++++++++++ 10 files changed, 101 insertions(+), 19 deletions(-) create mode 100644 types/src/attributes/attribute.rs rename types/src/{types/variables => attributes}/mod.rs (94%) create mode 100644 types/src/types/parameters/mod.rs rename types/src/types/{variables/variable.rs => parameters/parameter.rs} (87%) create mode 100644 types/src/types/type_variable.rs diff --git a/types/src/attributes/attribute.rs b/types/src/attributes/attribute.rs new file mode 100644 index 0000000000..0fa7153b69 --- /dev/null +++ b/types/src/attributes/attribute.rs @@ -0,0 +1,24 @@ +// 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 . + +use serde::{Deserialize, Serialize}; + +/// Indicates that a program variable has additional functionality. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum Attribute { + Mutable, + Static, +} diff --git a/types/src/types/variables/mod.rs b/types/src/attributes/mod.rs similarity index 94% rename from types/src/types/variables/mod.rs rename to types/src/attributes/mod.rs index 80950ed0c3..f8d19f5a62 100644 --- a/types/src/types/variables/mod.rs +++ b/types/src/attributes/mod.rs @@ -14,5 +14,5 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -pub mod variable; -pub use self::variable::*; +pub mod attribute; +pub use self::attribute::*; diff --git a/types/src/lib.rs b/types/src/lib.rs index 2166af9a94..d4f12a3f45 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -17,6 +17,9 @@ #[macro_use] extern crate thiserror; +pub mod attributes; +pub use self::attributes::*; + pub mod errors; pub use self::errors::*; diff --git a/types/src/types/functions/function_input.rs b/types/src/types/functions/function_input.rs index 08657d6f06..1a12ef178b 100644 --- a/types/src/types/functions/function_input.rs +++ b/types/src/types/functions/function_input.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{FunctionInputVariableType, ResolvedNode, SymbolTable, Type, TypeError, VariableType}; +use crate::{FunctionInputVariableType, ParameterType, ResolvedNode, SymbolTable, Type, TypeError}; use leo_typed::{FunctionInput, Identifier}; use serde::{Deserialize, Serialize}; @@ -93,7 +93,7 @@ impl FunctionInputType { /// /// If the symbol table did not have this name present, `None` is returned. /// - pub fn insert(&self, table: &mut SymbolTable) -> Option { + pub fn insert(&self, table: &mut SymbolTable) -> Option { match self { FunctionInputType::Variable(variable) => variable.insert(table), FunctionInputType::InputKeyword(_identifier) => { diff --git a/types/src/types/functions/function_input_variable.rs b/types/src/types/functions/function_input_variable.rs index 0d02e8b329..3df2e5bf36 100644 --- a/types/src/types/functions/function_input_variable.rs +++ b/types/src/types/functions/function_input_variable.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Attribute, ResolvedNode, SymbolTable, Type, TypeError, VariableType}; +use crate::{Attribute, ParameterType, ResolvedNode, SymbolTable, Type, TypeError}; use leo_typed::{FunctionInputVariable, Identifier, Span}; use serde::{Deserialize, Serialize}; @@ -94,9 +94,9 @@ impl FunctionInputVariableType { /// /// If the symbol table did not have this name present, `None` is returned. /// - pub fn insert(&self, table: &mut SymbolTable) -> Option { + pub fn insert(&self, table: &mut SymbolTable) -> Option { let key = self.identifier.name.clone(); - let value = VariableType::from(self.clone()); + let value = ParameterType::from(self.clone()); table.insert_variable(key, value) } diff --git a/types/src/types/mod.rs b/types/src/types/mod.rs index 0d27661ad9..90ec0339ce 100644 --- a/types/src/types/mod.rs +++ b/types/src/types/mod.rs @@ -23,5 +23,8 @@ pub use self::functions::*; pub mod type_; pub use self::type_::*; -pub mod variables; -pub use self::variables::*; +pub mod type_variable; +pub use self::type_variable::*; + +pub mod parameters; +pub use self::parameters::*; diff --git a/types/src/types/parameters/mod.rs b/types/src/types/parameters/mod.rs new file mode 100644 index 0000000000..2930d7be45 --- /dev/null +++ b/types/src/types/parameters/mod.rs @@ -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 . + +pub mod parameter; +pub use self::parameter::*; diff --git a/types/src/types/variables/variable.rs b/types/src/types/parameters/parameter.rs similarity index 87% rename from types/src/types/variables/variable.rs rename to types/src/types/parameters/parameter.rs index 4d30977fb7..9c269c926b 100644 --- a/types/src/types/variables/variable.rs +++ b/types/src/types/parameters/parameter.rs @@ -23,13 +23,13 @@ use std::fmt; /// /// This type should be added to the variable symbol table for a resolved syntax tree. #[derive(Clone, Debug, Eq, PartialEq, Hash)] -pub struct VariableType { +pub struct ParameterType { pub identifier: Identifier, pub type_: Type, pub attributes: Vec, } -impl VariableType { +impl ParameterType { /// /// Returns `true` if this variable's value can be modified. /// @@ -38,11 +38,11 @@ impl VariableType { } } -impl From for VariableType { +impl From for ParameterType { fn from(value: Circuit) -> Self { let identifier = value.circuit_name; - VariableType { + ParameterType { identifier: identifier.clone(), type_: Type::Circuit(identifier), attributes: vec![], @@ -50,11 +50,11 @@ impl From for VariableType { } } -impl From for VariableType { +impl From for ParameterType { fn from(value: Function) -> Self { let identifier = value.identifier; - VariableType { + ParameterType { identifier: identifier.clone(), type_: Type::Function(identifier.clone()), attributes: vec![], @@ -62,9 +62,9 @@ impl From for VariableType { } } -impl From for VariableType { +impl From for ParameterType { fn from(value: FunctionInputVariableType) -> Self { - VariableType { + ParameterType { identifier: value.identifier, type_: value.type_, attributes: value.attributes, @@ -72,7 +72,7 @@ impl From for VariableType { } } -impl fmt::Display for VariableType { +impl fmt::Display for ParameterType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.identifier) } diff --git a/types/src/types/type_.rs b/types/src/types/type_.rs index 788713644b..4de97f3a01 100644 --- a/types/src/types/type_.rs +++ b/types/src/types/type_.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ResolvedNode, SymbolTable, TypeError}; +use crate::{ResolvedNode, SymbolTable, TypeError, TypeVariable}; use leo_typed::{Identifier, IntegerType, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; @@ -36,6 +36,9 @@ pub enum Type { // User defined types Circuit(Identifier), Function(Identifier), + + // Unknown type variables + TypeVariable(TypeVariable), } impl Type { @@ -204,6 +207,7 @@ impl fmt::Display for Type { Type::Circuit(identifier) => write!(f, "circuit {}", identifier), Type::Function(identifier) => write!(f, "function {}", identifier), + Type::TypeVariable(type_variable) => write!(f, "{}", type_variable), } } } diff --git a/types/src/types/type_variable.rs b/types/src/types/type_variable.rs new file mode 100644 index 0000000000..cc1c0b1f5c --- /dev/null +++ b/types/src/types/type_variable.rs @@ -0,0 +1,30 @@ +// 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 . + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// An unknown type in a Leo program. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct TypeVariable { + name: String, +} + +impl fmt::Display for TypeVariable { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.name) + } +} From d29d01f4ffeaf833623c7034d681562faed1ce16 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 12 Oct 2020 12:32:29 -0700 Subject: [PATCH 013/139] move types into new static-check module --- Cargo.lock | 17 +- Cargo.toml | 7 +- dynamic-check/Cargo.toml | 4 +- dynamic-check/src/dynamic_check.rs | 6 +- dynamic-check/tests/mod.rs | 4 +- {symbol-table => static-check}/Cargo.toml | 2 +- .../src/attributes/attribute.rs | 0 .../src/attributes/mod.rs | 0 .../src/errors/mod.rs | 0 .../src/errors/symbol_table.rs | 0 {types => static-check}/src/errors/type_.rs | 0 {types => static-check}/src/lib.rs | 3 + .../src/symbol_table.rs | 51 ++-- .../src/types/circuits/circuit.rs | 10 +- .../src/types/circuits/circuit_function.rs | 0 .../src/types/circuits/circuit_variable.rs | 0 .../src/types/circuits/mod.rs | 0 .../src/types/functions/function.rs | 37 ++- .../src/types/functions/function_input.rs | 38 +-- .../functions/function_input_variable.rs | 8 +- .../src/types/functions/function_output.rs | 6 +- .../src/types/functions/mod.rs | 0 {types => static-check}/src/types/mod.rs | 0 .../src/types/parameters/mod.rs | 0 .../src/types/parameters/parameter.rs | 0 {types => static-check}/src/types/type_.rs | 6 +- .../src/types/type_variable.rs | 0 {symbol-table => static-check}/tests/mod.rs | 8 +- .../tests/symbol_table/duplicate_circuit.leo | 0 .../tests/symbol_table/duplicate_function.leo | 0 .../tests/symbol_table/mod.rs | 0 .../tests/symbol_table/self_not_available.leo | 0 .../tests/symbol_table/undefined_circuit.leo | 0 symbol-table/src/errors/type_.rs | 141 ----------- symbol-table/src/lib.rs | 52 ----- symbol-table/src/types/circuits/circuit.rs | 144 ------------ .../src/types/circuits/circuit_variable.rs | 30 --- symbol-table/src/types/functions/function.rs | 127 ---------- .../src/types/functions/function_input.rs | 109 --------- .../functions/function_input_variable.rs | 108 --------- .../src/types/functions/function_output.rs | 74 ------ symbol-table/src/types/mod.rs | 27 --- symbol-table/src/types/type_.rs | 221 ------------------ symbol-table/src/types/variables/mod.rs | 18 -- symbol-table/src/types/variables/variable.rs | 79 ------- types/Cargo.toml | 36 --- types/src/attributes/attribute.rs | 24 -- types/src/attributes/mod.rs | 18 -- types/src/errors/mod.rs | 21 -- types/src/errors/symbol_table.rs | 67 ------ types/src/types/circuits/circuit_function.rs | 27 --- types/src/types/circuits/mod.rs | 24 -- types/src/types/functions/mod.rs | 27 --- 53 files changed, 95 insertions(+), 1486 deletions(-) rename {symbol-table => static-check}/Cargo.toml (96%) rename {symbol-table => static-check}/src/attributes/attribute.rs (100%) rename {symbol-table => static-check}/src/attributes/mod.rs (100%) rename {symbol-table => static-check}/src/errors/mod.rs (100%) rename {symbol-table => static-check}/src/errors/symbol_table.rs (100%) rename {types => static-check}/src/errors/type_.rs (100%) rename {types => static-check}/src/lib.rs (94%) rename {symbol-table => static-check}/src/symbol_table.rs (87%) rename {types => static-check}/src/types/circuits/circuit.rs (95%) rename {symbol-table => static-check}/src/types/circuits/circuit_function.rs (100%) rename {types => static-check}/src/types/circuits/circuit_variable.rs (100%) rename {symbol-table => static-check}/src/types/circuits/mod.rs (100%) rename {types => static-check}/src/types/functions/function.rs (96%) rename {types => static-check}/src/types/functions/function_input.rs (94%) rename {types => static-check}/src/types/functions/function_input_variable.rs (92%) rename {types => static-check}/src/types/functions/function_output.rs (95%) rename {symbol-table => static-check}/src/types/functions/mod.rs (100%) rename {types => static-check}/src/types/mod.rs (100%) rename {types => static-check}/src/types/parameters/mod.rs (100%) rename {types => static-check}/src/types/parameters/parameter.rs (100%) rename {types => static-check}/src/types/type_.rs (97%) rename {types => static-check}/src/types/type_variable.rs (100%) rename {symbol-table => static-check}/tests/mod.rs (93%) rename {symbol-table => static-check}/tests/symbol_table/duplicate_circuit.leo (100%) rename {symbol-table => static-check}/tests/symbol_table/duplicate_function.leo (100%) rename {symbol-table => static-check}/tests/symbol_table/mod.rs (100%) rename {symbol-table => static-check}/tests/symbol_table/self_not_available.leo (100%) rename {symbol-table => static-check}/tests/symbol_table/undefined_circuit.leo (100%) delete mode 100644 symbol-table/src/errors/type_.rs delete mode 100644 symbol-table/src/lib.rs delete mode 100644 symbol-table/src/types/circuits/circuit.rs delete mode 100644 symbol-table/src/types/circuits/circuit_variable.rs delete mode 100644 symbol-table/src/types/functions/function.rs delete mode 100644 symbol-table/src/types/functions/function_input.rs delete mode 100644 symbol-table/src/types/functions/function_input_variable.rs delete mode 100644 symbol-table/src/types/functions/function_output.rs delete mode 100644 symbol-table/src/types/mod.rs delete mode 100644 symbol-table/src/types/type_.rs delete mode 100644 symbol-table/src/types/variables/mod.rs delete mode 100644 symbol-table/src/types/variables/variable.rs delete mode 100644 types/Cargo.toml delete mode 100644 types/src/attributes/attribute.rs delete mode 100644 types/src/attributes/mod.rs delete mode 100644 types/src/errors/mod.rs delete mode 100644 types/src/errors/symbol_table.rs delete mode 100644 types/src/types/circuits/circuit_function.rs delete mode 100644 types/src/types/circuits/mod.rs delete mode 100644 types/src/types/functions/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 553a4f3faf..c0042835bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1282,7 +1282,7 @@ version = "1.0.3" dependencies = [ "leo-ast", "leo-imports", - "leo-symbol-table", + "leo-static-check", "leo-typed", "serde", "thiserror", @@ -1347,7 +1347,7 @@ dependencies = [ "leo-input", "leo-package", "leo-state", - "leo-symbol-table", + "leo-static-check", "notify", "num-bigint", "rand", @@ -1408,7 +1408,7 @@ dependencies = [ ] [[package]] -name = "leo-symbol-table" +name = "leo-static-check" version = "1.0.3" dependencies = [ "leo-ast", @@ -1432,17 +1432,6 @@ dependencies = [ "snarkos-models", ] -[[package]] -name = "leo-types" -version = "1.0.3" -dependencies = [ - "leo-ast", - "leo-imports", - "leo-typed", - "serde", - "thiserror", -] - [[package]] name = "libc" version = "0.2.76" diff --git a/Cargo.toml b/Cargo.toml index 45431d65d8..071be4dddc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,9 +36,8 @@ members = [ "linter", "package", "typed", - "types", "state", - "symbol-table", + "static-check", ] [dependencies.leo-compiler] @@ -73,8 +72,8 @@ version = "1.0.3" path = "./state" version = "1.0.3" -[dependencies.leo-symbol-table] -path = "./symbol-table" +[dependencies.leo-static-check] +path = "./static-check" version = "1.0.3" [dependencies.snarkos-algorithms] diff --git a/dynamic-check/Cargo.toml b/dynamic-check/Cargo.toml index c00cbf8219..98e8994f27 100644 --- a/dynamic-check/Cargo.toml +++ b/dynamic-check/Cargo.toml @@ -25,8 +25,8 @@ version = "1.0.3" path = "../imports" version = "1.0.3" -[dependencies.leo-symbol-table] -path = "../symbol-table" +[dependencies.leo-static-check] +path = "../static-check" version = "1.0.3" [dependencies.leo-typed] diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 4a3f68fb1e..24c21d1db8 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -16,7 +16,7 @@ use leo_typed::{Expression, Function, Identifier, Program, Span, Statement}; -use leo_symbol_table::{ExtendedType, FunctionType, SymbolTable}; +use leo_static_check::{FunctionType, SymbolTable, Type}; use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -235,7 +235,7 @@ impl TypeAssertion { /// A `Type` or a `TypeVariable` in a `TypeAssertion`. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub enum TypeElement { - Type(ExtendedType), + Type(Type), Variable(TypeVariable), } @@ -256,7 +256,7 @@ impl TypeElement { /// Return a boolean `TypeElement`. /// pub fn boolean() -> Self { - TypeElement::Type(ExtendedType::Boolean) + TypeElement::Type(Type::Boolean) } /// diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 21c3928b25..7db75c9c6f 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -17,7 +17,7 @@ use leo_ast::LeoAst; use leo_dynamic_check::DynamicCheck; -use leo_symbol_table::SymbolTable; +use leo_symbol_table::OldSymbolTable; use leo_typed::LeoTypedAst; use std::path::PathBuf; @@ -45,7 +45,7 @@ impl TestDynamicCheck { let program = typed.into_repr(); // Create symbol table. - let mut symbol_table = SymbolTable::new(None); + let mut symbol_table = OldSymbolTable::new(None); // Load symbols into symbol table. symbol_table.pass_one(&program).unwrap(); diff --git a/symbol-table/Cargo.toml b/static-check/Cargo.toml similarity index 96% rename from symbol-table/Cargo.toml rename to static-check/Cargo.toml index 3e03c9ebe2..b1d204b109 100644 --- a/symbol-table/Cargo.toml +++ b/static-check/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "leo-symbol-table" +name = "leo-static-check" version = "1.0.3" authors = [ "The Aleo Team " ] description = "Stores user-defined variables during type resolution" diff --git a/symbol-table/src/attributes/attribute.rs b/static-check/src/attributes/attribute.rs similarity index 100% rename from symbol-table/src/attributes/attribute.rs rename to static-check/src/attributes/attribute.rs diff --git a/symbol-table/src/attributes/mod.rs b/static-check/src/attributes/mod.rs similarity index 100% rename from symbol-table/src/attributes/mod.rs rename to static-check/src/attributes/mod.rs diff --git a/symbol-table/src/errors/mod.rs b/static-check/src/errors/mod.rs similarity index 100% rename from symbol-table/src/errors/mod.rs rename to static-check/src/errors/mod.rs diff --git a/symbol-table/src/errors/symbol_table.rs b/static-check/src/errors/symbol_table.rs similarity index 100% rename from symbol-table/src/errors/symbol_table.rs rename to static-check/src/errors/symbol_table.rs diff --git a/types/src/errors/type_.rs b/static-check/src/errors/type_.rs similarity index 100% rename from types/src/errors/type_.rs rename to static-check/src/errors/type_.rs diff --git a/types/src/lib.rs b/static-check/src/lib.rs similarity index 94% rename from types/src/lib.rs rename to static-check/src/lib.rs index d4f12a3f45..b40c37f248 100644 --- a/types/src/lib.rs +++ b/static-check/src/lib.rs @@ -23,5 +23,8 @@ pub use self::attributes::*; pub mod errors; pub use self::errors::*; +pub mod symbol_table; +pub use self::symbol_table::*; + pub mod types; pub use self::types::*; diff --git a/symbol-table/src/symbol_table.rs b/static-check/src/symbol_table.rs similarity index 87% rename from symbol-table/src/symbol_table.rs rename to static-check/src/symbol_table.rs index 452269e8fb..96b18b493b 100644 --- a/symbol-table/src/symbol_table.rs +++ b/static-check/src/symbol_table.rs @@ -14,14 +14,13 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{CircuitType, FunctionType, ResolvedNode, SymbolTableError, VariableType}; +use crate::{CircuitType, FunctionType, ParameterType, SymbolTableError}; use leo_typed::{Circuit, Function, Identifier, Program as UnresolvedProgram}; use leo_imports::ImportParser; use std::collections::HashMap; -/// A abstract data type that tracks the current bindings of identifier -/// names to types in a Leo program. +/// A abstract data type that builds symbol tables for functions and circuits /// /// A symbol table has access to all function and circuit names in its /// parent's symbol table. @@ -29,13 +28,13 @@ use std::collections::HashMap; /// Children cannot access names in another sibling's symbol table. #[derive(Clone)] pub struct SymbolTable { - /// Maps variable name -> variable type. - variables: HashMap, + /// Maps name -> parameter type. + names: HashMap, /// Maps circuit name -> circuit type. circuits: HashMap, - ///Maps function name -> function type. + /// Maps function name -> function type. functions: HashMap, /// The parent of this symbol table. @@ -48,7 +47,7 @@ impl SymbolTable { /// pub fn new(parent: Option>) -> Self { SymbolTable { - variables: HashMap::new(), + names: HashMap::new(), circuits: HashMap::new(), functions: HashMap::new(), parent, @@ -56,14 +55,14 @@ impl SymbolTable { } /// - /// Insert a variable into the symbol table from a given name and variable type. + /// Insert a function or circuit name into the symbol table from a given name and variable type. /// /// If the symbol table did not have this name present, `None` is returned. /// If the symbol table did have this name present, the variable type is updated, and the old /// variable type is returned. /// - pub fn insert_variable(&mut self, name: String, variable_type: VariableType) -> Option { - self.variables.insert(name, variable_type) + pub fn insert_name(&mut self, name: String, variable_type: ParameterType) -> Option { + self.names.insert(name, variable_type) } /// @@ -90,18 +89,18 @@ impl SymbolTable { self.functions.insert(identifier.name, function_type) } - /// - /// Returns a reference to the variable type corresponding to the name. - /// - /// If the symbol table did not have this name present, then `None` is returned. - /// - pub fn get_variable(&self, name: &String) -> Option<&VariableType> { - // Lookup variable name in symbol table. - match self.variables.get(name) { - Some(variable) => Some(variable), - None => None, - } - } + // /// + // /// Returns a reference to the variable type corresponding to the name. + // /// + // /// If the symbol table did not have this name present, then `None` is returned. + // /// + // pub fn get_variable(&self, name: &String) -> Option<&ParameterType> { + // // Lookup variable name in symbol table. + // match self.names.get(name) { + // Some(variable) => Some(variable), + // None => None, + // } + // } /// /// Returns a reference to the circuit type corresponding to the name. @@ -163,7 +162,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_variable(identifier.to_string(), VariableType::from(circuit.clone())); + let duplicate = self.insert_name(identifier.to_string(), ParameterType::from(circuit.clone())); // Check that the circuit name is unique. if duplicate.is_some() { @@ -190,7 +189,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_variable(identifier.to_string(), VariableType::from(function.clone())); + let duplicate = self.insert_name(identifier.to_string(), ParameterType::from(function.clone())); // Check that the function name is unique. if duplicate.is_some() { @@ -221,7 +220,7 @@ impl SymbolTable { let identifier = circuit.circuit_name.clone(); // Resolve unknown types in the unresolved circuit definition. - let circuit_type = CircuitType::resolve(self, circuit.clone())?; + let circuit_type = CircuitType::new(self, circuit.clone())?; // Attempt to insert the circuit definition into the symbol table. self.insert_circuit(identifier, circuit_type); @@ -247,7 +246,7 @@ impl SymbolTable { let identifier = function.identifier.clone(); // Resolve unknown types in the unresolved function definition. - let function_type = FunctionType::resolve(self, function.clone())?; + let function_type = FunctionType::new(&self, function.clone())?; // Attempt to insert the function definition into the symbol table. self.insert_function(identifier, function_type); diff --git a/types/src/types/circuits/circuit.rs b/static-check/src/types/circuits/circuit.rs similarity index 95% rename from types/src/types/circuits/circuit.rs rename to static-check/src/types/circuits/circuit.rs index f20f9dc053..eb191ceb96 100644 --- a/types/src/types/circuits/circuit.rs +++ b/static-check/src/types/circuits/circuit.rs @@ -18,7 +18,6 @@ use crate::{ types::circuits::{CircuitFunctionType, CircuitVariableType}, Attribute, FunctionType, - ResolvedNode, SymbolTable, Type, TypeError, @@ -43,17 +42,14 @@ pub struct CircuitType { pub functions: Vec, } -impl ResolvedNode for CircuitType { - type Error = TypeError; - type UnresolvedNode = Circuit; - +impl CircuitType { /// /// Return a new `CircuitType` from a given `Circuit` definition. /// /// Performs a lookup in the given symbol table if the circuit definition contains /// user-defined types. /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + pub fn new(table: &SymbolTable, unresolved: Circuit) -> Result { let circuit_identifier = unresolved.circuit_name; let mut variables = vec![]; let mut functions = vec![]; @@ -109,9 +105,7 @@ impl ResolvedNode for CircuitType { functions, }) } -} -impl CircuitType { /// /// Returns the type of a circuit member. /// diff --git a/symbol-table/src/types/circuits/circuit_function.rs b/static-check/src/types/circuits/circuit_function.rs similarity index 100% rename from symbol-table/src/types/circuits/circuit_function.rs rename to static-check/src/types/circuits/circuit_function.rs diff --git a/types/src/types/circuits/circuit_variable.rs b/static-check/src/types/circuits/circuit_variable.rs similarity index 100% rename from types/src/types/circuits/circuit_variable.rs rename to static-check/src/types/circuits/circuit_variable.rs diff --git a/symbol-table/src/types/circuits/mod.rs b/static-check/src/types/circuits/mod.rs similarity index 100% rename from symbol-table/src/types/circuits/mod.rs rename to static-check/src/types/circuits/mod.rs diff --git a/types/src/types/functions/function.rs b/static-check/src/types/functions/function.rs similarity index 96% rename from types/src/types/functions/function.rs rename to static-check/src/types/functions/function.rs index 4f2657baf8..31465bfdd0 100644 --- a/types/src/types/functions/function.rs +++ b/static-check/src/types/functions/function.rs @@ -16,7 +16,6 @@ use crate::{ types::functions::{FunctionInputType, FunctionOutputType}, - ResolvedNode, SymbolTable, TypeError, }; @@ -47,7 +46,7 @@ impl FunctionType { /// Performs a lookup in the given symbol table if the function definition contains /// user-defined types. /// - pub fn new(table: &mut SymbolTable, unresolved: Function) -> Result { + pub fn new(table: &SymbolTable, unresolved: Function) -> Result { let mut inputs_resolved = vec![]; // Type check function inputs @@ -66,22 +65,6 @@ impl FunctionType { }) } - /// - /// Resolve a function definition and insert it into the given symbol table. - /// - pub fn insert_definition(table: &mut SymbolTable, unresolved_function: Function) -> Result<(), TypeError> { - // Get the identifier of the function. - let function_identifier = unresolved_function.identifier.clone(); - - // Resolve the function definition into a function type. - let function = Self::new(table, unresolved_function)?; - - // Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table. - table.insert_function(function_identifier, function); - - Ok(()) - } - /// /// Return a new `FunctionType` from a given `Function` definition. /// @@ -92,7 +75,7 @@ impl FunctionType { /// is used as the type. /// pub fn from_circuit( - table: &mut SymbolTable, + table: &SymbolTable, circuit_name: Identifier, unresolved_function: Function, ) -> Result { @@ -119,4 +102,20 @@ impl FunctionType { output, }) } + + /// + /// Resolve a function definition and insert it into the given symbol table. + /// + pub fn insert_definition(table: &mut SymbolTable, unresolved_function: Function) -> Result<(), TypeError> { + // Get the identifier of the function. + let function_identifier = unresolved_function.identifier.clone(); + + // Resolve the function definition into a function type. + let function = Self::new(table, unresolved_function)?; + + // Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table. + table.insert_function(function_identifier, function); + + Ok(()) + } } diff --git a/types/src/types/functions/function_input.rs b/static-check/src/types/functions/function_input.rs similarity index 94% rename from types/src/types/functions/function_input.rs rename to static-check/src/types/functions/function_input.rs index 1a12ef178b..6edc20e9ec 100644 --- a/types/src/types/functions/function_input.rs +++ b/static-check/src/types/functions/function_input.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{FunctionInputVariableType, ParameterType, ResolvedNode, SymbolTable, Type, TypeError}; +use crate::{FunctionInputVariableType, ParameterType, SymbolTable, Type, TypeError}; use leo_typed::{FunctionInput, Identifier}; use serde::{Deserialize, Serialize}; @@ -26,23 +26,6 @@ pub enum FunctionInputType { } impl FunctionInputType { - /// - /// Return a new `FunctionInputType` from a given `FunctionInput`. - /// - /// Performs a lookup in the given symbol table if the function input contains - /// user-defined types. - /// - pub fn new(table: &mut SymbolTable, unresolved: FunctionInput) -> Result { - Ok(match unresolved { - FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), - FunctionInput::Variable(variable) => { - let variable_resolved = FunctionInputVariableType::new(table, variable)?; - - FunctionInputType::Variable(variable_resolved) - } - }) - } - /// /// Return the `Identifier` containing name and span information about the current function input. /// @@ -63,6 +46,23 @@ impl FunctionInputType { } } + /// + /// Return a new `FunctionInputType` from a given `FunctionInput`. + /// + /// Performs a lookup in the given symbol table if the function input contains + /// user-defined types. + /// + pub fn new(table: &SymbolTable, unresolved: FunctionInput) -> Result { + Ok(match unresolved { + FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), + FunctionInput::Variable(variable) => { + let variable_resolved = FunctionInputVariableType::new(table, variable)?; + + FunctionInputType::Variable(variable_resolved) + } + }) + } + /// /// Return a new `FunctionInputType` from a given `FunctionInput`. /// @@ -73,7 +73,7 @@ impl FunctionInputType { /// is used as the type. /// pub fn new_from_circuit( - table: &mut SymbolTable, + table: &SymbolTable, unresolved: FunctionInput, circuit_name: Identifier, ) -> Result { diff --git a/types/src/types/functions/function_input_variable.rs b/static-check/src/types/functions/function_input_variable.rs similarity index 92% rename from types/src/types/functions/function_input_variable.rs rename to static-check/src/types/functions/function_input_variable.rs index 3df2e5bf36..80b6614525 100644 --- a/types/src/types/functions/function_input_variable.rs +++ b/static-check/src/types/functions/function_input_variable.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Attribute, ParameterType, ResolvedNode, SymbolTable, Type, TypeError}; +use crate::{Attribute, ParameterType, SymbolTable, Type, TypeError}; use leo_typed::{FunctionInputVariable, Identifier, Span}; use serde::{Deserialize, Serialize}; @@ -40,7 +40,7 @@ impl FunctionInputVariableType { /// /// Performs a lookup in the given symbol table if the type is user-defined. /// - pub fn new(table: &mut SymbolTable, unresolved: FunctionInputVariable) -> Result { + pub fn new(table: &SymbolTable, unresolved: FunctionInputVariable) -> Result { let type_ = Type::new(table, unresolved.type_, unresolved.span.clone())?; let attributes = if unresolved.mutable { vec![Attribute::Mutable] @@ -65,7 +65,7 @@ impl FunctionInputVariableType { /// identifier is used as the type. /// pub fn new_from_circuit( - table: &mut SymbolTable, + table: &SymbolTable, unresolved_function_input: FunctionInputVariable, circuit_name: Identifier, ) -> Result { @@ -98,6 +98,6 @@ impl FunctionInputVariableType { let key = self.identifier.name.clone(); let value = ParameterType::from(self.clone()); - table.insert_variable(key, value) + table.insert_name(key, value) } } diff --git a/types/src/types/functions/function_output.rs b/static-check/src/types/functions/function_output.rs similarity index 95% rename from types/src/types/functions/function_output.rs rename to static-check/src/types/functions/function_output.rs index 3d06cf69ed..a877c4ab94 100644 --- a/types/src/types/functions/function_output.rs +++ b/static-check/src/types/functions/function_output.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ResolvedNode, SymbolTable, Type, TypeError}; +use crate::{SymbolTable, Type, TypeError}; use leo_typed::{Identifier, Span, Type as UnresolvedType}; @@ -33,7 +33,7 @@ impl FunctionOutputType { /// Performs a lookup in the given symbol table if the return type is user-defined. /// pub(crate) fn new( - table: &mut SymbolTable, + table: &SymbolTable, function_output: Option, span: Span, ) -> Result { @@ -54,7 +54,7 @@ impl FunctionOutputType { /// identifier is used as the type. /// pub fn new_from_circuit( - table: &mut SymbolTable, + table: &SymbolTable, circuit_name: Identifier, unresolved: Option, span: Span, diff --git a/symbol-table/src/types/functions/mod.rs b/static-check/src/types/functions/mod.rs similarity index 100% rename from symbol-table/src/types/functions/mod.rs rename to static-check/src/types/functions/mod.rs diff --git a/types/src/types/mod.rs b/static-check/src/types/mod.rs similarity index 100% rename from types/src/types/mod.rs rename to static-check/src/types/mod.rs diff --git a/types/src/types/parameters/mod.rs b/static-check/src/types/parameters/mod.rs similarity index 100% rename from types/src/types/parameters/mod.rs rename to static-check/src/types/parameters/mod.rs diff --git a/types/src/types/parameters/parameter.rs b/static-check/src/types/parameters/parameter.rs similarity index 100% rename from types/src/types/parameters/parameter.rs rename to static-check/src/types/parameters/parameter.rs diff --git a/types/src/types/type_.rs b/static-check/src/types/type_.rs similarity index 97% rename from types/src/types/type_.rs rename to static-check/src/types/type_.rs index 4de97f3a01..8be3cab2e1 100644 --- a/types/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ResolvedNode, SymbolTable, TypeError, TypeVariable}; +use crate::{SymbolTable, TypeError, TypeVariable}; use leo_typed::{Identifier, IntegerType, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; @@ -45,7 +45,7 @@ impl Type { /// /// Return a new type from the given unresolved type. /// - pub fn new(table: &mut SymbolTable, type_: UnresolvedType, span: Span) -> Result { + pub fn new(table: &SymbolTable, type_: UnresolvedType, span: Span) -> Result { Ok(match type_ { UnresolvedType::Address => Type::Address, UnresolvedType::Boolean => Type::Boolean, @@ -89,7 +89,7 @@ impl Type { /// If this type is SelfType, return the circuit's type. /// pub fn new_from_circuit( - table: &mut SymbolTable, + table: &SymbolTable, type_: UnresolvedType, circuit_name: Identifier, span: Span, diff --git a/types/src/types/type_variable.rs b/static-check/src/types/type_variable.rs similarity index 100% rename from types/src/types/type_variable.rs rename to static-check/src/types/type_variable.rs diff --git a/symbol-table/tests/mod.rs b/static-check/tests/mod.rs similarity index 93% rename from symbol-table/tests/mod.rs rename to static-check/tests/mod.rs index 1ee70d31bb..f8b87e881d 100644 --- a/symbol-table/tests/mod.rs +++ b/static-check/tests/mod.rs @@ -17,7 +17,7 @@ pub mod symbol_table; use leo_ast::LeoAst; -use leo_symbol_table::{SymbolTable, SymbolTableError}; +use leo_symbol_table::{OldSymbolTable, SymbolTableError}; use leo_typed::LeoTypedAst; use std::path::PathBuf; @@ -59,7 +59,7 @@ impl TestSymbolTable { let program = self.typed.into_repr(); // Create new symbol table. - let symbol_table = &mut SymbolTable::new(None); + let symbol_table = &mut OldSymbolTable::new(None); // Run the first pass to check for duplicate names. symbol_table.pass_one(&program).unwrap(); @@ -78,7 +78,7 @@ impl TestSymbolTable { let program = self.typed.into_repr(); // Create new symbol table. - let symbol_table = &mut SymbolTable::new(None); + let symbol_table = &mut OldSymbolTable::new(None); // Run pass one and expect an error. let error = symbol_table.pass_one(&program).unwrap_err(); @@ -99,7 +99,7 @@ impl TestSymbolTable { let program = self.typed.into_repr(); // Create a new symbol table. - let symbol_table = &mut SymbolTable::new(None); + let symbol_table = &mut OldSymbolTable::new(None); // Run the pass one and expect no errors. symbol_table.pass_one(&program).unwrap(); diff --git a/symbol-table/tests/symbol_table/duplicate_circuit.leo b/static-check/tests/symbol_table/duplicate_circuit.leo similarity index 100% rename from symbol-table/tests/symbol_table/duplicate_circuit.leo rename to static-check/tests/symbol_table/duplicate_circuit.leo diff --git a/symbol-table/tests/symbol_table/duplicate_function.leo b/static-check/tests/symbol_table/duplicate_function.leo similarity index 100% rename from symbol-table/tests/symbol_table/duplicate_function.leo rename to static-check/tests/symbol_table/duplicate_function.leo diff --git a/symbol-table/tests/symbol_table/mod.rs b/static-check/tests/symbol_table/mod.rs similarity index 100% rename from symbol-table/tests/symbol_table/mod.rs rename to static-check/tests/symbol_table/mod.rs diff --git a/symbol-table/tests/symbol_table/self_not_available.leo b/static-check/tests/symbol_table/self_not_available.leo similarity index 100% rename from symbol-table/tests/symbol_table/self_not_available.leo rename to static-check/tests/symbol_table/self_not_available.leo diff --git a/symbol-table/tests/symbol_table/undefined_circuit.leo b/static-check/tests/symbol_table/undefined_circuit.leo similarity index 100% rename from symbol-table/tests/symbol_table/undefined_circuit.leo rename to static-check/tests/symbol_table/undefined_circuit.leo diff --git a/symbol-table/src/errors/type_.rs b/symbol-table/src/errors/type_.rs deleted file mode 100644 index 1b6e85c5a0..0000000000 --- a/symbol-table/src/errors/type_.rs +++ /dev/null @@ -1,141 +0,0 @@ -// 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 . - -use crate::ExtendedType; -use leo_typed::{Error as FormattedError, Identifier, Span}; - -use std::path::PathBuf; - -/// Errors encountered when resolving types. -#[derive(Debug, Error)] -pub enum TypeError { - #[error("{}", _0)] - Error(#[from] FormattedError), -} - -impl TypeError { - /// - /// Set the filepath for the error stacktrace. - /// - pub fn set_path(&mut self, path: PathBuf) { - match self { - TypeError::Error(error) => error.set_path(path), - } - } - - /// - /// Return a new formatted error with a given message and span information. - /// - fn new_from_span(message: String, span: Span) -> Self { - TypeError::Error(FormattedError::new_from_span(message, span)) - } - - /// - /// Expected an array type from the given expression. - /// - pub fn invalid_array(actual: &ExtendedType, span: Span) -> Self { - let message = format!("Expected array type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// Expected a circuit type from the given expression. - /// - pub fn invalid_circuit(actual: &ExtendedType, span: Span) -> Self { - let message = format!("Expected circuit type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// Expected a function type from the given expression. - /// - pub fn invalid_function(actual: &ExtendedType, span: Span) -> Self { - let message = format!("Expected function type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// Expected an integer type from the given expression. - /// - pub fn invalid_integer(actual: &ExtendedType, span: Span) -> Self { - let message = format!("Expected integer type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// Expected a tuple type from the given expression. - /// - pub fn invalid_tuple(actual: &ExtendedType, span: Span) -> Self { - let message = format!("Expected tuple type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// The value of the expression does not match the given explicit type. - /// - pub fn mismatched_types(expected: &ExtendedType, actual: &ExtendedType, span: Span) -> Self { - let message = format!("Expected type `{}`, found type `{}`.", expected, actual); - - Self::new_from_span(message, span) - } - - /// - /// The `Self` keyword was used outside of a circuit. - /// - pub fn self_not_available(span: Span) -> Self { - let message = format!("Type `Self` is only available in circuit definitions and circuit functions."); - - Self::new_from_span(message, span) - } - - /// - /// Found an unknown circuit name. - /// - pub fn undefined_circuit(identifier: Identifier) -> Self { - let message = format!( - "Type circuit `{}` must be defined before it is used in an expression.", - identifier.name - ); - - Self::new_from_span(message, identifier.span) - } - - /// - /// Found an unknown circuit member name. - /// - pub fn undefined_circuit_member(identifier: Identifier) -> Self { - let message = format!("Circuit has no member `{}`.", identifier.name); - - Self::new_from_span(message, identifier.span) - } - - /// - /// Found an unknown function name. - /// - pub fn undefined_function(identifier: Identifier) -> Self { - let message = format!( - "Type function `{}` must be defined before it is used in an expression.", - identifier.name - ); - - Self::new_from_span(message, identifier.span) - } -} diff --git a/symbol-table/src/lib.rs b/symbol-table/src/lib.rs deleted file mode 100644 index f4a5aaa97a..0000000000 --- a/symbol-table/src/lib.rs +++ /dev/null @@ -1,52 +0,0 @@ -// 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 . - -#[macro_use] -extern crate thiserror; - -pub mod attributes; -pub use self::attributes::*; - -pub mod errors; -pub use self::errors::*; - -pub mod symbol_table; -pub use self::symbol_table::*; - -pub mod types; -pub use self::types::*; - -/// A resolved node in an abstract syntax tree (AST). -/// -/// Resolved nodes can be any function, statement, expression, type, etc. in an AST. -/// Resolved nodes should not contain any illegal types. -/// Resolved nodes should not contain any implicit types. -pub trait ResolvedNode { - /// The expected error type if the type resolution fails. - type Error; - - /// The unresolved AST node that is being resolved. - type UnresolvedNode; - - /// - /// Returns a resolved AST representation given an unresolved AST representation. - /// - /// User-defined types are looked up using the given symbol table. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result - where - Self: std::marker::Sized; -} diff --git a/symbol-table/src/types/circuits/circuit.rs b/symbol-table/src/types/circuits/circuit.rs deleted file mode 100644 index c60fbc736a..0000000000 --- a/symbol-table/src/types/circuits/circuit.rs +++ /dev/null @@ -1,144 +0,0 @@ -// 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 . - -use crate::{ - types::circuits::{CircuitFunctionType, CircuitVariableType}, - Attribute, - ExtendedType, - FunctionType, - ResolvedNode, - SymbolTable, - TypeError, -}; -use leo_typed::{Circuit, CircuitMember, Identifier}; - -use serde::{Deserialize, Serialize}; - -/// Stores circuit definition details. -/// -/// This type should be added to the circuit symbol table for a resolved syntax tree. -/// This is a user-defined type. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct CircuitType { - /// The name of the circuit definition. - pub identifier: Identifier, - - /// The circuit variables. - pub variables: Vec, - - /// The circuit functions. - pub functions: Vec, -} - -impl ResolvedNode for CircuitType { - type Error = TypeError; - type UnresolvedNode = Circuit; - - /// - /// Return a new `CircuitType` from a given `Circuit` definition. - /// - /// Performs a lookup in the given symbol table if the circuit definition contains - /// user-defined types. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let circuit_identifier = unresolved.circuit_name; - let mut variables = vec![]; - let mut functions = vec![]; - - // Resolve the type of every circuit member. - for member in unresolved.members { - match member { - CircuitMember::CircuitVariable(is_mutable, variable_identifier, type_) => { - // Resolve the type of the circuit member variable. - let type_ = ExtendedType::from_circuit( - table, - type_, - circuit_identifier.clone(), - circuit_identifier.span.clone(), - )?; - - // Check if the circuit member variable is mutable. - let attributes = if is_mutable { vec![Attribute::Mutable] } else { vec![] }; - - // Create a new circuit variable type. - let variable = CircuitVariableType { - identifier: variable_identifier, - type_, - attributes, - }; - - // Store the circuit variable type. - variables.push(variable); - } - CircuitMember::CircuitFunction(is_static, function) => { - // Resolve the type of the circuit member function. - let function_type = FunctionType::from_circuit(table, circuit_identifier.clone(), function)?; - - // Check if the circuit member function is static. - let attributes = if is_static { vec![Attribute::Static] } else { vec![] }; - - // Create a new circuit function type. - let function = CircuitFunctionType { - function: function_type, - attributes, - }; - - // Store the circuit function type. - functions.push(function); - } - } - } - - // Return a new circuit type. - Ok(CircuitType { - identifier: circuit_identifier.clone(), - variables, - functions, - }) - } -} - -impl CircuitType { - /// - /// Returns the type of a circuit member. - /// - /// If the member is a circuit variable, then the type of the variable is returned. - /// If the member is a circuit function, then the return type of the function is returned. - /// - pub fn member_type(&self, identifier: &Identifier) -> Result<&ExtendedType, TypeError> { - // Check if the circuit member is a circuit variable. - let matched_variable = self - .variables - .iter() - .find(|variable| variable.identifier.eq(identifier)); - - match matched_variable { - Some(variable) => Ok(&variable.type_), - None => { - // Check if the circuit member is a circuit function. - let matched_function = self - .functions - .iter() - .find(|function| function.function.identifier.eq(identifier)); - - match matched_function { - Some(function) => Ok(&function.function.output.type_), - None => Err(TypeError::undefined_circuit_member(identifier.clone())), - } - } - } - } -} diff --git a/symbol-table/src/types/circuits/circuit_variable.rs b/symbol-table/src/types/circuits/circuit_variable.rs deleted file mode 100644 index 4f936d1237..0000000000 --- a/symbol-table/src/types/circuits/circuit_variable.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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 . - -use crate::{Attribute, ExtendedType}; -use leo_typed::Identifier; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct CircuitVariableType { - /// The name of the circuit variable - pub identifier: Identifier, - /// The type of the circuit variable - pub type_: ExtendedType, - /// The attributes of the circuit variable - pub attributes: Vec, -} diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs deleted file mode 100644 index 3a3d98475a..0000000000 --- a/symbol-table/src/types/functions/function.rs +++ /dev/null @@ -1,127 +0,0 @@ -// 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 . - -use crate::{ - types::functions::{FunctionInputType, FunctionOutputType}, - ResolvedNode, - SymbolTable, - TypeError, -}; -use leo_typed::{Function, Identifier}; - -use serde::{Deserialize, Serialize}; - -/// Stores function definition details. -/// -/// This type should be added to the function symbol table for a resolved syntax tree. -/// This is a user-defined type. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct FunctionType { - /// The name of the function definition. - pub identifier: Identifier, - - /// The function inputs. - pub inputs: Vec, - - /// The function output. - pub output: FunctionOutputType, -} - -impl ResolvedNode for FunctionType { - type Error = TypeError; - type UnresolvedNode = Function; - - /// - /// Return a new `FunctionType` from a given `Function` definition. - /// - /// Performs a lookup in the given symbol table if the function definition contains - /// user-defined types. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let mut inputs_resolved = vec![]; - - // Type check function inputs - for input in unresolved.input { - let input = FunctionInputType::resolve(table, input)?; - inputs_resolved.push(input); - } - - // Type check function output - let output = FunctionOutputType::resolve(table, (unresolved.output, unresolved.span))?; - - Ok(FunctionType { - identifier: unresolved.identifier, - inputs: inputs_resolved, - output, - }) - } -} - -impl FunctionType { - /// - /// Resolve a function definition and insert it into the given symbol table. - /// - pub fn insert_definition(table: &mut SymbolTable, unresolved_function: Function) -> Result<(), TypeError> { - // Get the identifier of the function. - let function_identifier = unresolved_function.identifier.clone(); - - // Resolve the function definition into a function type. - let function = Self::resolve(table, unresolved_function)?; - - // Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table. - table.insert_function(function_identifier, function); - - Ok(()) - } - - /// - /// Return a new `FunctionType` from a given `Function` definition. - /// - /// Performs a lookup in the given symbol table if the function definition contains - /// user-defined types. - /// - /// If the function definition contains the `Self` keyword, then the given circuit identifier - /// is used as the type. - /// - pub fn from_circuit( - table: &mut SymbolTable, - circuit_name: Identifier, - unresolved_function: Function, - ) -> Result { - let function_identifier = unresolved_function.identifier; - let mut inputs = vec![]; - - // Type check function inputs. - for unresolved_input in unresolved_function.input { - let input = FunctionInputType::from_circuit(table, unresolved_input, circuit_name.clone())?; - inputs.push(input); - } - - // Type check function output. - let output = FunctionOutputType::from_circuit( - table, - circuit_name.clone(), - unresolved_function.output, - unresolved_function.span, - )?; - - Ok(FunctionType { - identifier: function_identifier.clone(), - inputs, - output, - }) - } -} diff --git a/symbol-table/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs deleted file mode 100644 index 63bf3412c4..0000000000 --- a/symbol-table/src/types/functions/function_input.rs +++ /dev/null @@ -1,109 +0,0 @@ -// 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 . - -use crate::{ExtendedType, FunctionInputVariableType, ResolvedNode, SymbolTable, TypeError, VariableType}; -use leo_typed::{FunctionInput, Identifier}; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum FunctionInputType { - InputKeyword(Identifier), - Variable(FunctionInputVariableType), -} - -impl ResolvedNode for FunctionInputType { - type Error = TypeError; - type UnresolvedNode = FunctionInput; - - /// - /// Return a new `FunctionInputType` from a given `FunctionInput`. - /// - /// Performs a lookup in the given symbol table if the function input contains - /// user-defined types. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - Ok(match unresolved { - FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), - FunctionInput::Variable(variable) => { - let variable_resolved = FunctionInputVariableType::resolve(table, variable)?; - - FunctionInputType::Variable(variable_resolved) - } - }) - } -} - -impl FunctionInputType { - /// - /// Return the `Identifier` containing name and span information about the current function input. - /// - pub fn identifier(&self) -> &Identifier { - match self { - FunctionInputType::InputKeyword(identifier) => identifier, - FunctionInputType::Variable(variable) => &variable.identifier, - } - } - - /// - /// Return the `Type` of the current function input. - /// - pub fn type_(&self) -> &ExtendedType { - match self { - FunctionInputType::InputKeyword(_) => unimplemented!("ERROR: input type not implemented"), - FunctionInputType::Variable(variable) => &variable.type_, - } - } - - /// - /// Return a new `FunctionInputType` from a given `FunctionInput`. - /// - /// Performs a lookup in the given symbol table if the function input contains - /// user-defined types. - /// - /// If the type of the function input is the `Self` keyword, then the given circuit identifier - /// is used as the type. - /// - pub fn from_circuit( - table: &mut SymbolTable, - unresolved: FunctionInput, - circuit_name: Identifier, - ) -> Result { - Ok(match unresolved { - FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), - FunctionInput::Variable(unresolved_function_input) => { - let function_input = - FunctionInputVariableType::from_circuit(table, unresolved_function_input, circuit_name)?; - - FunctionInputType::Variable(function_input) - } - }) - } - - /// - /// Insert the current function input type into the given symbol table. - /// - /// If the symbol table did not have this name present, `None` is returned. - /// - pub fn insert(&self, table: &mut SymbolTable) -> Option { - match self { - FunctionInputType::Variable(variable) => variable.insert(table), - FunctionInputType::InputKeyword(_identifier) => { - unimplemented!("uncomment when support for input types is added") - } - } - } -} diff --git a/symbol-table/src/types/functions/function_input_variable.rs b/symbol-table/src/types/functions/function_input_variable.rs deleted file mode 100644 index ecb8086a1b..0000000000 --- a/symbol-table/src/types/functions/function_input_variable.rs +++ /dev/null @@ -1,108 +0,0 @@ -// 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 . - -use crate::{Attribute, ExtendedType, ResolvedNode, SymbolTable, TypeError, VariableType}; -use leo_typed::{FunctionInputVariable, Identifier, Span}; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct FunctionInputVariableType { - /// Name of function input. - pub identifier: Identifier, - - /// Type of function input. - pub type_: ExtendedType, - - /// The attributes of the function input. - pub attributes: Vec, - - /// The span of the function input. - pub span: Span, -} - -impl ResolvedNode for FunctionInputVariableType { - type Error = TypeError; - type UnresolvedNode = FunctionInputVariable; - - /// - /// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`. - /// - /// Performs a lookup in the given symbol table if the type is user-defined. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let type_ = ExtendedType::resolve(table, (unresolved.type_, unresolved.span.clone()))?; - let attributes = if unresolved.mutable { - vec![Attribute::Mutable] - } else { - vec![] - }; - - Ok(FunctionInputVariableType { - identifier: unresolved.identifier, - type_, - attributes, - span: unresolved.span, - }) - } -} - -impl FunctionInputVariableType { - /// - /// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`. - /// - /// Performs a lookup in the given symbol table if the type is user-defined. - /// - /// If the type of the function return type is the `Self` keyword, then the given circuit - /// identifier is used as the type. - /// - pub fn from_circuit( - table: &mut SymbolTable, - unresolved_function_input: FunctionInputVariable, - circuit_name: Identifier, - ) -> Result { - let type_ = ExtendedType::from_circuit( - table, - unresolved_function_input.type_, - circuit_name, - unresolved_function_input.span.clone(), - )?; - let attributes = if unresolved_function_input.mutable { - vec![Attribute::Mutable] - } else { - vec![] - }; - - Ok(FunctionInputVariableType { - identifier: unresolved_function_input.identifier, - type_, - attributes, - span: unresolved_function_input.span, - }) - } - - /// - /// Insert the current function input variable type into the given symbol table. - /// - /// If the symbol table did not have this name present, `None` is returned. - /// - pub fn insert(&self, table: &mut SymbolTable) -> Option { - let key = self.identifier.name.clone(); - let value = VariableType::from(self.clone()); - - table.insert_variable(key, value) - } -} diff --git a/symbol-table/src/types/functions/function_output.rs b/symbol-table/src/types/functions/function_output.rs deleted file mode 100644 index 837d1568ab..0000000000 --- a/symbol-table/src/types/functions/function_output.rs +++ /dev/null @@ -1,74 +0,0 @@ -// 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 . - -use crate::{ExtendedType, ResolvedNode, SymbolTable, TypeError}; - -use leo_typed::{Identifier, Span, Type as UnresolvedType}; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct FunctionOutputType { - /// Type of function output. - pub type_: ExtendedType, -} - -impl ResolvedNode for FunctionOutputType { - type Error = TypeError; - /// (optional function output, span) - type UnresolvedNode = (Option, Span); - - /// - /// Return a new `FunctionOutputType` from a given optional function return type and span. - /// - /// Performs a lookup in the given symbol table if the return type is user-defined. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let function_output = unresolved.0; - let span = unresolved.1; - - let type_ = match function_output { - None => ExtendedType::Tuple(vec![]), // functions with no return value return an empty tuple - Some(type_) => ExtendedType::resolve(table, (type_, span))?, - }; - - Ok(FunctionOutputType { type_ }) - } -} - -impl FunctionOutputType { - /// - /// Return a new `FunctionOutputType` from a given optional function return type and span. - /// - /// Performs a lookup in the given symbol table if the return type is user-defined. - /// - /// If the type of the function return type is the `Self` keyword, then the given circuit - /// identifier is used as the type. - /// - pub fn from_circuit( - table: &mut SymbolTable, - circuit_name: Identifier, - unresolved: Option, - span: Span, - ) -> Result { - let output_type = match unresolved { - None => ExtendedType::Tuple(vec![]), - Some(type_) => ExtendedType::from_circuit(table, type_, circuit_name, span)?, - }; - - Ok(FunctionOutputType { type_: output_type }) - } -} diff --git a/symbol-table/src/types/mod.rs b/symbol-table/src/types/mod.rs deleted file mode 100644 index 0d27661ad9..0000000000 --- a/symbol-table/src/types/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -pub mod circuits; -pub use self::circuits::*; - -pub mod functions; -pub use self::functions::*; - -pub mod type_; -pub use self::type_::*; - -pub mod variables; -pub use self::variables::*; diff --git a/symbol-table/src/types/type_.rs b/symbol-table/src/types/type_.rs deleted file mode 100644 index 9dc6105469..0000000000 --- a/symbol-table/src/types/type_.rs +++ /dev/null @@ -1,221 +0,0 @@ -// 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 . -use crate::{ResolvedNode, SymbolTable, TypeError}; -use leo_typed::{Identifier, IntegerType, Span, Type as UnresolvedType}; - -use serde::{Deserialize, Serialize}; -use std::fmt; - -/// A resolved type in a Leo program. -/// -/// This type cannot be an implicit or `Self` type. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum ExtendedType { - // Data types - Address, - Boolean, - Field, - Group, - IntegerType(IntegerType), - - // Data type wrappers - Array(Box, Vec), - Tuple(Vec), - - // User defined types - Circuit(Identifier), - Function(Identifier), -} - -impl ResolvedNode for ExtendedType { - type Error = TypeError; - type UnresolvedNode = (UnresolvedType, Span); - - /// - /// Resolves the given type. - /// - /// Cannot be an implicit or `Self` type. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let type_ = unresolved.0; - let span = unresolved.1; - - Ok(match type_ { - UnresolvedType::Address => ExtendedType::Address, - UnresolvedType::Boolean => ExtendedType::Boolean, - UnresolvedType::Field => ExtendedType::Field, - UnresolvedType::Group => ExtendedType::Group, - UnresolvedType::IntegerType(integer) => ExtendedType::IntegerType(integer), - - UnresolvedType::Array(type_, dimensions) => { - let array_type = ExtendedType::resolve(table, (*type_, span))?; - - ExtendedType::Array(Box::new(array_type), dimensions) - } - UnresolvedType::Tuple(types) => { - let tuple_types = types - .into_iter() - .map(|type_| ExtendedType::resolve(table, (type_, span.clone()))) - .collect::, _>>()?; - - ExtendedType::Tuple(tuple_types) - } - - UnresolvedType::Circuit(identifier) => { - // Lookup the circuit type in the symbol table - let circuit_type = table - .get_circuit(&identifier.name) - .ok_or(TypeError::undefined_circuit(identifier))?; - - ExtendedType::Circuit(circuit_type.identifier.clone()) - } - - UnresolvedType::SelfType => { - // Throw an error for using `Self` outside of a circuit - return Err(TypeError::self_not_available(span)); - } - }) - } -} - -impl ExtendedType { - /// - /// Resolve a type inside of a circuit definition. - /// - /// If this type is SelfType, return the circuit's type. - /// - pub fn from_circuit( - table: &mut SymbolTable, - type_: UnresolvedType, - circuit_name: Identifier, - span: Span, - ) -> Result { - Ok(match type_ { - UnresolvedType::Array(type_, dimensions) => { - let array_type = ExtendedType::from_circuit(table, *type_, circuit_name, span)?; - ExtendedType::Array(Box::new(array_type), dimensions) - } - UnresolvedType::Tuple(types) => { - let tuple_types = types - .into_iter() - .map(|type_| ExtendedType::from_circuit(table, type_, circuit_name.clone(), span.clone())) - .collect::, _>>()?; - - ExtendedType::Tuple(tuple_types) - } - UnresolvedType::SelfType => ExtendedType::Circuit(circuit_name), - // The unresolved type does not depend on the current circuit definition - unresolved => ExtendedType::resolve(table, (unresolved, span))?, - }) - } - - /// - /// Returns `Ok` if the given expected type is `Some` and expected type == actual type. - /// - pub fn check_type(expected_option: &Option, actual: &ExtendedType, span: Span) -> Result<(), TypeError> { - if let Some(expected) = expected_option { - if expected.ne(actual) { - return Err(TypeError::mismatched_types(expected, actual, span)); - } - } - Ok(()) - } - - /// - /// Returns `Ok` if self is an expected integer type `Type::IntegerType`. - /// - pub fn check_type_integer(&self, span: Span) -> Result<(), TypeError> { - match self { - ExtendedType::IntegerType(_) => Ok(()), - // Throw mismatched type error - type_ => Err(TypeError::invalid_integer(type_, span)), - } - } - - /// - /// Returns array element type and dimensions if self is an expected array type `Type::Array`. - /// - pub fn get_type_array(&self, span: Span) -> Result<(&ExtendedType, &Vec), TypeError> { - match self { - ExtendedType::Array(element_type, dimensions) => Ok((element_type, dimensions)), - // Throw mismatched type error - type_ => Err(TypeError::invalid_array(type_, span)), - } - } - - /// - /// Returns tuple element types if self is an expected tuple type `Type::Tuple`. - /// - pub fn get_type_tuple(&self, span: Span) -> Result<&Vec, TypeError> { - match self { - ExtendedType::Tuple(types) => Ok(types), - // Throw mismatched type error - type_ => Err(TypeError::invalid_tuple(type_, span)), - } - } - - /// - /// Returns circuit identifier if self is an expected circuit type `Type::Circuit`. - /// - pub fn get_type_circuit(&self, span: Span) -> Result<&Identifier, TypeError> { - match self { - ExtendedType::Circuit(identifier) => Ok(identifier), - // Throw mismatched type error - type_ => Err(TypeError::invalid_circuit(type_, span)), - } - } - - /// - /// Returns function identifier if self is an expected function type `Type::Function`. - /// - pub fn get_type_function(&self, span: Span) -> Result<&Identifier, TypeError> { - match self { - ExtendedType::Function(identifier) => Ok(identifier), - // Throw mismatched type error - type_ => Err(TypeError::invalid_function(type_, span)), - } - } -} - -impl fmt::Display for ExtendedType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match &self { - ExtendedType::Address => write!(f, "address"), - ExtendedType::Boolean => write!(f, "bool"), - ExtendedType::Field => write!(f, "field"), - ExtendedType::Group => write!(f, "group"), - ExtendedType::IntegerType(integer_type) => write!(f, "{}", integer_type), - - ExtendedType::Array(type_, dimensions) => { - let dimensions_string = dimensions - .iter() - .map(|dimension| format!("{}", dimension)) - .collect::>() - .join(", "); - - write!(f, "[{}; ({})]", *type_, dimensions_string) - } - ExtendedType::Tuple(tuple) => { - let tuple_string = tuple.iter().map(|x| format!("{}", x)).collect::>().join(", "); - - write!(f, "({})", tuple_string) - } - - ExtendedType::Circuit(identifier) => write!(f, "circuit {}", identifier), - ExtendedType::Function(identifier) => write!(f, "function {}", identifier), - } - } -} diff --git a/symbol-table/src/types/variables/mod.rs b/symbol-table/src/types/variables/mod.rs deleted file mode 100644 index 80950ed0c3..0000000000 --- a/symbol-table/src/types/variables/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod variable; -pub use self::variable::*; diff --git a/symbol-table/src/types/variables/variable.rs b/symbol-table/src/types/variables/variable.rs deleted file mode 100644 index e5ef783d93..0000000000 --- a/symbol-table/src/types/variables/variable.rs +++ /dev/null @@ -1,79 +0,0 @@ -// 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 . -use crate::{Attribute, ExtendedType}; -use leo_typed::{Circuit, Function, Identifier}; - -use crate::FunctionInputVariableType; -use std::fmt; - -/// Stores variable definition details. -/// -/// This type should be added to the variable symbol table for a resolved syntax tree. -#[derive(Clone, Debug, Eq, PartialEq, Hash)] -pub struct VariableType { - pub identifier: Identifier, - pub type_: ExtendedType, - pub attributes: Vec, -} - -impl VariableType { - /// - /// Returns `true` if this variable's value can be modified. - /// - pub fn is_mutable(&self) -> bool { - self.attributes.contains(&Attribute::Mutable) - } -} - -impl From for VariableType { - fn from(value: Circuit) -> Self { - let identifier = value.circuit_name; - - VariableType { - identifier: identifier.clone(), - type_: ExtendedType::Circuit(identifier), - attributes: vec![], - } - } -} - -impl From for VariableType { - fn from(value: Function) -> Self { - let identifier = value.identifier; - - VariableType { - identifier: identifier.clone(), - type_: ExtendedType::Function(identifier.clone()), - attributes: vec![], - } - } -} - -impl From for VariableType { - fn from(value: FunctionInputVariableType) -> Self { - VariableType { - identifier: value.identifier, - type_: value.type_, - attributes: value.attributes, - } - } -} - -impl fmt::Display for VariableType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.identifier) - } -} diff --git a/types/Cargo.toml b/types/Cargo.toml deleted file mode 100644 index ed9b068232..0000000000 --- a/types/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "leo-types" -version = "1.0.3" -authors = [ "The Aleo Team " ] -description = "Leo program type and type variables" -homepage = "https://aleo.org" -respository = "https://github.com/AleoHQ/leo" -keywords = [ - "aleo", - "cryptography", - "leo", - "programming-language", - "zero-knowledge" -] -categories = [ "cryptography::croptocurrencies", "web-programming" ] -include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] -license = "GPL-3.0" -edition = "2018" - -[dependencies.leo-ast] -path = "../ast" -version = "1.0.3" - -[dependencies.leo-imports] -path = "../imports" -version = "1.0.3" - -[dependencies.leo-typed] -path = "../typed" -version = "1.0.3" - -[dependencies.serde] -version = "1.0" - -[dependencies.thiserror] -version = "1.0" \ No newline at end of file diff --git a/types/src/attributes/attribute.rs b/types/src/attributes/attribute.rs deleted file mode 100644 index 0fa7153b69..0000000000 --- a/types/src/attributes/attribute.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 . - -use serde::{Deserialize, Serialize}; - -/// Indicates that a program variable has additional functionality. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum Attribute { - Mutable, - Static, -} diff --git a/types/src/attributes/mod.rs b/types/src/attributes/mod.rs deleted file mode 100644 index f8d19f5a62..0000000000 --- a/types/src/attributes/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod attribute; -pub use self::attribute::*; diff --git a/types/src/errors/mod.rs b/types/src/errors/mod.rs deleted file mode 100644 index 107ac193f8..0000000000 --- a/types/src/errors/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 . - -pub mod symbol_table; -pub use self::symbol_table::*; - -pub mod type_; -pub use self::type_::*; diff --git a/types/src/errors/symbol_table.rs b/types/src/errors/symbol_table.rs deleted file mode 100644 index deca39c4a1..0000000000 --- a/types/src/errors/symbol_table.rs +++ /dev/null @@ -1,67 +0,0 @@ -// 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 . - -use crate::TypeError; -use leo_typed::{Error as FormattedError, Identifier, Span}; - -use std::path::PathBuf; - -/// Errors encountered when tracking variable, function, and circuit names in a program -#[derive(Debug, Error)] -pub enum SymbolTableError { - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - TypeError(#[from] TypeError), -} - -impl SymbolTableError { - /// - /// Set the filepath for the error stacktrace - /// - pub fn set_path(&mut self, path: PathBuf) { - match self { - SymbolTableError::Error(error) => error.set_path(path), - SymbolTableError::TypeError(error) => error.set_path(path), - } - } - - /// - /// Return a new formatted error with a given message and span information - /// - fn new_from_span(message: String, span: Span) -> Self { - SymbolTableError::Error(FormattedError::new_from_span(message, span)) - } - - /// - /// 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); - - Self::new_from_span(message, 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); - - Self::new_from_span(message, span) - } -} diff --git a/types/src/types/circuits/circuit_function.rs b/types/src/types/circuits/circuit_function.rs deleted file mode 100644 index 0eff740236..0000000000 --- a/types/src/types/circuits/circuit_function.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -use crate::{types::FunctionType, Attribute}; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct CircuitFunctionType { - /// The function signature of the circuit function - pub function: FunctionType, - /// The attributes of the circuit function - pub attributes: Vec, -} diff --git a/types/src/types/circuits/mod.rs b/types/src/types/circuits/mod.rs deleted file mode 100644 index 8205016c50..0000000000 --- a/types/src/types/circuits/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 . - -pub mod circuit; -pub use self::circuit::*; - -pub mod circuit_function; -pub use self::circuit_function::*; - -pub mod circuit_variable; -pub use self::circuit_variable::*; diff --git a/types/src/types/functions/mod.rs b/types/src/types/functions/mod.rs deleted file mode 100644 index fe22157837..0000000000 --- a/types/src/types/functions/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -pub mod function; -pub use self::function::*; - -pub mod function_input; -pub use self::function_input::*; - -pub mod function_input_variable; -pub use self::function_input_variable::*; - -pub mod function_output; -pub use self::function_output::*; From cc6cf4e6a594d824cdf1b4779f8ddfa17b2c8398 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 13 Oct 2020 09:06:52 -0700 Subject: [PATCH 014/139] add new dynamic check protocol --- dynamic-check/src/dynamic_check.rs | 7 +++ dynamic-check/tests/mod.rs | 13 ++---- static-check/src/lib.rs | 3 ++ static-check/src/static_check.rs | 75 ++++++++++++++++++++++++++++++ static-check/src/symbol_table.rs | 33 ------------- static-check/src/types/type_.rs | 2 + 6 files changed, 91 insertions(+), 42 deletions(-) create mode 100644 static-check/src/static_check.rs diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 24c21d1db8..333a34a41e 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -103,8 +103,11 @@ impl FunctionBody { /// pub fn new(function: Function, symbol_table: SymbolTable) -> Self { let name = &function.identifier.name; + + // Get function type from symbol table. let function_type = symbol_table.get_function(name).unwrap().clone(); + // Create new function body struct. let mut function_body = Self { function_type, symbol_table, @@ -112,6 +115,10 @@ impl FunctionBody { type_variables: HashSet::new(), }; + // Build symbol table for variables. + // Initialize function inputs as variables. + // Update inputs when encountering let/const variable definitions. + // Create type assertions for function statements function_body.parse_statements(&function.statements); diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 7db75c9c6f..90a6147221 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -17,7 +17,7 @@ use leo_ast::LeoAst; use leo_dynamic_check::DynamicCheck; -use leo_symbol_table::OldSymbolTable; +use leo_static_check::StaticCheck; use leo_typed::LeoTypedAst; use std::path::PathBuf; @@ -44,16 +44,11 @@ impl TestDynamicCheck { let typed = LeoTypedAst::new(TEST_PROGRAM_NAME, &ast); let program = typed.into_repr(); - // Create symbol table. - let mut symbol_table = OldSymbolTable::new(None); - - // Load symbols into symbol table. - symbol_table.pass_one(&program).unwrap(); - - symbol_table.pass_two(&program).unwrap(); + // Create static check. + let mut static_check = StaticCheck::new(&program).unwrap(); // Create dynamic check - let dynamic_check = DynamicCheck::new(&program, symbol_table); + let dynamic_check = DynamicCheck::new(&program, static_check); Self { dynamic_check } } diff --git a/static-check/src/lib.rs b/static-check/src/lib.rs index b40c37f248..b985aab375 100644 --- a/static-check/src/lib.rs +++ b/static-check/src/lib.rs @@ -23,6 +23,9 @@ pub use self::attributes::*; pub mod errors; pub use self::errors::*; +pub mod static_check; +pub use self::static_check::*; + pub mod symbol_table; pub use self::symbol_table::*; diff --git a/static-check/src/static_check.rs b/static-check/src/static_check.rs new file mode 100644 index 0000000000..41508fc03e --- /dev/null +++ b/static-check/src/static_check.rs @@ -0,0 +1,75 @@ +// 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 . + +use crate::{SymbolTable, SymbolTableError}; +use leo_typed::Program as UnresolvedProgram; + +/// Performs a static type check over a program. +pub struct StaticCheck { + table: SymbolTable, +} + +impl StaticCheck { + /// + /// Return a new `StaticCheck` from a given program. + /// + pub fn new(program: &UnresolvedProgram) -> Result { + let mut check = Self { + table: SymbolTable::new(None), + }; + + // Run pass one checks + check.pass_one(program)?; + + // Run pass two checks + check.pass_two(program)?; + + Ok(check.table) + } + + /// + /// Checks for duplicate circuit and function names given an unresolved 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 pass_one(&mut self, program: &UnresolvedProgram) -> Result<(), SymbolTableError> { + // 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(()) + } + + /// + /// Checks for unknown types in circuit and function definitions given an unresolved program. + /// + /// If a circuit or function definition only contains known types, then it is inserted into the + /// symbol table. Variables defined later in the unresolved program can lookup the definition and + /// refer to its expected types. + /// + pub fn pass_two(&mut self, program: &UnresolvedProgram) -> Result<(), SymbolTableError> { + // Check unresolved program circuit definitions. + self.table.check_unknown_types_circuits(&program.circuits)?; + + // Check unresolved program function definitions. + self.table.check_unknown_types_functions(&program.functions)?; + + Ok(()) + } +} diff --git a/static-check/src/symbol_table.rs b/static-check/src/symbol_table.rs index 96b18b493b..f8c8aeca37 100644 --- a/static-check/src/symbol_table.rs +++ b/static-check/src/symbol_table.rs @@ -254,37 +254,4 @@ impl SymbolTable { Ok(()) } - - /// - /// Checks for duplicate circuit and function names given an unresolved 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 pass_one(&mut self, program: &UnresolvedProgram) -> Result<(), SymbolTableError> { - // 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 unknown types in circuit and function definitions given an unresolved program. - /// - /// If a circuit or function definition only contains known types, then it is inserted into the - /// symbol table. Variables defined later in the unresolved program can lookup the definition and - /// refer to its expected types. - /// - pub fn pass_two(&mut self, program: &UnresolvedProgram) -> Result<(), SymbolTableError> { - // Check unresolved program circuit definitions. - self.check_unknown_types_circuits(&program.circuits)?; - - // Check unresolved program function definitions. - self.check_unknown_types_functions(&program.functions)?; - - Ok(()) - } } diff --git a/static-check/src/types/type_.rs b/static-check/src/types/type_.rs index 8be3cab2e1..085bed6274 100644 --- a/static-check/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -45,6 +45,8 @@ impl Type { /// /// Return a new type from the given unresolved type. /// + /// Performs a lookup in the given symbol table if the type is user-defined. + /// pub fn new(table: &SymbolTable, type_: UnresolvedType, span: Span) -> Result { Ok(match type_ { UnresolvedType::Address => Type::Address, From de6f6ae7ae923d4e6f614abcb714d34c9aed8303 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 14 Oct 2020 15:12:55 -0700 Subject: [PATCH 015/139] add variable table to function body --- dynamic-check/src/dynamic_check.rs | 69 ++++++++++++++++++++++++------ static-check/src/static_check.rs | 8 ++-- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 333a34a41e..53b4fc8d4d 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -14,15 +14,15 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +use leo_static_check::{FunctionInputType, FunctionType, SymbolTable, Type}; use leo_typed::{Expression, Function, Identifier, Program, Span, Statement}; -use leo_static_check::{FunctionType, SymbolTable, Type}; use serde::{Deserialize, Serialize}; -use std::collections::HashSet; +use std::collections::HashMap; /// Performs a dynamic type inference check over a program. pub struct DynamicCheck { - symbol_table: SymbolTable, + table: SymbolTable, functions: Vec, } @@ -32,7 +32,7 @@ impl DynamicCheck { /// pub fn new(program: &Program, symbol_table: SymbolTable) -> Self { let mut dynamic_check = Self { - symbol_table, + table: symbol_table, functions: vec![], }; @@ -67,7 +67,7 @@ impl DynamicCheck { /// Collects a vector of `TypeAssertion` predicates from a function. /// fn parse_function(&mut self, function: &Function) { - let function_body = FunctionBody::new(function.clone(), self.symbol_table.clone()); + let function_body = FunctionBody::new(function.clone(), self.table.clone()); self.functions.push(function_body); } @@ -92,9 +92,9 @@ impl DynamicCheck { #[derive(Clone)] pub struct FunctionBody { function_type: FunctionType, - symbol_table: SymbolTable, + user_defined_types: SymbolTable, type_assertions: Vec, - type_variables: HashSet, + variable_table: VariableTable, } impl FunctionBody { @@ -107,18 +107,21 @@ impl FunctionBody { // Get function type from symbol table. let function_type = symbol_table.get_function(name).unwrap().clone(); + // Build symbol table for variables. + let mut variable_table = VariableTable::new(); + + // Initialize function inputs as variables. + variable_table.parse_function_inputs(&function_type.inputs); + // Create new function body struct. + // Update variables when encountering let/const variable definitions. let mut function_body = Self { function_type, - symbol_table, + user_defined_types: symbol_table, type_assertions: vec![], - type_variables: HashSet::new(), + variable_table, }; - // Build symbol table for variables. - // Initialize function inputs as variables. - // Update inputs when encountering let/const variable definitions. - // Create type assertions for function statements function_body.parse_statements(&function.statements); @@ -157,7 +160,7 @@ impl FunctionBody { let left = TypeElement::Type(output_type.clone()); // Create the right hand side from the statement return expression. - let right = TypeElement::new(expression, self.symbol_table.clone()); + let right = TypeElement::new(expression, self.user_defined_types.clone()); // Create a new type assertion for the statement return. let type_assertion = TypeAssertion::new(left, right); @@ -198,6 +201,44 @@ impl FunctionBody { } } +/// A structure for tracking the types of user defined variables in a program. +#[derive(Clone)] +pub struct VariableTable(pub HashMap); + +impl VariableTable { + /// + /// Return a new variable table + /// + pub fn new() -> Self { + Self(HashMap::new()) + } + + /// + /// Insert a name -> type pair into the variable table. + /// + /// If the variable table did not have this key present, [`None`] is returned. + /// + /// If the variable table did have this key present, the type is updated, and the old + /// type is returned. + /// + pub fn insert(&mut self, name: String, type_: Type) -> Option { + self.0.insert(name, type_) + } + + /// + /// Inserts a vector of function input types into the variable table. + /// + pub fn parse_function_inputs(&mut self, function_inputs: &Vec) { + for input in function_inputs { + let input_name = input.identifier().name.clone(); + let input_type = input.type_().clone(); + + // TODO (collinc97) throw an error for duplicate function input names. + self.insert(input_name, input_type); + } + } +} + /// A predicate that evaluates equality between two `TypeElement`s. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct TypeAssertion { diff --git a/static-check/src/static_check.rs b/static-check/src/static_check.rs index 41508fc03e..3cf3cfc525 100644 --- a/static-check/src/static_check.rs +++ b/static-check/src/static_check.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{SymbolTable, SymbolTableError}; -use leo_typed::Program as UnresolvedProgram; +use leo_typed::Program; /// Performs a static type check over a program. pub struct StaticCheck { @@ -26,7 +26,7 @@ impl StaticCheck { /// /// Return a new `StaticCheck` from a given program. /// - pub fn new(program: &UnresolvedProgram) -> Result { + pub fn new(program: &Program) -> Result { let mut check = Self { table: SymbolTable::new(None), }; @@ -46,7 +46,7 @@ impl StaticCheck { /// 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 pass_one(&mut self, program: &UnresolvedProgram) -> Result<(), SymbolTableError> { + pub fn pass_one(&mut self, program: &Program) -> Result<(), SymbolTableError> { // Check unresolved program circuit names. self.table.check_duplicate_circuits(&program.circuits)?; @@ -63,7 +63,7 @@ impl StaticCheck { /// symbol table. Variables defined later in the unresolved program can lookup the definition and /// refer to its expected types. /// - pub fn pass_two(&mut self, program: &UnresolvedProgram) -> Result<(), SymbolTableError> { + pub fn pass_two(&mut self, program: &Program) -> Result<(), SymbolTableError> { // Check unresolved program circuit definitions. self.table.check_unknown_types_circuits(&program.circuits)?; From 3221615f51e8b936d5161f9e4dbb39d2a461e71b Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 14 Oct 2020 16:27:55 -0700 Subject: [PATCH 016/139] fix stack check error naming --- static-check/src/errors/static_check.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 static-check/src/errors/static_check.rs diff --git a/static-check/src/errors/static_check.rs b/static-check/src/errors/static_check.rs new file mode 100644 index 0000000000..e69de29bb2 From a9b16cfaa806372ea9d312d09cb203abfe1af3b8 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 14 Oct 2020 16:37:19 -0700 Subject: [PATCH 017/139] update symbol table tests --- dynamic-check/src/dynamic_check.rs | 16 ++++---- dynamic-check/tests/mod.rs | 2 +- static-check/src/errors/mod.rs | 3 ++ static-check/src/errors/static_check.rs | 49 +++++++++++++++++++++++++ static-check/src/errors/symbol_table.rs | 10 ++--- static-check/src/static_check.rs | 21 +++++++---- static-check/src/symbol_table.rs | 2 +- static-check/tests/mod.rs | 28 ++++++-------- static-check/tests/symbol_table/mod.rs | 10 ++--- 9 files changed, 97 insertions(+), 44 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 53b4fc8d4d..96042dfe88 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -28,7 +28,7 @@ pub struct DynamicCheck { impl DynamicCheck { /// - /// Return a new `DynamicCheck` from a given program and symbol table. + /// Returns a new `DynamicCheck` from a given program and symbol table. /// pub fn new(program: &Program, symbol_table: SymbolTable) -> Self { let mut dynamic_check = Self { @@ -73,7 +73,7 @@ impl DynamicCheck { } /// - /// Return the result of evaluating all `TypeAssertion` predicates. + /// Returns the result of evaluating all `TypeAssertion` predicates. /// /// Will attempt to substitute a `Type` for all `TypeVariable`s. /// Returns `true` if all `TypeAssertion` predicates are true. @@ -207,7 +207,7 @@ pub struct VariableTable(pub HashMap); impl VariableTable { /// - /// Return a new variable table + /// Returns a new variable table /// pub fn new() -> Self { Self(HashMap::new()) @@ -248,14 +248,14 @@ pub struct TypeAssertion { impl TypeAssertion { /// - /// Return a `TypeAssertion` predicate from given left and right `TypeElement`s + /// Returns a `TypeAssertion` predicate from given left and right `TypeElement`s /// pub fn new(left: TypeElement, right: TypeElement) -> Self { Self { left, right } } /// - /// Substitute the given `TypeVariable` for each `TypeElement` in the `TypeAssertion`. + /// Substitutes the given `TypeVariable` for each `TypeElement` in the `TypeAssertion`. /// pub fn substitute(&mut self, variable: &TypeVariable, type_: &TypeElement) { self.left.substitute(variable, type_); @@ -289,7 +289,7 @@ pub enum TypeElement { impl TypeElement { /// - /// Return a new `TypeElement` from the given expression and symbol table. + /// Returns a new `TypeElement` from the given expression and symbol table. /// pub fn new(expression: &Expression, _symbol_table: SymbolTable) -> Self { match expression { @@ -301,14 +301,14 @@ impl TypeElement { } /// - /// Return a boolean `TypeElement`. + /// Returns a boolean `TypeElement`. /// pub fn boolean() -> Self { TypeElement::Type(Type::Boolean) } /// - /// Substitute the given `TypeElement` if self is equal to the given `TypeVariable`. + /// Substitutes the given `TypeElement` if self is equal to the given `TypeVariable`. /// pub fn substitute(&mut self, variable: &TypeVariable, type_: &TypeElement) { match self { diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 90a6147221..ce2ae7eb8b 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -45,7 +45,7 @@ impl TestDynamicCheck { let program = typed.into_repr(); // Create static check. - let mut static_check = StaticCheck::new(&program).unwrap(); + let mut static_check = StaticCheck::run(&program).unwrap(); // Create dynamic check let dynamic_check = DynamicCheck::new(&program, static_check); diff --git a/static-check/src/errors/mod.rs b/static-check/src/errors/mod.rs index 107ac193f8..56968c74ff 100644 --- a/static-check/src/errors/mod.rs +++ b/static-check/src/errors/mod.rs @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +pub mod static_check; +pub use self::static_check::*; + pub mod symbol_table; pub use self::symbol_table::*; diff --git a/static-check/src/errors/static_check.rs b/static-check/src/errors/static_check.rs index e69de29bb2..31bf2ab1da 100644 --- a/static-check/src/errors/static_check.rs +++ b/static-check/src/errors/static_check.rs @@ -0,0 +1,49 @@ +// 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 . + +use crate::SymbolTableError; +use leo_typed::Error as FormattedError; + +use std::path::PathBuf; + +/// Errors encountered when tracking variable, function and circuit names in a program. +#[derive(Debug, Error)] +pub enum StaticCheckError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + SymbolTableError(#[from] SymbolTableError), +} + +impl StaticCheckError { + /// + /// Sets the filepath for the error stacktrace. + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + StaticCheckError::Error(error) => error.set_path(path), + StaticCheckError::SymbolTableError(error) => error.set_path(path), + } + } + + // /// + // /// Returns a new formatted error with a given message and span information. + // /// + // fn new_from_span(message: String, span: Span) -> Self { + // StaticCheckError::Error(FormattedError::new_from_span(message, span)) + // } +} diff --git a/static-check/src/errors/symbol_table.rs b/static-check/src/errors/symbol_table.rs index deca39c4a1..59c722c1a1 100644 --- a/static-check/src/errors/symbol_table.rs +++ b/static-check/src/errors/symbol_table.rs @@ -19,7 +19,7 @@ use leo_typed::{Error as FormattedError, Identifier, Span}; use std::path::PathBuf; -/// Errors encountered when tracking variable, function, and circuit names in a program +/// Errors encountered when tracking variable, function, and circuit names in a program. #[derive(Debug, Error)] pub enum SymbolTableError { #[error("{}", _0)] @@ -31,7 +31,7 @@ pub enum SymbolTableError { impl SymbolTableError { /// - /// Set the filepath for the error stacktrace + /// Sets the filepath for the error stacktrace. /// pub fn set_path(&mut self, path: PathBuf) { match self { @@ -41,14 +41,14 @@ impl SymbolTableError { } /// - /// Return a new formatted error with a given message and span information + /// Returns a new formatted error with a given message and span information. /// fn new_from_span(message: String, span: Span) -> Self { SymbolTableError::Error(FormattedError::new_from_span(message, span)) } /// - /// Two circuits have been defined with the same name + /// 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); @@ -57,7 +57,7 @@ impl SymbolTableError { } /// - /// Two functions have been defined with the same name + /// 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); diff --git a/static-check/src/static_check.rs b/static-check/src/static_check.rs index 3cf3cfc525..fb24d1673a 100644 --- a/static-check/src/static_check.rs +++ b/static-check/src/static_check.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{SymbolTable, SymbolTableError}; +use crate::{StaticCheckError, SymbolTable}; use leo_typed::Program; /// Performs a static type check over a program. @@ -24,12 +24,19 @@ pub struct StaticCheck { impl StaticCheck { /// - /// Return a new `StaticCheck` from a given program. + /// Returns a new `StaticCheck` with an empty symbol table. /// - pub fn new(program: &Program) -> Result { - let mut check = Self { + pub fn new() -> Self { + Self { table: SymbolTable::new(None), - }; + } + } + + /// + /// Returns a new `SymbolTable` from a given program. + /// + pub fn run(program: &Program) -> Result { + let mut check = Self::new(); // Run pass one checks check.pass_one(program)?; @@ -46,7 +53,7 @@ impl StaticCheck { /// 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 pass_one(&mut self, program: &Program) -> Result<(), SymbolTableError> { + pub fn pass_one(&mut self, program: &Program) -> Result<(), StaticCheckError> { // Check unresolved program circuit names. self.table.check_duplicate_circuits(&program.circuits)?; @@ -63,7 +70,7 @@ impl StaticCheck { /// symbol table. Variables defined later in the unresolved program can lookup the definition and /// refer to its expected types. /// - pub fn pass_two(&mut self, program: &Program) -> Result<(), SymbolTableError> { + pub fn pass_two(&mut self, program: &Program) -> Result<(), StaticCheckError> { // Check unresolved program circuit definitions. self.table.check_unknown_types_circuits(&program.circuits)?; diff --git a/static-check/src/symbol_table.rs b/static-check/src/symbol_table.rs index f8c8aeca37..9f9b9bf3fe 100644 --- a/static-check/src/symbol_table.rs +++ b/static-check/src/symbol_table.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CircuitType, FunctionType, ParameterType, SymbolTableError}; -use leo_typed::{Circuit, Function, Identifier, Program as UnresolvedProgram}; +use leo_typed::{Circuit, Function, Identifier}; use leo_imports::ImportParser; use std::collections::HashMap; diff --git a/static-check/tests/mod.rs b/static-check/tests/mod.rs index f8b87e881d..b748415e6b 100644 --- a/static-check/tests/mod.rs +++ b/static-check/tests/mod.rs @@ -17,7 +17,7 @@ pub mod symbol_table; use leo_ast::LeoAst; -use leo_symbol_table::{OldSymbolTable, SymbolTableError}; +use leo_static_check::{StaticCheck, StaticCheckError, SymbolTableError}; use leo_typed::LeoTypedAst; use std::path::PathBuf; @@ -25,11 +25,11 @@ use std::path::PathBuf; const TEST_PROGRAM_PATH: &str = ""; /// A helper struct to test a `SymbolTable`. -pub struct TestSymbolTable { +pub struct TestStaticCheck { typed: LeoTypedAst, } -impl TestSymbolTable { +impl TestStaticCheck { /// /// Returns a typed syntax tree given a Leo program. /// @@ -59,13 +59,7 @@ impl TestSymbolTable { let program = self.typed.into_repr(); // Create new symbol table. - let symbol_table = &mut OldSymbolTable::new(None); - - // Run the first pass to check for duplicate names. - symbol_table.pass_one(&program).unwrap(); - - // Run the second pass to check for invalid definitions. - symbol_table.pass_two(&program).unwrap(); + let _symbol_table = StaticCheck::run(&program).unwrap(); } /// @@ -78,13 +72,13 @@ impl TestSymbolTable { let program = self.typed.into_repr(); // Create new symbol table. - let symbol_table = &mut OldSymbolTable::new(None); + let static_check = &mut StaticCheck::new(); // Run pass one and expect an error. - let error = symbol_table.pass_one(&program).unwrap_err(); + let error = static_check.pass_one(&program).unwrap_err(); match error { - SymbolTableError::Error(_) => {} // Ok + StaticCheckError::SymbolTableError(SymbolTableError::Error(_)) => {} // Ok error => panic!("Expected a symbol table error found `{}`", error), } } @@ -99,16 +93,16 @@ impl TestSymbolTable { let program = self.typed.into_repr(); // Create a new symbol table. - let symbol_table = &mut OldSymbolTable::new(None); + let static_check = &mut StaticCheck::new(); // Run the pass one and expect no errors. - symbol_table.pass_one(&program).unwrap(); + static_check.pass_one(&program).unwrap(); // Run the pass two and expect and error. - let error = symbol_table.pass_two(&program).unwrap_err(); + let error = static_check.pass_two(&program).unwrap_err(); match error { - SymbolTableError::TypeError(_) => {} //Ok + StaticCheckError::SymbolTableError(SymbolTableError::TypeError(_)) => {} //Ok error => panic!("Expected a type error found `{}`", error), } } diff --git a/static-check/tests/symbol_table/mod.rs b/static-check/tests/symbol_table/mod.rs index b6d511c89c..c703db4d17 100644 --- a/static-check/tests/symbol_table/mod.rs +++ b/static-check/tests/symbol_table/mod.rs @@ -11,7 +11,7 @@ // 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 . -use crate::TestSymbolTable; +use crate::TestStaticCheck; /// /// Defines a circuit `Foo {}`. @@ -23,7 +23,7 @@ use crate::TestSymbolTable; #[test] fn test_duplicate_circuit() { let program_bytes = include_bytes!("duplicate_circuit.leo"); - let resolver = TestSymbolTable::new(program_bytes); + let resolver = TestStaticCheck::new(program_bytes); resolver.expect_pass_one_error(); } @@ -38,7 +38,7 @@ fn test_duplicate_circuit() { #[test] fn test_duplicate_function() { let program_bytes = include_bytes!("duplicate_function.leo"); - let resolver = TestSymbolTable::new(program_bytes); + let resolver = TestStaticCheck::new(program_bytes); resolver.expect_pass_one_error(); } @@ -52,7 +52,7 @@ fn test_duplicate_function() { #[test] fn test_self_not_available() { let program_bytes = include_bytes!("self_not_available.leo"); - let resolver = TestSymbolTable::new(program_bytes); + let resolver = TestStaticCheck::new(program_bytes); resolver.expect_pass_two_error(); } @@ -66,7 +66,7 @@ fn test_self_not_available() { #[test] fn test_undefined_circuit() { let program_bytes = include_bytes!("undefined_circuit.leo"); - let resolver = TestSymbolTable::new(program_bytes); + let resolver = TestStaticCheck::new(program_bytes); resolver.expect_pass_two_error(); } From 0702e1f92f9c9249ef55b988a356725214e53d98 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 14 Oct 2020 17:10:51 -0700 Subject: [PATCH 018/139] update type assertions for new types --- dynamic-check/src/dynamic_check.rs | 136 ++++++++---------------- dynamic-check/tests/mod.rs | 4 +- static-check/src/types/type_variable.rs | 13 +++ 3 files changed, 61 insertions(+), 92 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 96042dfe88..2bf99f3033 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_static_check::{FunctionInputType, FunctionType, SymbolTable, Type}; +use leo_static_check::{FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; use leo_typed::{Expression, Function, Identifier, Program, Span, Statement}; use serde::{Deserialize, Serialize}; @@ -157,10 +157,10 @@ impl FunctionBody { let output_type = &self.function_type.output.type_; // Create the left hand side of a type assertion. - let left = TypeElement::Type(output_type.clone()); + let left = output_type.clone(); // Create the right hand side from the statement return expression. - let right = TypeElement::new(expression, self.user_defined_types.clone()); + let right = self.parse_expression(expression); // Create a new type assertion for the statement return. let type_assertion = TypeAssertion::new(left, right); @@ -169,6 +169,33 @@ impl FunctionBody { self.type_assertions.push(type_assertion) } + /// + /// Returns the type of an expression. + /// Collects a vector of `TypeAssertion` predicates from the expression. + /// + fn parse_expression(&mut self, expression: &Expression) -> Type { + match expression { + Expression::Identifier(identifier) => Self::parse_identifier(&identifier), + Expression::Implicit(name, _) => Self::parse_implicit(name), + Expression::Boolean(_, _) => Type::Boolean, + expression => unimplemented!("expression {} not implemented", expression), + } + } + + /// + /// Returns a new type variable from a given identifier + /// + fn parse_identifier(identifier: &Identifier) -> Type { + Type::TypeVariable(TypeVariable::from(identifier.name.clone())) + } + + /// + /// Returns a new type variable from a given identifier + /// + fn parse_implicit(name: &String) -> Type { + Type::TypeVariable(TypeVariable::from(identifier.name.clone())) + } + /// /// Iteratively solves all `TypeAssertions`. /// @@ -182,7 +209,7 @@ impl FunctionBody { println!("assertion: {:?}", type_assertion); // Get type variable and type - if let Some((type_variable, type_)) = type_assertion.get_substitute() { + if let Some((type_variable, type_)) = type_assertion.get_pair() { // Substitute type variable for type in unsolved for original in &mut unsolved { original.substitute(&type_variable, &type_) @@ -239,115 +266,44 @@ impl VariableTable { } } -/// A predicate that evaluates equality between two `TypeElement`s. +/// A predicate that evaluates equality between two `Types`s. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct TypeAssertion { - left: TypeElement, - right: TypeElement, + left: Type, + right: Type, } impl TypeAssertion { /// - /// Returns a `TypeAssertion` predicate from given left and right `TypeElement`s + /// Returns a `TypeAssertion` predicate from given left and right `Types`s /// - pub fn new(left: TypeElement, right: TypeElement) -> Self { + pub fn new(left: Type, right: Type) -> Self { Self { left, right } } /// - /// Substitutes the given `TypeVariable` for each `TypeElement` in the `TypeAssertion`. + /// Substitutes the given `TypeVariable` for each `Types` in the `TypeAssertion`. /// - pub fn substitute(&mut self, variable: &TypeVariable, type_: &TypeElement) { + pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { self.left.substitute(variable, type_); self.right.substitute(variable, type_); } /// - /// Returns true if the left `TypeElement` is equal to the right `TypeElement`. + /// Returns true if the left `Types` is equal to the right `Types`. /// pub fn evaluate(&self) -> bool { self.left.eq(&self.right) } - pub fn get_substitute(&self) -> Option<(TypeVariable, TypeElement)> { + /// + /// Returns the (type variable, type) pair from this assertion. + /// + pub fn get_pair(&self) -> Option<(TypeVariable, Type)> { match (&self.left, &self.right) { - (TypeElement::Variable(variable), element) => Some((variable.clone(), element.clone())), - (TypeElement::Type(type_), TypeElement::Variable(variable)) => { - Some((variable.clone(), TypeElement::Type(type_.clone()))) - } - (TypeElement::Type(_), TypeElement::Type(_)) => None, + (Type::TypeVariable(variable), type_) => Some((variable.clone(), type_.clone())), + (type_, Type::TypeVariable(variable)) => Some((variable.clone(), type_.clone())), + (_type, _type) => None, // No (type variable, type) pair can be returned from two types } } } - -/// A `Type` or a `TypeVariable` in a `TypeAssertion`. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub enum TypeElement { - Type(Type), - Variable(TypeVariable), -} - -impl TypeElement { - /// - /// Returns a new `TypeElement` from the given expression and symbol table. - /// - pub fn new(expression: &Expression, _symbol_table: SymbolTable) -> Self { - match expression { - Expression::Identifier(identifier) => Self::from(identifier.clone()), - Expression::Implicit(name, _) => Self::from(name.clone()), - Expression::Boolean(_, _) => Self::boolean(), - expression => unimplemented!("expression {} not implemented", expression), - } - } - - /// - /// Returns a boolean `TypeElement`. - /// - pub fn boolean() -> Self { - TypeElement::Type(Type::Boolean) - } - - /// - /// Substitutes the given `TypeElement` if self is equal to the given `TypeVariable`. - /// - pub fn substitute(&mut self, variable: &TypeVariable, type_: &TypeElement) { - match self { - TypeElement::Type(_) => {} - TypeElement::Variable(original) => { - if original.eq(&variable) { - *self = type_.clone() - } - } - } - } -} - -impl From for TypeElement { - fn from(name: String) -> Self { - Self::Variable(TypeVariable::from(name)) - } -} - -impl From for TypeElement { - fn from(identifier: Identifier) -> Self { - Self::Variable(TypeVariable::from(identifier)) - } -} - -/// An unknown type in a `TypeAssertion`. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct TypeVariable { - name: String, -} - -impl From for TypeVariable { - fn from(name: String) -> Self { - Self { name } - } -} - -impl From for TypeVariable { - fn from(identifier: Identifier) -> Self { - Self::from(identifier.name) - } -} diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index ce2ae7eb8b..0a2eca61f1 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -45,10 +45,10 @@ impl TestDynamicCheck { let program = typed.into_repr(); // Create static check. - let mut static_check = StaticCheck::run(&program).unwrap(); + let symbol_table = StaticCheck::run(&program).unwrap(); // Create dynamic check - let dynamic_check = DynamicCheck::new(&program, static_check); + let dynamic_check = DynamicCheck::new(&program, symbol_table); Self { dynamic_check } } diff --git a/static-check/src/types/type_variable.rs b/static-check/src/types/type_variable.rs index cc1c0b1f5c..d38cd402c2 100644 --- a/static-check/src/types/type_variable.rs +++ b/static-check/src/types/type_variable.rs @@ -13,6 +13,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +use leo_typed::Identifier; use serde::{Deserialize, Serialize}; use std::fmt; @@ -28,3 +29,15 @@ impl fmt::Display for TypeVariable { write!(f, "{}", self.name) } } + +impl From for TypeVariable { + fn from(name: String) -> Self { + Self { name } + } +} + +impl From for TypeVariable { + fn from(identifier: Identifier) -> Self { + Self::from(identifier.name) + } +} From 6e8170a58f84dee3560242448e4a6121c63b15b4 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 14 Oct 2020 18:11:35 -0700 Subject: [PATCH 019/139] parse expression types for operations --- dynamic-check/src/dynamic_check.rs | 80 ++++++++++++++++++++++++++++++ typed/src/expression.rs | 2 +- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 2bf99f3033..a52843b391 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -175,13 +175,93 @@ impl FunctionBody { /// fn parse_expression(&mut self, expression: &Expression) -> Type { match expression { + // Type variables Expression::Identifier(identifier) => Self::parse_identifier(&identifier), Expression::Implicit(name, _) => Self::parse_implicit(name), + + // Explicit types Expression::Boolean(_, _) => Type::Boolean, + Expression::Address(_, _) => Type::Address, + Expression::Field(_, _) => Type::Field, + Expression::Group(_) => Type::Group, + Expression::Integer(integer_type, _, _) => Type::IntegerType(integer_type.clone()), + + // Number operations + Expression::Add(left, right, span) => self.parse_binary_expression(left, right, span), + Expression::Sub(left, right, span) => self.parse_binary_expression(left, right, span), + Expression::Mul(left, right, span) => self.parse_binary_expression(left, right, span), + Expression::Div(left, right, span) => self.parse_binary_expression(left, right, span), + Expression::Pow(left, right, span) => self.parse_binary_expression(left, right, span), + Expression::Negate(expression, _span) => self.parse_expression(expression), + + // Boolean operations + Expression::Not(expression, _span) => self.parse_boolean_expression(expression), + Expression::Or(left, right, span) => self.parse_boolean_binary_expression(left, right, span), + Expression::And(left, right, span) => self.parse_boolean_binary_expression(left, right, span), + Expression::Eq(left, right, span) => self.parse_boolean_binary_expression(left, right, span), + Expression::Ge(left, right, span) => self.parse_boolean_binary_expression(left, right, span), + Expression::Le(left, right, span) => self.parse_boolean_binary_expression(left, right, span), + Expression::Lt(left, right, span) => self.parse_boolean_binary_expression(left, right, span), + expression => unimplemented!("expression {} not implemented", expression), } } + /// + /// Returns the `Boolean` type if the expression is a `Boolean` type. + /// + fn parse_boolean_expression(&mut self, expression: &Expression) -> Type { + // Return the `Boolean` type + let boolean_type = Type::Boolean; + + // Get the type of the expression + let expression_type = self.parse_expression(expression); + + // TODO (collinc97) throw an error if the expression is not a `Boolean` type. + if expression_type.ne(&boolean_type) { + unimplemented!("Mismatched types parse_boolean_expression") + } + + boolean_type + } + + /// + /// Returns the type of a binary expression. + /// Collects a vector of `TypeAssertion` predicates from the expression. + /// + fn parse_binary_expression(&mut self, left: &Expression, right: &Expression, _span: &Span) -> Type { + // Get the left expression type. + let left_type = self.parse_expression(left); + + // Get the right expression type. + let right_type = self.parse_expression(right); + + // TODO (collinc97) throw an error if left type does not match right type + if left_type.ne(&right_type) { + unimplemented!("Mismatched types parse_binary_expression") + } + + left_type + } + + /// + /// Returns the `Boolean` type if the binary expression is a `Boolean` type. + /// + fn parse_boolean_binary_expression(&mut self, left: &Expression, right: &Expression, _span: &Span) -> Type { + // Return the `Boolean` type. + let boolean_type = Type::Boolean; + + // Get the type of the binary expression. + let binary_expression_type = self.parse_binary_expression(left, right, _span); + + // TODO (collinc97) throw an error if the binary expression is not a `Boolean` type. + if binary_expression_type.ne(&boolean_type) { + unimplemented!("Mismatched types parse_boolean_binary_expression") + } + + boolean_type + } + /// /// Returns a new type variable from a given identifier /// diff --git a/typed/src/expression.rs b/typed/src/expression.rs index 5fc2543c1a..4f7f907405 100644 --- a/typed/src/expression.rs +++ b/typed/src/expression.rs @@ -74,10 +74,10 @@ pub enum Expression { Mul(Box, Box, Span), Div(Box, Box, Span), Pow(Box, Box, Span), + Negate(Box, Span), // Boolean operations Not(Box, Span), - Negate(Box, Span), Or(Box, Box, Span), And(Box, Box, Span), Eq(Box, Box, Span), From 5188d3b6b43c74e9f941ab5b8cdabfdb97f0aef3 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 14 Oct 2020 18:34:43 -0700 Subject: [PATCH 020/139] parse conditional expression types --- dynamic-check/src/dynamic_check.rs | 78 +++++++++++++++++++----------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index a52843b391..e73e0ed565 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -171,7 +171,6 @@ impl FunctionBody { /// /// Returns the type of an expression. - /// Collects a vector of `TypeAssertion` predicates from the expression. /// fn parse_expression(&mut self, expression: &Expression) -> Type { match expression { @@ -203,10 +202,47 @@ impl FunctionBody { Expression::Le(left, right, span) => self.parse_boolean_binary_expression(left, right, span), Expression::Lt(left, right, span) => self.parse_boolean_binary_expression(left, right, span), + // Conditionals + Expression::IfElse(condition, first, second, span) => { + self.parse_conditional_expression(condition, first, second, span) + } + expression => unimplemented!("expression {} not implemented", expression), } } + /// + /// Returns a new type variable from a given identifier + /// + fn parse_identifier(identifier: &Identifier) -> Type { + Type::TypeVariable(TypeVariable::from(identifier.name.clone())) + } + + /// + /// Returns a new type variable from a given identifier + /// + fn parse_implicit(name: &String) -> Type { + Type::TypeVariable(TypeVariable::from(identifier.name.clone())) + } + + /// + /// Returns the type of a binary expression. + /// + fn parse_binary_expression(&mut self, left: &Expression, right: &Expression, _span: &Span) -> Type { + // Get the left expression type. + let left_type = self.parse_expression(left); + + // Get the right expression type. + let right_type = self.parse_expression(right); + + // TODO (collinc97) throw an error if left type does not match right type + if left_type.ne(&right_type) { + unimplemented!("Mismatched types parse_binary_expression") + } + + left_type + } + /// /// Returns the `Boolean` type if the expression is a `Boolean` type. /// @@ -225,25 +261,6 @@ impl FunctionBody { boolean_type } - /// - /// Returns the type of a binary expression. - /// Collects a vector of `TypeAssertion` predicates from the expression. - /// - fn parse_binary_expression(&mut self, left: &Expression, right: &Expression, _span: &Span) -> Type { - // Get the left expression type. - let left_type = self.parse_expression(left); - - // Get the right expression type. - let right_type = self.parse_expression(right); - - // TODO (collinc97) throw an error if left type does not match right type - if left_type.ne(&right_type) { - unimplemented!("Mismatched types parse_binary_expression") - } - - left_type - } - /// /// Returns the `Boolean` type if the binary expression is a `Boolean` type. /// @@ -263,17 +280,20 @@ impl FunctionBody { } /// - /// Returns a new type variable from a given identifier + /// Returns the type of the conditional expression. /// - fn parse_identifier(identifier: &Identifier) -> Type { - Type::TypeVariable(TypeVariable::from(identifier.name.clone())) - } + fn parse_conditional_expression( + &mut self, + condition: &Expression, + first: &Expression, + second: &Expression, + _span: &Span, + ) -> Type { + // Check that the type of the condition expression is a boolean. + let _condition_type = self.parse_boolean_expression(condition); - /// - /// Returns a new type variable from a given identifier - /// - fn parse_implicit(name: &String) -> Type { - Type::TypeVariable(TypeVariable::from(identifier.name.clone())) + // Check that the types of the first and second expression are equal. + self.parse_binary_expression(first, second, span) } /// From 5edbcf0e056a4fa12d8982457b6ad4cb95ab441e Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 15 Oct 2020 17:06:34 -0700 Subject: [PATCH 021/139] add work from resolver branch --- dynamic-check/src/ast/circuits/circuit.rs | 84 ++++++ dynamic-check/src/ast/circuits/mod.rs | 18 ++ dynamic-check/src/ast/console/mod.rs | 15 ++ .../src/ast/expressions/arithmetic/add.rs | 38 +++ .../src/ast/expressions/arithmetic/div.rs | 38 +++ .../src/ast/expressions/arithmetic/mod.rs | 33 +++ .../src/ast/expressions/arithmetic/mul.rs | 38 +++ .../src/ast/expressions/arithmetic/negate.rs | 36 +++ .../src/ast/expressions/arithmetic/pow.rs | 38 +++ .../src/ast/expressions/arithmetic/sub.rs | 38 +++ .../src/ast/expressions/array/array.rs | 71 +++++ .../src/ast/expressions/array/array_access.rs | 42 +++ .../src/ast/expressions/array/mod.rs | 27 ++ .../expressions/array/range_or_expression.rs | 62 +++++ .../expressions/array/spread_or_expression.rs | 59 +++++ .../src/ast/expressions/binary/binary.rs | 41 +++ .../src/ast/expressions/binary/mod.rs | 18 ++ .../src/ast/expressions/circuit/circuit.rs | 78 ++++++ .../ast/expressions/circuit/circuit_access.rs | 79 ++++++ .../circuit/circuit_static_access.rs | 66 +++++ .../circuit/circuit_variable_definition.rs | 47 ++++ .../src/ast/expressions/circuit/mod.rs | 27 ++ .../expressions/conditional/conditional.rs | 50 ++++ .../src/ast/expressions/conditional/mod.rs | 18 ++ .../src/ast/expressions/expression.rs | 133 ++++++++++ .../src/ast/expressions/expression_value.rs | 133 ++++++++++ .../ast/expressions/function/core_circuit.rs | 32 +++ .../ast/expressions/function/function_call.rs | 71 +++++ .../src/ast/expressions/function/mod.rs | 21 ++ .../ast/expressions/identifier/identifier.rs | 45 ++++ .../src/ast/expressions/identifier/mod.rs | 18 ++ .../src/ast/expressions/logical/and.rs | 43 +++ .../src/ast/expressions/logical/mod.rs | 24 ++ .../src/ast/expressions/logical/not.rs | 42 +++ .../src/ast/expressions/logical/or.rs | 43 +++ dynamic-check/src/ast/expressions/mod.rs | 54 ++++ .../src/ast/expressions/relational/eq.rs | 43 +++ .../src/ast/expressions/relational/ge.rs | 48 ++++ .../src/ast/expressions/relational/gt.rs | 48 ++++ .../src/ast/expressions/relational/le.rs | 48 ++++ .../src/ast/expressions/relational/lt.rs | 48 ++++ .../src/ast/expressions/relational/mod.rs | 30 +++ .../src/ast/expressions/tuple/mod.rs | 21 ++ .../src/ast/expressions/tuple/tuple.rs | 78 ++++++ .../src/ast/expressions/tuple/tuple_access.rs | 56 ++++ .../src/ast/expressions/values/address.rs | 38 +++ .../src/ast/expressions/values/boolean.rs | 38 +++ .../src/ast/expressions/values/field.rs | 38 +++ .../src/ast/expressions/values/group.rs | 35 +++ .../src/ast/expressions/values/implicit.rs | 45 ++++ .../src/ast/expressions/values/integer.rs | 39 +++ .../src/ast/expressions/values/mod.rs | 33 +++ dynamic-check/src/ast/functions/function.rs | 78 ++++++ dynamic-check/src/ast/functions/mod.rs | 21 ++ .../src/ast/functions/test_function.rs | 47 ++++ dynamic-check/src/ast/imports/import.rs | 38 +++ dynamic-check/src/ast/imports/mod.rs | 18 ++ dynamic-check/src/ast/mod.rs | 35 +++ dynamic-check/src/ast/programs/mod.rs | 18 ++ dynamic-check/src/ast/programs/program.rs | 95 +++++++ .../src/ast/statements/assign/assign.rs | 99 +++++++ .../src/ast/statements/assign/mod.rs | 18 ++ .../ast/statements/conditional/conditional.rs | 130 +++++++++ .../src/ast/statements/conditional/mod.rs | 18 ++ .../ast/statements/definition/definition.rs | 249 ++++++++++++++++++ .../src/ast/statements/definition/mod.rs | 18 ++ .../src/ast/statements/iteration/iteration.rs | 75 ++++++ .../src/ast/statements/iteration/mod.rs | 18 ++ dynamic-check/src/ast/statements/mod.rs | 33 +++ .../src/ast/statements/return_/mod.rs | 18 ++ .../src/ast/statements/return_/return_.rs | 33 +++ dynamic-check/src/ast/statements/statement.rs | 64 +++++ dynamic-check/src/errors/circuit.rs | 45 ++++ dynamic-check/src/errors/expression.rs | 178 +++++++++++++ dynamic-check/src/errors/function.rs | 60 +++++ dynamic-check/src/errors/mod.rs | 39 +++ dynamic-check/src/errors/program.rs | 49 ++++ dynamic-check/src/errors/resolver.rs | 34 +++ dynamic-check/src/errors/statement.rs | 137 ++++++++++ dynamic-check/src/errors/symbol_table.rs | 59 +++++ dynamic-check/src/errors/type_.rs | 117 ++++++++ dynamic-check/src/resolver.rs | 114 ++++++++ dynamic-check/src/resolver_lib.rs | 27 ++ 83 files changed, 4388 insertions(+) create mode 100644 dynamic-check/src/ast/circuits/circuit.rs create mode 100644 dynamic-check/src/ast/circuits/mod.rs create mode 100644 dynamic-check/src/ast/console/mod.rs create mode 100644 dynamic-check/src/ast/expressions/arithmetic/add.rs create mode 100644 dynamic-check/src/ast/expressions/arithmetic/div.rs create mode 100644 dynamic-check/src/ast/expressions/arithmetic/mod.rs create mode 100644 dynamic-check/src/ast/expressions/arithmetic/mul.rs create mode 100644 dynamic-check/src/ast/expressions/arithmetic/negate.rs create mode 100644 dynamic-check/src/ast/expressions/arithmetic/pow.rs create mode 100644 dynamic-check/src/ast/expressions/arithmetic/sub.rs create mode 100644 dynamic-check/src/ast/expressions/array/array.rs create mode 100644 dynamic-check/src/ast/expressions/array/array_access.rs create mode 100644 dynamic-check/src/ast/expressions/array/mod.rs create mode 100644 dynamic-check/src/ast/expressions/array/range_or_expression.rs create mode 100644 dynamic-check/src/ast/expressions/array/spread_or_expression.rs create mode 100644 dynamic-check/src/ast/expressions/binary/binary.rs create mode 100644 dynamic-check/src/ast/expressions/binary/mod.rs create mode 100644 dynamic-check/src/ast/expressions/circuit/circuit.rs create mode 100644 dynamic-check/src/ast/expressions/circuit/circuit_access.rs create mode 100644 dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs create mode 100644 dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs create mode 100644 dynamic-check/src/ast/expressions/circuit/mod.rs create mode 100644 dynamic-check/src/ast/expressions/conditional/conditional.rs create mode 100644 dynamic-check/src/ast/expressions/conditional/mod.rs create mode 100644 dynamic-check/src/ast/expressions/expression.rs create mode 100644 dynamic-check/src/ast/expressions/expression_value.rs create mode 100644 dynamic-check/src/ast/expressions/function/core_circuit.rs create mode 100644 dynamic-check/src/ast/expressions/function/function_call.rs create mode 100644 dynamic-check/src/ast/expressions/function/mod.rs create mode 100644 dynamic-check/src/ast/expressions/identifier/identifier.rs create mode 100644 dynamic-check/src/ast/expressions/identifier/mod.rs create mode 100644 dynamic-check/src/ast/expressions/logical/and.rs create mode 100644 dynamic-check/src/ast/expressions/logical/mod.rs create mode 100644 dynamic-check/src/ast/expressions/logical/not.rs create mode 100644 dynamic-check/src/ast/expressions/logical/or.rs create mode 100644 dynamic-check/src/ast/expressions/mod.rs create mode 100644 dynamic-check/src/ast/expressions/relational/eq.rs create mode 100644 dynamic-check/src/ast/expressions/relational/ge.rs create mode 100644 dynamic-check/src/ast/expressions/relational/gt.rs create mode 100644 dynamic-check/src/ast/expressions/relational/le.rs create mode 100644 dynamic-check/src/ast/expressions/relational/lt.rs create mode 100644 dynamic-check/src/ast/expressions/relational/mod.rs create mode 100644 dynamic-check/src/ast/expressions/tuple/mod.rs create mode 100644 dynamic-check/src/ast/expressions/tuple/tuple.rs create mode 100644 dynamic-check/src/ast/expressions/tuple/tuple_access.rs create mode 100644 dynamic-check/src/ast/expressions/values/address.rs create mode 100644 dynamic-check/src/ast/expressions/values/boolean.rs create mode 100644 dynamic-check/src/ast/expressions/values/field.rs create mode 100644 dynamic-check/src/ast/expressions/values/group.rs create mode 100644 dynamic-check/src/ast/expressions/values/implicit.rs create mode 100644 dynamic-check/src/ast/expressions/values/integer.rs create mode 100644 dynamic-check/src/ast/expressions/values/mod.rs create mode 100644 dynamic-check/src/ast/functions/function.rs create mode 100644 dynamic-check/src/ast/functions/mod.rs create mode 100644 dynamic-check/src/ast/functions/test_function.rs create mode 100644 dynamic-check/src/ast/imports/import.rs create mode 100644 dynamic-check/src/ast/imports/mod.rs create mode 100644 dynamic-check/src/ast/mod.rs create mode 100644 dynamic-check/src/ast/programs/mod.rs create mode 100644 dynamic-check/src/ast/programs/program.rs create mode 100644 dynamic-check/src/ast/statements/assign/assign.rs create mode 100644 dynamic-check/src/ast/statements/assign/mod.rs create mode 100644 dynamic-check/src/ast/statements/conditional/conditional.rs create mode 100644 dynamic-check/src/ast/statements/conditional/mod.rs create mode 100644 dynamic-check/src/ast/statements/definition/definition.rs create mode 100644 dynamic-check/src/ast/statements/definition/mod.rs create mode 100644 dynamic-check/src/ast/statements/iteration/iteration.rs create mode 100644 dynamic-check/src/ast/statements/iteration/mod.rs create mode 100644 dynamic-check/src/ast/statements/mod.rs create mode 100644 dynamic-check/src/ast/statements/return_/mod.rs create mode 100644 dynamic-check/src/ast/statements/return_/return_.rs create mode 100644 dynamic-check/src/ast/statements/statement.rs create mode 100644 dynamic-check/src/errors/circuit.rs create mode 100644 dynamic-check/src/errors/expression.rs create mode 100644 dynamic-check/src/errors/function.rs create mode 100644 dynamic-check/src/errors/mod.rs create mode 100644 dynamic-check/src/errors/program.rs create mode 100644 dynamic-check/src/errors/resolver.rs create mode 100644 dynamic-check/src/errors/statement.rs create mode 100644 dynamic-check/src/errors/symbol_table.rs create mode 100644 dynamic-check/src/errors/type_.rs create mode 100644 dynamic-check/src/resolver.rs create mode 100644 dynamic-check/src/resolver_lib.rs diff --git a/dynamic-check/src/ast/circuits/circuit.rs b/dynamic-check/src/ast/circuits/circuit.rs new file mode 100644 index 0000000000..0e346b7a03 --- /dev/null +++ b/dynamic-check/src/ast/circuits/circuit.rs @@ -0,0 +1,84 @@ +// 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 . + +use crate::{CircuitError, Function}; +use leo_symbol_table::{Attribute, CircuitType, ResolvedNode, SymbolTable, Type, VariableType}; +use leo_typed::{circuit::Circuit as UnresolvedCircuit, identifier::Identifier, CircuitMember}; + +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// A circuit in the resolved syntax tree. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Circuit { + /// The user-defined type of this circuit. + pub type_: CircuitType, + + /// The circuit member functions. + pub functions: HashMap, +} + +impl ResolvedNode for Circuit { + type Error = CircuitError; + type UnresolvedNode = UnresolvedCircuit; + + /// + /// Return a new `Circuit` from a given `UnresolvedCircuit`. + /// + /// Performs a lookup in the given symbol table if the circuit contains user-defined types. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let identifier = unresolved.circuit_name; + let type_ = table.get_circuit(&identifier.name).unwrap().clone(); + + // Create circuit context + let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); + + // Create self variable + let self_key = "self".to_owned(); + let self_variable = VariableType { + identifier: identifier.clone(), + type_: Type::Circuit(identifier.clone()), + attributes: vec![Attribute::Mutable], + }; + child_table.insert_variable(self_key, self_variable); + + // Insert circuit functions into symbol table + for function in type_.functions.iter() { + let function_key = function.function.identifier.clone(); + let function_type = function.function.clone(); + + child_table.insert_function(function_key, function_type); + } + + // Resolve all circuit functions + let mut functions = HashMap::new(); + + for member in unresolved.members { + match member { + CircuitMember::CircuitVariable(_, _, _) => {} + CircuitMember::CircuitFunction(_, function) => { + let identifier = function.identifier.clone(); + let function_resolved = Function::resolve(&mut child_table.clone(), function)?; + + functions.insert(identifier, function_resolved); + } + } + } + + Ok(Circuit { type_, functions }) + } +} diff --git a/dynamic-check/src/ast/circuits/mod.rs b/dynamic-check/src/ast/circuits/mod.rs new file mode 100644 index 0000000000..5aa364bd84 --- /dev/null +++ b/dynamic-check/src/ast/circuits/mod.rs @@ -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 . + +pub mod circuit; +pub use self::circuit::*; diff --git a/dynamic-check/src/ast/console/mod.rs b/dynamic-check/src/ast/console/mod.rs new file mode 100644 index 0000000000..600f61b496 --- /dev/null +++ b/dynamic-check/src/ast/console/mod.rs @@ -0,0 +1,15 @@ +// 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 . diff --git a/dynamic-check/src/ast/expressions/arithmetic/add.rs b/dynamic-check/src/ast/expressions/arithmetic/add.rs new file mode 100644 index 0000000000..0a68369126 --- /dev/null +++ b/dynamic-check/src/ast/expressions/arithmetic/add.rs @@ -0,0 +1,38 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of adding `lhs + rhs` + pub(crate) fn add( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + // Resolve lhs and rhs expressions + let (lhs_resolved, rhs_resolved) = Self::binary(table, expected_type, lhs, rhs, span.clone())?; + + Ok(Expression { + type_: lhs_resolved.type_.clone(), + value: ExpressionValue::Add(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/arithmetic/div.rs b/dynamic-check/src/ast/expressions/arithmetic/div.rs new file mode 100644 index 0000000000..8a5bd4d779 --- /dev/null +++ b/dynamic-check/src/ast/expressions/arithmetic/div.rs @@ -0,0 +1,38 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of dividing `lhs / rhs` + pub(crate) fn div( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + // Resolve lhs and rhs expressions + let (lhs_resolved, rhs_resolved) = Self::binary(table, expected_type, lhs, rhs, span.clone())?; + + Ok(Expression { + type_: lhs_resolved.type_.clone(), + value: ExpressionValue::Div(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/arithmetic/mod.rs b/dynamic-check/src/ast/expressions/arithmetic/mod.rs new file mode 100644 index 0000000000..8888661b3d --- /dev/null +++ b/dynamic-check/src/ast/expressions/arithmetic/mod.rs @@ -0,0 +1,33 @@ +// 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 . + +pub mod add; +pub use self::add::*; + +pub mod div; +pub use self::div::*; + +pub mod mul; +pub use self::mul::*; + +pub mod negate; +pub use self::negate::*; + +pub mod pow; +pub use self::pow::*; + +pub mod sub; +pub use self::sub::*; diff --git a/dynamic-check/src/ast/expressions/arithmetic/mul.rs b/dynamic-check/src/ast/expressions/arithmetic/mul.rs new file mode 100644 index 0000000000..0e53130a0c --- /dev/null +++ b/dynamic-check/src/ast/expressions/arithmetic/mul.rs @@ -0,0 +1,38 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of multiplying `lhs * rhs` + pub(crate) fn mul( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + // Resolve lhs and rhs expressions + let (lhs_resolved, rhs_resolved) = Self::binary(table, expected_type, lhs, rhs, span.clone())?; + + Ok(Expression { + type_: lhs_resolved.type_.clone(), + value: ExpressionValue::Mul(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/arithmetic/negate.rs b/dynamic-check/src/ast/expressions/arithmetic/negate.rs new file mode 100644 index 0000000000..e2c988d37c --- /dev/null +++ b/dynamic-check/src/ast/expressions/arithmetic/negate.rs @@ -0,0 +1,36 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of negating `-expression` + pub(crate) fn negate( + table: &mut SymbolTable, + expected_type: Option, + expression: UnresolvedExpression, + span: Span, + ) -> Result { + let expression_resolved = Self::resolve(table, (expected_type, expression))?; + + Ok(Expression { + type_: expression_resolved.type_.clone(), + value: ExpressionValue::Negate(Box::new(expression_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/arithmetic/pow.rs b/dynamic-check/src/ast/expressions/arithmetic/pow.rs new file mode 100644 index 0000000000..4938d85ed9 --- /dev/null +++ b/dynamic-check/src/ast/expressions/arithmetic/pow.rs @@ -0,0 +1,38 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of exponentiation `lhs ** rhs` + pub(crate) fn pow( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + // Resolve lhs and rhs expressions + let (lhs_resolved, rhs_resolved) = Self::binary(table, expected_type, lhs, rhs, span.clone())?; + + Ok(Expression { + type_: lhs_resolved.type_.clone(), + value: ExpressionValue::Pow(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/arithmetic/sub.rs b/dynamic-check/src/ast/expressions/arithmetic/sub.rs new file mode 100644 index 0000000000..bef35c4040 --- /dev/null +++ b/dynamic-check/src/ast/expressions/arithmetic/sub.rs @@ -0,0 +1,38 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of subtracting `lhs - rhs` + pub(crate) fn sub( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + // Resolve lhs and rhs expressions + let (lhs_resolved, rhs_resolved) = Self::binary(table, expected_type, lhs, rhs, span.clone())?; + + Ok(Expression { + type_: lhs_resolved.type_.clone(), + value: ExpressionValue::Sub(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/array/array.rs b/dynamic-check/src/ast/expressions/array/array.rs new file mode 100644 index 0000000000..6b71320711 --- /dev/null +++ b/dynamic-check/src/ast/expressions/array/array.rs @@ -0,0 +1,71 @@ +// 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 . + +use crate::{ast::expressions::array::SpreadOrExpression, Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Span, SpreadOrExpression as UnresolvedSpreadOrExpression}; + +impl Expression { + /// Resolves an array expression + pub(crate) fn array( + table: &mut SymbolTable, + expected_type: Option, + expressions: Vec>, + span: Span, + ) -> Result { + // Expressions should evaluate to array type or array element type + let expected_element_type = if let Some(type_) = expected_type { + let (element_type, dimensions) = type_.get_type_array(span.clone())?; + + if dimensions[0] != expressions.len() { + //throw array dimension mismatch error + return Err(ExpressionError::invalid_length_array( + dimensions[0], + expressions.len(), + span.clone(), + )); + } + + Some(element_type.clone()) + } else { + None + }; + + // Store actual array element type + let mut actual_element_type = None; + let mut array = vec![]; + + // Resolve all array elements + for expression in expressions { + let expression_resolved = SpreadOrExpression::resolve(table, (expected_element_type.clone(), *expression))?; + let expression_type = expression_resolved.type_().clone(); + + array.push(Box::new(expression_resolved)); + actual_element_type = Some(expression_type); + } + + // Define array type for expression + let type_ = match actual_element_type { + Some(type_) => type_, + None => unimplemented!("ERROR: Arrays of size zero are no-op"), + }; + + Ok(Expression { + type_, + value: ExpressionValue::Array(array, span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/array/array_access.rs b/dynamic-check/src/ast/expressions/array/array_access.rs new file mode 100644 index 0000000000..66b5af8278 --- /dev/null +++ b/dynamic-check/src/ast/expressions/array/array_access.rs @@ -0,0 +1,42 @@ +// 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 . + +use crate::{ast::expressions::array::RangeOrExpression, Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, RangeOrExpression as UnresolvedRangeOrExpression, Span}; + +impl Expression { + /// Resolves an array access expression + pub(crate) fn array_access( + table: &mut SymbolTable, + expected_type: Option, + array: Box, + range: Box, + span: Span, + ) -> Result { + // Lookup the array in the symbol table. + // We do not know the length from this context so `expected_type = None`. + let array_resolved = Expression::resolve(table, (None, *array))?; + + // Resolve the range or expression + let range_resolved = RangeOrExpression::resolve(table, (expected_type, *range))?; + + Ok(Expression { + type_: range_resolved.type_().clone(), + value: ExpressionValue::ArrayAccess(Box::new(array_resolved), Box::new(range_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/array/mod.rs b/dynamic-check/src/ast/expressions/array/mod.rs new file mode 100644 index 0000000000..0c59a9f5d4 --- /dev/null +++ b/dynamic-check/src/ast/expressions/array/mod.rs @@ -0,0 +1,27 @@ +// 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 . + +pub mod array; +pub use self::array::*; + +pub mod array_access; +pub use self::array_access::*; + +pub mod range_or_expression; +pub use self::range_or_expression::*; + +pub mod spread_or_expression; +pub use self::spread_or_expression::*; diff --git a/dynamic-check/src/ast/expressions/array/range_or_expression.rs b/dynamic-check/src/ast/expressions/array/range_or_expression.rs new file mode 100644 index 0000000000..c0a01896d3 --- /dev/null +++ b/dynamic-check/src/ast/expressions/array/range_or_expression.rs @@ -0,0 +1,62 @@ +// 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 . + +use crate::{Expression, ExpressionError}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::RangeOrExpression as UnresolvedRangeOrExpression; + +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum RangeOrExpression { + Range(Expression, Expression), + Expression(Expression), +} + +impl RangeOrExpression { + /// If this is a range, return an array type. + /// If this is an expression, return a data type. + pub(crate) fn type_(&self) -> &Type { + match self { + RangeOrExpression::Range(expresion, _expression) => expresion.type_(), + RangeOrExpression::Expression(expression) => expression.type_(), + } + } +} + +impl ResolvedNode for RangeOrExpression { + type Error = ExpressionError; + type UnresolvedNode = (Option, UnresolvedRangeOrExpression); + + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let expected_type = unresolved.0; + let r_or_e = unresolved.1; + + Ok(match r_or_e { + UnresolvedRangeOrExpression::Range(from, to) => { + let resolved_from = Expression::resolve(table, (expected_type.clone(), from.unwrap())).unwrap(); + let resolved_to = Expression::resolve(table, (expected_type, to.unwrap())).unwrap(); + // TODO: add check for range type and array type + RangeOrExpression::Range(resolved_from, resolved_to) + } + UnresolvedRangeOrExpression::Expression(expression) => { + let expression_resolved = Expression::resolve(table, (expected_type, expression)).unwrap(); + // TODO: add check for array type + RangeOrExpression::Expression(expression_resolved) + } + }) + } +} diff --git a/dynamic-check/src/ast/expressions/array/spread_or_expression.rs b/dynamic-check/src/ast/expressions/array/spread_or_expression.rs new file mode 100644 index 0000000000..4997f7664b --- /dev/null +++ b/dynamic-check/src/ast/expressions/array/spread_or_expression.rs @@ -0,0 +1,59 @@ +// 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 . + +use crate::{Expression, ExpressionError}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::SpreadOrExpression as UnresolvedSpreadOrExpression; + +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum SpreadOrExpression { + Spread(Expression), + Expression(Expression), +} + +impl SpreadOrExpression { + pub(crate) fn type_(&self) -> &Type { + match self { + SpreadOrExpression::Spread(expression) => expression.type_(), + SpreadOrExpression::Expression(expression) => expression.type_(), + } + } +} + +impl ResolvedNode for SpreadOrExpression { + type Error = ExpressionError; + type UnresolvedNode = (Option, UnresolvedSpreadOrExpression); + + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let expected_type = unresolved.0; + let s_or_e = unresolved.1; + + Ok(match s_or_e { + UnresolvedSpreadOrExpression::Spread(spread) => { + let spread_resolved = Expression::resolve(table, (expected_type, spread)).unwrap(); + // TODO: add check for array type or array element type + SpreadOrExpression::Spread(spread_resolved) + } + UnresolvedSpreadOrExpression::Expression(expression) => { + let expression_resolved = Expression::resolve(table, (expected_type, expression)).unwrap(); + // TODO: add check for array type or array element type + SpreadOrExpression::Expression(expression_resolved) + } + }) + } +} diff --git a/dynamic-check/src/ast/expressions/binary/binary.rs b/dynamic-check/src/ast/expressions/binary/binary.rs new file mode 100644 index 0000000000..872e280f0a --- /dev/null +++ b/dynamic-check/src/ast/expressions/binary/binary.rs @@ -0,0 +1,41 @@ +// 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 . +use crate::{Expression, ExpressionError}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve a binary expression from left to right. + /// If no expected type is given, then the expression resolves to the lhs type. + pub(crate) fn binary( + table: &mut SymbolTable, + mut expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + _span: Span, + ) -> Result<(Self, Self), ExpressionError> { + // Resolve lhs with expected type + let lhs_resolved = Expression::resolve(table, (expected_type, lhs))?; + + // Set the expected type to the lhs type + expected_type = Some(lhs_resolved.type_.clone()); + + // Resolve the rhs with expected type + let rhs_resolved = Expression::resolve(table, (expected_type, rhs))?; + + Ok((lhs_resolved, rhs_resolved)) + } +} diff --git a/dynamic-check/src/ast/expressions/binary/mod.rs b/dynamic-check/src/ast/expressions/binary/mod.rs new file mode 100644 index 0000000000..e2c63f7183 --- /dev/null +++ b/dynamic-check/src/ast/expressions/binary/mod.rs @@ -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 . + +pub mod binary; +pub use self::binary::*; diff --git a/dynamic-check/src/ast/expressions/circuit/circuit.rs b/dynamic-check/src/ast/expressions/circuit/circuit.rs new file mode 100644 index 0000000000..57f306e41f --- /dev/null +++ b/dynamic-check/src/ast/expressions/circuit/circuit.rs @@ -0,0 +1,78 @@ +// 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 . +use crate::{CircuitVariableDefinition, Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{CircuitVariableDefinition as UnresolvedCircuitVariableDefinition, Identifier, Span}; + +impl Expression { + /// + /// Resolves an inline circuit expression. + /// + pub(crate) fn circuit( + table: &mut SymbolTable, + expected_type: Option, + identifier: Identifier, + variables: Vec, + span: Span, + ) -> Result { + // Check expected type + let type_ = Type::Circuit(identifier.clone()); + Type::check_type(&expected_type, &type_, span.clone())?; + + // Lookup circuit in symbol table + let circuit = table + .get_circuit(&identifier.name) + .ok_or(ExpressionError::undefined_circuit(identifier.clone()))?; + + // Check the number of variables given + let expected_variables = circuit.variables.clone(); + + if variables.len() != expected_variables.len() { + return Err(ExpressionError::invalid_length_circuit_members( + expected_variables.len(), + variables.len(), + span, + )); + } + + // Check the name and type for each circuit variable + let mut variables_resolved = vec![]; + + for variable in variables { + // Find variable by name + let matched_variable = expected_variables + .iter() + .find(|expected| expected.identifier.eq(&variable.identifier)); + + let variable_type = match matched_variable { + Some(variable_type) => variable_type, + None => return Err(ExpressionError::undefined_circuit_variable(variable.identifier)), + }; + + // Resolve the variable expression using the expected variable type + let expected_variable_type = Some(variable_type.type_.clone()); + + let variable_resolved = CircuitVariableDefinition::resolve(table, (expected_variable_type, variable))?; + + variables_resolved.push(variable_resolved); + } + + Ok(Expression { + type_, + value: ExpressionValue::Circuit(identifier, variables_resolved, span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_access.rs b/dynamic-check/src/ast/expressions/circuit/circuit_access.rs new file mode 100644 index 0000000000..c63ba5bb42 --- /dev/null +++ b/dynamic-check/src/ast/expressions/circuit/circuit_access.rs @@ -0,0 +1,79 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{Attribute, ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Identifier, Span}; + +impl Expression { + /// Resolve the type of a circuit member + pub(crate) fn circuit_access( + table: &mut SymbolTable, + expected_type: Option, + circuit: Box, + member: Identifier, + span: Span, + ) -> Result { + // Lookup the circuit in the symbol table. + // We do not know the exact circuit type from this context so `expected_type = None`. + let circuit_resolved = Expression::resolve(table, (None, *circuit))?; + let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?; + + // Lookup the circuit type in the symbol table + let circuit_type = table + .get_circuit(&circuit_name.name) + .ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?; + + // Resolve the circuit member as a circuit variable + let matched_variable = circuit_type + .variables + .iter() + .find(|variable| variable.identifier.eq(&member)); + + let type_ = match matched_variable { + // Return variable type + Some(variable) => variable.type_.clone(), + None => { + // Resolve the circuit member as a circuit function + let matched_function = circuit_type + .functions + .iter() + .find(|function| function.function.identifier.eq(&member)); + + match matched_function { + // Return function output type + Some(function) => { + // Check non-static method + if function.attributes.contains(&Attribute::Static) { + return Err(ExpressionError::invalid_static_member_access(member.name.clone(), span)); + } + + function.function.output.type_.clone() + } + None => return Err(ExpressionError::undefined_circuit_function(member, span)), + } + } + }; + + // Check type of circuit member + Type::check_type(&expected_type, &type_, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::CircuitMemberAccess(Box::new(circuit_resolved), member, span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs b/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs new file mode 100644 index 0000000000..278180746d --- /dev/null +++ b/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs @@ -0,0 +1,66 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{Attribute, ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Identifier, Span}; + +impl Expression { + /// Resolve the type of a static circuit member + pub(crate) fn circuit_static_access( + table: &mut SymbolTable, + expected_type: Option, + circuit: Box, + member: Identifier, + span: Span, + ) -> Result { + // Lookup the circuit in the symbol table. + // We do not know the exact circuit type from this context so `expected_type = None`. + let circuit_resolved = Expression::resolve(table, (None, *circuit))?; + let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?; + + // Lookup the circuit type in the symbol table + let circuit_type = table + .get_circuit(&circuit_name.name) + .ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?; + + // Resolve the circuit member as a circuit function + let matched_function = circuit_type + .functions + .iter() + .find(|function| function.function.identifier.eq(&member)); + + let type_ = match matched_function { + Some(function) => { + // Check static method + if function.attributes.contains(&Attribute::Static) { + function.function.output.type_.clone() + } else { + return Err(ExpressionError::invalid_member_access(member.name, span)); + } + } + None => return Err(ExpressionError::undefined_circuit_function_static(member, span)), + }; + + // Check type of static circuit function output + Type::check_type(&expected_type, &type_, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::CircuitStaticFunctionAccess(Box::new(circuit_resolved), member, span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs b/dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs new file mode 100644 index 0000000000..422942a731 --- /dev/null +++ b/dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs @@ -0,0 +1,47 @@ +// 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 . + +use crate::{Expression, ExpressionError}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{CircuitVariableDefinition as UnresolvedCircuitVariableDefinition, Identifier}; + +use serde::{Deserialize, Serialize}; + +/// A circuit variable with an assigned expression. Used when defining an inline circuit expression. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct CircuitVariableDefinition { + identifier: Identifier, + expression: Expression, +} + +impl ResolvedNode for CircuitVariableDefinition { + type Error = ExpressionError; + type UnresolvedNode = (Option, UnresolvedCircuitVariableDefinition); + + /// + /// Type check a circuit variable in an inline circuit expression + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let expected_type = unresolved.0; + let circuit_variable = unresolved.1; + + // Resolve circuit variable expression with expected type + Ok(CircuitVariableDefinition { + identifier: circuit_variable.identifier, + expression: Expression::resolve(table, (expected_type, circuit_variable.expression))?, + }) + } +} diff --git a/dynamic-check/src/ast/expressions/circuit/mod.rs b/dynamic-check/src/ast/expressions/circuit/mod.rs new file mode 100644 index 0000000000..a1c5db9a5c --- /dev/null +++ b/dynamic-check/src/ast/expressions/circuit/mod.rs @@ -0,0 +1,27 @@ +// 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 . + +pub mod circuit; +pub use self::circuit::*; + +pub mod circuit_access; +pub use self::circuit_access::*; + +pub mod circuit_static_access; +pub use self::circuit_static_access::*; + +pub mod circuit_variable_definition; +pub use self::circuit_variable_definition::*; diff --git a/dynamic-check/src/ast/expressions/conditional/conditional.rs b/dynamic-check/src/ast/expressions/conditional/conditional.rs new file mode 100644 index 0000000000..21bb247d7b --- /dev/null +++ b/dynamic-check/src/ast/expressions/conditional/conditional.rs @@ -0,0 +1,50 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolves an `if {cond} ? {first} : {second}` expression + /// `{cond}` should resolve to a boolean type + /// `{first}` and `{second}` should have equal types + pub(crate) fn conditional( + table: &mut SymbolTable, + expected_type: Option, + cond: UnresolvedExpression, + first: UnresolvedExpression, + second: UnresolvedExpression, + span: Span, + ) -> Result { + // Resolve the condition to a boolean type + let cond_type = Some(Type::Boolean); + let cond_resolved = Expression::resolve(table, (cond_type, cond))?; + + // Resolve the first and second expressions to the expected type + let (first_resolved, second_resolved) = Expression::binary(table, expected_type, first, second, span.clone())?; + + Ok(Expression { + type_: first_resolved.type_.clone(), + value: ExpressionValue::IfElse( + Box::new(cond_resolved), + Box::new(first_resolved), + Box::new(second_resolved), + span, + ), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/conditional/mod.rs b/dynamic-check/src/ast/expressions/conditional/mod.rs new file mode 100644 index 0000000000..e7a9ed3b86 --- /dev/null +++ b/dynamic-check/src/ast/expressions/conditional/mod.rs @@ -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 . + +pub mod conditional; +pub use self::conditional::*; diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs new file mode 100644 index 0000000000..f81166c955 --- /dev/null +++ b/dynamic-check/src/ast/expressions/expression.rs @@ -0,0 +1,133 @@ +// 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 . + +use crate::{ExpressionError, ExpressionValue}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +use serde::{Deserialize, Serialize}; + +/// Stores a type-checked expression +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Expression { + /// The type this expression evaluates to + pub(crate) type_: Type, + /// The value of this expression + pub(crate) value: ExpressionValue, +} + +impl Expression { + /// Return the type this expression evaluates to + pub fn type_(&self) -> &Type { + &self.type_ + } + + /// Return the span + pub fn span(&self) -> &Span { + self.value.span() + } + + /// Returns `Ok` if this expression resolves to an integer type + pub fn check_type_integer(&self) -> Result<(), ExpressionError> { + self.type_.check_type_integer(self.value.span().clone())?; + + Ok(()) + } +} + +impl ResolvedNode for Expression { + type Error = ExpressionError; + /// (expected type, unresolved expression) + type UnresolvedNode = (Option, UnresolvedExpression); + + /// Type check an expression inside a program AST + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let expected_type = unresolved.0; + let expression = unresolved.1; + + match expression { + // Identifier + UnresolvedExpression::Identifier(identifier) => Self::identifier(table, expected_type, identifier), + + // Values + UnresolvedExpression::Address(string, span) => Self::address(expected_type, string, span), + UnresolvedExpression::Boolean(string, span) => Self::boolean(expected_type, string, span), + UnresolvedExpression::Field(string, span) => Self::field(expected_type, string, span), + UnresolvedExpression::Group(group_value) => Self::group(expected_type, group_value), + UnresolvedExpression::Implicit(string, span) => Self::implicit(expected_type, string, span), + UnresolvedExpression::Integer(integer_type, string, span) => { + Self::integer(expected_type, integer_type, string, span) + } + + // Arithmetic Operations + UnresolvedExpression::Add(lhs, rhs, span) => Self::add(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Div(lhs, rhs, span) => Self::div(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Negate(expression, span) => Self::negate(table, expected_type, *expression, span), + + // Logical Operations + UnresolvedExpression::And(lhs, rhs, span) => Self::and(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Or(lhs, rhs, span) => Self::or(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Not(expression, span) => Self::not(table, expected_type, *expression, span), + + // Relational Operations + UnresolvedExpression::Eq(lhs, rhs, span) => Self::eq(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Ge(lhs, rhs, span) => Self::ge(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Gt(lhs, rhs, span) => Self::gt(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Le(lhs, rhs, span) => Self::le(table, expected_type, *lhs, *rhs, span), + UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(table, expected_type, *lhs, *rhs, span), + + // Conditionals + UnresolvedExpression::IfElse(cond, first, second, span) => { + Self::conditional(table, expected_type, *cond, *first, *second, span) + } + + // Arrays + UnresolvedExpression::Array(elements, span) => Self::array(table, expected_type, elements, span), + UnresolvedExpression::ArrayAccess(array, access, span) => { + Self::array_access(table, expected_type, array, access, span) + } + + // Tuples + UnresolvedExpression::Tuple(elements, span) => Self::tuple(table, expected_type, elements, span), + UnresolvedExpression::TupleAccess(tuple, index, span) => { + Self::tuple_access(table, expected_type, tuple, index, span) + } + + // Circuits + UnresolvedExpression::Circuit(identifier, variables, span) => { + Self::circuit(table, expected_type, identifier, variables, span) + } + UnresolvedExpression::CircuitMemberAccess(circuit, member, span) => { + Self::circuit_access(table, expected_type, circuit, member, span) + } + UnresolvedExpression::CircuitStaticFunctionAccess(circuit, member, span) => { + Self::circuit_static_access(table, expected_type, circuit, member, span) + } + + // Functions + UnresolvedExpression::FunctionCall(function, inputs, span) => { + Self::function_call(table, expected_type, function, inputs, span) + } + UnresolvedExpression::CoreFunctionCall(_name, _inputs, _output, _span) => { + unimplemented!("core function calls not type checked") + // Self::core_function_call(table, expected_type, function, inputs, span) + } + } + } +} diff --git a/dynamic-check/src/ast/expressions/expression_value.rs b/dynamic-check/src/ast/expressions/expression_value.rs new file mode 100644 index 0000000000..cf70b0bfcf --- /dev/null +++ b/dynamic-check/src/ast/expressions/expression_value.rs @@ -0,0 +1,133 @@ +// 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 . + +use crate::{ + expressions::array::{RangeOrExpression, SpreadOrExpression}, + CircuitVariableDefinition, + Expression, +}; +use leo_typed::{GroupValue, Identifier, IntegerType, Span}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum ExpressionValue { + // Identifier + Identifier(Identifier), + + // Values + Address(String, Span), + Boolean(String, Span), + Field(String, Span), + Group(GroupValue), + Integer(IntegerType, String, Span), + + // Arithmetic operations + Add(Box, Box, Span), + Sub(Box, Box, Span), + Mul(Box, Box, Span), + Div(Box, Box, Span), + Pow(Box, Box, Span), + Negate(Box, Span), + + // Logical operations + And(Box, Box, Span), + Or(Box, Box, Span), + Not(Box, Span), + + // Relational operations + Eq(Box, Box, Span), + Ge(Box, Box, Span), + Gt(Box, Box, Span), + Le(Box, Box, Span), + Lt(Box, Box, Span), + + // Conditionals + // (conditional, first_value, second_value, span) + IfElse(Box, Box, Box, Span), + + // Arrays + // (array_elements, span) + Array(Vec>, Span), + // (array_name, range, span) + ArrayAccess(Box, Box, Span), + + // Tuples + // (tuple_elements, span) + Tuple(Vec, Span), + // (tuple_name, index, span) + TupleAccess(Box, usize, Span), + + // Circuits + // (defined_circuit_name, circuit_members, span) + Circuit(Identifier, Vec, Span), + // (declared_circuit name, circuit_member_name, span) + CircuitMemberAccess(Box, Identifier, Span), + // (defined_circuit name, circuit_static_function_name, span) + CircuitStaticFunctionAccess(Box, Identifier, Span), + + // Functions + // (declared_function_name, function_arguments, span) + FunctionCall(Box, Vec, Span), + // (core_function_name, function_arguments, span) + CoreFunctionCall(String, Vec, Span), +} + +impl ExpressionValue { + /// Return the span + pub fn span(&self) -> &Span { + match self { + ExpressionValue::Identifier(identifier) => &identifier.span, + ExpressionValue::Address(_, span) => span, + ExpressionValue::Boolean(_, span) => span, + ExpressionValue::Field(_, span) => span, + ExpressionValue::Group(group_value) => group_value.span(), + ExpressionValue::Integer(_type, _, span) => span, + + ExpressionValue::Add(_, _, span) => span, + ExpressionValue::Sub(_, _, span) => span, + ExpressionValue::Mul(_, _, span) => span, + ExpressionValue::Div(_, _, span) => span, + ExpressionValue::Pow(_, _, span) => span, + ExpressionValue::Negate(_, span) => span, + + ExpressionValue::And(_, _, span) => span, + ExpressionValue::Or(_, _, span) => span, + ExpressionValue::Not(_, span) => span, + + ExpressionValue::Eq(_, _, span) => span, + ExpressionValue::Ge(_, _, span) => span, + ExpressionValue::Gt(_, _, span) => span, + ExpressionValue::Le(_, _, span) => span, + ExpressionValue::Lt(_, _, span) => span, + + ExpressionValue::IfElse(_, _, _, span) => span, + + ExpressionValue::Array(_, span) => span, + ExpressionValue::ArrayAccess(_, _, span) => span, + + ExpressionValue::Tuple(_, span) => span, + ExpressionValue::TupleAccess(_, _, span) => span, + + ExpressionValue::Circuit(_, _, span) => span, + ExpressionValue::CircuitMemberAccess(_, _, span) => span, + ExpressionValue::CircuitStaticFunctionAccess(_, _, span) => span, + + ExpressionValue::FunctionCall(_, _, span) => span, + ExpressionValue::CoreFunctionCall(_, _, span) => span, + } + } +} diff --git a/dynamic-check/src/ast/expressions/function/core_circuit.rs b/dynamic-check/src/ast/expressions/function/core_circuit.rs new file mode 100644 index 0000000000..89cbfc6477 --- /dev/null +++ b/dynamic-check/src/ast/expressions/function/core_circuit.rs @@ -0,0 +1,32 @@ +// 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 . + +// use crate::{Expression, ExpressionValue, ResolvedNode, SymbolTable, Type}; +// use leo_typed::{Expression as UnresolvedExpression, Span, Type as UnresolvedType}; +// +// impl Expression { +// /// Resolves inputs for a call to a core circuit. +// pub(crate) fn core_circuit_call( +// table: &mut SymbolTable, +// expected_type: Option, +// function: String, +// inputs: Vec, +// output_type: UnresolvedType, +// span: Span, +// ) -> Result { +// +// } +// } diff --git a/dynamic-check/src/ast/expressions/function/function_call.rs b/dynamic-check/src/ast/expressions/function/function_call.rs new file mode 100644 index 0000000000..5de4d20405 --- /dev/null +++ b/dynamic-check/src/ast/expressions/function/function_call.rs @@ -0,0 +1,71 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolves an inline function call + /// Checks for errors in function name, inputs, and output. + pub(crate) fn function_call( + table: &mut SymbolTable, + expected_type: Option, + function: Box, + inputs: Vec, + span: Span, + ) -> Result { + // Lookup function in symbol table. + // We do not know the exact function type from this context so `expected_type = None`. + let function_resolved = Expression::resolve(table, (None, *function))?; + let function_name = function_resolved.type_().get_type_function(span.clone())?; + + // Lookup the function type in the symbol table + let function_type = table + .get_function(&function_name.name) + .ok_or(ExpressionError::undefined_function(function_name.clone()))?; + + let type_ = function_type.output.type_.clone(); + let expected_inputs = function_type.inputs.clone(); + + // Check the number of inputs given + if inputs.len() != expected_inputs.len() { + return Err(ExpressionError::invalid_length_function_inputs( + expected_inputs.len(), + inputs.len(), + span, + )); + } + + // Check the type for each function input + let mut inputs_resolved = vec![]; + + for (input, function_input_type) in inputs.into_iter().zip(expected_inputs) { + let input_type = function_input_type.type_().clone(); + let input_resolved = Expression::resolve(table, (Some(input_type), input))?; + + inputs_resolved.push(input_resolved) + } + + // Check the function output type + Type::check_type(&expected_type, &type_, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::FunctionCall(Box::new(function_resolved), inputs_resolved, span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/function/mod.rs b/dynamic-check/src/ast/expressions/function/mod.rs new file mode 100644 index 0000000000..f5c92c10a4 --- /dev/null +++ b/dynamic-check/src/ast/expressions/function/mod.rs @@ -0,0 +1,21 @@ +// 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 . + +pub mod core_circuit; +pub use self::core_circuit::*; + +pub mod function_call; +pub use self::function_call::*; diff --git a/dynamic-check/src/ast/expressions/identifier/identifier.rs b/dynamic-check/src/ast/expressions/identifier/identifier.rs new file mode 100644 index 0000000000..b351c871e1 --- /dev/null +++ b/dynamic-check/src/ast/expressions/identifier/identifier.rs @@ -0,0 +1,45 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::Identifier; + +impl Expression { + /// Resolve the type of an identifier expression + pub(crate) fn identifier( + table: &SymbolTable, + expected_type: Option, + identifier: Identifier, + ) -> Result { + // Lookup identifier in symbol table + let variable = table + .get_variable(&identifier.name) + .ok_or(ExpressionError::undefined_identifier(identifier.clone()))?; + + // Get type of symbol table entry + let variable_type = variable.type_.clone(); + let span = identifier.span.clone(); + + // Check the expected type if given + Type::check_type(&expected_type, &variable_type, span)?; + + Ok(Expression { + type_: variable_type, + value: ExpressionValue::Identifier(identifier), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/identifier/mod.rs b/dynamic-check/src/ast/expressions/identifier/mod.rs new file mode 100644 index 0000000000..29ea470671 --- /dev/null +++ b/dynamic-check/src/ast/expressions/identifier/mod.rs @@ -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 . + +pub mod identifier; +pub use self::identifier::*; diff --git a/dynamic-check/src/ast/expressions/logical/and.rs b/dynamic-check/src/ast/expressions/logical/and.rs new file mode 100644 index 0000000000..4b3a34d4b8 --- /dev/null +++ b/dynamic-check/src/ast/expressions/logical/and.rs @@ -0,0 +1,43 @@ +// 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 . +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of `lhs && rhs` + pub(crate) fn and( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + let type_ = Type::Boolean; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + // Resolve lhs and rhs expressions to boolean type + let boolean_type = Some(type_.clone()); + let (lhs_resolved, rhs_resolved) = Self::binary(table, boolean_type, lhs, rhs, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::And(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/logical/mod.rs b/dynamic-check/src/ast/expressions/logical/mod.rs new file mode 100644 index 0000000000..56200117ee --- /dev/null +++ b/dynamic-check/src/ast/expressions/logical/mod.rs @@ -0,0 +1,24 @@ +// 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 . + +pub mod and; +pub use self::and::*; + +pub mod not; +pub use self::not::*; + +pub mod or; +pub use self::or::*; diff --git a/dynamic-check/src/ast/expressions/logical/not.rs b/dynamic-check/src/ast/expressions/logical/not.rs new file mode 100644 index 0000000000..bf891fd85b --- /dev/null +++ b/dynamic-check/src/ast/expressions/logical/not.rs @@ -0,0 +1,42 @@ +// 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 . +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of `!expression` + pub(crate) fn not( + table: &mut SymbolTable, + expected_type: Option, + expression: UnresolvedExpression, + span: Span, + ) -> Result { + let type_ = Type::Boolean; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + // Resolve lhs and rhs expressions to boolean type + let boolean_type = Some(type_.clone()); + let expression_resolved = Self::resolve(table, (boolean_type, expression))?; + + Ok(Expression { + type_, + value: ExpressionValue::Not(Box::new(expression_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/logical/or.rs b/dynamic-check/src/ast/expressions/logical/or.rs new file mode 100644 index 0000000000..3af380c368 --- /dev/null +++ b/dynamic-check/src/ast/expressions/logical/or.rs @@ -0,0 +1,43 @@ +// 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 . +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of `lhs || rhs` + pub(crate) fn or( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + let type_ = Type::Boolean; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + // Resolve lhs and rhs expressions to boolean type + let boolean_type = Some(type_.clone()); + let (lhs_resolved, rhs_resolved) = Self::binary(table, boolean_type, lhs, rhs, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::Or(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/mod.rs b/dynamic-check/src/ast/expressions/mod.rs new file mode 100644 index 0000000000..6531a18d36 --- /dev/null +++ b/dynamic-check/src/ast/expressions/mod.rs @@ -0,0 +1,54 @@ +// 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 . + +pub mod arithmetic; +pub use self::arithmetic::*; + +pub mod array; +pub use self::array::*; + +pub mod binary; +pub use self::binary::*; + +pub mod circuit; +pub use self::circuit::*; + +pub mod conditional; +pub use self::conditional::*; + +pub mod expression; +pub use self::expression::*; + +pub mod expression_value; +pub use self::expression_value::*; + +pub mod function; +pub use self::function::*; + +pub mod identifier; +pub use self::identifier::*; + +pub mod logical; +pub use self::logical::*; + +pub mod relational; +pub use self::relational::*; + +pub mod tuple; +pub use self::tuple::*; + +pub mod values; +pub use self::values::*; diff --git a/dynamic-check/src/ast/expressions/relational/eq.rs b/dynamic-check/src/ast/expressions/relational/eq.rs new file mode 100644 index 0000000000..607b991675 --- /dev/null +++ b/dynamic-check/src/ast/expressions/relational/eq.rs @@ -0,0 +1,43 @@ +// 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 . +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of `lhs == rhs` + pub(crate) fn eq( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + // This expression results in a boolean type + let type_ = Type::Boolean; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + // Resolve lhs and rhs expressions + let (lhs_resolved, rhs_resolved) = Self::binary(table, None, lhs, rhs, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::Eq(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/relational/ge.rs b/dynamic-check/src/ast/expressions/relational/ge.rs new file mode 100644 index 0000000000..cce64ba3dd --- /dev/null +++ b/dynamic-check/src/ast/expressions/relational/ge.rs @@ -0,0 +1,48 @@ +// 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 . +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of `lhs >= rhs` + pub(crate) fn ge( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + // This expression results in a boolean type + let type_ = Type::Boolean; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + // Resolve lhs and rhs expressions + let (lhs_resolved, rhs_resolved) = Self::binary(table, None, lhs, rhs, span.clone())?; + + // Check that expressions are integer type + lhs_resolved.check_type_integer()?; + rhs_resolved.check_type_integer()?; + + Ok(Expression { + // This expression results in a boolean type + type_, + value: ExpressionValue::Ge(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/relational/gt.rs b/dynamic-check/src/ast/expressions/relational/gt.rs new file mode 100644 index 0000000000..4580863c3b --- /dev/null +++ b/dynamic-check/src/ast/expressions/relational/gt.rs @@ -0,0 +1,48 @@ +// 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 . +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of `lhs > rhs` + pub(crate) fn gt( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + // This expression results in a boolean type + let type_ = Type::Boolean; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + // Resolve lhs and rhs expressions + let (lhs_resolved, rhs_resolved) = Self::binary(table, None, lhs, rhs, span.clone())?; + + // Check that expressions are integer type + lhs_resolved.check_type_integer()?; + rhs_resolved.check_type_integer()?; + + Ok(Expression { + // This expression results in a boolean type + type_: Type::Boolean, + value: ExpressionValue::Gt(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/relational/le.rs b/dynamic-check/src/ast/expressions/relational/le.rs new file mode 100644 index 0000000000..d6647461fd --- /dev/null +++ b/dynamic-check/src/ast/expressions/relational/le.rs @@ -0,0 +1,48 @@ +// 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 . +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of `lhs <= rhs` + pub(crate) fn le( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + // This expression results in a boolean type + let type_ = Type::Boolean; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + // Resolve lhs and rhs expressions + let (lhs_resolved, rhs_resolved) = Self::binary(table, None, lhs, rhs, span.clone())?; + + // Check that expressions are integer type + lhs_resolved.check_type_integer()?; + rhs_resolved.check_type_integer()?; + + Ok(Expression { + // This expression results in a boolean type + type_: Type::Boolean, + value: ExpressionValue::Le(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/relational/lt.rs b/dynamic-check/src/ast/expressions/relational/lt.rs new file mode 100644 index 0000000000..dcd33a229a --- /dev/null +++ b/dynamic-check/src/ast/expressions/relational/lt.rs @@ -0,0 +1,48 @@ +// 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 . +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolve the type of `lhs < rhs` + pub(crate) fn lt( + table: &mut SymbolTable, + expected_type: Option, + lhs: UnresolvedExpression, + rhs: UnresolvedExpression, + span: Span, + ) -> Result { + // This expression results in a boolean type + let type_ = Type::Boolean; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + // Resolve lhs and rhs expressions + let (lhs_resolved, rhs_resolved) = Self::binary(table, None, lhs, rhs, span.clone())?; + + // Check that expressions are integer type + lhs_resolved.check_type_integer()?; + rhs_resolved.check_type_integer()?; + + Ok(Expression { + // This expression results in a boolean type + type_: Type::Boolean, + value: ExpressionValue::Lt(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/relational/mod.rs b/dynamic-check/src/ast/expressions/relational/mod.rs new file mode 100644 index 0000000000..a912ceaa23 --- /dev/null +++ b/dynamic-check/src/ast/expressions/relational/mod.rs @@ -0,0 +1,30 @@ +// 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 . + +pub mod eq; +pub use self::eq::*; + +pub mod ge; +pub use self::ge::*; + +pub mod gt; +pub use self::gt::*; + +pub mod le; +pub use self::le::*; + +pub mod lt; +pub use self::lt::*; diff --git a/dynamic-check/src/ast/expressions/tuple/mod.rs b/dynamic-check/src/ast/expressions/tuple/mod.rs new file mode 100644 index 0000000000..9125265b0e --- /dev/null +++ b/dynamic-check/src/ast/expressions/tuple/mod.rs @@ -0,0 +1,21 @@ +// 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 . + +pub mod tuple; +pub use self::tuple::*; + +pub mod tuple_access; +pub use self::tuple_access::*; diff --git a/dynamic-check/src/ast/expressions/tuple/tuple.rs b/dynamic-check/src/ast/expressions/tuple/tuple.rs new file mode 100644 index 0000000000..fa53532d0c --- /dev/null +++ b/dynamic-check/src/ast/expressions/tuple/tuple.rs @@ -0,0 +1,78 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolves a tuple of expressions to the given tuple type + pub(crate) fn tuple( + table: &mut SymbolTable, + expected_type: Option, + expressions: Vec, + span: Span, + ) -> Result { + // If the expected type is given, then it must be a tuple of types + let expected_element_types = check_tuple_type(expected_type, expressions.len(), span.clone())?; + + // Check length of tuple against expected types + if expected_element_types.len() != expressions.len() { + return Err(ExpressionError::invalid_length_tuple( + expected_element_types.len(), + expressions.len(), + span.clone(), + )); + } + + // Resolve all tuple elements + let mut tuple = vec![]; + + for (expression, element_type) in expressions.into_iter().zip(expected_element_types) { + let expression_resolved = Expression::resolve(table, (element_type, expression))?; + + tuple.push(expression_resolved); + } + + // Define tuple type for expression + let actual_element_types = tuple + .iter() + .map(|expression| expression.type_().clone()) + .collect::>(); + + let type_ = Type::Tuple(actual_element_types); + + Ok(Expression { + type_, + value: ExpressionValue::Tuple(tuple, span), + }) + } +} + +/// Return a tuple of types given some expected type tuple. Otherwise return a tuple of `None` types. +pub fn check_tuple_type( + expected_type: Option, + length: usize, + span: Span, +) -> Result>, ExpressionError> { + Ok(match expected_type { + Some(type_) => { + let types = type_.get_type_tuple(span.clone())?; + types.iter().map(|type_| Some(type_.clone())).collect::>() + } + None => vec![None; length], + }) +} diff --git a/dynamic-check/src/ast/expressions/tuple/tuple_access.rs b/dynamic-check/src/ast/expressions/tuple/tuple_access.rs new file mode 100644 index 0000000000..91def0bd53 --- /dev/null +++ b/dynamic-check/src/ast/expressions/tuple/tuple_access.rs @@ -0,0 +1,56 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Expression { + /// Resolves a tuple access expression + pub(crate) fn tuple_access( + table: &mut SymbolTable, + expected_type: Option, + tuple: Box, + index: usize, + span: Span, + ) -> Result { + // Lookup the tuple in the symbol table. + // We do not know the length from this context so `expected_type = None`. + let tuple_resolved = Expression::resolve(table, (None, *tuple))?; + + // Resolve the tuple index type + let type_tuple = tuple_resolved.type_().get_type_tuple(span.clone())?; + + // Throw a tuple out of bounds error for an index that does not exist + if index > type_tuple.len() { + return Err(ExpressionError::invalid_index_tuple( + index, + type_tuple.len(), + span.clone(), + )); + } + + let type_ = type_tuple[index].clone(); + + // Check that expected type matches + Type::check_type(&expected_type, &type_, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::TupleAccess(Box::new(tuple_resolved), index, span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/values/address.rs b/dynamic-check/src/ast/expressions/values/address.rs new file mode 100644 index 0000000000..5761fb5b1e --- /dev/null +++ b/dynamic-check/src/ast/expressions/values/address.rs @@ -0,0 +1,38 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::Type; +use leo_typed::Span; + +impl Expression { + /// Resolve an address expression + pub(crate) fn address( + expected_type: Option, + address_string: String, + span: Span, + ) -> Result { + let type_ = Type::Address; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::Address(address_string, span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/values/boolean.rs b/dynamic-check/src/ast/expressions/values/boolean.rs new file mode 100644 index 0000000000..05123e29e1 --- /dev/null +++ b/dynamic-check/src/ast/expressions/values/boolean.rs @@ -0,0 +1,38 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::Type; +use leo_typed::Span; + +impl Expression { + /// Resolve a boolean expression + pub(crate) fn boolean( + expected_type: Option, + boolean_string: String, + span: Span, + ) -> Result { + let type_ = Type::Boolean; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::Boolean(boolean_string, span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/values/field.rs b/dynamic-check/src/ast/expressions/values/field.rs new file mode 100644 index 0000000000..020c61f071 --- /dev/null +++ b/dynamic-check/src/ast/expressions/values/field.rs @@ -0,0 +1,38 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::Type; +use leo_typed::Span; + +impl Expression { + /// Resolve a field expression + pub(crate) fn field( + expected_type: Option, + field_string: String, + span: Span, + ) -> Result { + let type_ = Type::Field; + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::Field(field_string, span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/values/group.rs b/dynamic-check/src/ast/expressions/values/group.rs new file mode 100644 index 0000000000..2adc837a2b --- /dev/null +++ b/dynamic-check/src/ast/expressions/values/group.rs @@ -0,0 +1,35 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::Type; +use leo_typed::GroupValue; + +impl Expression { + /// Resolve an group expression + pub(crate) fn group(expected_type: Option, group_value: GroupValue) -> Result { + let type_ = Type::Group; + let span = group_value.span().clone(); + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span)?; + + Ok(Expression { + type_, + value: ExpressionValue::Group(group_value), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/values/implicit.rs b/dynamic-check/src/ast/expressions/values/implicit.rs new file mode 100644 index 0000000000..93e17f1ab6 --- /dev/null +++ b/dynamic-check/src/ast/expressions/values/implicit.rs @@ -0,0 +1,45 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::Type; +use leo_typed::{GroupValue, Span}; + +impl Expression { + /// Resolve an implicit expression + pub(crate) fn implicit( + expected_type: Option, + implicit_string: String, + span: Span, + ) -> Result { + // TODO: impl type lookahead - need to save this implicit value if there is no expected type + let type_ = expected_type.unwrap(); + + let value = match &type_ { + Type::Address => ExpressionValue::Address(implicit_string, span), + Type::Boolean => ExpressionValue::Boolean(implicit_string, span), + Type::Field => ExpressionValue::Field(implicit_string, span), + Type::Group => ExpressionValue::Group(GroupValue::Single(implicit_string, span)), + Type::IntegerType(integer_type) => ExpressionValue::Integer(integer_type.clone(), implicit_string, span), + Type::Array(_type, _dimensions) => unimplemented!("ERROR: Arrays cannot be implicit"), + Type::Tuple(_types) => unimplemented!("ERROR: Tuples cannot be implicit"), + Type::Function(_name) => unimplemented!("ERROR: Functions cannot be implicit"), + Type::Circuit(_name) => unimplemented!("ERROR: Circuits cannot be implicit"), + }; + + Ok(Expression { type_, value }) + } +} diff --git a/dynamic-check/src/ast/expressions/values/integer.rs b/dynamic-check/src/ast/expressions/values/integer.rs new file mode 100644 index 0000000000..47f7d04086 --- /dev/null +++ b/dynamic-check/src/ast/expressions/values/integer.rs @@ -0,0 +1,39 @@ +// 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 . + +use crate::{Expression, ExpressionError, ExpressionValue}; +use leo_symbol_table::Type; +use leo_typed::{IntegerType, Span}; + +impl Expression { + /// Resolve an integer expression + pub(crate) fn integer( + expected_type: Option, + integer_type: IntegerType, + integer_string: String, + span: Span, + ) -> Result { + let type_ = Type::IntegerType(integer_type); + + // Check the expected type if given + Type::check_type(&expected_type, &type_, span.clone())?; + + Ok(Expression { + type_, + value: ExpressionValue::Address(integer_string, span), + }) + } +} diff --git a/dynamic-check/src/ast/expressions/values/mod.rs b/dynamic-check/src/ast/expressions/values/mod.rs new file mode 100644 index 0000000000..fbc8b53bd0 --- /dev/null +++ b/dynamic-check/src/ast/expressions/values/mod.rs @@ -0,0 +1,33 @@ +// 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 . + +pub mod address; +pub use self::address::*; + +pub mod boolean; +pub use self::boolean::*; + +pub mod field; +pub use self::field::*; + +pub mod group; +pub use self::group::*; + +pub mod implicit; +pub use self::implicit::*; + +pub mod integer; +pub use self::integer::*; diff --git a/dynamic-check/src/ast/functions/function.rs b/dynamic-check/src/ast/functions/function.rs new file mode 100644 index 0000000000..0e8b9a4097 --- /dev/null +++ b/dynamic-check/src/ast/functions/function.rs @@ -0,0 +1,78 @@ +// 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 . + +use crate::{FunctionError, Statement}; +use leo_symbol_table::{FunctionType, ResolvedNode, SymbolTable, TypeError}; +use leo_typed::Function as UnresolvedFunction; + +use serde::{Deserialize, Serialize}; + +/// A function in a resolved syntax tree. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Function { + /// The user-defined type of this function. + pub type_: FunctionType, + + /// The function statements. + pub statements: Vec, +} + +impl ResolvedNode for Function { + type Error = FunctionError; + type UnresolvedNode = UnresolvedFunction; + + /// + /// Return a new `Function` from a given `UnresolvedFunction`. + /// + /// Performs a lookup in the given symbol table if the function contains user-defined types. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + // Lookup function identifier in symbol table + let identifier = unresolved.identifier; + + // Throw an error if the function does not exist + let type_ = table + .get_function(&identifier.name) + .ok_or(FunctionError::TypeError(TypeError::undefined_function(identifier)))? + .clone(); + + // // Create function context + // let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); + + // Insert function input types into the symbol table + for input in type_.inputs.clone() { + let exists = input.insert(table); + + // Throw an error if two function inputs have been defined with the same name + if exists.is_some() { + return Err(FunctionError::duplicate_input(input.identifier().clone())); + } + } + + // Pass expected function output to resolved statements + let output = type_.output.clone(); + let mut statements = vec![]; + + // Resolve all function statements + for (_i, statement) in unresolved.statements.into_iter().enumerate() { + let statement = Statement::resolve(table, (output.clone(), statement))?; + + statements.push(statement); + } + + Ok(Function { type_, statements }) + } +} diff --git a/dynamic-check/src/ast/functions/mod.rs b/dynamic-check/src/ast/functions/mod.rs new file mode 100644 index 0000000000..db7036b538 --- /dev/null +++ b/dynamic-check/src/ast/functions/mod.rs @@ -0,0 +1,21 @@ +// 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 . + +pub mod function; +pub use self::function::*; + +pub mod test_function; +pub use self::test_function::*; diff --git a/dynamic-check/src/ast/functions/test_function.rs b/dynamic-check/src/ast/functions/test_function.rs new file mode 100644 index 0000000000..63d226d43f --- /dev/null +++ b/dynamic-check/src/ast/functions/test_function.rs @@ -0,0 +1,47 @@ +// 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 . + +use crate::{Function, FunctionError}; +use leo_symbol_table::{ResolvedNode, SymbolTable}; +use leo_typed::{Identifier, TestFunction as UnresolvedTestFunction}; + +use serde::{Deserialize, Serialize}; + +/// A test function in a resolved syntax tree. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct TestFunction { + /// The test function. + pub function: Function, + /// The custom test input file. + pub input_file: Option, +} + +impl ResolvedNode for TestFunction { + type Error = FunctionError; + type UnresolvedNode = UnresolvedTestFunction; + + /// + /// Return a new `TestFunction` from a given `UnresolvedTestFunction`. + /// + /// Performs a lookup in the given symbol table if the test function contains user-defined types. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + Ok(TestFunction { + function: Function::resolve(table, unresolved.function).unwrap(), + input_file: unresolved.input_file, + }) + } +} diff --git a/dynamic-check/src/ast/imports/import.rs b/dynamic-check/src/ast/imports/import.rs new file mode 100644 index 0000000000..ef046c160d --- /dev/null +++ b/dynamic-check/src/ast/imports/import.rs @@ -0,0 +1,38 @@ +// 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 . + +use leo_symbol_table::{ResolvedNode, SymbolTable}; +use leo_typed::Import as UnresolvedImport; + +use serde::{Deserialize, Serialize}; + +/// An import in a resolved syntax tree. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Import {} + +impl ResolvedNode for Import { + type Error = (); + type UnresolvedNode = UnresolvedImport; + + /// + /// Return a new `Import` from a given `UnresolvedImport`. + /// + /// Performs a lookup in the given symbol table if the import contains user-defined types. + /// + fn resolve(_table: &mut SymbolTable, _resolved: Self::UnresolvedNode) -> Result { + Ok(Import {}) + } +} diff --git a/dynamic-check/src/ast/imports/mod.rs b/dynamic-check/src/ast/imports/mod.rs new file mode 100644 index 0000000000..9f45af0270 --- /dev/null +++ b/dynamic-check/src/ast/imports/mod.rs @@ -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 . + +pub mod import; +pub use self::import::*; diff --git a/dynamic-check/src/ast/mod.rs b/dynamic-check/src/ast/mod.rs new file mode 100644 index 0000000000..70fcc62cd8 --- /dev/null +++ b/dynamic-check/src/ast/mod.rs @@ -0,0 +1,35 @@ +// 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 . +pub mod circuits; +pub use self::circuits::*; + +pub mod console; +pub use self::console::*; + +pub mod expressions; +pub use self::expressions::*; + +pub mod functions; +pub use self::functions::*; + +pub mod imports; +pub use self::imports::*; + +pub mod programs; +pub use self::programs::*; + +pub mod statements; +pub use self::statements::*; diff --git a/dynamic-check/src/ast/programs/mod.rs b/dynamic-check/src/ast/programs/mod.rs new file mode 100644 index 0000000000..86fb38e5ab --- /dev/null +++ b/dynamic-check/src/ast/programs/mod.rs @@ -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 . + +pub mod program; +pub use self::program::*; diff --git a/dynamic-check/src/ast/programs/program.rs b/dynamic-check/src/ast/programs/program.rs new file mode 100644 index 0000000000..0de4e91e19 --- /dev/null +++ b/dynamic-check/src/ast/programs/program.rs @@ -0,0 +1,95 @@ +// 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 . + +use crate::{Circuit, Function, ProgramError, TestFunction}; +use leo_symbol_table::{ResolvedNode, SymbolTable}; +use leo_typed::{programs::Program as UnresolvedProgram, Identifier}; + +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +pub static MAIN_FUNCTION_NAME: &str = "main"; + +/// The root of the resolved syntax tree. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Program { + // pub imports: Vec, + pub circuits: HashMap, + pub functions: HashMap, + pub tests: HashMap, +} + +impl ResolvedNode for Program { + type Error = ProgramError; + type UnresolvedNode = UnresolvedProgram; + + /// + /// Returns a `Program` given an `UnresolvedProgram` AST. + /// + /// At each AST node: + /// 1. Resolve all child AST nodes. + /// 2. Resolve current AST node. + /// + /// Performs a lookup in the given symbol table if the function contains user-defined types. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let mut circuits = HashMap::new(); + let mut functions = HashMap::new(); + let mut tests = HashMap::new(); + + // TODO: Resolve import statements + + // Resolve circuit definitions + for (identifier, circuit) in unresolved.circuits { + let resolved_circuit = Circuit::resolve(table, circuit)?; + + circuits.insert(identifier, resolved_circuit); + } + + // Resolve function statements + for (identifier, function) in unresolved.functions { + let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); + let resolved_function = Function::resolve(&mut child_table, function)?; + + functions.insert(identifier, resolved_function); + } + + // Resolve tests + for (identifier, test) in unresolved.tests { + let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); + let resolved_test = TestFunction::resolve(&mut child_table, test)?; + + tests.insert(identifier, resolved_test); + } + + // Look for main function + // let main = unresolved.functions.into_iter().find(|(identifier, _)| { + // identifier.name.eq(MAIN_FUNCTION_NAME) + // }); + // + // //TODO: return no main function error + // let program = match main { + // Some((_identifier, function)) => , + // None => unimplemented!("ERROR: main function not found"), + // } + + Ok(Program { + circuits, + functions, + tests, + }) + } +} diff --git a/dynamic-check/src/ast/statements/assign/assign.rs b/dynamic-check/src/ast/statements/assign/assign.rs new file mode 100644 index 0000000000..21de091dc7 --- /dev/null +++ b/dynamic-check/src/ast/statements/assign/assign.rs @@ -0,0 +1,99 @@ +// 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 . + +use crate::{Expression, Statement, StatementError}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Assignee, AssigneeAccess, Expression as UnresolvedExpression, Span}; + +use serde::{Deserialize, Serialize}; + +/// A statement that assigns `Assignee = Expression;`. +/// Checks that the expression resolves to the assignee's type +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Assign { + pub assignee: Assignee, + pub expression: Expression, + pub span: Span, +} + +impl Statement { + /// + /// Resolves an assign statement + /// + pub(crate) fn assign( + table: &mut SymbolTable, + assignee: Assignee, + expression: UnresolvedExpression, + span: Span, + ) -> Result { + // Lookup variable in symbol table + let key = &assignee.identifier.name; + let variable = table + .get_variable(key) + .ok_or(StatementError::undefined_variable(key.clone(), span.clone()))?; + + // Throw an error if this variable is not mutable + if !variable.is_mutable() { + return Err(StatementError::immutable_assign(variable.identifier.name.clone(), span)); + } + + // Get inner assignee type + let type_ = get_inner_assignee_type(table, variable.type_.clone(), assignee.accesses.clone(), span.clone())?; + + // Resolve the expression based on the assignee type + let expression_resolved = Expression::resolve(table, (Some(type_), expression))?; + + Ok(Statement::Assign(Assign { + assignee, + expression: expression_resolved, + span, + })) + } +} + +/// +/// Accesses the inner type of an assignee such as an array, tuple, or circuit member. +/// Returns an error for invalid accesses. +/// +fn get_inner_assignee_type( + table: &SymbolTable, + type_: Type, + accesses: Vec, + span: Span, +) -> Result { + match accesses.first() { + None => Ok(type_), + Some(access) => { + // Check that we are correctly accessing the type + let next_type = match (&type_, access) { + (Type::Array(next_type, _), AssigneeAccess::Array(_)) => *next_type.clone(), + (Type::Tuple(types), AssigneeAccess::Tuple(index)) => types[*index].clone(), + (Type::Circuit(identifier), AssigneeAccess::Member(member)) => { + let circuit_type_option = table.get_circuit(&identifier.name); + + let circuit_type = match circuit_type_option { + Some(circuit_type) => circuit_type, + None => return Err(StatementError::undefined_circuit(identifier.clone())), + }; + circuit_type.member_type(member)?.clone() + } + (type_, _) => return Err(StatementError::invalid_assign(type_, span)), + }; + + return get_inner_assignee_type(table, next_type, accesses[1..].to_vec(), span); + } + } +} diff --git a/dynamic-check/src/ast/statements/assign/mod.rs b/dynamic-check/src/ast/statements/assign/mod.rs new file mode 100644 index 0000000000..5236b5fc8e --- /dev/null +++ b/dynamic-check/src/ast/statements/assign/mod.rs @@ -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 . + +pub mod assign; +pub use self::assign::*; diff --git a/dynamic-check/src/ast/statements/conditional/conditional.rs b/dynamic-check/src/ast/statements/conditional/conditional.rs new file mode 100644 index 0000000000..6d30a5dbe0 --- /dev/null +++ b/dynamic-check/src/ast/statements/conditional/conditional.rs @@ -0,0 +1,130 @@ +// 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 . + +use crate::{Expression, Statement, StatementError}; +use leo_symbol_table::{FunctionOutputType, ResolvedNode, SymbolTable, Type}; +use leo_typed::{ + ConditionalNestedOrEndStatement as UnresolvedNestedOrEnd, + ConditionalStatement as UnresolvedConditional, + Span, + Statement as UnresolvedStatement, +}; + +use serde::{Deserialize, Serialize}; + +/// A nested `else if` or an ending `else` clause +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum ConditionalNestedOrEndStatement { + Nested(Box), + End(Vec), +} + +/// An `if else` statement with resolved inner statements +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Conditional { + pub condition: Expression, + pub statements: Vec, + pub next: Option, + pub span: Span, +} + +impl Conditional { + /// + /// Resolves a conditional statement. + /// + pub(crate) fn from_unresolved( + table: &mut SymbolTable, + return_type: FunctionOutputType, + conditional: UnresolvedConditional, + span: Span, + ) -> Result { + // Create child symbol table. + let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); + + // Resolve the condition to a boolean. + let type_boolean = Some(Type::Boolean); + let condition_resolved = Expression::resolve(&mut child_table, (type_boolean, conditional.condition))?; + + // Resolve all statements. + let statements_resolved = resolve_statements(&mut child_table, return_type.clone(), conditional.statements)?; + + // Check for an `else if` or `else` clause. + let nested_or_end = match conditional.next { + Some(nested_or_end) => nested_or_end, + None => { + return Ok(Conditional { + condition: condition_resolved, + statements: statements_resolved, + next: None, + span, + }); + } + }; + + // Evaluate the `else if` or `else` clause. + let next_resolved = match nested_or_end { + UnresolvedNestedOrEnd::Nested(conditional) => { + // Type check the `else if` clause. + let conditional_resolved = + Self::from_unresolved(table, return_type.clone(), *conditional, span.clone())?; + + ConditionalNestedOrEndStatement::Nested(Box::new(conditional_resolved)) + } + UnresolvedNestedOrEnd::End(statements) => { + // Create child symbol table. + let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); + + // Type check the `else` clause. + let statements_resolved = resolve_statements(&mut child_table, return_type, statements)?; + + ConditionalNestedOrEndStatement::End(statements_resolved) + } + }; + + Ok(Conditional { + condition: condition_resolved, + statements: statements_resolved, + next: Some(next_resolved), + span, + }) + } +} + +/// Resolve an array of statements. +fn resolve_statements( + table: &mut SymbolTable, + return_type: FunctionOutputType, + statements: Vec, +) -> Result, StatementError> { + Ok(statements + .into_iter() + .map(|statement| Statement::resolve(table, (return_type.clone(), statement))) + .collect::, _>>()?) +} + +impl Statement { + /// Resolves a conditional statement. + pub(crate) fn conditional( + table: &mut SymbolTable, + return_type: FunctionOutputType, + conditional: UnresolvedConditional, + span: Span, + ) -> Result { + let conditional = Conditional::from_unresolved(table, return_type, conditional, span)?; + + Ok(Statement::Conditional(conditional)) + } +} diff --git a/dynamic-check/src/ast/statements/conditional/mod.rs b/dynamic-check/src/ast/statements/conditional/mod.rs new file mode 100644 index 0000000000..e7a9ed3b86 --- /dev/null +++ b/dynamic-check/src/ast/statements/conditional/mod.rs @@ -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 . + +pub mod conditional; +pub use self::conditional::*; diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs new file mode 100644 index 0000000000..7e26158f5f --- /dev/null +++ b/dynamic-check/src/ast/statements/definition/definition.rs @@ -0,0 +1,249 @@ +// 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 . + +use crate::{check_tuple_type, Expression, ExpressionValue, Statement, StatementError}; +use leo_symbol_table::{Attribute, ResolvedNode, SymbolTable, Type, VariableType}; +use leo_typed::{Declare, Expression as UnresolvedExpression, Span, VariableName, Variables}; + +use serde::{Deserialize, Serialize}; + +/// A `let` or `const` definition statement. +/// Defines one or more variables with resolved types. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Definition { + pub declare: Declare, + pub variables: DefinitionVariables, + pub span: Span, +} + +/// One or more variables with resolved types. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum DefinitionVariables { + Single(VariableName, Expression), + Tuple(VariableName, Expression), + MultipleVariable(Vec, Vec), + MultipleVariableTuple(Vec, Expression), +} + +impl DefinitionVariables { + /// Resolves a single variable with a single value + fn single( + table: &mut SymbolTable, + variable: VariableName, + expected_type: Option, + expression: UnresolvedExpression, + span: Span, + ) -> Result { + // Resolve expression with given expected type + let expression_resolved = Expression::resolve(table, (expected_type, expression))?; + let type_ = expression_resolved.type_(); + + // Insert variable into symbol table + insert_defined_variable(table, &variable, type_, span.clone())?; + + Ok(DefinitionVariables::Single(variable, expression_resolved)) + } + + /// Resolves a tuple (single variable with multiple values) + fn tuple( + table: &mut SymbolTable, + variable: VariableName, + expected_type: Option, + expressions: Vec, + span: Span, + ) -> Result { + // Resolve tuple of expressions + let tuple_resolved = Expression::tuple(table, expected_type, expressions, span.clone())?; + let type_ = tuple_resolved.type_(); + + // Insert variable into symbol table + insert_defined_variable(table, &variable, type_, span.clone())?; + + Ok(DefinitionVariables::Tuple(variable, tuple_resolved)) + } + + /// Resolves multiple variables for multiple expressions + fn multiple_variable( + table: &mut SymbolTable, + variables: Variables, + expected_type: Option, + expressions: Vec, + span: Span, + ) -> Result { + // If the expected type is given, then it must be a tuple of types + let explicit_types = check_tuple_type(expected_type, expressions.len(), span.clone())?; + + // Check number of variables == types + if variables.names.len() != explicit_types.len() { + return Err(StatementError::multiple_variable_types( + variables.names.len(), + explicit_types.len(), + span, + )); + } + + // Check number of variables == expressions + if variables.names.len() != expressions.len() { + return Err(StatementError::multiple_variable_expressions( + variables.names.len(), + expressions.len(), + span, + )); + } + + // Resolve expressions + let mut expressions_resolved = vec![]; + + for (expression, type_) in expressions.into_iter().zip(explicit_types) { + let expression_resolved = Expression::resolve(table, (type_, expression))?; + + expressions_resolved.push(expression_resolved); + } + + // Insert variables into symbol table + for (variable, expression) in variables.names.clone().iter().zip(expressions_resolved.iter()) { + insert_defined_variable(table, variable, expression.type_(), span.clone())?; + } + + Ok(DefinitionVariables::MultipleVariable( + variables.names, + expressions_resolved, + )) + } + + /// Resolves multiple variables for an expression that returns a tuple + fn multiple_variable_tuple( + table: &mut SymbolTable, + variables: Variables, + expected_type: Option, + expression: UnresolvedExpression, + span: Span, + ) -> Result { + // Resolve tuple expression + let expression_resolved = Expression::resolve(table, (expected_type, expression.clone()))?; + + let expressions_resolved = match &expression_resolved.value { + ExpressionValue::Tuple(expressions_resolved, _span) => expressions_resolved.clone(), + _ => return Err(StatementError::invalid_tuple(variables.names.len(), expression, span)), + }; + + // Insert variables into symbol table + for (variable, expression) in variables.names.clone().iter().zip(expressions_resolved.iter()) { + insert_defined_variable(table, variable, expression.type_(), span.clone())?; + } + + Ok(DefinitionVariables::MultipleVariableTuple( + variables.names, + expression_resolved, + )) + } +} + +/// Inserts a variable definition into the given symbol table +fn insert_defined_variable( + table: &mut SymbolTable, + variable: &VariableName, + type_: &Type, + span: Span, +) -> Result<(), StatementError> { + let attributes = if variable.mutable { + vec![Attribute::Mutable] + } else { + vec![] + }; + + // Insert variable into symbol table + let key = variable.identifier.name.clone(); + let value = VariableType { + identifier: variable.identifier.clone(), + type_: type_.clone(), + attributes, + }; + + // Check that variable name was not defined twice + let duplicate = table.insert_variable(key, value); + + if duplicate.is_some() { + return Err(StatementError::duplicate_variable( + variable.identifier.name.clone(), + span, + )); + } + + Ok(()) +} + +impl Statement { + /// Resolves a definition statement + pub(crate) fn definition( + table: &mut SymbolTable, + declare: Declare, + variables: Variables, + expressions: Vec, + span: Span, + ) -> Result { + let num_variables = variables.names.len(); + let num_values = expressions.len(); + + // If an explicit type is given check that it is valid + let expected_type = match &variables.type_ { + Some(type_) => Some(Type::resolve(table, (type_.clone(), span.clone()))?), + None => None, + }; + + let variables = if num_variables == 1 && num_values == 1 { + // Define a single variable with a single value + + DefinitionVariables::single( + table, + variables.names[0].clone(), + expected_type, + expressions[0].clone(), + span.clone(), + ) + } else if num_variables == 1 && num_values > 1 { + // Define a tuple (single variable with multiple values) + + DefinitionVariables::tuple( + table, + variables.names[0].clone(), + expected_type, + expressions, + span.clone(), + ) + } else if num_variables > 1 && num_values == 1 { + // Define multiple variables for an expression that returns a tuple + + DefinitionVariables::multiple_variable_tuple( + table, + variables, + expected_type, + expressions[0].clone(), + span.clone(), + ) + } else { + // Define multiple variables for multiple expressions + + DefinitionVariables::multiple_variable(table, variables, expected_type, expressions, span.clone()) + }?; + + Ok(Statement::Definition(Definition { + declare, + variables, + span, + })) + } +} diff --git a/dynamic-check/src/ast/statements/definition/mod.rs b/dynamic-check/src/ast/statements/definition/mod.rs new file mode 100644 index 0000000000..2b20761620 --- /dev/null +++ b/dynamic-check/src/ast/statements/definition/mod.rs @@ -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 . + +pub mod definition; +pub use self::definition::*; diff --git a/dynamic-check/src/ast/statements/iteration/iteration.rs b/dynamic-check/src/ast/statements/iteration/iteration.rs new file mode 100644 index 0000000000..9bc6a646a1 --- /dev/null +++ b/dynamic-check/src/ast/statements/iteration/iteration.rs @@ -0,0 +1,75 @@ +// 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 . +use crate::{Expression, Statement, StatementError}; +use leo_symbol_table::{FunctionOutputType, ResolvedNode, SymbolTable, Type, VariableType}; +use leo_typed::{Expression as UnresolvedExpression, Identifier, IntegerType, Span, Statement as UnresolvedStatement}; + +use serde::{Deserialize, Serialize}; + +/// A resolved iteration statement +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Iteration { + pub index: Identifier, + pub start: Expression, + pub stop: Expression, + pub statements: Vec, + pub span: Span, +} + +impl Statement { + /// Resolve an iteration statement + pub(crate) fn iteration( + table: &mut SymbolTable, + return_type: FunctionOutputType, + index: Identifier, + start: UnresolvedExpression, + stop: UnresolvedExpression, + statements: Vec, + span: Span, + ) -> Result { + // TODO: Create child symbol table and add variables from parent + + // Resolve index numbers to a u32 type + let type_number = Type::IntegerType(IntegerType::U32); + + let start_resolved = Expression::resolve(table, (Some(type_number.clone()), start))?; + let stop_resolved = Expression::resolve(table, (Some(type_number.clone()), stop))?; + + // Add index to symbol table + let key = index.name.clone(); + let value = VariableType { + identifier: index.clone(), + type_: type_number, + attributes: vec![], + }; + + table.insert_variable(key, value); + + // Resolve statements + let statements_resolved = statements + .into_iter() + .map(|statement| Statement::resolve(table, (return_type.clone(), statement))) + .collect::, _>>()?; + + Ok(Statement::Iteration(Iteration { + index, + start: start_resolved, + stop: stop_resolved, + statements: statements_resolved, + span, + })) + } +} diff --git a/dynamic-check/src/ast/statements/iteration/mod.rs b/dynamic-check/src/ast/statements/iteration/mod.rs new file mode 100644 index 0000000000..d37c83519b --- /dev/null +++ b/dynamic-check/src/ast/statements/iteration/mod.rs @@ -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 . + +pub mod iteration; +pub use self::iteration::*; diff --git a/dynamic-check/src/ast/statements/mod.rs b/dynamic-check/src/ast/statements/mod.rs new file mode 100644 index 0000000000..ff0e53541a --- /dev/null +++ b/dynamic-check/src/ast/statements/mod.rs @@ -0,0 +1,33 @@ +// 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 . + +pub mod assign; +pub use self::assign::*; + +pub mod conditional; +pub use self::conditional::*; + +pub mod definition; +pub use self::definition::*; + +pub mod iteration; +pub use self::iteration::*; + +pub mod return_; +pub use self::return_::*; + +pub mod statement; +pub use self::statement::*; diff --git a/dynamic-check/src/ast/statements/return_/mod.rs b/dynamic-check/src/ast/statements/return_/mod.rs new file mode 100644 index 0000000000..a58752e3b2 --- /dev/null +++ b/dynamic-check/src/ast/statements/return_/mod.rs @@ -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 . + +pub mod return_; +pub use self::return_::*; diff --git a/dynamic-check/src/ast/statements/return_/return_.rs b/dynamic-check/src/ast/statements/return_/return_.rs new file mode 100644 index 0000000000..6024b20b13 --- /dev/null +++ b/dynamic-check/src/ast/statements/return_/return_.rs @@ -0,0 +1,33 @@ +// 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 . + +use crate::{Expression, Statement, StatementError}; +use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use leo_typed::{Expression as UnresolvedExpression, Span}; + +impl Statement { + /// Resolve return statement to function output type + pub(crate) fn resolve_return( + table: &mut SymbolTable, + expected_type: Type, + expression: UnresolvedExpression, + span: Span, + ) -> Result { + let expression = Expression::resolve(table, (Some(expected_type), expression))?; + + Ok(Statement::Return(expression, span)) + } +} diff --git a/dynamic-check/src/ast/statements/statement.rs b/dynamic-check/src/ast/statements/statement.rs new file mode 100644 index 0000000000..9e7a7259a6 --- /dev/null +++ b/dynamic-check/src/ast/statements/statement.rs @@ -0,0 +1,64 @@ +// 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 . +use crate::{Assign, Conditional, Definition, Expression, Iteration, StatementError}; +use leo_symbol_table::{FunctionOutputType, ResolvedNode, SymbolTable}; +use leo_typed::{ConsoleFunctionCall, Span, Statement as UnresolvedStatement}; + +use serde::{Deserialize, Serialize}; + +/// Stores a type-checked statement in a Leo program +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum Statement { + Return(Expression, Span), + Definition(Definition), + Assign(Assign), + Conditional(Conditional), + Iteration(Iteration), + Console(ConsoleFunctionCall), + Expression(Expression, Span), +} + +impl ResolvedNode for Statement { + type Error = StatementError; + type UnresolvedNode = (FunctionOutputType, UnresolvedStatement); + + /// Type check a statement inside a program AST + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { + let return_type = unresolved.0; + let statement = unresolved.1; + + match statement { + UnresolvedStatement::Return(expression, span) => { + Self::resolve_return(table, return_type.type_, expression, span) + } + UnresolvedStatement::Definition(declare, variables, expressions, span) => { + Self::definition(table, declare, variables, expressions, span) + } + UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(table, assignee, expression, span), + UnresolvedStatement::Conditional(conditional, span) => { + Self::conditional(table, return_type, conditional, span) + } + UnresolvedStatement::Iteration(index, start, stop, statements, span) => { + Self::iteration(table, return_type, index, start, stop, statements, span) + } + UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)), + UnresolvedStatement::Expression(expression, span) => Ok(Statement::Expression( + Expression::resolve(table, (None, expression))?, + span, + )), + } + } +} diff --git a/dynamic-check/src/errors/circuit.rs b/dynamic-check/src/errors/circuit.rs new file mode 100644 index 0000000000..58d264209c --- /dev/null +++ b/dynamic-check/src/errors/circuit.rs @@ -0,0 +1,45 @@ +// 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 . + +use crate::FunctionError; +use leo_typed::{Error as FormattedError, Span}; + +use std::path::PathBuf; + +/// Errors encountered when resolving a program +#[derive(Debug, Error)] +pub enum CircuitError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + FunctionError(#[from] FunctionError), +} + +impl CircuitError { + /// Set the filepath for the error stacktrace + pub fn set_path(&mut self, path: PathBuf) { + match self { + CircuitError::Error(error) => error.set_path(path), + CircuitError::FunctionError(error) => error.set_path(path), + } + } + + /// Return a new formatted error with a given message and span information + fn new_from_span(message: String, span: Span) -> Self { + CircuitError::Error(FormattedError::new_from_span(message, span)) + } +} diff --git a/dynamic-check/src/errors/expression.rs b/dynamic-check/src/errors/expression.rs new file mode 100644 index 0000000000..cefe168c3b --- /dev/null +++ b/dynamic-check/src/errors/expression.rs @@ -0,0 +1,178 @@ +// 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 . + +use leo_symbol_table::TypeError; +use leo_typed::{Error as FormattedError, Identifier, Span}; + +use std::path::PathBuf; + +/// Errors encountered when resolving an expression. +#[derive(Debug, Error)] +pub enum ExpressionError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + TypeError(#[from] TypeError), +} + +impl ExpressionError { + /// + /// Set the filepath for the error stacktrace. + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + ExpressionError::Error(error) => error.set_path(path), + ExpressionError::TypeError(error) => error.set_path(path), + } + } + + /// + /// Return a new formatted error with a given message and span information. + /// + fn new_from_span(message: String, span: Span) -> Self { + ExpressionError::Error(FormattedError::new_from_span(message, span)) + } + + /// + /// Attempted to access a circuit member that is static using double colon syntax. + /// + pub fn invalid_member_access(member: String, span: Span) -> Self { + let message = format!("Circuit member `{}` must be accessed using `::` syntax.", member); + + Self::new_from_span(message, span) + } + + /// + /// Attempted to access a circuit member that is static using dot syntax. + /// + pub fn invalid_static_member_access(member: String, span: Span) -> Self { + let message = format!("Static member `{}` must be accessed using `.` syntax.", member); + + Self::new_from_span(message, span) + } + + /// + /// Attempted to access a tuple index that does not exist. + /// + pub fn invalid_index_tuple(index: usize, max: usize, span: Span) -> Self { + let message = format!("Attempted to access index {} of tuple with length {}.", index, max); + + Self::new_from_span(message, span) + } + + /// + /// Found an array with an unexpected length. + /// + pub fn invalid_length_array(expected: usize, actual: usize, span: Span) -> Self { + let message = format!( + "Expected array with length {}, found array with length {}.", + expected, actual + ); + + Self::new_from_span(message, span) + } + + /// + /// Found a circuit with an incorrect number of members + /// + pub fn invalid_length_circuit_members(expected: usize, actual: usize, span: Span) -> Self { + let message = format!( + "Expected circuit with {} members, found circuit with {} members.", + expected, actual + ); + + Self::new_from_span(message, span) + } + + /// + /// Found a circuit with an incorrect number of members. + /// + pub fn invalid_length_function_inputs(expected: usize, actual: usize, span: Span) -> Self { + let message = format!( + "Function expected {} inputs, found function with {} members.", + expected, actual + ); + + Self::new_from_span(message, span) + } + + /// + /// Found a tuple with an unexpected length. + /// + pub fn invalid_length_tuple(expected: usize, actual: usize, span: Span) -> Self { + let message = format!( + "Expected tuple with length {}, found tuple with length {}.", + expected, actual + ); + + Self::new_from_span(message, span) + } + + /// + /// Attempted to lookup an unknown variable name. + /// + pub fn undefined_identifier(identifier: Identifier) -> Self { + let message = format!("Cannot find variable `{}` in this scope.", identifier.name); + + Self::new_from_span(message, identifier.span) + } + + /// + /// Attempted to lookup an unknown circuit name. + /// + pub fn undefined_circuit(identifier: Identifier) -> Self { + let message = format!("Cannot find circuit `{}` in this scope.", identifier.name); + + Self::new_from_span(message, identifier.span) + } + + /// + /// Attempted to lookup an unknown circuit variable name. + /// + pub fn undefined_circuit_variable(identifier: Identifier) -> Self { + let message = format!("Circuit has no member variable named `{}`.", identifier.name); + + Self::new_from_span(message, identifier.span) + } + + /// + /// Attempted to lookup an unknown circuit function name. + /// + pub fn undefined_circuit_function(identifier: Identifier, span: Span) -> Self { + let message = format!("Circuit has no member function named `{}`.", identifier.name); + + Self::new_from_span(message, span) + } + + /// + /// Attempted to lookup an unknown circuit function static name. + /// + pub fn undefined_circuit_function_static(identifier: Identifier, span: Span) -> Self { + let message = format!("Circuit has no static member function named `{}`.", identifier.name); + + Self::new_from_span(message, span) + } + + /// + /// Attempted to lookup an unknown circuit name. + /// + pub fn undefined_function(identifier: Identifier) -> Self { + let message = format!("Cannot find function `{}` in this scope.", identifier.name); + + Self::new_from_span(message, identifier.span) + } +} diff --git a/dynamic-check/src/errors/function.rs b/dynamic-check/src/errors/function.rs new file mode 100644 index 0000000000..81fd47baac --- /dev/null +++ b/dynamic-check/src/errors/function.rs @@ -0,0 +1,60 @@ +// 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 . + +use crate::StatementError; +use leo_symbol_table::TypeError; +use leo_typed::{Error as FormattedError, Identifier, Span}; + +use std::path::PathBuf; + +/// Errors encountered when resolving a function +#[derive(Debug, Error)] +pub enum FunctionError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + StatementError(#[from] StatementError), + + #[error("{}", _0)] + TypeError(#[from] TypeError), +} + +impl FunctionError { + /// Set the filepath for the error stacktrace + pub fn set_path(&mut self, path: PathBuf) { + match self { + FunctionError::Error(error) => error.set_path(path), + FunctionError::StatementError(error) => error.set_path(path), + FunctionError::TypeError(error) => error.set_path(path), + } + } + + /// Return a new formatted error with a given message and span information + fn new_from_span(message: String, span: Span) -> Self { + FunctionError::Error(FormattedError::new_from_span(message, span)) + } + + /// Found two function inputs with the same name + pub fn duplicate_input(identifier: Identifier) -> Self { + let message = format!( + "Function input `{}` is bound more than once in this parameter list", + identifier + ); + + Self::new_from_span(message, identifier.span) + } +} diff --git a/dynamic-check/src/errors/mod.rs b/dynamic-check/src/errors/mod.rs new file mode 100644 index 0000000000..7d83b4184d --- /dev/null +++ b/dynamic-check/src/errors/mod.rs @@ -0,0 +1,39 @@ +// 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 . + +pub mod circuit; +pub use self::circuit::*; + +pub mod expression; +pub use self::expression::*; + +pub mod function; +pub use self::function::*; + +pub mod program; +pub use self::program::*; + +pub mod resolver; +pub use self::resolver::*; + +pub mod statement; +pub use self::statement::*; + +// pub mod symbol_table; +// pub use self::symbol_table::*; + +// pub mod type_; +// pub use self::type_::*; diff --git a/dynamic-check/src/errors/program.rs b/dynamic-check/src/errors/program.rs new file mode 100644 index 0000000000..58eb922113 --- /dev/null +++ b/dynamic-check/src/errors/program.rs @@ -0,0 +1,49 @@ +// 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 . + +use crate::{CircuitError, FunctionError}; +use leo_typed::{Error as FormattedError, Span}; + +use std::path::PathBuf; + +/// Errors encountered when resolving a program +#[derive(Debug, Error)] +pub enum ProgramError { + #[error("{}", _0)] + CircuitError(#[from] CircuitError), + + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + FunctionError(#[from] FunctionError), +} + +impl ProgramError { + /// Set the filepath for the error stacktrace + pub fn set_path(&mut self, path: PathBuf) { + match self { + ProgramError::CircuitError(error) => error.set_path(path), + ProgramError::Error(error) => error.set_path(path), + ProgramError::FunctionError(error) => error.set_path(path), + } + } + + /// Return a new formatted error with a given message and span information + fn new_from_span(message: String, span: Span) -> Self { + ProgramError::Error(FormattedError::new_from_span(message, span)) + } +} diff --git a/dynamic-check/src/errors/resolver.rs b/dynamic-check/src/errors/resolver.rs new file mode 100644 index 0000000000..a33b7d69c4 --- /dev/null +++ b/dynamic-check/src/errors/resolver.rs @@ -0,0 +1,34 @@ +// 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 . +use crate::ProgramError; +use leo_imports::ImportParserError; +use leo_symbol_table::SymbolTableError; +use leo_typed::Error as FormattedError; + +#[derive(Debug, Error)] +pub enum ResolverError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + ImportParserError(#[from] ImportParserError), + + #[error("{}", _0)] + ProgramError(#[from] ProgramError), + + #[error("{}", _0)] + SymbolTableError(#[from] SymbolTableError), +} diff --git a/dynamic-check/src/errors/statement.rs b/dynamic-check/src/errors/statement.rs new file mode 100644 index 0000000000..c1734411d3 --- /dev/null +++ b/dynamic-check/src/errors/statement.rs @@ -0,0 +1,137 @@ +// 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 . + +use crate::ExpressionError; +use leo_symbol_table::{Type, TypeError}; +use leo_typed::{Error as FormattedError, Expression as UnresolvedExpression, Identifier, Span}; + +use std::path::PathBuf; + +/// +/// Errors encountered when resolving a statement +/// +#[derive(Debug, Error)] +pub enum StatementError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + ExpressionError(#[from] ExpressionError), + + #[error("{}", _0)] + TypeError(#[from] TypeError), +} + +impl StatementError { + /// + /// Set the filepath for the error stacktrace. + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + StatementError::Error(error) => error.set_path(path), + StatementError::ExpressionError(error) => error.set_path(path), + StatementError::TypeError(error) => error.set_path(path), + } + } + + /// + /// Return a new formatted error with a given message and span information. + /// + fn new_from_span(message: String, span: Span) -> Self { + StatementError::Error(FormattedError::new_from_span(message, span)) + } + + /// + /// Attempted to define a variable name twice. + /// + pub fn duplicate_variable(name: String, span: Span) -> Self { + let message = format!("Duplicate variable definition found for `{}`", name); + + Self::new_from_span(message, span) + } + + /// + /// Attempted to assign to an immutable variable. + /// + pub fn immutable_assign(name: String, span: Span) -> Self { + let message = format!("Cannot assign to immutable variable `{}`.", name); + + Self::new_from_span(message, span) + } + + /// + /// Attempted to assign to a non-variable type. + /// + pub fn invalid_assign(type_: &Type, span: Span) -> Self { + let message = format!("Cannot assign to type `{}` in a statement.", type_); + + Self::new_from_span(message, span) + } + + /// + /// Provided a different number of explicit types than variables being defined in a tuple + /// + pub fn multiple_variable_types(expected: usize, actual: usize, span: Span) -> Self { + let message = format!( + "Expected {} explicit types when defining variables, found {}", + expected, actual + ); + + Self::new_from_span(message, span) + } + + /// + /// Provided a different number of expression values than variables being defined in a tuple + /// + pub fn multiple_variable_expressions(expected: usize, actual: usize, span: Span) -> Self { + let message = format!( + "Expected {} values when defining variables, found {} values", + expected, actual + ); + + Self::new_from_span(message, span) + } + + /// + /// Attempted to assign multiple variables to a single expression value. + /// + pub fn invalid_tuple(expected: usize, expression: UnresolvedExpression, span: Span) -> Self { + let message = format!( + "Expected {} values when defining variables, found single value `{}`", + expected, expression + ); + + Self::new_from_span(message, span) + } + + /// + /// Attempted to assign to an unknown variable. + /// + pub fn undefined_variable(name: String, span: Span) -> Self { + let message = format!("Attempted to assign to unknown variable `{}`.", name); + + Self::new_from_span(message, span) + } + + /// + /// Attempted to assign to an undefined circuit. + /// + pub fn undefined_circuit(identifier: Identifier) -> Self { + let message = format!("Attempted to assign to unknown circuit `{}`.", identifier.name); + + Self::new_from_span(message, identifier.span) + } +} diff --git a/dynamic-check/src/errors/symbol_table.rs b/dynamic-check/src/errors/symbol_table.rs new file mode 100644 index 0000000000..b05a884bc1 --- /dev/null +++ b/dynamic-check/src/errors/symbol_table.rs @@ -0,0 +1,59 @@ +// 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 . + +use crate::TypeError; +use leo_typed::{Error as FormattedError, Identifier, Span}; + +use std::path::PathBuf; + +/// Errors encountered when tracking variable, function, and circuit names in a program +#[derive(Debug, Error)] +pub enum SymbolTableError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + TypeError(#[from] TypeError), +} + +impl SymbolTableError { + /// Set the filepath for the error stacktrace + pub fn set_path(&mut self, path: PathBuf) { + match self { + SymbolTableError::Error(error) => error.set_path(path), + SymbolTableError::TypeError(error) => error.set_path(path), + } + } + + /// Return a new formatted error with a given message and span information + fn new_from_span(message: String, span: Span) -> Self { + SymbolTableError::Error(FormattedError::new_from_span(message, span)) + } + + /// 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); + + Self::new_from_span(message, 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); + + Self::new_from_span(message, span) + } +} diff --git a/dynamic-check/src/errors/type_.rs b/dynamic-check/src/errors/type_.rs new file mode 100644 index 0000000000..f7e6ad79ae --- /dev/null +++ b/dynamic-check/src/errors/type_.rs @@ -0,0 +1,117 @@ +// 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 . + +use crate::Type; +use leo_typed::{Error as FormattedError, Identifier, Span}; + +use std::path::PathBuf; + +/// Errors encountered when resolving types +#[derive(Debug, Error)] +pub enum TypeError { + #[error("{}", _0)] + Error(#[from] FormattedError), +} + +impl TypeError { + /// Set the filepath for the error stacktrace + pub fn set_path(&mut self, path: PathBuf) { + match self { + TypeError::Error(error) => error.set_path(path), + } + } + + /// Return a new formatted error with a given message and span information + fn new_from_span(message: String, span: Span) -> Self { + TypeError::Error(FormattedError::new_from_span(message, span)) + } + + /// Expected an array type from the given expression + pub fn invalid_array(actual: &Type, span: Span) -> Self { + let message = format!("Expected array type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// Expected a circuit type from the given expression + pub fn invalid_circuit(actual: &Type, span: Span) -> Self { + let message = format!("Expected circuit type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// Expected a function type from the given expression + pub fn invalid_function(actual: &Type, span: Span) -> Self { + let message = format!("Expected function type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// Expected an integer type from the given expression + pub fn invalid_integer(actual: &Type, span: Span) -> Self { + let message = format!("Expected integer type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// Expected a tuple type from the given expression + pub fn invalid_tuple(actual: &Type, span: Span) -> Self { + let message = format!("Expected tuple type, found type `{}`.", actual); + + Self::new_from_span(message, span) + } + + /// The value of the expression does not match the given explicit type + pub fn mismatched_types(expected: &Type, actual: &Type, span: Span) -> Self { + let message = format!("Expected type `{}`, found type `{}`.", expected, actual); + + Self::new_from_span(message, span) + } + + /// The `Self` keyword was used outside of a circuit + pub fn self_not_available(span: Span) -> Self { + let message = format!("Type `Self` is only available in circuit definitions and circuit functions."); + + Self::new_from_span(message, span) + } + + /// Found an unknown circuit name + pub fn undefined_circuit(identifier: Identifier) -> Self { + let message = format!( + "Type circuit `{}` must be defined before it is used in an expression.", + identifier.name + ); + + Self::new_from_span(message, identifier.span) + } + + /// Found an unknown circuit member name + pub fn undefined_circuit_member(identifier: Identifier) -> Self { + let message = format!("Circuit has no member `{}`.", identifier.name); + + Self::new_from_span(message, identifier.span) + } + + /// Found an unknown function name + pub fn undefined_function(identifier: Identifier) -> Self { + let message = format!( + "Type function `{}` must be defined before it is used in an expression.", + identifier.name + ); + + Self::new_from_span(message, identifier.span) + } +} diff --git a/dynamic-check/src/resolver.rs b/dynamic-check/src/resolver.rs new file mode 100644 index 0000000000..da70812e0e --- /dev/null +++ b/dynamic-check/src/resolver.rs @@ -0,0 +1,114 @@ +// 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 . + +use crate::{Program, ResolverError}; +use leo_imports::ImportParser; +use leo_symbol_table::{ResolvedNode, SymbolTable}; +use leo_typed::LeoTypedAst; + +use serde_json; +use std::path::PathBuf; + +/// A resolved abstract syntax tree without implicit types. +#[derive(Debug, Eq, PartialEq)] +pub struct LeoResolvedAst { + pub resolved_ast: Program, +} + +impl LeoResolvedAst { + /// + /// Creates a new `LeoResolvedAst` resolved syntax tree from a given `LeoTypedAst` + /// typed syntax tree and main file path. + /// + pub fn new(ast: LeoTypedAst, path: PathBuf) -> Result { + // Get program typed syntax tree representation. + let program = ast.into_repr(); + + // Get imported program typed syntax tree representations. + let _imported_programs = ImportParser::parse(&program)?; + + // TODO (collinc97): Get input and state file typed syntax tree representations. + + // Create a new symbol table to track of program variables, circuits, and functions by name. + let mut symbol_table = SymbolTable::new(None); + + // Pass 1: Check for circuit and function name collisions. + symbol_table.pass_one(&program).map_err(|mut e| { + // Set the filepath for the error stacktrace. + e.set_path(path.clone()); + + e + })?; + + // Pass 2: Check circuit and function definitions for unknown types. + symbol_table.pass_two(&program).map_err(|mut e| { + // Set the filepath for the error stacktrace. + e.set_path(path.clone()); + + e + })?; + + // Pass 3: Check statements for type errors. + let resolved_ast = Program::resolve(&mut symbol_table, program).map_err(|mut e| { + // Set the filepath for the error stacktrace. + e.set_path(path); + + e + })?; + + Ok(Self { resolved_ast }) + } + + /// + /// Returns a reference to the inner resolved syntax tree representation. + /// + pub fn into_repr(self) -> Program { + self.resolved_ast + } + + /// + /// Serializes the resolved syntax tree into a JSON string. + /// + pub fn to_json_string(&self) -> Result { + Ok(serde_json::to_string_pretty(&self.resolved_ast)?) + } + + /// + /// Deserializes the JSON string into a resolved syntax tree. + /// + pub fn from_json_string(json: &str) -> Result { + let resolved_ast: Program = serde_json::from_str(json)?; + Ok(Self { resolved_ast }) + } +} +// +// /// A node in the `LeoResolvedAST`. +// /// +// /// This node and all of its children should not contain any implicit types. +// pub trait ResolvedNode { +// /// The expected error type if the type resolution fails. +// type Error; +// +// /// The `leo-typed` AST node that is being type checked. +// type UnresolvedNode; +// +// /// +// /// Returns a resolved AST representation given an unresolved AST representation and symbol table. +// /// +// fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result +// where +// Self: std::marker::Sized; +// } diff --git a/dynamic-check/src/resolver_lib.rs b/dynamic-check/src/resolver_lib.rs new file mode 100644 index 0000000000..0377f4ced9 --- /dev/null +++ b/dynamic-check/src/resolver_lib.rs @@ -0,0 +1,27 @@ +// // 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 . +// +// #[macro_use] +// extern crate thiserror; +// +// pub mod ast; +// pub use self::ast::*; +// +// pub mod errors; +// pub use self::errors::*; +// +// pub mod resolver; +// pub use self::resolver::*; From a4dab9594db12809885b828bc9d21bc08c5bafa6 Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 15 Oct 2020 17:58:56 -0700 Subject: [PATCH 022/139] fix resolver errors wip --- dynamic-check/src/{resolver.rs => ast/ast.rs} | 40 +++++++++---------- dynamic-check/src/ast/circuits/circuit.rs | 6 +-- .../src/ast/expressions/arithmetic/add.rs | 2 +- .../src/ast/expressions/arithmetic/div.rs | 2 +- .../src/ast/expressions/arithmetic/mul.rs | 2 +- .../src/ast/expressions/arithmetic/negate.rs | 4 +- .../src/ast/expressions/arithmetic/pow.rs | 2 +- .../src/ast/expressions/arithmetic/sub.rs | 2 +- .../src/ast/expressions/array/array.rs | 4 +- .../src/ast/expressions/array/array_access.rs | 4 +- .../expressions/array/range_or_expression.rs | 4 +- .../expressions/array/spread_or_expression.rs | 4 +- .../src/ast/expressions/binary/binary.rs | 4 +- .../src/ast/expressions/circuit/circuit.rs | 4 +- .../ast/expressions/circuit/circuit_access.rs | 4 +- .../circuit/circuit_static_access.rs | 4 +- .../circuit/circuit_variable_definition.rs | 4 +- .../expressions/conditional/conditional.rs | 4 +- .../src/ast/expressions/expression.rs | 4 +- .../ast/expressions/function/function_call.rs | 4 +- .../ast/expressions/identifier/identifier.rs | 2 +- .../src/ast/expressions/logical/and.rs | 2 +- .../src/ast/expressions/logical/not.rs | 4 +- .../src/ast/expressions/logical/or.rs | 2 +- .../src/ast/expressions/relational/eq.rs | 2 +- .../src/ast/expressions/relational/ge.rs | 2 +- .../src/ast/expressions/relational/gt.rs | 2 +- .../src/ast/expressions/relational/le.rs | 2 +- .../src/ast/expressions/relational/lt.rs | 2 +- .../src/ast/expressions/tuple/tuple.rs | 4 +- .../src/ast/expressions/tuple/tuple_access.rs | 4 +- .../src/ast/expressions/values/address.rs | 2 +- .../src/ast/expressions/values/boolean.rs | 2 +- .../src/ast/expressions/values/field.rs | 2 +- .../src/ast/expressions/values/group.rs | 2 +- .../src/ast/expressions/values/implicit.rs | 2 +- .../src/ast/expressions/values/integer.rs | 2 +- dynamic-check/src/ast/functions/function.rs | 4 +- .../src/ast/functions/test_function.rs | 4 +- dynamic-check/src/ast/imports/import.rs | 3 +- dynamic-check/src/ast/mod.rs | 4 ++ dynamic-check/src/ast/programs/program.rs | 6 +-- .../src/ast/statements/assign/assign.rs | 4 +- .../ast/statements/conditional/conditional.rs | 4 +- .../ast/statements/definition/definition.rs | 4 +- .../src/ast/statements/iteration/iteration.rs | 4 +- .../src/ast/statements/return_/return_.rs | 4 +- dynamic-check/src/ast/statements/statement.rs | 4 +- .../src/{ => dynamic_check}/dynamic_check.rs | 0 dynamic-check/src/dynamic_check/mod.rs | 18 +++++++++ dynamic-check/src/errors/expression.rs | 2 +- dynamic-check/src/errors/function.rs | 2 +- dynamic-check/src/errors/resolver.rs | 2 +- dynamic-check/src/errors/statement.rs | 2 +- dynamic-check/src/lib.rs | 9 +++++ dynamic-check/src/resolver_lib.rs | 27 ------------- 56 files changed, 130 insertions(+), 125 deletions(-) rename dynamic-check/src/{resolver.rs => ast/ast.rs} (81%) rename dynamic-check/src/{ => dynamic_check}/dynamic_check.rs (100%) create mode 100644 dynamic-check/src/dynamic_check/mod.rs delete mode 100644 dynamic-check/src/resolver_lib.rs diff --git a/dynamic-check/src/resolver.rs b/dynamic-check/src/ast/ast.rs similarity index 81% rename from dynamic-check/src/resolver.rs rename to dynamic-check/src/ast/ast.rs index da70812e0e..85779fb910 100644 --- a/dynamic-check/src/resolver.rs +++ b/dynamic-check/src/ast/ast.rs @@ -16,13 +16,13 @@ use crate::{Program, ResolverError}; use leo_imports::ImportParser; -use leo_symbol_table::{ResolvedNode, SymbolTable}; +use leo_static_check::SymbolTable; use leo_typed::LeoTypedAst; use serde_json; use std::path::PathBuf; -/// A resolved abstract syntax tree without implicit types. +/// A program abstract syntax tree without implicit types. #[derive(Debug, Eq, PartialEq)] pub struct LeoResolvedAst { pub resolved_ast: Program, @@ -94,21 +94,21 @@ impl LeoResolvedAst { Ok(Self { resolved_ast }) } } -// -// /// A node in the `LeoResolvedAST`. -// /// -// /// This node and all of its children should not contain any implicit types. -// pub trait ResolvedNode { -// /// The expected error type if the type resolution fails. -// type Error; -// -// /// The `leo-typed` AST node that is being type checked. -// type UnresolvedNode; -// -// /// -// /// Returns a resolved AST representation given an unresolved AST representation and symbol table. -// /// -// fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result -// where -// Self: std::marker::Sized; -// } + +/// A node in the `LeoResolvedAST`. +/// +/// This node and all of its children should not contain any implicit types. +pub trait ResolvedNode { + /// The expected error type if the type resolution fails. + type Error; + + /// The `leo-typed` AST node that is being type checked. + type UnresolvedNode; + + /// + /// Returns a resolved AST representation given an unresolved AST representation and symbol table. + /// + fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result + where + Self: std::marker::Sized; +} diff --git a/dynamic-check/src/ast/circuits/circuit.rs b/dynamic-check/src/ast/circuits/circuit.rs index 0e346b7a03..35026f9d6c 100644 --- a/dynamic-check/src/ast/circuits/circuit.rs +++ b/dynamic-check/src/ast/circuits/circuit.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{CircuitError, Function}; -use leo_symbol_table::{Attribute, CircuitType, ResolvedNode, SymbolTable, Type, VariableType}; +use crate::{CircuitError, Function, ResolvedNode}; +use leo_static_check::{Attribute, CircuitType, ParameterType, SymbolTable, Type}; use leo_typed::{circuit::Circuit as UnresolvedCircuit, identifier::Identifier, CircuitMember}; use serde::{Deserialize, Serialize}; @@ -49,7 +49,7 @@ impl ResolvedNode for Circuit { // Create self variable let self_key = "self".to_owned(); - let self_variable = VariableType { + let self_variable = ParameterType { identifier: identifier.clone(), type_: Type::Circuit(identifier.clone()), attributes: vec![Attribute::Mutable], diff --git a/dynamic-check/src/ast/expressions/arithmetic/add.rs b/dynamic-check/src/ast/expressions/arithmetic/add.rs index 0a68369126..54236b6464 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/add.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/add.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/arithmetic/div.rs b/dynamic-check/src/ast/expressions/arithmetic/div.rs index 8a5bd4d779..4c657d1808 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/div.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/div.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/arithmetic/mul.rs b/dynamic-check/src/ast/expressions/arithmetic/mul.rs index 0e53130a0c..a2fe20b878 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/mul.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/mul.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/arithmetic/negate.rs b/dynamic-check/src/ast/expressions/arithmetic/negate.rs index e2c988d37c..8bdfc77b88 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/negate.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/negate.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/arithmetic/pow.rs b/dynamic-check/src/ast/expressions/arithmetic/pow.rs index 4938d85ed9..e60443a33d 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/pow.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/pow.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/arithmetic/sub.rs b/dynamic-check/src/ast/expressions/arithmetic/sub.rs index bef35c4040..777aa5494c 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/sub.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/sub.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/array/array.rs b/dynamic-check/src/ast/expressions/array/array.rs index 6b71320711..792fa25eb4 100644 --- a/dynamic-check/src/ast/expressions/array/array.rs +++ b/dynamic-check/src/ast/expressions/array/array.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ast::expressions::array::SpreadOrExpression, Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{ast::expressions::array::SpreadOrExpression, Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Span, SpreadOrExpression as UnresolvedSpreadOrExpression}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/array/array_access.rs b/dynamic-check/src/ast/expressions/array/array_access.rs index 66b5af8278..dfde2506bc 100644 --- a/dynamic-check/src/ast/expressions/array/array_access.rs +++ b/dynamic-check/src/ast/expressions/array/array_access.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ast::expressions::array::RangeOrExpression, Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{ast::expressions::array::RangeOrExpression, Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, RangeOrExpression as UnresolvedRangeOrExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/array/range_or_expression.rs b/dynamic-check/src/ast/expressions/array/range_or_expression.rs index c0a01896d3..788cc56e2a 100644 --- a/dynamic-check/src/ast/expressions/array/range_or_expression.rs +++ b/dynamic-check/src/ast/expressions/array/range_or_expression.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::RangeOrExpression as UnresolvedRangeOrExpression; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/ast/expressions/array/spread_or_expression.rs b/dynamic-check/src/ast/expressions/array/spread_or_expression.rs index 4997f7664b..80fd4e6ea6 100644 --- a/dynamic-check/src/ast/expressions/array/spread_or_expression.rs +++ b/dynamic-check/src/ast/expressions/array/spread_or_expression.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::SpreadOrExpression as UnresolvedSpreadOrExpression; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/ast/expressions/binary/binary.rs b/dynamic-check/src/ast/expressions/binary/binary.rs index 872e280f0a..1c0d298eb3 100644 --- a/dynamic-check/src/ast/expressions/binary/binary.rs +++ b/dynamic-check/src/ast/expressions/binary/binary.rs @@ -13,8 +13,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/circuit/circuit.rs b/dynamic-check/src/ast/expressions/circuit/circuit.rs index 57f306e41f..78e544a167 100644 --- a/dynamic-check/src/ast/expressions/circuit/circuit.rs +++ b/dynamic-check/src/ast/expressions/circuit/circuit.rs @@ -13,8 +13,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{CircuitVariableDefinition, Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{CircuitVariableDefinition, Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{CircuitVariableDefinition as UnresolvedCircuitVariableDefinition, Identifier, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_access.rs b/dynamic-check/src/ast/expressions/circuit/circuit_access.rs index c63ba5bb42..e7e73920be 100644 --- a/dynamic-check/src/ast/expressions/circuit/circuit_access.rs +++ b/dynamic-check/src/ast/expressions/circuit/circuit_access.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{Attribute, ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{Attribute, SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Identifier, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs b/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs index 278180746d..9bdd5cc4cc 100644 --- a/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs +++ b/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{Attribute, ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{Attribute, SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Identifier, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs b/dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs index 422942a731..17b69b0f4f 100644 --- a/dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs +++ b/dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{CircuitVariableDefinition as UnresolvedCircuitVariableDefinition, Identifier}; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/ast/expressions/conditional/conditional.rs b/dynamic-check/src/ast/expressions/conditional/conditional.rs index 21bb247d7b..260f9b0412 100644 --- a/dynamic-check/src/ast/expressions/conditional/conditional.rs +++ b/dynamic-check/src/ast/expressions/conditional/conditional.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs index f81166c955..924a58a444 100644 --- a/dynamic-check/src/ast/expressions/expression.rs +++ b/dynamic-check/src/ast/expressions/expression.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ExpressionError, ExpressionValue}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/ast/expressions/function/function_call.rs b/dynamic-check/src/ast/expressions/function/function_call.rs index 5de4d20405..720d2e05a2 100644 --- a/dynamic-check/src/ast/expressions/function/function_call.rs +++ b/dynamic-check/src/ast/expressions/function/function_call.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/identifier/identifier.rs b/dynamic-check/src/ast/expressions/identifier/identifier.rs index b351c871e1..bfb79e855b 100644 --- a/dynamic-check/src/ast/expressions/identifier/identifier.rs +++ b/dynamic-check/src/ast/expressions/identifier/identifier.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::Identifier; impl Expression { diff --git a/dynamic-check/src/ast/expressions/logical/and.rs b/dynamic-check/src/ast/expressions/logical/and.rs index 4b3a34d4b8..8b0ed9fcc3 100644 --- a/dynamic-check/src/ast/expressions/logical/and.rs +++ b/dynamic-check/src/ast/expressions/logical/and.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/logical/not.rs b/dynamic-check/src/ast/expressions/logical/not.rs index bf891fd85b..9d56fc616a 100644 --- a/dynamic-check/src/ast/expressions/logical/not.rs +++ b/dynamic-check/src/ast/expressions/logical/not.rs @@ -13,8 +13,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/logical/or.rs b/dynamic-check/src/ast/expressions/logical/or.rs index 3af380c368..6e35ab6bf2 100644 --- a/dynamic-check/src/ast/expressions/logical/or.rs +++ b/dynamic-check/src/ast/expressions/logical/or.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/relational/eq.rs b/dynamic-check/src/ast/expressions/relational/eq.rs index 607b991675..fbbbd84d3f 100644 --- a/dynamic-check/src/ast/expressions/relational/eq.rs +++ b/dynamic-check/src/ast/expressions/relational/eq.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/relational/ge.rs b/dynamic-check/src/ast/expressions/relational/ge.rs index cce64ba3dd..4ea8f90591 100644 --- a/dynamic-check/src/ast/expressions/relational/ge.rs +++ b/dynamic-check/src/ast/expressions/relational/ge.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/relational/gt.rs b/dynamic-check/src/ast/expressions/relational/gt.rs index 4580863c3b..6388f97333 100644 --- a/dynamic-check/src/ast/expressions/relational/gt.rs +++ b/dynamic-check/src/ast/expressions/relational/gt.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/relational/le.rs b/dynamic-check/src/ast/expressions/relational/le.rs index d6647461fd..0a1a02b015 100644 --- a/dynamic-check/src/ast/expressions/relational/le.rs +++ b/dynamic-check/src/ast/expressions/relational/le.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/relational/lt.rs b/dynamic-check/src/ast/expressions/relational/lt.rs index dcd33a229a..4f874b5e2d 100644 --- a/dynamic-check/src/ast/expressions/relational/lt.rs +++ b/dynamic-check/src/ast/expressions/relational/lt.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{SymbolTable, Type}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/tuple/tuple.rs b/dynamic-check/src/ast/expressions/tuple/tuple.rs index fa53532d0c..66bef80542 100644 --- a/dynamic-check/src/ast/expressions/tuple/tuple.rs +++ b/dynamic-check/src/ast/expressions/tuple/tuple.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/tuple/tuple_access.rs b/dynamic-check/src/ast/expressions/tuple/tuple_access.rs index 91def0bd53..31f52553a6 100644 --- a/dynamic-check/src/ast/expressions/tuple/tuple_access.rs +++ b/dynamic-check/src/ast/expressions/tuple/tuple_access.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/values/address.rs b/dynamic-check/src/ast/expressions/values/address.rs index 5761fb5b1e..f855fc910f 100644 --- a/dynamic-check/src/ast/expressions/values/address.rs +++ b/dynamic-check/src/ast/expressions/values/address.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::Type; +use leo_static_check::Type; use leo_typed::Span; impl Expression { diff --git a/dynamic-check/src/ast/expressions/values/boolean.rs b/dynamic-check/src/ast/expressions/values/boolean.rs index 05123e29e1..d8af250ab3 100644 --- a/dynamic-check/src/ast/expressions/values/boolean.rs +++ b/dynamic-check/src/ast/expressions/values/boolean.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::Type; +use leo_static_check::Type; use leo_typed::Span; impl Expression { diff --git a/dynamic-check/src/ast/expressions/values/field.rs b/dynamic-check/src/ast/expressions/values/field.rs index 020c61f071..ea1a85272d 100644 --- a/dynamic-check/src/ast/expressions/values/field.rs +++ b/dynamic-check/src/ast/expressions/values/field.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::Type; +use leo_static_check::Type; use leo_typed::Span; impl Expression { diff --git a/dynamic-check/src/ast/expressions/values/group.rs b/dynamic-check/src/ast/expressions/values/group.rs index 2adc837a2b..39b68f5f2d 100644 --- a/dynamic-check/src/ast/expressions/values/group.rs +++ b/dynamic-check/src/ast/expressions/values/group.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::Type; +use leo_static_check::Type; use leo_typed::GroupValue; impl Expression { diff --git a/dynamic-check/src/ast/expressions/values/implicit.rs b/dynamic-check/src/ast/expressions/values/implicit.rs index 93e17f1ab6..95fed873a0 100644 --- a/dynamic-check/src/ast/expressions/values/implicit.rs +++ b/dynamic-check/src/ast/expressions/values/implicit.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::Type; +use leo_static_check::Type; use leo_typed::{GroupValue, Span}; impl Expression { diff --git a/dynamic-check/src/ast/expressions/values/integer.rs b/dynamic-check/src/ast/expressions/values/integer.rs index 47f7d04086..ed6c5142be 100644 --- a/dynamic-check/src/ast/expressions/values/integer.rs +++ b/dynamic-check/src/ast/expressions/values/integer.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_symbol_table::Type; +use leo_static_check::Type; use leo_typed::{IntegerType, Span}; impl Expression { diff --git a/dynamic-check/src/ast/functions/function.rs b/dynamic-check/src/ast/functions/function.rs index 0e8b9a4097..477e0e576f 100644 --- a/dynamic-check/src/ast/functions/function.rs +++ b/dynamic-check/src/ast/functions/function.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{FunctionError, Statement}; -use leo_symbol_table::{FunctionType, ResolvedNode, SymbolTable, TypeError}; +use crate::{FunctionError, ResolvedNode, Statement}; +use leo_static_check::{FunctionType, SymbolTable, TypeError}; use leo_typed::Function as UnresolvedFunction; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/ast/functions/test_function.rs b/dynamic-check/src/ast/functions/test_function.rs index 63d226d43f..1259a6be43 100644 --- a/dynamic-check/src/ast/functions/test_function.rs +++ b/dynamic-check/src/ast/functions/test_function.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Function, FunctionError}; -use leo_symbol_table::{ResolvedNode, SymbolTable}; +use crate::{Function, FunctionError, ResolvedNode}; +use leo_static_check::SymbolTable; use leo_typed::{Identifier, TestFunction as UnresolvedTestFunction}; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/ast/imports/import.rs b/dynamic-check/src/ast/imports/import.rs index ef046c160d..8223b64184 100644 --- a/dynamic-check/src/ast/imports/import.rs +++ b/dynamic-check/src/ast/imports/import.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_symbol_table::{ResolvedNode, SymbolTable}; +use crate::ResolvedNode; +use leo_static_check::SymbolTable; use leo_typed::Import as UnresolvedImport; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/ast/mod.rs b/dynamic-check/src/ast/mod.rs index 70fcc62cd8..8195841282 100644 --- a/dynamic-check/src/ast/mod.rs +++ b/dynamic-check/src/ast/mod.rs @@ -13,6 +13,10 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . + +pub mod ast; +pub use self::ast::*; + pub mod circuits; pub use self::circuits::*; diff --git a/dynamic-check/src/ast/programs/program.rs b/dynamic-check/src/ast/programs/program.rs index 0de4e91e19..3d8a18e2b9 100644 --- a/dynamic-check/src/ast/programs/program.rs +++ b/dynamic-check/src/ast/programs/program.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Circuit, Function, ProgramError, TestFunction}; -use leo_symbol_table::{ResolvedNode, SymbolTable}; -use leo_typed::{programs::Program as UnresolvedProgram, Identifier}; +use crate::{Circuit, Function, ProgramError, ResolvedNode, TestFunction}; +use leo_static_check::SymbolTable; +use leo_typed::{Identifier, Program as UnresolvedProgram}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; diff --git a/dynamic-check/src/ast/statements/assign/assign.rs b/dynamic-check/src/ast/statements/assign/assign.rs index 21de091dc7..7fa441e9dc 100644 --- a/dynamic-check/src/ast/statements/assign/assign.rs +++ b/dynamic-check/src/ast/statements/assign/assign.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, Statement, StatementError}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ResolvedNode, Statement, StatementError}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Assignee, AssigneeAccess, Expression as UnresolvedExpression, Span}; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/ast/statements/conditional/conditional.rs b/dynamic-check/src/ast/statements/conditional/conditional.rs index 6d30a5dbe0..a603bc69f8 100644 --- a/dynamic-check/src/ast/statements/conditional/conditional.rs +++ b/dynamic-check/src/ast/statements/conditional/conditional.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, Statement, StatementError}; -use leo_symbol_table::{FunctionOutputType, ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ResolvedNode, Statement, StatementError}; +use leo_static_check::{FunctionOutputType, SymbolTable, Type}; use leo_typed::{ ConditionalNestedOrEndStatement as UnresolvedNestedOrEnd, ConditionalStatement as UnresolvedConditional, diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs index 7e26158f5f..fcbe78f66d 100644 --- a/dynamic-check/src/ast/statements/definition/definition.rs +++ b/dynamic-check/src/ast/statements/definition/definition.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{check_tuple_type, Expression, ExpressionValue, Statement, StatementError}; -use leo_symbol_table::{Attribute, ResolvedNode, SymbolTable, Type, VariableType}; +use crate::{check_tuple_type, Expression, ExpressionValue, ResolvedNode, Statement, StatementError}; +use leo_static_check::{Attribute, SymbolTable, Type, VariableType}; use leo_typed::{Declare, Expression as UnresolvedExpression, Span, VariableName, Variables}; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/ast/statements/iteration/iteration.rs b/dynamic-check/src/ast/statements/iteration/iteration.rs index 9bc6a646a1..323bb6da7f 100644 --- a/dynamic-check/src/ast/statements/iteration/iteration.rs +++ b/dynamic-check/src/ast/statements/iteration/iteration.rs @@ -13,8 +13,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, Statement, StatementError}; -use leo_symbol_table::{FunctionOutputType, ResolvedNode, SymbolTable, Type, VariableType}; +use crate::{Expression, ResolvedNode, Statement, StatementError}; +use leo_static_check::{FunctionOutputType, SymbolTable, Type, VariableType}; use leo_typed::{Expression as UnresolvedExpression, Identifier, IntegerType, Span, Statement as UnresolvedStatement}; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/ast/statements/return_/return_.rs b/dynamic-check/src/ast/statements/return_/return_.rs index 6024b20b13..acc3d416f5 100644 --- a/dynamic-check/src/ast/statements/return_/return_.rs +++ b/dynamic-check/src/ast/statements/return_/return_.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, Statement, StatementError}; -use leo_symbol_table::{ResolvedNode, SymbolTable, Type}; +use crate::{Expression, ResolvedNode, Statement, StatementError}; +use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Statement { diff --git a/dynamic-check/src/ast/statements/statement.rs b/dynamic-check/src/ast/statements/statement.rs index 9e7a7259a6..90f92c9f4a 100644 --- a/dynamic-check/src/ast/statements/statement.rs +++ b/dynamic-check/src/ast/statements/statement.rs @@ -13,8 +13,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Assign, Conditional, Definition, Expression, Iteration, StatementError}; -use leo_symbol_table::{FunctionOutputType, ResolvedNode, SymbolTable}; +use crate::{Assign, Conditional, Definition, Expression, Iteration, ResolvedNode, StatementError}; +use leo_static_check::{FunctionOutputType, SymbolTable}; use leo_typed::{ConsoleFunctionCall, Span, Statement as UnresolvedStatement}; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check/dynamic_check.rs similarity index 100% rename from dynamic-check/src/dynamic_check.rs rename to dynamic-check/src/dynamic_check/dynamic_check.rs diff --git a/dynamic-check/src/dynamic_check/mod.rs b/dynamic-check/src/dynamic_check/mod.rs new file mode 100644 index 0000000000..ddebbdd6a7 --- /dev/null +++ b/dynamic-check/src/dynamic_check/mod.rs @@ -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 . + +pub mod dynamic_check; +pub use self::dynamic_check::*; diff --git a/dynamic-check/src/errors/expression.rs b/dynamic-check/src/errors/expression.rs index cefe168c3b..75f84bbfcb 100644 --- a/dynamic-check/src/errors/expression.rs +++ b/dynamic-check/src/errors/expression.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_symbol_table::TypeError; +use leo_static_check::TypeError; use leo_typed::{Error as FormattedError, Identifier, Span}; use std::path::PathBuf; diff --git a/dynamic-check/src/errors/function.rs b/dynamic-check/src/errors/function.rs index 81fd47baac..87b29f1850 100644 --- a/dynamic-check/src/errors/function.rs +++ b/dynamic-check/src/errors/function.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::StatementError; -use leo_symbol_table::TypeError; +use leo_static_check::TypeError; use leo_typed::{Error as FormattedError, Identifier, Span}; use std::path::PathBuf; diff --git a/dynamic-check/src/errors/resolver.rs b/dynamic-check/src/errors/resolver.rs index a33b7d69c4..3fa847e8f3 100644 --- a/dynamic-check/src/errors/resolver.rs +++ b/dynamic-check/src/errors/resolver.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::ProgramError; use leo_imports::ImportParserError; -use leo_symbol_table::SymbolTableError; +use leo_static_check::SymbolTableError; use leo_typed::Error as FormattedError; #[derive(Debug, Error)] diff --git a/dynamic-check/src/errors/statement.rs b/dynamic-check/src/errors/statement.rs index c1734411d3..bfd96c2e5c 100644 --- a/dynamic-check/src/errors/statement.rs +++ b/dynamic-check/src/errors/statement.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::ExpressionError; -use leo_symbol_table::{Type, TypeError}; +use leo_static_check::{Type, TypeError}; use leo_typed::{Error as FormattedError, Expression as UnresolvedExpression, Identifier, Span}; use std::path::PathBuf; diff --git a/dynamic-check/src/lib.rs b/dynamic-check/src/lib.rs index ddebbdd6a7..5e2064d95f 100644 --- a/dynamic-check/src/lib.rs +++ b/dynamic-check/src/lib.rs @@ -14,5 +14,14 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +#[macro_use] +extern crate thiserror; + +pub mod ast; +pub use self::ast::*; + pub mod dynamic_check; pub use self::dynamic_check::*; + +pub mod errors; +pub use self::errors::*; diff --git a/dynamic-check/src/resolver_lib.rs b/dynamic-check/src/resolver_lib.rs deleted file mode 100644 index 0377f4ced9..0000000000 --- a/dynamic-check/src/resolver_lib.rs +++ /dev/null @@ -1,27 +0,0 @@ -// // 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 . -// -// #[macro_use] -// extern crate thiserror; -// -// pub mod ast; -// pub use self::ast::*; -// -// pub mod errors; -// pub use self::errors::*; -// -// pub mod resolver; -// pub use self::resolver::*; From 3bd6d2e6b6866cf9b59699b4262529d50b182645 Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 15 Oct 2020 18:04:58 -0700 Subject: [PATCH 023/139] use simpler assignee access in leo typed --- typed/src/common/assignee.rs | 78 ++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/typed/src/common/assignee.rs b/typed/src/common/assignee.rs index afa7f1c460..5d6af0f6ee 100644 --- a/typed/src/common/assignee.rs +++ b/typed/src/common/assignee.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, Identifier, RangeOrExpression}; +use crate::{Expression, Identifier, RangeOrExpression, Span}; use leo_ast::{ access::AssigneeAccess as AstAssigneeAccess, common::{Assignee as AstAssignee, Identifier as AstIdentifier, SelfKeywordOrIdentifier}, @@ -23,56 +23,64 @@ use leo_ast::{ use serde::{Deserialize, Serialize}; use std::fmt; -/// Definition assignee: v, arr[0..2], Point p.x #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum Assignee { - Identifier(Identifier), - Array(Box, RangeOrExpression), - Tuple(Box, usize), - CircuitField(Box, Identifier), // (circuit name, circuit field name) +pub enum AssigneeAccess { + Array(RangeOrExpression), + Tuple(usize), + Member(Identifier), } -impl<'ast> From> for Assignee { - fn from(variable: AstIdentifier<'ast>) -> Self { - Assignee::Identifier(Identifier::from(variable)) +impl<'ast> From> for AssigneeAccess { + fn from(access: AstAssigneeAccess<'ast>) -> Self { + match access { + AstAssigneeAccess::Array(array) => AssigneeAccess::Array(RangeOrExpression::from(array.expression)), + AstAssigneeAccess::Tuple(tuple) => AssigneeAccess::Tuple(Expression::get_count_from_ast(tuple.number)), + AstAssigneeAccess::Member(member) => AssigneeAccess::Member(Identifier::from(member.identifier)), + } } } -impl<'ast> From> for Assignee { - fn from(name: SelfKeywordOrIdentifier<'ast>) -> Self { - Assignee::Identifier(Identifier::from(name)) +/// Definition assignee: v, arr[0..2], Point p.x +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Assignee { + pub identifier: Identifier, + pub accesses: Vec, + pub span: Span, +} + +impl Assignee { + /// Returns the name of the variable being assigned to + pub fn identifier(&self) -> &Identifier { + &self.identifier } } impl<'ast> From> for Assignee { fn from(assignee: AstAssignee<'ast>) -> Self { - let variable = Assignee::from(assignee.name); - - // We start with the id, and we fold the array of accesses by wrapping the current value - assignee - .accesses - .into_iter() - .fold(variable, |acc, access| match access { - AstAssigneeAccess::Array(array) => { - Assignee::Array(Box::new(acc), RangeOrExpression::from(array.expression)) - } - AstAssigneeAccess::Tuple(tuple) => { - Assignee::Tuple(Box::new(acc), Expression::get_count_from_ast(tuple.number)) - } - AstAssigneeAccess::Member(circuit_variable) => { - Assignee::CircuitField(Box::new(acc), Identifier::from(circuit_variable.identifier)) - } - }) + Assignee { + identifier: Identifier::from(assignee.name), + accesses: assignee + .accesses + .into_iter() + .map(|access| AssigneeAccess::from(access)) + .collect::>(), + span: Span::from(assignee.span), + } } } impl fmt::Display for Assignee { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Assignee::Identifier(ref variable) => write!(f, "{}", variable), - Assignee::Array(ref array, ref index) => write!(f, "{}[{}]", array, index), - Assignee::Tuple(ref tuple, ref index) => write!(f, "{}.{}", tuple, index), - Assignee::CircuitField(ref circuit_variable, ref member) => write!(f, "{}.{}", circuit_variable, member), + write!(f, "{}", self.identifier)?; + + for access in &self.accesses { + match access { + AssigneeAccess::Array(expression) => write!(f, "[{}]", expression)?, + AssigneeAccess::Tuple(index) => write!(f, ".{}", index)?, + AssigneeAccess::Member(member) => write!(f, ".{}", member)?, + } } + + write!(f, "") } } From 323992696ceab3abae3cf3b35b0b8643cfe41448 Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 15 Oct 2020 18:11:39 -0700 Subject: [PATCH 024/139] use typed assignee access --- compiler/src/statement/assign/assign.rs | 73 +++++++++++------------ compiler/src/statement/assign/assignee.rs | 7 +-- 2 files changed, 35 insertions(+), 45 deletions(-) diff --git a/compiler/src/statement/assign/assign.rs b/compiler/src/statement/assign/assign.rs index dcd7da37bb..a0943107d9 100644 --- a/compiler/src/statement/assign/assign.rs +++ b/compiler/src/statement/assign/assign.rs @@ -24,7 +24,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_typed::{Assignee, Expression, Span}; +use leo_typed::{Assignee, AssigneeAccess, Expression, Span}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -54,61 +54,56 @@ impl> ConstrainedProgram { self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), None, expression)?; // Mutate the old value into the new value - match assignee { - Assignee::Identifier(_identifier) => { - let condition = indicator.unwrap_or(Boolean::Constant(true)); - let old_value = self.get_mutable_assignee(variable_name.clone(), span.clone())?; + if assignee.accesses.is_empty() { + let condition = indicator.unwrap_or(Boolean::Constant(true)); + let old_value = self.get_mutable_assignee(variable_name.clone(), span.clone())?; - new_value.resolve_type(Some(old_value.to_type(span.clone())?), span.clone())?; + new_value.resolve_type(Some(old_value.to_type(span.clone())?), span.clone())?; - let name_unique = format!("select {} {}:{}", new_value, span.line, span.start); - let selected_value = - ConstrainedValue::conditionally_select(cs.ns(|| name_unique), &condition, &new_value, old_value) - .map_err(|_| StatementError::select_fail(new_value.to_string(), old_value.to_string(), span))?; + let name_unique = format!("select {} {}:{}", new_value, span.line, span.start); + let selected_value = + ConstrainedValue::conditionally_select(cs.ns(|| name_unique), &condition, &new_value, old_value) + .map_err(|_| StatementError::select_fail(new_value.to_string(), old_value.to_string(), span))?; - *old_value = selected_value; + *old_value = selected_value; - Ok(()) - } - Assignee::Array(_assignee, range_or_expression) => self.assign_array( - cs, - file_scope, - function_scope, - indicator, - variable_name, - range_or_expression, - new_value, - span, - ), - Assignee::Tuple(_tuple, index) => self.assign_tuple(cs, indicator, variable_name, index, new_value, span), - Assignee::CircuitField(assignee, circuit_variable) => { - // Mutate a circuit variable using the self keyword. - if let Assignee::Identifier(circuit_name) = *assignee { - if circuit_name.is_self() { - let self_circuit_variable_name = new_scope(circuit_name.name, circuit_variable.name.clone()); + return Ok(()); + } else { + match assignee.accesses[0].clone() { + AssigneeAccess::Array(range_or_expression) => self.assign_array( + cs, + file_scope, + function_scope, + indicator, + variable_name, + range_or_expression, + new_value, + span, + ), + AssigneeAccess::Tuple(index) => self.assign_tuple(cs, indicator, variable_name, index, new_value, span), + AssigneeAccess::Member(identifier) => { + // Mutate a circuit variable using the self keyword. + if assignee.identifier.is_self() { + let self_circuit_variable_name = + new_scope(assignee.identifier.name.clone(), identifier.name.clone()); let self_variable_name = new_scope(file_scope, self_circuit_variable_name); let value = self.mutate_circuit_variable( cs, indicator, declared_circuit_reference, - circuit_variable, + identifier, new_value, span, )?; self.store(self_variable_name, value); } else { - let _value = self.mutate_circuit_variable( - cs, - indicator, - variable_name, - circuit_variable, - new_value, - span, - )?; + let _value = + self.mutate_circuit_variable(cs, indicator, variable_name, identifier, new_value, span)?; } + + Ok(()) } - Ok(()) } } } diff --git a/compiler/src/statement/assign/assignee.rs b/compiler/src/statement/assign/assignee.rs index 99716431ea..d7528189af 100644 --- a/compiler/src/statement/assign/assignee.rs +++ b/compiler/src/statement/assign/assignee.rs @@ -22,12 +22,7 @@ use leo_typed::{Assignee, Span}; use snarkos_models::curves::{Field, PrimeField}; pub fn resolve_assignee(scope: String, assignee: Assignee) -> String { - match assignee { - Assignee::Identifier(name) => new_scope(scope, name.to_string()), - Assignee::Array(array, _index) => resolve_assignee(scope, *array), - Assignee::Tuple(tuple, _index) => resolve_assignee(scope, *tuple), - Assignee::CircuitField(circuit_name, _member) => resolve_assignee(scope, *circuit_name), - } + new_scope(scope, assignee.identifier().to_string()) } impl> ConstrainedProgram { From 8f34904fdccccb83aed51c7fdc1a9840294df7f4 Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 15 Oct 2020 19:57:26 -0700 Subject: [PATCH 025/139] fix resolver errors wip 2 --- Cargo.lock | 1 + dynamic-check/Cargo.toml | 3 ++ dynamic-check/src/ast/ast.rs | 54 +++++++++---------- dynamic-check/src/ast/circuits/circuit.rs | 2 +- .../src/ast/expressions/expression.rs | 2 +- .../ast/statements/definition/definition.rs | 6 +-- .../src/dynamic_check/dynamic_check.rs | 6 +-- static-check/src/symbol_table.rs | 24 ++++----- typed/src/common/variable_name.rs | 2 +- 9 files changed, 52 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c0042835bc..7c3d37aa70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1285,6 +1285,7 @@ dependencies = [ "leo-static-check", "leo-typed", "serde", + "serde_json", "thiserror", ] diff --git a/dynamic-check/Cargo.toml b/dynamic-check/Cargo.toml index 98e8994f27..c10ea4bc98 100644 --- a/dynamic-check/Cargo.toml +++ b/dynamic-check/Cargo.toml @@ -25,6 +25,9 @@ version = "1.0.3" path = "../imports" version = "1.0.3" +[dependencies.serde_json] +version = "1.0" + [dependencies.leo-static-check] path = "../static-check" version = "1.0.3" diff --git a/dynamic-check/src/ast/ast.rs b/dynamic-check/src/ast/ast.rs index 85779fb910..1f0e69491f 100644 --- a/dynamic-check/src/ast/ast.rs +++ b/dynamic-check/src/ast/ast.rs @@ -41,33 +41,33 @@ impl LeoResolvedAst { let _imported_programs = ImportParser::parse(&program)?; // TODO (collinc97): Get input and state file typed syntax tree representations. - - // Create a new symbol table to track of program variables, circuits, and functions by name. - let mut symbol_table = SymbolTable::new(None); - - // Pass 1: Check for circuit and function name collisions. - symbol_table.pass_one(&program).map_err(|mut e| { - // Set the filepath for the error stacktrace. - e.set_path(path.clone()); - - e - })?; - - // Pass 2: Check circuit and function definitions for unknown types. - symbol_table.pass_two(&program).map_err(|mut e| { - // Set the filepath for the error stacktrace. - e.set_path(path.clone()); - - e - })?; - - // Pass 3: Check statements for type errors. - let resolved_ast = Program::resolve(&mut symbol_table, program).map_err(|mut e| { - // Set the filepath for the error stacktrace. - e.set_path(path); - - e - })?; + // + // // Create a new symbol table to track of program variables, circuits, and functions by name. + // let mut symbol_table = SymbolTable::new(None); + // + // // Pass 1: Check for circuit and function name collisions. + // symbol_table.pass_one(&program).map_err(|mut e| { + // // Set the filepath for the error stacktrace. + // e.set_path(path.clone()); + // + // e + // })?; + // + // // Pass 2: Check circuit and function definitions for unknown types. + // symbol_table.pass_two(&program).map_err(|mut e| { + // // Set the filepath for the error stacktrace. + // e.set_path(path.clone()); + // + // e + // })?; + // + // // Pass 3: Check statements for type errors. + // let resolved_ast = Program::resolve(&mut symbol_table, program).map_err(|mut e| { + // // Set the filepath for the error stacktrace. + // e.set_path(path); + // + // e + // })?; Ok(Self { resolved_ast }) } diff --git a/dynamic-check/src/ast/circuits/circuit.rs b/dynamic-check/src/ast/circuits/circuit.rs index 35026f9d6c..96d0574694 100644 --- a/dynamic-check/src/ast/circuits/circuit.rs +++ b/dynamic-check/src/ast/circuits/circuit.rs @@ -54,7 +54,7 @@ impl ResolvedNode for Circuit { type_: Type::Circuit(identifier.clone()), attributes: vec![Attribute::Mutable], }; - child_table.insert_variable(self_key, self_variable); + child_table.insert_name(self_key, self_variable); // Insert circuit functions into symbol table for function in type_.functions.iter() { diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs index 924a58a444..7564e71f14 100644 --- a/dynamic-check/src/ast/expressions/expression.rs +++ b/dynamic-check/src/ast/expressions/expression.rs @@ -124,7 +124,7 @@ impl ResolvedNode for Expression { UnresolvedExpression::FunctionCall(function, inputs, span) => { Self::function_call(table, expected_type, function, inputs, span) } - UnresolvedExpression::CoreFunctionCall(_name, _inputs, _output, _span) => { + UnresolvedExpression::CoreFunctionCall(_name, _inputs, _span) => { unimplemented!("core function calls not type checked") // Self::core_function_call(table, expected_type, function, inputs, span) } diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs index fcbe78f66d..41de351285 100644 --- a/dynamic-check/src/ast/statements/definition/definition.rs +++ b/dynamic-check/src/ast/statements/definition/definition.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{check_tuple_type, Expression, ExpressionValue, ResolvedNode, Statement, StatementError}; -use leo_static_check::{Attribute, SymbolTable, Type, VariableType}; +use leo_static_check::{Attribute, ParameterType, SymbolTable, Type}; use leo_typed::{Declare, Expression as UnresolvedExpression, Span, VariableName, Variables}; use serde::{Deserialize, Serialize}; @@ -167,7 +167,7 @@ fn insert_defined_variable( // Insert variable into symbol table let key = variable.identifier.name.clone(); - let value = VariableType { + let value = ParameterType { identifier: variable.identifier.clone(), type_: type_.clone(), attributes, @@ -200,7 +200,7 @@ impl Statement { // If an explicit type is given check that it is valid let expected_type = match &variables.type_ { - Some(type_) => Some(Type::resolve(table, (type_.clone(), span.clone()))?), + Some(type_) => Some(Type::new(table, type_.clone(), span.clone())?), None => None, }; diff --git a/dynamic-check/src/dynamic_check/dynamic_check.rs b/dynamic-check/src/dynamic_check/dynamic_check.rs index e73e0ed565..91a50de753 100644 --- a/dynamic-check/src/dynamic_check/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check/dynamic_check.rs @@ -222,7 +222,7 @@ impl FunctionBody { /// Returns a new type variable from a given identifier /// fn parse_implicit(name: &String) -> Type { - Type::TypeVariable(TypeVariable::from(identifier.name.clone())) + Type::TypeVariable(TypeVariable::from(name.clone())) } /// @@ -293,7 +293,7 @@ impl FunctionBody { let _condition_type = self.parse_boolean_expression(condition); // Check that the types of the first and second expression are equal. - self.parse_binary_expression(first, second, span) + self.parse_binary_expression(first, second, _span) } /// @@ -403,7 +403,7 @@ impl TypeAssertion { match (&self.left, &self.right) { (Type::TypeVariable(variable), type_) => Some((variable.clone(), type_.clone())), (type_, Type::TypeVariable(variable)) => Some((variable.clone(), type_.clone())), - (_type, _type) => None, // No (type variable, type) pair can be returned from two types + (_type1, _type2) => None, // No (type variable, type) pair can be returned from two types } } } diff --git a/static-check/src/symbol_table.rs b/static-check/src/symbol_table.rs index 9f9b9bf3fe..9d36f80447 100644 --- a/static-check/src/symbol_table.rs +++ b/static-check/src/symbol_table.rs @@ -89,18 +89,18 @@ impl SymbolTable { self.functions.insert(identifier.name, function_type) } - // /// - // /// Returns a reference to the variable type corresponding to the name. - // /// - // /// If the symbol table did not have this name present, then `None` is returned. - // /// - // pub fn get_variable(&self, name: &String) -> Option<&ParameterType> { - // // Lookup variable name in symbol table. - // match self.names.get(name) { - // Some(variable) => Some(variable), - // None => None, - // } - // } + /// + /// Returns a reference to the variable type corresponding to the name. + /// + /// If the symbol table did not have this name present, then `None` is returned. + /// + pub fn get_variable(&self, name: &String) -> Option<&ParameterType> { + // Lookup variable name in symbol table. + match self.names.get(name) { + Some(variable) => Some(variable), + None => None, + } + } /// /// Returns a reference to the circuit type corresponding to the name. diff --git a/typed/src/common/variable_name.rs b/typed/src/common/variable_name.rs index ac93f2dc60..bb0a92300f 100644 --- a/typed/src/common/variable_name.rs +++ b/typed/src/common/variable_name.rs @@ -20,7 +20,7 @@ use leo_ast::common::VariableName as AstVariableName; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct VariableName { pub mutable: bool, pub identifier: Identifier, From f1a692e8d571df25f6b31e3dd4710f7bc30dad13 Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 15 Oct 2020 20:20:02 -0700 Subject: [PATCH 026/139] fix resolver errors 3 final --- dynamic-check/src/ast/ast.rs | 6 ++++-- dynamic-check/src/ast/expressions/values/implicit.rs | 1 + .../src/ast/statements/definition/definition.rs | 2 +- .../src/ast/statements/iteration/iteration.rs | 6 +++--- dynamic-check/src/dynamic_check/dynamic_check.rs | 6 +++--- dynamic-check/src/errors/circuit.rs | 10 +++++----- dynamic-check/src/errors/program.rs | 10 +++++----- typed/src/common/assignee.rs | 5 +---- typed/src/console/console_function_call.rs | 6 ++++++ typed/src/groups/group_value.rs | 7 +++++++ 10 files changed, 36 insertions(+), 23 deletions(-) diff --git a/dynamic-check/src/ast/ast.rs b/dynamic-check/src/ast/ast.rs index 1f0e69491f..704a6762c3 100644 --- a/dynamic-check/src/ast/ast.rs +++ b/dynamic-check/src/ast/ast.rs @@ -33,7 +33,7 @@ impl LeoResolvedAst { /// Creates a new `LeoResolvedAst` resolved syntax tree from a given `LeoTypedAst` /// typed syntax tree and main file path. /// - pub fn new(ast: LeoTypedAst, path: PathBuf) -> Result { + pub fn new(ast: LeoTypedAst, _path: PathBuf) -> Result<(), ResolverError> { // Get program typed syntax tree representation. let program = ast.into_repr(); @@ -69,7 +69,9 @@ impl LeoResolvedAst { // e // })?; - Ok(Self { resolved_ast }) + // Ok(Self { resolved_ast }) + + Ok(()) } /// diff --git a/dynamic-check/src/ast/expressions/values/implicit.rs b/dynamic-check/src/ast/expressions/values/implicit.rs index 95fed873a0..d2f01b0b96 100644 --- a/dynamic-check/src/ast/expressions/values/implicit.rs +++ b/dynamic-check/src/ast/expressions/values/implicit.rs @@ -38,6 +38,7 @@ impl Expression { Type::Tuple(_types) => unimplemented!("ERROR: Tuples cannot be implicit"), Type::Function(_name) => unimplemented!("ERROR: Functions cannot be implicit"), Type::Circuit(_name) => unimplemented!("ERROR: Circuits cannot be implicit"), + Type::TypeVariable(_name) => unimplemented!("ERROR: Type variables not implemented"), }; Ok(Expression { type_, value }) diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs index 41de351285..28d6d0c66d 100644 --- a/dynamic-check/src/ast/statements/definition/definition.rs +++ b/dynamic-check/src/ast/statements/definition/definition.rs @@ -174,7 +174,7 @@ fn insert_defined_variable( }; // Check that variable name was not defined twice - let duplicate = table.insert_variable(key, value); + let duplicate = table.insert_name(key, value); if duplicate.is_some() { return Err(StatementError::duplicate_variable( diff --git a/dynamic-check/src/ast/statements/iteration/iteration.rs b/dynamic-check/src/ast/statements/iteration/iteration.rs index 323bb6da7f..c744bbb40e 100644 --- a/dynamic-check/src/ast/statements/iteration/iteration.rs +++ b/dynamic-check/src/ast/statements/iteration/iteration.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{Expression, ResolvedNode, Statement, StatementError}; -use leo_static_check::{FunctionOutputType, SymbolTable, Type, VariableType}; +use leo_static_check::{FunctionOutputType, ParameterType, SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Identifier, IntegerType, Span, Statement as UnresolvedStatement}; use serde::{Deserialize, Serialize}; @@ -50,13 +50,13 @@ impl Statement { // Add index to symbol table let key = index.name.clone(); - let value = VariableType { + let value = ParameterType { identifier: index.clone(), type_: type_number, attributes: vec![], }; - table.insert_variable(key, value); + table.insert_name(key, value); // Resolve statements let statements_resolved = statements diff --git a/dynamic-check/src/dynamic_check/dynamic_check.rs b/dynamic-check/src/dynamic_check/dynamic_check.rs index 91a50de753..77b86c4cd6 100644 --- a/dynamic-check/src/dynamic_check/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check/dynamic_check.rs @@ -384,9 +384,9 @@ impl TypeAssertion { /// /// Substitutes the given `TypeVariable` for each `Types` in the `TypeAssertion`. /// - pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { - self.left.substitute(variable, type_); - self.right.substitute(variable, type_); + pub fn substitute(&mut self, _variable: &TypeVariable, _type_: &Type) { + // self.left.substitute(variable, type_); + // self.right.substitute(variable, type_); } /// diff --git a/dynamic-check/src/errors/circuit.rs b/dynamic-check/src/errors/circuit.rs index 58d264209c..2c78160e95 100644 --- a/dynamic-check/src/errors/circuit.rs +++ b/dynamic-check/src/errors/circuit.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::FunctionError; -use leo_typed::{Error as FormattedError, Span}; +use leo_typed::Error as FormattedError; use std::path::PathBuf; @@ -38,8 +38,8 @@ impl CircuitError { } } - /// Return a new formatted error with a given message and span information - fn new_from_span(message: String, span: Span) -> Self { - CircuitError::Error(FormattedError::new_from_span(message, span)) - } + // /// Return a new formatted error with a given message and span information + // fn new_from_span(message: String, span: Span) -> Self { + // CircuitError::Error(FormattedError::new_from_span(message, span)) + // } } diff --git a/dynamic-check/src/errors/program.rs b/dynamic-check/src/errors/program.rs index 58eb922113..9fb6c79401 100644 --- a/dynamic-check/src/errors/program.rs +++ b/dynamic-check/src/errors/program.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CircuitError, FunctionError}; -use leo_typed::{Error as FormattedError, Span}; +use leo_typed::Error as FormattedError; use std::path::PathBuf; @@ -42,8 +42,8 @@ impl ProgramError { } } - /// Return a new formatted error with a given message and span information - fn new_from_span(message: String, span: Span) -> Self { - ProgramError::Error(FormattedError::new_from_span(message, span)) - } + // /// Return a new formatted error with a given message and span information + // fn new_from_span(message: String, span: Span) -> Self { + // ProgramError::Error(FormattedError::new_from_span(message, span)) + // } } diff --git a/typed/src/common/assignee.rs b/typed/src/common/assignee.rs index 5d6af0f6ee..b548450166 100644 --- a/typed/src/common/assignee.rs +++ b/typed/src/common/assignee.rs @@ -15,10 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, Identifier, RangeOrExpression, Span}; -use leo_ast::{ - access::AssigneeAccess as AstAssigneeAccess, - common::{Assignee as AstAssignee, Identifier as AstIdentifier, SelfKeywordOrIdentifier}, -}; +use leo_ast::{access::AssigneeAccess as AstAssigneeAccess, common::Assignee as AstAssignee}; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/typed/src/console/console_function_call.rs b/typed/src/console/console_function_call.rs index b2a9ef09f1..b036528bd3 100644 --- a/typed/src/console/console_function_call.rs +++ b/typed/src/console/console_function_call.rs @@ -40,3 +40,9 @@ impl fmt::Display for ConsoleFunctionCall { write!(f, "console.{};", self.function) } } + +impl fmt::Debug for ConsoleFunctionCall { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "console.{};", self.function) + } +} diff --git a/typed/src/groups/group_value.rs b/typed/src/groups/group_value.rs index 01ef67253d..77097def85 100644 --- a/typed/src/groups/group_value.rs +++ b/typed/src/groups/group_value.rs @@ -42,6 +42,13 @@ impl GroupValue { GroupValue::Tuple(tuple) => tuple.span = new_span.clone(), } } + + pub fn span(&self) -> &Span { + match self { + GroupValue::Single(_, span) => span, + GroupValue::Tuple(tuple) => &tuple.span, + } + } } impl<'ast> From> for GroupValue { From 13d3a78659336883fc25fa5375e87fb61bff63d9 Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 15 Oct 2020 22:30:05 -0700 Subject: [PATCH 027/139] use variable table in expressions 1 --- .../src/ast/expressions/expression.rs | 82 ++++++++++++++++++- .../src/ast/expressions/expression_value.rs | 6 +- .../ast/expressions/identifier/identifier.rs | 31 +++---- dynamic-check/src/ast/functions/function.rs | 35 +++++++- .../src/ast/statements/return_/return_.rs | 16 ++-- dynamic-check/src/ast/statements/statement.rs | 35 +++++++- .../src/{dynamic_check => }/dynamic_check.rs | 52 ++++++++---- dynamic-check/src/dynamic_check/mod.rs | 18 ---- dynamic-check/src/errors/dynamic_check.rs | 52 ++++++++++++ dynamic-check/src/errors/mod.rs | 3 + 10 files changed, 263 insertions(+), 67 deletions(-) rename dynamic-check/src/{dynamic_check => }/dynamic_check.rs (89%) delete mode 100644 dynamic-check/src/dynamic_check/mod.rs create mode 100644 dynamic-check/src/errors/dynamic_check.rs diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs index 7564e71f14..c0af4a1a47 100644 --- a/dynamic-check/src/ast/expressions/expression.rs +++ b/dynamic-check/src/ast/expressions/expression.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ExpressionError, ExpressionValue, ResolvedNode}; +use crate::{ExpressionError, ExpressionValue, ResolvedNode, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; @@ -46,6 +46,86 @@ impl Expression { Ok(()) } + + /// + /// Returns a new `Expression` from a given `UnresolvedExpression`. + /// + /// Performs a lookup in the given variable table if the expression contains user-defined types. + /// + pub fn new( + variable_table: &VariableTable, + unresolved_expression: UnresolvedExpression, + ) -> Result { + match unresolved_expression { + // Identifier + UnresolvedExpression::Identifier(identifier) => Self::variable(variable_table, identifier), + + // Values + UnresolvedExpression::Address(string, span) => Self::address(string, span), + UnresolvedExpression::Boolean(string, span) => Self::boolean(string, span), + UnresolvedExpression::Field(string, span) => Self::field(string, span), + UnresolvedExpression::Group(group_value) => Self::group(group_value), + UnresolvedExpression::Implicit(string, span) => Self::implicit(string, span), + UnresolvedExpression::Integer(integer_type, string, span) => Self::integer(integer_type, string, span), + + // Arithmetic Operations + UnresolvedExpression::Add(lhs, rhs, span) => Self::add(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Div(lhs, rhs, span) => Self::div(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Negate(expression, span) => Self::negate(variable_table, *expression, span), + + // Logical Operations + UnresolvedExpression::And(lhs, rhs, span) => Self::and(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Or(lhs, rhs, span) => Self::or(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Not(expression, span) => Self::not(variable_table, *expression, span), + + // Relational Operations + UnresolvedExpression::Eq(lhs, rhs, span) => Self::eq(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Ge(lhs, rhs, span) => Self::ge(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Gt(lhs, rhs, span) => Self::gt(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Le(lhs, rhs, span) => Self::le(variable_table, *lhs, *rhs, span), + UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(variable_table, *lhs, *rhs, span), + + // Conditionals + UnresolvedExpression::IfElse(cond, first, second, span) => { + Self::conditional(variable_table, *cond, *first, *second, span) + } + + // Arrays + UnresolvedExpression::Array(elements, span) => Self::array(variable_table, elements, span), + UnresolvedExpression::ArrayAccess(array, access, span) => { + Self::array_access(variable_table, array, access, span) + } + + // Tuples + UnresolvedExpression::Tuple(elements, span) => Self::tuple(variable_table, elements, span), + UnresolvedExpression::TupleAccess(tuple, index, span) => { + Self::tuple_access(variable_table, tuple, index, span) + } + + // Circuits + UnresolvedExpression::Circuit(identifier, variables, span) => { + Self::circuit(variable_table, identifier, variables, span) + } + UnresolvedExpression::CircuitMemberAccess(circuit, member, span) => { + Self::circuit_access(variable_table, circuit, member, span) + } + UnresolvedExpression::CircuitStaticFunctionAccess(circuit, member, span) => { + Self::circuit_static_access(variable_table, circuit, member, span) + } + + // Functions + UnresolvedExpression::FunctionCall(function, inputs, span) => { + Self::function_call(variable_table, function, inputs, span) + } + UnresolvedExpression::CoreFunctionCall(_name, _inputs, _span) => { + unimplemented!("core function calls not type checked") + // Self::core_function_call(variable_table, expected_type, function, inputs, span) + } + } + } } impl ResolvedNode for Expression { diff --git a/dynamic-check/src/ast/expressions/expression_value.rs b/dynamic-check/src/ast/expressions/expression_value.rs index cf70b0bfcf..30b94ad2a2 100644 --- a/dynamic-check/src/ast/expressions/expression_value.rs +++ b/dynamic-check/src/ast/expressions/expression_value.rs @@ -25,8 +25,8 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum ExpressionValue { - // Identifier - Identifier(Identifier), + // Variable + Variable(Identifier), // Values Address(String, Span), @@ -90,7 +90,7 @@ impl ExpressionValue { /// Return the span pub fn span(&self) -> &Span { match self { - ExpressionValue::Identifier(identifier) => &identifier.span, + ExpressionValue::Variable(identifier) => &identifier.span, ExpressionValue::Address(_, span) => span, ExpressionValue::Boolean(_, span) => span, ExpressionValue::Field(_, span) => span, diff --git a/dynamic-check/src/ast/expressions/identifier/identifier.rs b/dynamic-check/src/ast/expressions/identifier/identifier.rs index bfb79e855b..a6ae0d73b9 100644 --- a/dynamic-check/src/ast/expressions/identifier/identifier.rs +++ b/dynamic-check/src/ast/expressions/identifier/identifier.rs @@ -14,32 +14,25 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; +use crate::{Expression, ExpressionError, ExpressionValue, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::Identifier; impl Expression { - /// Resolve the type of an identifier expression - pub(crate) fn identifier( - table: &SymbolTable, - expected_type: Option, - identifier: Identifier, - ) -> Result { - // Lookup identifier in symbol table - let variable = table - .get_variable(&identifier.name) + /// + /// Returns a new variable expression from a given `UnresolvedExpression`. + /// + /// Performs a lookup in the given variable table to find the variable's type. + /// + pub(crate) fn variable(variable_table: &VariableTable, identifier: Identifier) -> Result { + // Lookup the type of the given variable. + let type_ = variable_table + .get(&identifier.name) .ok_or(ExpressionError::undefined_identifier(identifier.clone()))?; - // Get type of symbol table entry - let variable_type = variable.type_.clone(); - let span = identifier.span.clone(); - - // Check the expected type if given - Type::check_type(&expected_type, &variable_type, span)?; - Ok(Expression { - type_: variable_type, - value: ExpressionValue::Identifier(identifier), + type_: type_.clone(), + value: ExpressionValue::Variable(identifier), }) } } diff --git a/dynamic-check/src/ast/functions/function.rs b/dynamic-check/src/ast/functions/function.rs index 477e0e576f..b347b13437 100644 --- a/dynamic-check/src/ast/functions/function.rs +++ b/dynamic-check/src/ast/functions/function.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{FunctionError, ResolvedNode, Statement}; +use crate::{FunctionError, ResolvedNode, Statement, StatementError, VariableTable}; use leo_static_check::{FunctionType, SymbolTable, TypeError}; -use leo_typed::Function as UnresolvedFunction; +use leo_typed::{Function as UnresolvedFunction, Statement as UnresolvedStatement}; use serde::{Deserialize, Serialize}; @@ -24,12 +24,36 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Function { /// The user-defined type of this function. - pub type_: FunctionType, + pub function_type: FunctionType, /// The function statements. pub statements: Vec, } +impl Function { + /// + /// Returns a new `Function` from a given `UnresolvedFunction`. + /// + /// Performs a lookup in the given variable table if the function contains user-defined types. + /// + pub fn new( + variable_table: VariableTable, + function_type: FunctionType, + unresolved_statements: Vec, + ) -> Result { + // Create a new `Statement` from every given `UnresolvedStatement`. + let statements = unresolved_statements + .iter() + .for_each(|unresolved_statement| Statement::new(&variable_table, unresolved_statement)) + .collect::, StatementError>>()?; + + Ok(Function { + function_type, + statements, + }) + } +} + impl ResolvedNode for Function { type Error = FunctionError; type UnresolvedNode = UnresolvedFunction; @@ -73,6 +97,9 @@ impl ResolvedNode for Function { statements.push(statement); } - Ok(Function { type_, statements }) + Ok(Function { + function_type: type_, + statements, + }) } } diff --git a/dynamic-check/src/ast/statements/return_/return_.rs b/dynamic-check/src/ast/statements/return_/return_.rs index acc3d416f5..520aba0a88 100644 --- a/dynamic-check/src/ast/statements/return_/return_.rs +++ b/dynamic-check/src/ast/statements/return_/return_.rs @@ -14,19 +14,23 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ResolvedNode, Statement, StatementError}; +use crate::{Expression, ResolvedNode, Statement, StatementError, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Statement { - /// Resolve return statement to function output type + /// + /// Returns a new return statement from a given `UnresolvedExpression`. + /// + /// Performs a lookup in the given variable table if the statement contains user-defined types. + /// pub(crate) fn resolve_return( - table: &mut SymbolTable, - expected_type: Type, - expression: UnresolvedExpression, + table: &VariableTable, + unresolved_expression: UnresolvedExpression, span: Span, ) -> Result { - let expression = Expression::resolve(table, (Some(expected_type), expression))?; + // Create a new `Expression` from the unresolved return expression + let expression = Expression::new(table, unresolved_expression)?; Ok(Statement::Return(expression, span)) } diff --git a/dynamic-check/src/ast/statements/statement.rs b/dynamic-check/src/ast/statements/statement.rs index 90f92c9f4a..a76e36fc8a 100644 --- a/dynamic-check/src/ast/statements/statement.rs +++ b/dynamic-check/src/ast/statements/statement.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Assign, Conditional, Definition, Expression, Iteration, ResolvedNode, StatementError}; +use crate::{Assign, Conditional, Definition, Expression, Iteration, ResolvedNode, StatementError, VariableTable}; use leo_static_check::{FunctionOutputType, SymbolTable}; use leo_typed::{ConsoleFunctionCall, Span, Statement as UnresolvedStatement}; @@ -31,6 +31,39 @@ pub enum Statement { Expression(Expression, Span), } +impl Statement { + /// + /// Returns a new `Statement` from a given `UnresolvedStatement`. + /// + /// Performs a lookup in the given variable table if the statement contains user-defined types. + /// + pub fn new( + variable_table: &VariableTable, + unresolved_statement: UnresolvedStatement, + ) -> Result { + match unresolved_statement { + UnresolvedStatement::Return(expression, span) => Self::resolve_return(variable_table, expression, span), + UnresolvedStatement::Definition(declare, variables, expressions, span) => { + Self::definition(variable_table, declare, variables, expressions, span) + } + UnresolvedStatement::Assign(assignee, expression, span) => { + Self::assign(variable_table, assignee, expression, span) + } + UnresolvedStatement::Conditional(conditional, span) => { + Self::conditional(variable_table, return_type, conditional, span) + } + UnresolvedStatement::Iteration(index, start, stop, statements, span) => { + Self::iteration(variable_table, return_type, index, start, stop, statements, span) + } + UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)), + UnresolvedStatement::Expression(expression, span) => Ok(Statement::Expression( + Expression::resolve(variable_table, expression)?, + span, + )), + } + } +} + impl ResolvedNode for Statement { type Error = StatementError; type UnresolvedNode = (FunctionOutputType, UnresolvedStatement); diff --git a/dynamic-check/src/dynamic_check/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs similarity index 89% rename from dynamic-check/src/dynamic_check/dynamic_check.rs rename to dynamic-check/src/dynamic_check.rs index 77b86c4cd6..ad2cfc4c84 100644 --- a/dynamic-check/src/dynamic_check/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -14,8 +14,16 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +use crate::{DynamicCheckError, Function, FunctionError, LeoResolvedAst}; use leo_static_check::{FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; -use leo_typed::{Expression, Function, Identifier, Program, Span, Statement}; +use leo_typed::{ + Expression, + Function as UnresolvedFunction, + Identifier, + Program, + Span, + Statement as UnresolvedStatement, +}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -57,7 +65,7 @@ impl DynamicCheck { /// /// Collects a vector of `TypeAssertion` predicates from a vector of functions. /// - fn parse_functions(&mut self, functions: Vec<&Function>) { + fn parse_functions(&mut self, functions: Vec<&UnresolvedFunction>) { for function in functions { self.parse_function(function) } @@ -66,7 +74,7 @@ impl DynamicCheck { /// /// Collects a vector of `TypeAssertion` predicates from a function. /// - fn parse_function(&mut self, function: &Function) { + fn parse_function(&mut self, function: &UnresolvedFunction) { let function_body = FunctionBody::new(function.clone(), self.table.clone()); self.functions.push(function_body); @@ -76,15 +84,15 @@ impl DynamicCheck { /// Returns the result of evaluating all `TypeAssertion` predicates. /// /// Will attempt to substitute a `Type` for all `TypeVariable`s. - /// Returns `true` if all `TypeAssertion` predicates are true. + /// Returns a `LeoResolvedAst` if all `TypeAssertion` predicates are true. /// Returns ERROR if a `TypeAssertion` predicate is false or a solution does not exist. /// - pub fn solve(self) -> bool { + pub fn solve(self) -> Result { for function_body in self.functions { function_body.solve(); } - true + Ok(LeoResolvedAst::new()) } } @@ -92,6 +100,7 @@ impl DynamicCheck { #[derive(Clone)] pub struct FunctionBody { function_type: FunctionType, + statements: Vec, user_defined_types: SymbolTable, type_assertions: Vec, variable_table: VariableTable, @@ -101,13 +110,13 @@ impl FunctionBody { /// /// Collects a vector of `TypeAssertion` predicates from a function. /// - pub fn new(function: Function, symbol_table: SymbolTable) -> Self { + pub fn new(function: UnresolvedFunction, symbol_table: SymbolTable) -> Self { let name = &function.identifier.name; // Get function type from symbol table. let function_type = symbol_table.get_function(name).unwrap().clone(); - // Build symbol table for variables. + // Create a new mapping of variables to types. let mut variable_table = VariableTable::new(); // Initialize function inputs as variables. @@ -116,6 +125,7 @@ impl FunctionBody { // Create new function body struct. // Update variables when encountering let/const variable definitions. let mut function_body = Self { + statements: function.statements, function_type, user_defined_types: symbol_table, type_assertions: vec![], @@ -123,7 +133,7 @@ impl FunctionBody { }; // Create type assertions for function statements - function_body.parse_statements(&function.statements); + function_body.parse_statements(); function_body } @@ -131,8 +141,8 @@ impl FunctionBody { /// /// Collects a vector of `TypeAssertion` predicates from a vector of statements. /// - fn parse_statements(&mut self, statements: &Vec) { - for statement in statements { + fn parse_statements(&mut self) { + for statement in &self.statements { self.parse_statement(statement); } } @@ -140,9 +150,9 @@ impl FunctionBody { /// /// Collects a vector of `TypeAssertion` predicates from a statement. /// - fn parse_statement(&mut self, statement: &Statement) { + fn parse_statement(&mut self, statement: &UnresolvedStatement) { match statement { - Statement::Return(expression, span) => { + UnresolvedStatement::Return(expression, span) => { self.parse_statement_return(expression, span); } statement => unimplemented!("statement {} not implemented", statement), @@ -297,9 +307,9 @@ impl FunctionBody { } /// - /// Iteratively solves all `TypeAssertions`. + /// Returns a new `Function` if all `TypeAssertions` can be solved successfully. /// - fn solve(self) { + fn solve(self) -> Result { let mut unsolved = self.type_assertions.clone(); while !unsolved.is_empty() { @@ -325,6 +335,9 @@ impl FunctionBody { // } // } // } + + // Return a new resolved function struct. + Function::new(self.variable_table, self.function_type, self.statements) } } @@ -352,6 +365,15 @@ impl VariableTable { self.0.insert(name, type_) } + /// + /// Returns a reference to the type corresponding to the name. + /// + /// If the variable table did not have this name present, [`None`] is returned. + /// + pub fn get(&self, name: &String) -> Option<&Type> { + self.0.get(name) + } + /// /// Inserts a vector of function input types into the variable table. /// diff --git a/dynamic-check/src/dynamic_check/mod.rs b/dynamic-check/src/dynamic_check/mod.rs deleted file mode 100644 index ddebbdd6a7..0000000000 --- a/dynamic-check/src/dynamic_check/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod dynamic_check; -pub use self::dynamic_check::*; diff --git a/dynamic-check/src/errors/dynamic_check.rs b/dynamic-check/src/errors/dynamic_check.rs new file mode 100644 index 0000000000..841264c84e --- /dev/null +++ b/dynamic-check/src/errors/dynamic_check.rs @@ -0,0 +1,52 @@ +// 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 . + +use crate::{ExpressionError, FunctionError, ProgramError, StatementError}; +use leo_typed::Error as FormattedError; + +use std::path::PathBuf; + +/// Errors encountered when running dynamic type inference checks. +#[derive(Debug, Error)] +pub enum DynamicCheckError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + ExpressionError(#[from] ExpressionError), + + #[error("{}", _0)] + FunctionError(#[from] FunctionError), + + #[error("{}", _0)] + StatementError(#[from] StatementError), + + #[error("{}", _0)] + ProgramError(#[from] ProgramError), +} + +impl DynamicCheckError { + /// Set the filepath for the error stacktrace + pub fn set_path(&mut self, path: PathBuf) { + match self { + DynamicCheckError::Error(error) => error.set_path(path), + DynamicCheckError::ExpressionError(error) => error.set_path(path), + DynamicCheckError::FunctionError(error) => error.set_path(path), + DynamicCheckError::StatementError(error) => error.set_path(path), + DynamicCheckError::ProgramError(error) => error.set_path(path), + } + } +} diff --git a/dynamic-check/src/errors/mod.rs b/dynamic-check/src/errors/mod.rs index 7d83b4184d..fbfbf1aa56 100644 --- a/dynamic-check/src/errors/mod.rs +++ b/dynamic-check/src/errors/mod.rs @@ -17,6 +17,9 @@ pub mod circuit; pub use self::circuit::*; +pub mod dynamic_check; +pub use self::dynamic_check::*; + pub mod expression; pub use self::expression::*; From 3acb8b9f653dac9f91e65e14ec1ff5a112dfe436 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 16 Oct 2020 10:52:55 -0700 Subject: [PATCH 028/139] pass function body to statements --- .../src/ast/expressions/expression.rs | 9 +- .../ast/expressions/identifier/identifier.rs | 9 +- .../src/ast/expressions/tuple/tuple.rs | 35 ++++---- dynamic-check/src/ast/functions/function.rs | 22 +++-- .../ast/statements/definition/definition.rs | 90 +++++++++---------- .../src/ast/statements/return_/return_.rs | 6 +- dynamic-check/src/ast/statements/statement.rs | 21 +++-- dynamic-check/src/dynamic_check.rs | 12 +-- 8 files changed, 108 insertions(+), 96 deletions(-) diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs index c0af4a1a47..05923a36aa 100644 --- a/dynamic-check/src/ast/expressions/expression.rs +++ b/dynamic-check/src/ast/expressions/expression.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ExpressionError, ExpressionValue, ResolvedNode, VariableTable}; +use crate::{ExpressionError, ExpressionValue, FunctionBody, ResolvedNode, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; @@ -50,15 +50,16 @@ impl Expression { /// /// Returns a new `Expression` from a given `UnresolvedExpression`. /// - /// Performs a lookup in the given variable table if the expression contains user-defined types. + /// Performs a lookup in the given function body's variable table if the expression contains + /// user-defined variables. /// pub fn new( - variable_table: &VariableTable, + function_body: &FunctionBody, unresolved_expression: UnresolvedExpression, ) -> Result { match unresolved_expression { // Identifier - UnresolvedExpression::Identifier(identifier) => Self::variable(variable_table, identifier), + UnresolvedExpression::Identifier(identifier) => Self::variable(function_body, identifier), // Values UnresolvedExpression::Address(string, span) => Self::address(string, span), diff --git a/dynamic-check/src/ast/expressions/identifier/identifier.rs b/dynamic-check/src/ast/expressions/identifier/identifier.rs index a6ae0d73b9..9b0f7b3e7e 100644 --- a/dynamic-check/src/ast/expressions/identifier/identifier.rs +++ b/dynamic-check/src/ast/expressions/identifier/identifier.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue, VariableTable}; +use crate::{Expression, ExpressionError, ExpressionValue, FunctionBody, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::Identifier; @@ -22,11 +22,12 @@ impl Expression { /// /// Returns a new variable expression from a given `UnresolvedExpression`. /// - /// Performs a lookup in the given variable table to find the variable's type. + /// Performs a lookup in the given function body's variable table to find the variable's type. /// - pub(crate) fn variable(variable_table: &VariableTable, identifier: Identifier) -> Result { + pub(crate) fn variable(function_body: &FunctionBody, identifier: Identifier) -> Result { // Lookup the type of the given variable. - let type_ = variable_table + let type_ = function_body + .variable_table .get(&identifier.name) .ok_or(ExpressionError::undefined_identifier(identifier.clone()))?; diff --git a/dynamic-check/src/ast/expressions/tuple/tuple.rs b/dynamic-check/src/ast/expressions/tuple/tuple.rs index 66bef80542..847db78df1 100644 --- a/dynamic-check/src/ast/expressions/tuple/tuple.rs +++ b/dynamic-check/src/ast/expressions/tuple/tuple.rs @@ -14,35 +14,38 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolves a tuple of expressions to the given tuple type + /// + /// Returns a new expression that defines a tuple (single variable with multiple values). + /// + /// Performs a lookup in the given variable table if an `UnresolvedExpression` contains user-defined types. + /// pub(crate) fn tuple( - table: &mut SymbolTable, - expected_type: Option, - expressions: Vec, + variable_table: &VariableTable, + unresolved_expressions: Vec, span: Span, ) -> Result { - // If the expected type is given, then it must be a tuple of types - let expected_element_types = check_tuple_type(expected_type, expressions.len(), span.clone())?; + // // If the expected type is given, then it must be a tuple of types + // let expected_element_types = check_tuple_type(expected_type, expressions.len(), span.clone())?; // Check length of tuple against expected types - if expected_element_types.len() != expressions.len() { - return Err(ExpressionError::invalid_length_tuple( - expected_element_types.len(), - expressions.len(), - span.clone(), - )); - } + // if expected_element_types.len() != unresolved_expressions.len() { + // return Err(ExpressionError::invalid_length_tuple( + // expected_element_types.len(), + // unresolved_expressions.len(), + // span.clone(), + // )); + // } // Resolve all tuple elements let mut tuple = vec![]; - for (expression, element_type) in expressions.into_iter().zip(expected_element_types) { - let expression_resolved = Expression::resolve(table, (element_type, expression))?; + for (expression, _) in unresolved_expressions.into_iter().zip(expected_element_types) { + let expression_resolved = Expression::new(variable_table, expression)?; tuple.push(expression_resolved); } diff --git a/dynamic-check/src/ast/functions/function.rs b/dynamic-check/src/ast/functions/function.rs index b347b13437..72b0c7cb00 100644 --- a/dynamic-check/src/ast/functions/function.rs +++ b/dynamic-check/src/ast/functions/function.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{FunctionError, ResolvedNode, Statement, StatementError, VariableTable}; +use crate::{FunctionBody, FunctionError, ResolvedNode, Statement, StatementError, VariableTable}; use leo_static_check::{FunctionType, SymbolTable, TypeError}; use leo_typed::{Function as UnresolvedFunction, Statement as UnresolvedStatement}; @@ -32,23 +32,21 @@ pub struct Function { impl Function { /// - /// Returns a new `Function` from a given `UnresolvedFunction`. + /// Returns a new `Function` from a given `FunctionBody`. /// - /// Performs a lookup in the given variable table if the function contains user-defined types. + /// Performs a lookup in the given function body's variable table if the statement contains + /// user-defined types.. /// - pub fn new( - variable_table: VariableTable, - function_type: FunctionType, - unresolved_statements: Vec, - ) -> Result { + pub fn new(function_body: FunctionBody) -> Result { // Create a new `Statement` from every given `UnresolvedStatement`. - let statements = unresolved_statements - .iter() - .for_each(|unresolved_statement| Statement::new(&variable_table, unresolved_statement)) + let statements = function_body + .statements + .into_iter() + .map(|unresolved_statement| Statement::new(&function_body, unresolved_statement)) .collect::, StatementError>>()?; Ok(Function { - function_type, + function_type: function_body.function_type, statements, }) } diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs index 28d6d0c66d..d3119c1131 100644 --- a/dynamic-check/src/ast/statements/definition/definition.rs +++ b/dynamic-check/src/ast/statements/definition/definition.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{check_tuple_type, Expression, ExpressionValue, ResolvedNode, Statement, StatementError}; +use crate::{check_tuple_type, Expression, ExpressionValue, ResolvedNode, Statement, StatementError, VariableTable}; use leo_static_check::{Attribute, ParameterType, SymbolTable, Type}; use leo_typed::{Declare, Expression as UnresolvedExpression, Span, VariableName, Variables}; @@ -39,40 +39,36 @@ pub enum DefinitionVariables { } impl DefinitionVariables { - /// Resolves a single variable with a single value + /// + /// Returns a new statement that defines a single variable with a single value. + /// + /// Performs a lookup in the given variable table if the `UnresolvedExpression` contains user-defined variables. + /// fn single( - table: &mut SymbolTable, + table: &VariableTable, variable: VariableName, - expected_type: Option, - expression: UnresolvedExpression, - span: Span, + unresolved_expression: UnresolvedExpression, ) -> Result { - // Resolve expression with given expected type - let expression_resolved = Expression::resolve(table, (expected_type, expression))?; - let type_ = expression_resolved.type_(); + // Create a new `Expression` from the given `UnresolvedExpression`. + let expression = Expression::new(table, unresolved_expression)?; - // Insert variable into symbol table - insert_defined_variable(table, &variable, type_, span.clone())?; - - Ok(DefinitionVariables::Single(variable, expression_resolved)) + Ok(DefinitionVariables::Single(variable, expression)) } - /// Resolves a tuple (single variable with multiple values) + /// + /// Returns a new statement that defines a tuple (single variable with multiple values). + /// + /// Performs a lookup in the given variable table if an `UnresolvedExpression` contains user-defined variables. + /// fn tuple( - table: &mut SymbolTable, + table: &VariableTable, variable: VariableName, - expected_type: Option, - expressions: Vec, - span: Span, + unresolved_expressions: Vec, ) -> Result { - // Resolve tuple of expressions - let tuple_resolved = Expression::tuple(table, expected_type, expressions, span.clone())?; - let type_ = tuple_resolved.type_(); + // Create a new tuple of `Expression`s from the given vector of `UnresolvedExpression's. + let tuple = Expression::tuple(table, unresolved_expressions, span.clone())?; - // Insert variable into symbol table - insert_defined_variable(table, &variable, type_, span.clone())?; - - Ok(DefinitionVariables::Tuple(variable, tuple_resolved)) + Ok(DefinitionVariables::Tuple(variable, tuple)) } /// Resolves multiple variables for multiple expressions @@ -187,22 +183,26 @@ fn insert_defined_variable( } impl Statement { - /// Resolves a definition statement + /// + /// Returns a new `let` or `const` definition statement from a given `UnresolvedExpression`. + /// + /// Performs a lookup in the given variable table if the statement contains user-defined variables. + /// pub(crate) fn definition( - table: &mut SymbolTable, + table: &VariableTable, declare: Declare, variables: Variables, - expressions: Vec, + unresolved_expressions: Vec, span: Span, ) -> Result { let num_variables = variables.names.len(); - let num_values = expressions.len(); + let num_values = unresolved_expressions.len(); - // If an explicit type is given check that it is valid - let expected_type = match &variables.type_ { - Some(type_) => Some(Type::new(table, type_.clone(), span.clone())?), - None => None, - }; + // // If an explicit type is given check that it is valid + // let expected_type = match &variables.type_ { + // Some(type_) => Some(Type::new(table, type_.clone(), span.clone())?), + // None => None, + // }; let variables = if num_variables == 1 && num_values == 1 { // Define a single variable with a single value @@ -210,34 +210,32 @@ impl Statement { DefinitionVariables::single( table, variables.names[0].clone(), - expected_type, - expressions[0].clone(), + unresolved_expressions[0].clone(), span.clone(), ) } else if num_variables == 1 && num_values > 1 { // Define a tuple (single variable with multiple values) - DefinitionVariables::tuple( - table, - variables.names[0].clone(), - expected_type, - expressions, - span.clone(), - ) + DefinitionVariables::tuple(table, variables.names[0].clone(), unresolved_expressions, span.clone()) } else if num_variables > 1 && num_values == 1 { // Define multiple variables for an expression that returns a tuple DefinitionVariables::multiple_variable_tuple( table, variables, - expected_type, - expressions[0].clone(), + unresolved_expressions[0].clone(), span.clone(), ) } else { // Define multiple variables for multiple expressions - DefinitionVariables::multiple_variable(table, variables, expected_type, expressions, span.clone()) + DefinitionVariables::multiple_variable( + table, + variables, + expected_type, + unresolved_expressions, + span.clone(), + ) }?; Ok(Statement::Definition(Definition { diff --git a/dynamic-check/src/ast/statements/return_/return_.rs b/dynamic-check/src/ast/statements/return_/return_.rs index 520aba0a88..7c3eb9f42f 100644 --- a/dynamic-check/src/ast/statements/return_/return_.rs +++ b/dynamic-check/src/ast/statements/return_/return_.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ResolvedNode, Statement, StatementError, VariableTable}; +use crate::{Expression, FunctionBody, ResolvedNode, Statement, StatementError, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; @@ -25,12 +25,12 @@ impl Statement { /// Performs a lookup in the given variable table if the statement contains user-defined types. /// pub(crate) fn resolve_return( - table: &VariableTable, + function_body: &FunctionBody, unresolved_expression: UnresolvedExpression, span: Span, ) -> Result { // Create a new `Expression` from the unresolved return expression - let expression = Expression::new(table, unresolved_expression)?; + let expression = Expression::new(function_body, unresolved_expression)?; Ok(Statement::Return(expression, span)) } diff --git a/dynamic-check/src/ast/statements/statement.rs b/dynamic-check/src/ast/statements/statement.rs index a76e36fc8a..18429c4243 100644 --- a/dynamic-check/src/ast/statements/statement.rs +++ b/dynamic-check/src/ast/statements/statement.rs @@ -13,8 +13,18 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Assign, Conditional, Definition, Expression, Iteration, ResolvedNode, StatementError, VariableTable}; -use leo_static_check::{FunctionOutputType, SymbolTable}; +use crate::{ + Assign, + Conditional, + Definition, + Expression, + FunctionBody, + Iteration, + ResolvedNode, + StatementError, + VariableTable, +}; +use leo_static_check::{FunctionOutputType, FunctionType, SymbolTable}; use leo_typed::{ConsoleFunctionCall, Span, Statement as UnresolvedStatement}; use serde::{Deserialize, Serialize}; @@ -35,14 +45,15 @@ impl Statement { /// /// Returns a new `Statement` from a given `UnresolvedStatement`. /// - /// Performs a lookup in the given variable table if the statement contains user-defined types. + /// Performs a lookup in the given function body's variable table if the statement contains + /// user-defined types. /// pub fn new( - variable_table: &VariableTable, + function_body: &FunctionBody, unresolved_statement: UnresolvedStatement, ) -> Result { match unresolved_statement { - UnresolvedStatement::Return(expression, span) => Self::resolve_return(variable_table, expression, span), + UnresolvedStatement::Return(expression, span) => Self::resolve_return(function_body, expression, span), UnresolvedStatement::Definition(declare, variables, expressions, span) => { Self::definition(variable_table, declare, variables, expressions, span) } diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index ad2cfc4c84..ad0aa4bbd0 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -99,11 +99,11 @@ impl DynamicCheck { /// A vector of `TypeAssertion` predicates created from a function body. #[derive(Clone)] pub struct FunctionBody { - function_type: FunctionType, - statements: Vec, - user_defined_types: SymbolTable, - type_assertions: Vec, - variable_table: VariableTable, + pub function_type: FunctionType, + pub statements: Vec, + pub user_defined_types: SymbolTable, + pub type_assertions: Vec, + pub variable_table: VariableTable, } impl FunctionBody { @@ -337,7 +337,7 @@ impl FunctionBody { // } // Return a new resolved function struct. - Function::new(self.variable_table, self.function_type, self.statements) + Function::new(self) } } From 43bcc2b2109897bb619a135534be39466a27d8ce Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 16 Oct 2020 12:33:46 -0700 Subject: [PATCH 029/139] pass type to expressions --- .../src/ast/expressions/expression.rs | 15 ++++++----- .../ast/expressions/identifier/identifier.rs | 10 +++---- .../src/ast/expressions/values/address.rs | 21 +++++---------- .../src/ast/expressions/values/boolean.rs | 21 +++++---------- .../src/ast/expressions/values/field.rs | 23 ++++++---------- .../src/ast/expressions/values/group.rs | 18 +++++-------- .../src/ast/expressions/values/implicit.rs | 18 ++++++------- .../src/ast/expressions/values/integer.rs | 24 ++++++----------- .../ast/statements/definition/definition.rs | 26 ++++++++++++++----- dynamic-check/src/ast/statements/statement.rs | 2 +- 10 files changed, 80 insertions(+), 98 deletions(-) diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs index 05923a36aa..0ef7211f9d 100644 --- a/dynamic-check/src/ast/expressions/expression.rs +++ b/dynamic-check/src/ast/expressions/expression.rs @@ -55,6 +55,7 @@ impl Expression { /// pub fn new( function_body: &FunctionBody, + type_: &Type, unresolved_expression: UnresolvedExpression, ) -> Result { match unresolved_expression { @@ -62,12 +63,14 @@ impl Expression { UnresolvedExpression::Identifier(identifier) => Self::variable(function_body, identifier), // Values - UnresolvedExpression::Address(string, span) => Self::address(string, span), - UnresolvedExpression::Boolean(string, span) => Self::boolean(string, span), - UnresolvedExpression::Field(string, span) => Self::field(string, span), - UnresolvedExpression::Group(group_value) => Self::group(group_value), - UnresolvedExpression::Implicit(string, span) => Self::implicit(string, span), - UnresolvedExpression::Integer(integer_type, string, span) => Self::integer(integer_type, string, span), + UnresolvedExpression::Address(string, span) => Ok(Self::address(type_, string, span)), + UnresolvedExpression::Boolean(string, span) => Ok(Self::boolean(type_, string, span)), + UnresolvedExpression::Field(string, span) => Ok(Self::field(type_, string, span)), + UnresolvedExpression::Group(group_value) => Ok(Self::group(type_, group_value)), + UnresolvedExpression::Integer(integer_type, string, span) => { + Ok(Self::integer(type_, integer_type, string, span)) + } + UnresolvedExpression::Implicit(string, span) => Self::implicit(type_, string, span), // Arithmetic Operations UnresolvedExpression::Add(lhs, rhs, span) => Self::add(variable_table, *lhs, *rhs, span), diff --git a/dynamic-check/src/ast/expressions/identifier/identifier.rs b/dynamic-check/src/ast/expressions/identifier/identifier.rs index 9b0f7b3e7e..4c12cdf7bd 100644 --- a/dynamic-check/src/ast/expressions/identifier/identifier.rs +++ b/dynamic-check/src/ast/expressions/identifier/identifier.rs @@ -20,20 +20,20 @@ use leo_typed::Identifier; impl Expression { /// - /// Returns a new variable expression from a given `UnresolvedExpression`. + /// Returns a new variable expression from a given variable. /// /// Performs a lookup in the given function body's variable table to find the variable's type. /// - pub(crate) fn variable(function_body: &FunctionBody, identifier: Identifier) -> Result { + pub(crate) fn variable(function_body: &FunctionBody, variable: Identifier) -> Result { // Lookup the type of the given variable. let type_ = function_body .variable_table - .get(&identifier.name) - .ok_or(ExpressionError::undefined_identifier(identifier.clone()))?; + .get(&variable.name) + .ok_or(ExpressionError::undefined_identifier(variable.clone()))?; Ok(Expression { type_: type_.clone(), - value: ExpressionValue::Variable(identifier), + value: ExpressionValue::Variable(variable), }) } } diff --git a/dynamic-check/src/ast/expressions/values/address.rs b/dynamic-check/src/ast/expressions/values/address.rs index f855fc910f..7ae85019e4 100644 --- a/dynamic-check/src/ast/expressions/values/address.rs +++ b/dynamic-check/src/ast/expressions/values/address.rs @@ -19,20 +19,13 @@ use leo_static_check::Type; use leo_typed::Span; impl Expression { - /// Resolve an address expression - pub(crate) fn address( - expected_type: Option, - address_string: String, - span: Span, - ) -> Result { - let type_ = Type::Address; - - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - - Ok(Expression { - type_, + /// + /// Returns a new address `Expression` from a given type and address string. + /// + pub(crate) fn address(type_: &Type, address_string: String, span: Span) -> Self { + Expression { + type_: type_.clone(), value: ExpressionValue::Address(address_string, span), - }) + } } } diff --git a/dynamic-check/src/ast/expressions/values/boolean.rs b/dynamic-check/src/ast/expressions/values/boolean.rs index d8af250ab3..8ffd41ae0e 100644 --- a/dynamic-check/src/ast/expressions/values/boolean.rs +++ b/dynamic-check/src/ast/expressions/values/boolean.rs @@ -19,20 +19,13 @@ use leo_static_check::Type; use leo_typed::Span; impl Expression { - /// Resolve a boolean expression - pub(crate) fn boolean( - expected_type: Option, - boolean_string: String, - span: Span, - ) -> Result { - let type_ = Type::Boolean; - - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - - Ok(Expression { - type_, + /// + /// Returns a new boolean expression from a given type and boolean string. + /// + pub(crate) fn boolean(type_: &Type, boolean_string: String, span: Span) -> Self { + Expression { + type_: type_.clone(), value: ExpressionValue::Boolean(boolean_string, span), - }) + } } } diff --git a/dynamic-check/src/ast/expressions/values/field.rs b/dynamic-check/src/ast/expressions/values/field.rs index ea1a85272d..1f23db1cf4 100644 --- a/dynamic-check/src/ast/expressions/values/field.rs +++ b/dynamic-check/src/ast/expressions/values/field.rs @@ -14,25 +14,18 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; +use crate::{Expression, ExpressionValue}; use leo_static_check::Type; use leo_typed::Span; impl Expression { - /// Resolve a field expression - pub(crate) fn field( - expected_type: Option, - field_string: String, - span: Span, - ) -> Result { - let type_ = Type::Field; - - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - - Ok(Expression { - type_, + /// + /// Returns a new field expression from a given type and field string. + /// + pub(crate) fn field(type_: &Type, field_string: String, span: Span) -> Self { + Expression { + type_: type_.clone(), value: ExpressionValue::Field(field_string, span), - }) + } } } diff --git a/dynamic-check/src/ast/expressions/values/group.rs b/dynamic-check/src/ast/expressions/values/group.rs index 39b68f5f2d..b51db3467a 100644 --- a/dynamic-check/src/ast/expressions/values/group.rs +++ b/dynamic-check/src/ast/expressions/values/group.rs @@ -19,17 +19,13 @@ use leo_static_check::Type; use leo_typed::GroupValue; impl Expression { - /// Resolve an group expression - pub(crate) fn group(expected_type: Option, group_value: GroupValue) -> Result { - let type_ = Type::Group; - let span = group_value.span().clone(); - - // Check the expected type if given - Type::check_type(&expected_type, &type_, span)?; - - Ok(Expression { - type_, + /// + /// Returns a new group `Expression` from the given type and group value. + /// + pub(crate) fn group(type_: &Type, group_value: GroupValue) -> Self { + Expression { + type_: type_.clone(), value: ExpressionValue::Group(group_value), - }) + } } } diff --git a/dynamic-check/src/ast/expressions/values/implicit.rs b/dynamic-check/src/ast/expressions/values/implicit.rs index d2f01b0b96..8c0189281d 100644 --- a/dynamic-check/src/ast/expressions/values/implicit.rs +++ b/dynamic-check/src/ast/expressions/values/implicit.rs @@ -19,15 +19,10 @@ use leo_static_check::Type; use leo_typed::{GroupValue, Span}; impl Expression { - /// Resolve an implicit expression - pub(crate) fn implicit( - expected_type: Option, - implicit_string: String, - span: Span, - ) -> Result { - // TODO: impl type lookahead - need to save this implicit value if there is no expected type - let type_ = expected_type.unwrap(); - + /// + /// Returns a new `Expression` from a given type and implicit number string. + /// + pub(crate) fn implicit(type_: &Type, implicit_string: String, span: Span) -> Result { let value = match &type_ { Type::Address => ExpressionValue::Address(implicit_string, span), Type::Boolean => ExpressionValue::Boolean(implicit_string, span), @@ -41,6 +36,9 @@ impl Expression { Type::TypeVariable(_name) => unimplemented!("ERROR: Type variables not implemented"), }; - Ok(Expression { type_, value }) + Ok(Expression { + type_: type_.clone(), + value, + }) } } diff --git a/dynamic-check/src/ast/expressions/values/integer.rs b/dynamic-check/src/ast/expressions/values/integer.rs index ed6c5142be..57d2c73df7 100644 --- a/dynamic-check/src/ast/expressions/values/integer.rs +++ b/dynamic-check/src/ast/expressions/values/integer.rs @@ -19,21 +19,13 @@ use leo_static_check::Type; use leo_typed::{IntegerType, Span}; impl Expression { - /// Resolve an integer expression - pub(crate) fn integer( - expected_type: Option, - integer_type: IntegerType, - integer_string: String, - span: Span, - ) -> Result { - let type_ = Type::IntegerType(integer_type); - - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - - Ok(Expression { - type_, - value: ExpressionValue::Address(integer_string, span), - }) + /// + /// Returns a new integer `Expression` from a given type, integer type, and integer string. + /// + pub(crate) fn integer(type_: &Type, integer_type: IntegerType, integer_string: String, span: Span) -> Self { + Expression { + type_: type_.clone(), + value: ExpressionValue::Integer(integer_type, integer_string, span), + } } } diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs index d3119c1131..5855b12f58 100644 --- a/dynamic-check/src/ast/statements/definition/definition.rs +++ b/dynamic-check/src/ast/statements/definition/definition.rs @@ -14,7 +14,16 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{check_tuple_type, Expression, ExpressionValue, ResolvedNode, Statement, StatementError, VariableTable}; +use crate::{ + check_tuple_type, + Expression, + ExpressionValue, + FunctionBody, + ResolvedNode, + Statement, + StatementError, + VariableTable, +}; use leo_static_check::{Attribute, ParameterType, SymbolTable, Type}; use leo_typed::{Declare, Expression as UnresolvedExpression, Span, VariableName, Variables}; @@ -189,7 +198,7 @@ impl Statement { /// Performs a lookup in the given variable table if the statement contains user-defined variables. /// pub(crate) fn definition( - table: &VariableTable, + function_body: &FunctionBody, declare: Declare, variables: Variables, unresolved_expressions: Vec, @@ -208,7 +217,7 @@ impl Statement { // Define a single variable with a single value DefinitionVariables::single( - table, + function_body, variables.names[0].clone(), unresolved_expressions[0].clone(), span.clone(), @@ -216,12 +225,17 @@ impl Statement { } else if num_variables == 1 && num_values > 1 { // Define a tuple (single variable with multiple values) - DefinitionVariables::tuple(table, variables.names[0].clone(), unresolved_expressions, span.clone()) + DefinitionVariables::tuple( + function_body, + variables.names[0].clone(), + unresolved_expressions, + span.clone(), + ) } else if num_variables > 1 && num_values == 1 { // Define multiple variables for an expression that returns a tuple DefinitionVariables::multiple_variable_tuple( - table, + function_body, variables, unresolved_expressions[0].clone(), span.clone(), @@ -230,7 +244,7 @@ impl Statement { // Define multiple variables for multiple expressions DefinitionVariables::multiple_variable( - table, + function_body, variables, expected_type, unresolved_expressions, diff --git a/dynamic-check/src/ast/statements/statement.rs b/dynamic-check/src/ast/statements/statement.rs index 18429c4243..1c74043ffb 100644 --- a/dynamic-check/src/ast/statements/statement.rs +++ b/dynamic-check/src/ast/statements/statement.rs @@ -55,7 +55,7 @@ impl Statement { match unresolved_statement { UnresolvedStatement::Return(expression, span) => Self::resolve_return(function_body, expression, span), UnresolvedStatement::Definition(declare, variables, expressions, span) => { - Self::definition(variable_table, declare, variables, expressions, span) + Self::definition(function_body, declare, variables, expressions, span) } UnresolvedStatement::Assign(assignee, expression, span) => { Self::assign(variable_table, assignee, expression, span) From 1849a5ddcc3473b7ad6f7835d79ce5472ddac475 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 16 Oct 2020 14:15:53 -0700 Subject: [PATCH 030/139] impl definition statements 1 --- .../src/ast/expressions/expression.rs | 262 +++++++++--------- .../ast/expressions/identifier/identifier.rs | 5 +- .../src/ast/expressions/tuple/tuple.rs | 40 +-- .../ast/statements/definition/definition.rs | 35 +-- dynamic-check/src/dynamic_check.rs | 11 +- dynamic-check/src/errors/expression.rs | 15 +- dynamic-check/src/errors/mod.rs | 3 + dynamic-check/src/errors/statement.rs | 6 +- dynamic-check/src/errors/variable_table.rs | 53 ++++ typed/src/common/variable_name.rs | 9 + 10 files changed, 257 insertions(+), 182 deletions(-) create mode 100644 dynamic-check/src/errors/variable_table.rs diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs index 0ef7211f9d..11a79d8e88 100644 --- a/dynamic-check/src/ast/expressions/expression.rs +++ b/dynamic-check/src/ast/expressions/expression.rs @@ -72,62 +72,63 @@ impl Expression { } UnresolvedExpression::Implicit(string, span) => Self::implicit(type_, string, span), - // Arithmetic Operations - UnresolvedExpression::Add(lhs, rhs, span) => Self::add(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Div(lhs, rhs, span) => Self::div(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Negate(expression, span) => Self::negate(variable_table, *expression, span), - - // Logical Operations - UnresolvedExpression::And(lhs, rhs, span) => Self::and(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Or(lhs, rhs, span) => Self::or(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Not(expression, span) => Self::not(variable_table, *expression, span), - - // Relational Operations - UnresolvedExpression::Eq(lhs, rhs, span) => Self::eq(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Ge(lhs, rhs, span) => Self::ge(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Gt(lhs, rhs, span) => Self::gt(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Le(lhs, rhs, span) => Self::le(variable_table, *lhs, *rhs, span), - UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(variable_table, *lhs, *rhs, span), - - // Conditionals - UnresolvedExpression::IfElse(cond, first, second, span) => { - Self::conditional(variable_table, *cond, *first, *second, span) - } - - // Arrays - UnresolvedExpression::Array(elements, span) => Self::array(variable_table, elements, span), - UnresolvedExpression::ArrayAccess(array, access, span) => { - Self::array_access(variable_table, array, access, span) - } - - // Tuples - UnresolvedExpression::Tuple(elements, span) => Self::tuple(variable_table, elements, span), - UnresolvedExpression::TupleAccess(tuple, index, span) => { - Self::tuple_access(variable_table, tuple, index, span) - } - - // Circuits - UnresolvedExpression::Circuit(identifier, variables, span) => { - Self::circuit(variable_table, identifier, variables, span) - } - UnresolvedExpression::CircuitMemberAccess(circuit, member, span) => { - Self::circuit_access(variable_table, circuit, member, span) - } - UnresolvedExpression::CircuitStaticFunctionAccess(circuit, member, span) => { - Self::circuit_static_access(variable_table, circuit, member, span) - } - - // Functions - UnresolvedExpression::FunctionCall(function, inputs, span) => { - Self::function_call(variable_table, function, inputs, span) - } - UnresolvedExpression::CoreFunctionCall(_name, _inputs, _span) => { - unimplemented!("core function calls not type checked") - // Self::core_function_call(variable_table, expected_type, function, inputs, span) - } + // // Arithmetic Operations + // UnresolvedExpression::Add(lhs, rhs, span) => Self::add(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Div(lhs, rhs, span) => Self::div(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Negate(expression, span) => Self::negate(variable_table, *expression, span), + // + // // Logical Operations + // UnresolvedExpression::And(lhs, rhs, span) => Self::and(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Or(lhs, rhs, span) => Self::or(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Not(expression, span) => Self::not(variable_table, *expression, span), + // + // // Relational Operations + // UnresolvedExpression::Eq(lhs, rhs, span) => Self::eq(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Ge(lhs, rhs, span) => Self::ge(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Gt(lhs, rhs, span) => Self::gt(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Le(lhs, rhs, span) => Self::le(variable_table, *lhs, *rhs, span), + // UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(variable_table, *lhs, *rhs, span), + // + // // Conditionals + // UnresolvedExpression::IfElse(cond, first, second, span) => { + // Self::conditional(variable_table, *cond, *first, *second, span) + // } + // + // // Arrays + // UnresolvedExpression::Array(elements, span) => Self::array(variable_table, elements, span), + // UnresolvedExpression::ArrayAccess(array, access, span) => { + // Self::array_access(variable_table, array, access, span) + // } + // + // // Tuples + // UnresolvedExpression::Tuple(elements, span) => Self::tuple(variable_table, elements, span), + // UnresolvedExpression::TupleAccess(tuple, index, span) => { + // Self::tuple_access(variable_table, tuple, index, span) + // } + // + // // Circuits + // UnresolvedExpression::Circuit(identifier, variables, span) => { + // Self::circuit(variable_table, identifier, variables, span) + // } + // UnresolvedExpression::CircuitMemberAccess(circuit, member, span) => { + // Self::circuit_access(variable_table, circuit, member, span) + // } + // UnresolvedExpression::CircuitStaticFunctionAccess(circuit, member, span) => { + // Self::circuit_static_access(variable_table, circuit, member, span) + // } + // + // // Functions + // UnresolvedExpression::FunctionCall(function, inputs, span) => { + // Self::function_call(variable_table, function, inputs, span) + // } + // UnresolvedExpression::CoreFunctionCall(_name, _inputs, _span) => { + // unimplemented!("core function calls not type checked") + // // Self::core_function_call(variable_table, expected_type, function, inputs, span) + // } + _ => unimplemented!("expression not impl yet"), } } } @@ -139,79 +140,80 @@ impl ResolvedNode for Expression { /// Type check an expression inside a program AST fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let expected_type = unresolved.0; - let expression = unresolved.1; - - match expression { - // Identifier - UnresolvedExpression::Identifier(identifier) => Self::identifier(table, expected_type, identifier), - - // Values - UnresolvedExpression::Address(string, span) => Self::address(expected_type, string, span), - UnresolvedExpression::Boolean(string, span) => Self::boolean(expected_type, string, span), - UnresolvedExpression::Field(string, span) => Self::field(expected_type, string, span), - UnresolvedExpression::Group(group_value) => Self::group(expected_type, group_value), - UnresolvedExpression::Implicit(string, span) => Self::implicit(expected_type, string, span), - UnresolvedExpression::Integer(integer_type, string, span) => { - Self::integer(expected_type, integer_type, string, span) - } - - // Arithmetic Operations - UnresolvedExpression::Add(lhs, rhs, span) => Self::add(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Div(lhs, rhs, span) => Self::div(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Negate(expression, span) => Self::negate(table, expected_type, *expression, span), - - // Logical Operations - UnresolvedExpression::And(lhs, rhs, span) => Self::and(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Or(lhs, rhs, span) => Self::or(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Not(expression, span) => Self::not(table, expected_type, *expression, span), - - // Relational Operations - UnresolvedExpression::Eq(lhs, rhs, span) => Self::eq(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Ge(lhs, rhs, span) => Self::ge(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Gt(lhs, rhs, span) => Self::gt(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Le(lhs, rhs, span) => Self::le(table, expected_type, *lhs, *rhs, span), - UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(table, expected_type, *lhs, *rhs, span), - - // Conditionals - UnresolvedExpression::IfElse(cond, first, second, span) => { - Self::conditional(table, expected_type, *cond, *first, *second, span) - } - - // Arrays - UnresolvedExpression::Array(elements, span) => Self::array(table, expected_type, elements, span), - UnresolvedExpression::ArrayAccess(array, access, span) => { - Self::array_access(table, expected_type, array, access, span) - } - - // Tuples - UnresolvedExpression::Tuple(elements, span) => Self::tuple(table, expected_type, elements, span), - UnresolvedExpression::TupleAccess(tuple, index, span) => { - Self::tuple_access(table, expected_type, tuple, index, span) - } - - // Circuits - UnresolvedExpression::Circuit(identifier, variables, span) => { - Self::circuit(table, expected_type, identifier, variables, span) - } - UnresolvedExpression::CircuitMemberAccess(circuit, member, span) => { - Self::circuit_access(table, expected_type, circuit, member, span) - } - UnresolvedExpression::CircuitStaticFunctionAccess(circuit, member, span) => { - Self::circuit_static_access(table, expected_type, circuit, member, span) - } - - // Functions - UnresolvedExpression::FunctionCall(function, inputs, span) => { - Self::function_call(table, expected_type, function, inputs, span) - } - UnresolvedExpression::CoreFunctionCall(_name, _inputs, _span) => { - unimplemented!("core function calls not type checked") - // Self::core_function_call(table, expected_type, function, inputs, span) - } - } + unimplemented!("expression resolve method deprecated") + // let expected_type = unresolved.0; + // let expression = unresolved.1; + // + // match expression { + // // Identifier + // UnresolvedExpression::Identifier(identifier) => Self::identifier(table, expected_type, identifier), + // + // // Values + // UnresolvedExpression::Address(string, span) => Self::address(expected_type, string, span), + // UnresolvedExpression::Boolean(string, span) => Self::boolean(expected_type, string, span), + // UnresolvedExpression::Field(string, span) => Self::field(expected_type, string, span), + // UnresolvedExpression::Group(group_value) => Self::group(expected_type, group_value), + // UnresolvedExpression::Implicit(string, span) => Self::implicit(expected_type, string, span), + // UnresolvedExpression::Integer(integer_type, string, span) => { + // Self::integer(expected_type, integer_type, string, span) + // } + // + // // Arithmetic Operations + // UnresolvedExpression::Add(lhs, rhs, span) => Self::add(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Div(lhs, rhs, span) => Self::div(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Negate(expression, span) => Self::negate(table, expected_type, *expression, span), + // + // // Logical Operations + // UnresolvedExpression::And(lhs, rhs, span) => Self::and(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Or(lhs, rhs, span) => Self::or(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Not(expression, span) => Self::not(table, expected_type, *expression, span), + // + // // Relational Operations + // UnresolvedExpression::Eq(lhs, rhs, span) => Self::eq(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Ge(lhs, rhs, span) => Self::ge(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Gt(lhs, rhs, span) => Self::gt(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Le(lhs, rhs, span) => Self::le(table, expected_type, *lhs, *rhs, span), + // UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(table, expected_type, *lhs, *rhs, span), + // + // // Conditionals + // UnresolvedExpression::IfElse(cond, first, second, span) => { + // Self::conditional(table, expected_type, *cond, *first, *second, span) + // } + // + // // Arrays + // UnresolvedExpression::Array(elements, span) => Self::array(table, expected_type, elements, span), + // UnresolvedExpression::ArrayAccess(array, access, span) => { + // Self::array_access(table, expected_type, array, access, span) + // } + // + // // Tuples + // UnresolvedExpression::Tuple(elements, span) => Self::tuple(table, expected_type, elements, span), + // UnresolvedExpression::TupleAccess(tuple, index, span) => { + // Self::tuple_access(table, expected_type, tuple, index, span) + // } + // + // // Circuits + // UnresolvedExpression::Circuit(identifier, variables, span) => { + // Self::circuit(table, expected_type, identifier, variables, span) + // } + // UnresolvedExpression::CircuitMemberAccess(circuit, member, span) => { + // Self::circuit_access(table, expected_type, circuit, member, span) + // } + // UnresolvedExpression::CircuitStaticFunctionAccess(circuit, member, span) => { + // Self::circuit_static_access(table, expected_type, circuit, member, span) + // } + // + // // Functions + // UnresolvedExpression::FunctionCall(function, inputs, span) => { + // Self::function_call(table, expected_type, function, inputs, span) + // } + // UnresolvedExpression::CoreFunctionCall(_name, _inputs, _span) => { + // unimplemented!("core function calls not type checked") + // // Self::core_function_call(table, expected_type, function, inputs, span) + // } + // } } } diff --git a/dynamic-check/src/ast/expressions/identifier/identifier.rs b/dynamic-check/src/ast/expressions/identifier/identifier.rs index 4c12cdf7bd..2a9bfa09e6 100644 --- a/dynamic-check/src/ast/expressions/identifier/identifier.rs +++ b/dynamic-check/src/ast/expressions/identifier/identifier.rs @@ -26,10 +26,7 @@ impl Expression { /// pub(crate) fn variable(function_body: &FunctionBody, variable: Identifier) -> Result { // Lookup the type of the given variable. - let type_ = function_body - .variable_table - .get(&variable.name) - .ok_or(ExpressionError::undefined_identifier(variable.clone()))?; + let type_ = function_body.variable_table.get(&variable.name, &variable.span)?; Ok(Expression { type_: type_.clone(), diff --git a/dynamic-check/src/ast/expressions/tuple/tuple.rs b/dynamic-check/src/ast/expressions/tuple/tuple.rs index 847db78df1..d3bc3d6ed5 100644 --- a/dynamic-check/src/ast/expressions/tuple/tuple.rs +++ b/dynamic-check/src/ast/expressions/tuple/tuple.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode, VariableTable}; +use crate::{Expression, ExpressionError, ExpressionValue, FunctionBody, ResolvedNode, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; @@ -25,41 +25,29 @@ impl Expression { /// Performs a lookup in the given variable table if an `UnresolvedExpression` contains user-defined types. /// pub(crate) fn tuple( - variable_table: &VariableTable, + function_body: &FunctionBody, + type_: &Type, unresolved_expressions: Vec, span: Span, ) -> Result { - // // If the expected type is given, then it must be a tuple of types - // let expected_element_types = check_tuple_type(expected_type, expressions.len(), span.clone())?; + // Get the type of each element in the tuple. + // If the type is not a tuple type, throw an error. + let element_types = match type_ { + Type::Tuple(types) => types, + type_ => return Err(ExpressionError::invalid_type_tuple(type_, &span)), + }; - // Check length of tuple against expected types - // if expected_element_types.len() != unresolved_expressions.len() { - // return Err(ExpressionError::invalid_length_tuple( - // expected_element_types.len(), - // unresolved_expressions.len(), - // span.clone(), - // )); - // } - - // Resolve all tuple elements + // Create a new vector of `Expression`s from the given vector of `UnresolvedExpression`s. let mut tuple = vec![]; - for (expression, _) in unresolved_expressions.into_iter().zip(expected_element_types) { - let expression_resolved = Expression::new(variable_table, expression)?; + for (unresolved_expression, element_type) in unresolved_expressions.into_iter().zip(element_types) { + let expression = Expression::new(function_body, element_type, unresolved_expression)?; - tuple.push(expression_resolved); + tuple.push(expression); } - // Define tuple type for expression - let actual_element_types = tuple - .iter() - .map(|expression| expression.type_().clone()) - .collect::>(); - - let type_ = Type::Tuple(actual_element_types); - Ok(Expression { - type_, + type_: type_.clone(), value: ExpressionValue::Tuple(tuple, span), }) } diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs index 5855b12f58..8580623098 100644 --- a/dynamic-check/src/ast/statements/definition/definition.rs +++ b/dynamic-check/src/ast/statements/definition/definition.rs @@ -49,33 +49,41 @@ pub enum DefinitionVariables { impl DefinitionVariables { /// - /// Returns a new statement that defines a single variable with a single value. + /// Returns a new statement that defines a single variable with a single expression. /// /// Performs a lookup in the given variable table if the `UnresolvedExpression` contains user-defined variables. /// fn single( - table: &VariableTable, - variable: VariableName, + function_body: &FunctionBody, + variable_name: VariableName, unresolved_expression: UnresolvedExpression, + span: &Span, ) -> Result { - // Create a new `Expression` from the given `UnresolvedExpression`. - let expression = Expression::new(table, unresolved_expression)?; + // Get the type of the variable. + let type_ = function_body.variable_table.get(variable_name.name_string(), span)?; - Ok(DefinitionVariables::Single(variable, expression)) + // Create a new `Expression` from the given `UnresolvedExpression`. + let expression = Expression::new(function_body, type_, unresolved_expression)?; + + Ok(DefinitionVariables::Single(variable_name, expression)) } /// - /// Returns a new statement that defines a tuple (single variable with multiple values). + /// Returns a new statement that defines a tuple (single variable with multiple expressions). /// /// Performs a lookup in the given variable table if an `UnresolvedExpression` contains user-defined variables. /// fn tuple( - table: &VariableTable, + function_body: &FunctionBody, variable: VariableName, unresolved_expressions: Vec, + span: &Span, ) -> Result { + // Get the type of the variable. + let type_ = function_body.variable_table.get(variable.name_string(), span)?; + // Create a new tuple of `Expression`s from the given vector of `UnresolvedExpression's. - let tuple = Expression::tuple(table, unresolved_expressions, span.clone())?; + let tuple = Expression::tuple(function_body, type_, unresolved_expressions, span.clone())?; Ok(DefinitionVariables::Tuple(variable, tuple)) } @@ -220,17 +228,12 @@ impl Statement { function_body, variables.names[0].clone(), unresolved_expressions[0].clone(), - span.clone(), + &span, ) } else if num_variables == 1 && num_values > 1 { // Define a tuple (single variable with multiple values) - DefinitionVariables::tuple( - function_body, - variables.names[0].clone(), - unresolved_expressions, - span.clone(), - ) + DefinitionVariables::tuple(function_body, variables.names[0].clone(), unresolved_expressions, &span) } else if num_variables > 1 && num_values == 1 { // Define multiple variables for an expression that returns a tuple diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index ad0aa4bbd0..9bb47e63cc 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{DynamicCheckError, Function, FunctionError, LeoResolvedAst}; +use crate::{DynamicCheckError, Function, FunctionError, LeoResolvedAst, VariableTableError}; use leo_static_check::{FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; use leo_typed::{ Expression, @@ -368,10 +368,13 @@ impl VariableTable { /// /// Returns a reference to the type corresponding to the name. /// - /// If the variable table did not have this name present, [`None`] is returned. + /// If the variable table did not have this key present, throw an undefined variable error + /// using the given span. /// - pub fn get(&self, name: &String) -> Option<&Type> { - self.0.get(name) + pub fn get(&self, name: &String, span: &Span) -> Result<&Type, VariableTableError> { + self.0 + .get(name) + .ok_or(VariableTableError::undefined_variable_name(name, span)) } /// diff --git a/dynamic-check/src/errors/expression.rs b/dynamic-check/src/errors/expression.rs index 75f84bbfcb..84df4f4635 100644 --- a/dynamic-check/src/errors/expression.rs +++ b/dynamic-check/src/errors/expression.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_static_check::TypeError; +use crate::VariableTableError; +use leo_static_check::{Type, TypeError}; use leo_typed::{Error as FormattedError, Identifier, Span}; use std::path::PathBuf; @@ -27,6 +28,9 @@ pub enum ExpressionError { #[error("{}", _0)] TypeError(#[from] TypeError), + + #[error("{}", _0)] + VariableTableError(#[from] VariableTableError), } impl ExpressionError { @@ -122,6 +126,15 @@ impl ExpressionError { Self::new_from_span(message, span) } + /// + /// Attempted to assign a tuple expression to a variable with a different explicit type. + /// + pub fn invalid_type_tuple(actual: &Type, span: &Span) -> Self { + let message = format!("Expected tuple type, found type {}", actual); + + Self::new_from_span(message, span.clone()) + } + /// /// Attempted to lookup an unknown variable name. /// diff --git a/dynamic-check/src/errors/mod.rs b/dynamic-check/src/errors/mod.rs index fbfbf1aa56..e80b09f007 100644 --- a/dynamic-check/src/errors/mod.rs +++ b/dynamic-check/src/errors/mod.rs @@ -35,6 +35,9 @@ pub use self::resolver::*; pub mod statement; pub use self::statement::*; +pub mod variable_table; +pub use self::variable_table::*; + // pub mod symbol_table; // pub use self::symbol_table::*; diff --git a/dynamic-check/src/errors/statement.rs b/dynamic-check/src/errors/statement.rs index bfd96c2e5c..35f99b2cfc 100644 --- a/dynamic-check/src/errors/statement.rs +++ b/dynamic-check/src/errors/statement.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::ExpressionError; +use crate::{ExpressionError, VariableTableError}; use leo_static_check::{Type, TypeError}; use leo_typed::{Error as FormattedError, Expression as UnresolvedExpression, Identifier, Span}; @@ -33,6 +33,9 @@ pub enum StatementError { #[error("{}", _0)] TypeError(#[from] TypeError), + + #[error("{}", _0)] + VariableTableError(#[from] VariableTableError), } impl StatementError { @@ -44,6 +47,7 @@ impl StatementError { StatementError::Error(error) => error.set_path(path), StatementError::ExpressionError(error) => error.set_path(path), StatementError::TypeError(error) => error.set_path(path), + StatementError::VariableTableError(error) => error.set_path(path), } } diff --git a/dynamic-check/src/errors/variable_table.rs b/dynamic-check/src/errors/variable_table.rs new file mode 100644 index 0000000000..39ff924532 --- /dev/null +++ b/dynamic-check/src/errors/variable_table.rs @@ -0,0 +1,53 @@ +// 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 . + +use leo_typed::{Error as FormattedError, Span}; + +use std::path::PathBuf; + +/// Errors encountered when tracking variable names in a program. +#[derive(Debug, Error)] +pub enum VariableTableError { + #[error("{}", _0)] + Error(#[from] FormattedError), +} + +impl VariableTableError { + /// + /// Set the filepath for the error stacktrace + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + VariableTableError::Error(error) => error.set_path(path), + } + } + + /// + /// Return a new formatted error with a given message and span information + /// + fn new_from_span(message: String, span: Span) -> Self { + VariableTableError::Error(FormattedError::new_from_span(message, span)) + } + + /// + /// Attempted to lookup a variable name that does not exist in the table. + /// + pub fn undefined_variable_name(name: &String, span: &Span) -> Self { + let message = format!("Cannot find variable `{}` in this scope.", name); + + Self::new_from_span(message, span.clone()) + } +} diff --git a/typed/src/common/variable_name.rs b/typed/src/common/variable_name.rs index bb0a92300f..6cf69fec81 100644 --- a/typed/src/common/variable_name.rs +++ b/typed/src/common/variable_name.rs @@ -27,6 +27,15 @@ pub struct VariableName { pub span: Span, } +impl VariableName { + /// + /// Returns the name of the `VariableName` as a string. + /// + pub fn name_string(&self) -> &String { + &self.identifier.name + } +} + impl<'ast> From> for VariableName { fn from(name: AstVariableName<'ast>) -> Self { Self { From 42a892480a9e9734211d67ba0e9bc433d35bfc76 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 16 Oct 2020 14:39:39 -0700 Subject: [PATCH 031/139] impl definition statements 2 --- .../ast/statements/definition/definition.rs | 91 +++++++------------ dynamic-check/src/errors/statement.rs | 4 +- 2 files changed, 35 insertions(+), 60 deletions(-) diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs index 8580623098..d19a4c10a2 100644 --- a/dynamic-check/src/ast/statements/definition/definition.rs +++ b/dynamic-check/src/ast/statements/definition/definition.rs @@ -23,6 +23,7 @@ use crate::{ Statement, StatementError, VariableTable, + VariableTableError, }; use leo_static_check::{Attribute, ParameterType, SymbolTable, Type}; use leo_typed::{Declare, Expression as UnresolvedExpression, Span, VariableName, Variables}; @@ -90,47 +91,36 @@ impl DefinitionVariables { /// Resolves multiple variables for multiple expressions fn multiple_variable( - table: &mut SymbolTable, + function_body: &FunctionBody, variables: Variables, - expected_type: Option, - expressions: Vec, - span: Span, + unresolved_expressions: Vec, + span: &Span, ) -> Result { - // If the expected type is given, then it must be a tuple of types - let explicit_types = check_tuple_type(expected_type, expressions.len(), span.clone())?; - - // Check number of variables == types - if variables.names.len() != explicit_types.len() { - return Err(StatementError::multiple_variable_types( - variables.names.len(), - explicit_types.len(), - span, - )); - } - // Check number of variables == expressions - if variables.names.len() != expressions.len() { + if variables.names.len() != unresolved_expressions.len() { return Err(StatementError::multiple_variable_expressions( variables.names.len(), - expressions.len(), + unresolved_expressions.len(), span, )); } - // Resolve expressions + // Get the type of each variable. + let variable_types = variables + .names + .iter() + .map(|variable_name| function_body.variable_table.get(variable_name.name_string(), span)) + .collect::, VariableTableError>>()?; + + // Create a new vector of `Expression`s from the given vector of `UnresolvedExpression`s. let mut expressions_resolved = vec![]; - for (expression, type_) in expressions.into_iter().zip(explicit_types) { - let expression_resolved = Expression::resolve(table, (type_, expression))?; + for (unresolved_expression, variable_type) in unresolved_expressions.into_iter().zip(variable_types) { + let expression_resolved = Expression::new(function_body, &variable_type, unresolved_expression)?; expressions_resolved.push(expression_resolved); } - // Insert variables into symbol table - for (variable, expression) in variables.names.clone().iter().zip(expressions_resolved.iter()) { - insert_defined_variable(table, variable, expression.type_(), span.clone())?; - } - Ok(DefinitionVariables::MultipleVariable( variables.names, expressions_resolved, @@ -139,29 +129,26 @@ impl DefinitionVariables { /// Resolves multiple variables for an expression that returns a tuple fn multiple_variable_tuple( - table: &mut SymbolTable, + function_body: &FunctionBody, variables: Variables, - expected_type: Option, - expression: UnresolvedExpression, - span: Span, + unresolved_expression: UnresolvedExpression, + span: &Span, ) -> Result { - // Resolve tuple expression - let expression_resolved = Expression::resolve(table, (expected_type, expression.clone()))?; + // Get the type of each variable. + let variable_types = variables + .names + .iter() + .map(|variable_name| function_body.variable_table.get(variable_name.name_string(), span)) + .collect::, VariableTableError>>()?; - let expressions_resolved = match &expression_resolved.value { - ExpressionValue::Tuple(expressions_resolved, _span) => expressions_resolved.clone(), - _ => return Err(StatementError::invalid_tuple(variables.names.len(), expression, span)), - }; + // Create a new tuple type from the vector of variable types. + let tuple_type = Type::Tuple(variable_types); - // Insert variables into symbol table - for (variable, expression) in variables.names.clone().iter().zip(expressions_resolved.iter()) { - insert_defined_variable(table, variable, expression.type_(), span.clone())?; - } + // Create a new `Expression` from the given `UnresolvedExpression`. + // This expression should return a tuple. + let expression = Expression::new(function_body, &tuple_type, unresolved_expression)?; - Ok(DefinitionVariables::MultipleVariableTuple( - variables.names, - expression_resolved, - )) + Ok(DefinitionVariables::MultipleVariableTuple(variables.names, expression)) } } @@ -215,12 +202,6 @@ impl Statement { let num_variables = variables.names.len(); let num_values = unresolved_expressions.len(); - // // If an explicit type is given check that it is valid - // let expected_type = match &variables.type_ { - // Some(type_) => Some(Type::new(table, type_.clone(), span.clone())?), - // None => None, - // }; - let variables = if num_variables == 1 && num_values == 1 { // Define a single variable with a single value @@ -241,18 +222,12 @@ impl Statement { function_body, variables, unresolved_expressions[0].clone(), - span.clone(), + &span, ) } else { // Define multiple variables for multiple expressions - DefinitionVariables::multiple_variable( - function_body, - variables, - expected_type, - unresolved_expressions, - span.clone(), - ) + DefinitionVariables::multiple_variable(function_body, variables, unresolved_expressions, &span) }?; Ok(Statement::Definition(Definition { diff --git a/dynamic-check/src/errors/statement.rs b/dynamic-check/src/errors/statement.rs index 35f99b2cfc..52ac639368 100644 --- a/dynamic-check/src/errors/statement.rs +++ b/dynamic-check/src/errors/statement.rs @@ -100,13 +100,13 @@ impl StatementError { /// /// Provided a different number of expression values than variables being defined in a tuple /// - pub fn multiple_variable_expressions(expected: usize, actual: usize, span: Span) -> Self { + pub fn multiple_variable_expressions(expected: usize, actual: usize, span: &Span) -> Self { let message = format!( "Expected {} values when defining variables, found {} values", expected, actual ); - Self::new_from_span(message, span) + Self::new_from_span(message, span.clone()) } /// From 154fa45b4d90b34e76dca832a6e5771f2792384e Mon Sep 17 00:00:00 2001 From: collin Date: Sat, 17 Oct 2020 16:47:33 -0700 Subject: [PATCH 032/139] impl expression operations --- .../src/ast/expressions/arithmetic/add.rs | 16 +++++++----- .../src/ast/expressions/arithmetic/div.rs | 16 +++++++----- .../src/ast/expressions/arithmetic/mul.rs | 16 +++++++----- .../src/ast/expressions/arithmetic/negate.rs | 14 +++++----- .../src/ast/expressions/arithmetic/pow.rs | 16 +++++++----- .../src/ast/expressions/arithmetic/sub.rs | 16 +++++++----- .../src/ast/expressions/binary/binary.rs | 17 +++++------- .../src/ast/expressions/expression.rs | 22 ++++++++-------- .../ast/expressions/identifier/identifier.rs | 4 +-- .../src/ast/expressions/tuple/tuple.rs | 4 +-- dynamic-check/src/ast/functions/function.rs | 4 +-- .../src/ast/statements/assign/assign.rs | 17 +++++++----- .../ast/statements/conditional/conditional.rs | 4 +-- .../ast/statements/definition/definition.rs | 12 ++++----- .../src/ast/statements/return_/return_.rs | 4 +-- dynamic-check/src/ast/statements/statement.rs | 26 +++++++------------ dynamic-check/src/dynamic_check.rs | 8 +++--- 17 files changed, 110 insertions(+), 106 deletions(-) diff --git a/dynamic-check/src/ast/expressions/arithmetic/add.rs b/dynamic-check/src/ast/expressions/arithmetic/add.rs index 54236b6464..b4409f6d28 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/add.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/add.rs @@ -14,24 +14,26 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of adding `lhs + rhs` + /// + /// Returns a new `Expression` adding `lhs + rhs`. + /// pub(crate) fn add( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, + type_: &Type, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(table, expected_type, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, type_, lhs, rhs, &span)?; Ok(Expression { - type_: lhs_resolved.type_.clone(), + type_: type_.clone(), value: ExpressionValue::Add(Box::new(lhs_resolved), Box::new(rhs_resolved), span), }) } diff --git a/dynamic-check/src/ast/expressions/arithmetic/div.rs b/dynamic-check/src/ast/expressions/arithmetic/div.rs index 4c657d1808..a52a1790eb 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/div.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/div.rs @@ -14,24 +14,26 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of dividing `lhs / rhs` + /// + /// Returns a new `Expression` dividing `lhs / rhs`. + /// pub(crate) fn div( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, + type_: &Type, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(table, expected_type, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, type_, lhs, rhs, &span)?; Ok(Expression { - type_: lhs_resolved.type_.clone(), + type_: type_.clone(), value: ExpressionValue::Div(Box::new(lhs_resolved), Box::new(rhs_resolved), span), }) } diff --git a/dynamic-check/src/ast/expressions/arithmetic/mul.rs b/dynamic-check/src/ast/expressions/arithmetic/mul.rs index a2fe20b878..9e984943ac 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/mul.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/mul.rs @@ -14,24 +14,26 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of multiplying `lhs * rhs` + /// + /// Returns a new `Expression` multiplying `lhs * rhs`. + /// pub(crate) fn mul( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, + type_: &Type, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(table, expected_type, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, type_, lhs, rhs, &span)?; Ok(Expression { - type_: lhs_resolved.type_.clone(), + type_: type_.clone(), value: ExpressionValue::Mul(Box::new(lhs_resolved), Box::new(rhs_resolved), span), }) } diff --git a/dynamic-check/src/ast/expressions/arithmetic/negate.rs b/dynamic-check/src/ast/expressions/arithmetic/negate.rs index 8bdfc77b88..9cf00663c1 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/negate.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/negate.rs @@ -14,22 +14,22 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { /// Resolve the type of negating `-expression` pub(crate) fn negate( - table: &mut SymbolTable, - expected_type: Option, - expression: UnresolvedExpression, + frame: &Frame, + type_: &Type, + unresolved_expression: UnresolvedExpression, span: Span, ) -> Result { - let expression_resolved = Self::resolve(table, (expected_type, expression))?; + let expression_resolved = Self::new(frame, type_, unresolved_expression)?; Ok(Expression { - type_: expression_resolved.type_.clone(), + type_: type_.clone(), value: ExpressionValue::Negate(Box::new(expression_resolved), span), }) } diff --git a/dynamic-check/src/ast/expressions/arithmetic/pow.rs b/dynamic-check/src/ast/expressions/arithmetic/pow.rs index e60443a33d..29969d71c4 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/pow.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/pow.rs @@ -14,24 +14,26 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of exponentiation `lhs ** rhs` + /// + /// Returns a new `Expression` raising `lhs` to the power of `rhs`. + /// pub(crate) fn pow( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, + type_: &Type, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(table, expected_type, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, type_, lhs, rhs, &span)?; Ok(Expression { - type_: lhs_resolved.type_.clone(), + type_: type_.clone(), value: ExpressionValue::Pow(Box::new(lhs_resolved), Box::new(rhs_resolved), span), }) } diff --git a/dynamic-check/src/ast/expressions/arithmetic/sub.rs b/dynamic-check/src/ast/expressions/arithmetic/sub.rs index 777aa5494c..8a3b0c5ada 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/sub.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/sub.rs @@ -14,24 +14,26 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of subtracting `lhs - rhs` + /// + /// Returns a new `Expression` subtracting `lhs - rhs`. + /// pub(crate) fn sub( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, + type_: &Type, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(table, expected_type, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, type_, lhs, rhs, &span)?; Ok(Expression { - type_: lhs_resolved.type_.clone(), + type_: type_.clone(), value: ExpressionValue::Sub(Box::new(lhs_resolved), Box::new(rhs_resolved), span), }) } diff --git a/dynamic-check/src/ast/expressions/binary/binary.rs b/dynamic-check/src/ast/expressions/binary/binary.rs index 1c0d298eb3..88d1d4c3f6 100644 --- a/dynamic-check/src/ast/expressions/binary/binary.rs +++ b/dynamic-check/src/ast/expressions/binary/binary.rs @@ -13,28 +13,25 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; +use crate::{Expression, ExpressionError, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { /// Resolve a binary expression from left to right. /// If no expected type is given, then the expression resolves to the lhs type. pub(crate) fn binary( - table: &mut SymbolTable, - mut expected_type: Option, + frame: &Frame, + type_: &Type, lhs: UnresolvedExpression, rhs: UnresolvedExpression, - _span: Span, + _span: &Span, ) -> Result<(Self, Self), ExpressionError> { // Resolve lhs with expected type - let lhs_resolved = Expression::resolve(table, (expected_type, lhs))?; - - // Set the expected type to the lhs type - expected_type = Some(lhs_resolved.type_.clone()); + let lhs_resolved = Expression::new(frame, type_, lhs)?; // Resolve the rhs with expected type - let rhs_resolved = Expression::resolve(table, (expected_type, rhs))?; + let rhs_resolved = Expression::new(frame, type_, rhs)?; Ok((lhs_resolved, rhs_resolved)) } diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs index 11a79d8e88..14e626dd56 100644 --- a/dynamic-check/src/ast/expressions/expression.rs +++ b/dynamic-check/src/ast/expressions/expression.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ExpressionError, ExpressionValue, FunctionBody, ResolvedNode, VariableTable}; +use crate::{ExpressionError, ExpressionValue, Frame, ResolvedNode, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; @@ -54,13 +54,13 @@ impl Expression { /// user-defined variables. /// pub fn new( - function_body: &FunctionBody, + frame: &Frame, type_: &Type, unresolved_expression: UnresolvedExpression, ) -> Result { match unresolved_expression { // Identifier - UnresolvedExpression::Identifier(identifier) => Self::variable(function_body, identifier), + UnresolvedExpression::Identifier(identifier) => Self::variable(frame, identifier), // Values UnresolvedExpression::Address(string, span) => Ok(Self::address(type_, string, span)), @@ -72,14 +72,14 @@ impl Expression { } UnresolvedExpression::Implicit(string, span) => Self::implicit(type_, string, span), - // // Arithmetic Operations - // UnresolvedExpression::Add(lhs, rhs, span) => Self::add(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Div(lhs, rhs, span) => Self::div(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Negate(expression, span) => Self::negate(variable_table, *expression, span), - // + // Arithmetic Operations + UnresolvedExpression::Add(lhs, rhs, span) => Self::add(variable_table, type_, *lhs, *rhs, span), + UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(variable_table, type_, *lhs, *rhs, span), + UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(variable_table, type_, *lhs, *rhs, span), + UnresolvedExpression::Div(lhs, rhs, span) => Self::div(variable_table, type_, *lhs, *rhs, span), + UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(variable_table, type_, *lhs, *rhs, span), + UnresolvedExpression::Negate(expression, span) => Self::negate(variable_table, type_, *expression, span), + // // Logical Operations // UnresolvedExpression::And(lhs, rhs, span) => Self::and(variable_table, *lhs, *rhs, span), // UnresolvedExpression::Or(lhs, rhs, span) => Self::or(variable_table, *lhs, *rhs, span), diff --git a/dynamic-check/src/ast/expressions/identifier/identifier.rs b/dynamic-check/src/ast/expressions/identifier/identifier.rs index 2a9bfa09e6..4e061d64d4 100644 --- a/dynamic-check/src/ast/expressions/identifier/identifier.rs +++ b/dynamic-check/src/ast/expressions/identifier/identifier.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue, FunctionBody, VariableTable}; +use crate::{Expression, ExpressionError, ExpressionValue, Frame, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::Identifier; @@ -24,7 +24,7 @@ impl Expression { /// /// Performs a lookup in the given function body's variable table to find the variable's type. /// - pub(crate) fn variable(function_body: &FunctionBody, variable: Identifier) -> Result { + pub(crate) fn variable(function_body: &Frame, variable: Identifier) -> Result { // Lookup the type of the given variable. let type_ = function_body.variable_table.get(&variable.name, &variable.span)?; diff --git a/dynamic-check/src/ast/expressions/tuple/tuple.rs b/dynamic-check/src/ast/expressions/tuple/tuple.rs index d3bc3d6ed5..028dba221c 100644 --- a/dynamic-check/src/ast/expressions/tuple/tuple.rs +++ b/dynamic-check/src/ast/expressions/tuple/tuple.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue, FunctionBody, ResolvedNode, VariableTable}; +use crate::{Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; @@ -25,7 +25,7 @@ impl Expression { /// Performs a lookup in the given variable table if an `UnresolvedExpression` contains user-defined types. /// pub(crate) fn tuple( - function_body: &FunctionBody, + function_body: &Frame, type_: &Type, unresolved_expressions: Vec, span: Span, diff --git a/dynamic-check/src/ast/functions/function.rs b/dynamic-check/src/ast/functions/function.rs index 72b0c7cb00..5cb1d003aa 100644 --- a/dynamic-check/src/ast/functions/function.rs +++ b/dynamic-check/src/ast/functions/function.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{FunctionBody, FunctionError, ResolvedNode, Statement, StatementError, VariableTable}; +use crate::{Frame, FunctionError, ResolvedNode, Statement, StatementError, VariableTable}; use leo_static_check::{FunctionType, SymbolTable, TypeError}; use leo_typed::{Function as UnresolvedFunction, Statement as UnresolvedStatement}; @@ -37,7 +37,7 @@ impl Function { /// Performs a lookup in the given function body's variable table if the statement contains /// user-defined types.. /// - pub fn new(function_body: FunctionBody) -> Result { + pub fn new(function_body: Frame) -> Result { // Create a new `Statement` from every given `UnresolvedStatement`. let statements = function_body .statements diff --git a/dynamic-check/src/ast/statements/assign/assign.rs b/dynamic-check/src/ast/statements/assign/assign.rs index 7fa441e9dc..799e6a0a9a 100644 --- a/dynamic-check/src/ast/statements/assign/assign.rs +++ b/dynamic-check/src/ast/statements/assign/assign.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ResolvedNode, Statement, StatementError}; +use crate::{Expression, Frame, ResolvedNode, Statement, StatementError, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Assignee, AssigneeAccess, Expression as UnresolvedExpression, Span}; @@ -34,16 +34,14 @@ impl Statement { /// Resolves an assign statement /// pub(crate) fn assign( - table: &mut SymbolTable, + function_body: &Frame, assignee: Assignee, expression: UnresolvedExpression, span: Span, ) -> Result { // Lookup variable in symbol table let key = &assignee.identifier.name; - let variable = table - .get_variable(key) - .ok_or(StatementError::undefined_variable(key.clone(), span.clone()))?; + let variable = function_body.variable_table.get(key, &span)?; // Throw an error if this variable is not mutable if !variable.is_mutable() { @@ -51,10 +49,15 @@ impl Statement { } // Get inner assignee type - let type_ = get_inner_assignee_type(table, variable.type_.clone(), assignee.accesses.clone(), span.clone())?; + let type_ = get_inner_assignee_type( + variable_table, + variable.type_.clone(), + assignee.accesses.clone(), + span.clone(), + )?; // Resolve the expression based on the assignee type - let expression_resolved = Expression::resolve(table, (Some(type_), expression))?; + let expression_resolved = Expression::new(variable_table, (Some(type_), expression))?; Ok(Statement::Assign(Assign { assignee, diff --git a/dynamic-check/src/ast/statements/conditional/conditional.rs b/dynamic-check/src/ast/statements/conditional/conditional.rs index a603bc69f8..9e5ae0c4ce 100644 --- a/dynamic-check/src/ast/statements/conditional/conditional.rs +++ b/dynamic-check/src/ast/statements/conditional/conditional.rs @@ -118,12 +118,12 @@ fn resolve_statements( impl Statement { /// Resolves a conditional statement. pub(crate) fn conditional( - table: &mut SymbolTable, + function_body: &function_body, return_type: FunctionOutputType, conditional: UnresolvedConditional, span: Span, ) -> Result { - let conditional = Conditional::from_unresolved(table, return_type, conditional, span)?; + let conditional = Conditional::from_unresolved(function_body, return_type, conditional, span)?; Ok(Statement::Conditional(conditional)) } diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs index d19a4c10a2..bba6190e0e 100644 --- a/dynamic-check/src/ast/statements/definition/definition.rs +++ b/dynamic-check/src/ast/statements/definition/definition.rs @@ -18,7 +18,7 @@ use crate::{ check_tuple_type, Expression, ExpressionValue, - FunctionBody, + Frame, ResolvedNode, Statement, StatementError, @@ -55,7 +55,7 @@ impl DefinitionVariables { /// Performs a lookup in the given variable table if the `UnresolvedExpression` contains user-defined variables. /// fn single( - function_body: &FunctionBody, + function_body: &Frame, variable_name: VariableName, unresolved_expression: UnresolvedExpression, span: &Span, @@ -75,7 +75,7 @@ impl DefinitionVariables { /// Performs a lookup in the given variable table if an `UnresolvedExpression` contains user-defined variables. /// fn tuple( - function_body: &FunctionBody, + function_body: &Frame, variable: VariableName, unresolved_expressions: Vec, span: &Span, @@ -91,7 +91,7 @@ impl DefinitionVariables { /// Resolves multiple variables for multiple expressions fn multiple_variable( - function_body: &FunctionBody, + function_body: &Frame, variables: Variables, unresolved_expressions: Vec, span: &Span, @@ -129,7 +129,7 @@ impl DefinitionVariables { /// Resolves multiple variables for an expression that returns a tuple fn multiple_variable_tuple( - function_body: &FunctionBody, + function_body: &Frame, variables: Variables, unresolved_expression: UnresolvedExpression, span: &Span, @@ -193,7 +193,7 @@ impl Statement { /// Performs a lookup in the given variable table if the statement contains user-defined variables. /// pub(crate) fn definition( - function_body: &FunctionBody, + function_body: &Frame, declare: Declare, variables: Variables, unresolved_expressions: Vec, diff --git a/dynamic-check/src/ast/statements/return_/return_.rs b/dynamic-check/src/ast/statements/return_/return_.rs index 7c3eb9f42f..2ef06d26c1 100644 --- a/dynamic-check/src/ast/statements/return_/return_.rs +++ b/dynamic-check/src/ast/statements/return_/return_.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, FunctionBody, ResolvedNode, Statement, StatementError, VariableTable}; +use crate::{Expression, Frame, ResolvedNode, Statement, StatementError, VariableTable}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; @@ -25,7 +25,7 @@ impl Statement { /// Performs a lookup in the given variable table if the statement contains user-defined types. /// pub(crate) fn resolve_return( - function_body: &FunctionBody, + function_body: &Frame, unresolved_expression: UnresolvedExpression, span: Span, ) -> Result { diff --git a/dynamic-check/src/ast/statements/statement.rs b/dynamic-check/src/ast/statements/statement.rs index 1c74043ffb..946761d056 100644 --- a/dynamic-check/src/ast/statements/statement.rs +++ b/dynamic-check/src/ast/statements/statement.rs @@ -18,7 +18,7 @@ use crate::{ Conditional, Definition, Expression, - FunctionBody, + Frame, Iteration, ResolvedNode, StatementError, @@ -48,29 +48,23 @@ impl Statement { /// Performs a lookup in the given function body's variable table if the statement contains /// user-defined types. /// - pub fn new( - function_body: &FunctionBody, - unresolved_statement: UnresolvedStatement, - ) -> Result { + pub fn new(frame: &Frame, unresolved_statement: UnresolvedStatement) -> Result { match unresolved_statement { - UnresolvedStatement::Return(expression, span) => Self::resolve_return(function_body, expression, span), + UnresolvedStatement::Return(expression, span) => Self::resolve_return(frame, expression, span), UnresolvedStatement::Definition(declare, variables, expressions, span) => { - Self::definition(function_body, declare, variables, expressions, span) - } - UnresolvedStatement::Assign(assignee, expression, span) => { - Self::assign(variable_table, assignee, expression, span) + Self::definition(frame, declare, variables, expressions, span) } + UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(frame, assignee, expression, span), UnresolvedStatement::Conditional(conditional, span) => { - Self::conditional(variable_table, return_type, conditional, span) + Self::conditional(frame, return_type, conditional, span) } UnresolvedStatement::Iteration(index, start, stop, statements, span) => { - Self::iteration(variable_table, return_type, index, start, stop, statements, span) + Self::iteration(frame, return_type, index, start, stop, statements, span) } UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)), - UnresolvedStatement::Expression(expression, span) => Ok(Statement::Expression( - Expression::resolve(variable_table, expression)?, - span, - )), + UnresolvedStatement::Expression(expression, span) => { + Ok(Statement::Expression(Expression::new(frame, expression)?, span)) + } } } } diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 9bb47e63cc..9687dba02f 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -31,7 +31,7 @@ use std::collections::HashMap; /// Performs a dynamic type inference check over a program. pub struct DynamicCheck { table: SymbolTable, - functions: Vec, + functions: Vec, } impl DynamicCheck { @@ -75,7 +75,7 @@ impl DynamicCheck { /// Collects a vector of `TypeAssertion` predicates from a function. /// fn parse_function(&mut self, function: &UnresolvedFunction) { - let function_body = FunctionBody::new(function.clone(), self.table.clone()); + let function_body = Frame::new(function.clone(), self.table.clone()); self.functions.push(function_body); } @@ -98,7 +98,7 @@ impl DynamicCheck { /// A vector of `TypeAssertion` predicates created from a function body. #[derive(Clone)] -pub struct FunctionBody { +pub struct Frame { pub function_type: FunctionType, pub statements: Vec, pub user_defined_types: SymbolTable, @@ -106,7 +106,7 @@ pub struct FunctionBody { pub variable_table: VariableTable, } -impl FunctionBody { +impl Frame { /// /// Collects a vector of `TypeAssertion` predicates from a function. /// From 8de889ada5505a6590e7aa2daec95007a03eee22 Mon Sep 17 00:00:00 2001 From: collin Date: Sat, 17 Oct 2020 18:48:20 -0700 Subject: [PATCH 033/139] impl expression operations logical and relational --- .../src/ast/expressions/arithmetic/negate.rs | 4 ++- .../src/ast/expressions/expression.rs | 36 +++++++++---------- .../src/ast/expressions/logical/and.rs | 18 +++++----- .../src/ast/expressions/logical/not.rs | 21 ++++------- .../src/ast/expressions/logical/or.rs | 20 +++++------ .../src/ast/expressions/relational/eq.rs | 19 +++++----- .../src/ast/expressions/relational/ge.rs | 19 +++++----- .../src/ast/expressions/relational/gt.rs | 21 ++++++----- .../src/ast/expressions/relational/le.rs | 21 ++++++----- .../src/ast/expressions/relational/lt.rs | 21 ++++++----- 10 files changed, 93 insertions(+), 107 deletions(-) diff --git a/dynamic-check/src/ast/expressions/arithmetic/negate.rs b/dynamic-check/src/ast/expressions/arithmetic/negate.rs index 9cf00663c1..af4b77ceaa 100644 --- a/dynamic-check/src/ast/expressions/arithmetic/negate.rs +++ b/dynamic-check/src/ast/expressions/arithmetic/negate.rs @@ -19,7 +19,9 @@ use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of negating `-expression` + /// + /// Returns a new `Expression` negating the `UnresolvedExpression`. + /// pub(crate) fn negate( frame: &Frame, type_: &Type, diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs index 14e626dd56..9bc5bf8055 100644 --- a/dynamic-check/src/ast/expressions/expression.rs +++ b/dynamic-check/src/ast/expressions/expression.rs @@ -73,25 +73,25 @@ impl Expression { UnresolvedExpression::Implicit(string, span) => Self::implicit(type_, string, span), // Arithmetic Operations - UnresolvedExpression::Add(lhs, rhs, span) => Self::add(variable_table, type_, *lhs, *rhs, span), - UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(variable_table, type_, *lhs, *rhs, span), - UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(variable_table, type_, *lhs, *rhs, span), - UnresolvedExpression::Div(lhs, rhs, span) => Self::div(variable_table, type_, *lhs, *rhs, span), - UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(variable_table, type_, *lhs, *rhs, span), - UnresolvedExpression::Negate(expression, span) => Self::negate(variable_table, type_, *expression, span), + UnresolvedExpression::Add(lhs, rhs, span) => Self::add(frame, type_, *lhs, *rhs, span), + UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(frame, type_, *lhs, *rhs, span), + UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(frame, type_, *lhs, *rhs, span), + UnresolvedExpression::Div(lhs, rhs, span) => Self::div(frame, type_, *lhs, *rhs, span), + UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(frame, type_, *lhs, *rhs, span), + UnresolvedExpression::Negate(expression, span) => Self::negate(frame, type_, *expression, span), + + // Logical Operations + UnresolvedExpression::And(lhs, rhs, span) => Self::and(frame, *lhs, *rhs, span), + UnresolvedExpression::Or(lhs, rhs, span) => Self::or(frame, *lhs, *rhs, span), + UnresolvedExpression::Not(expression, span) => Self::not(frame, *expression, span), + + // Relational Operations + UnresolvedExpression::Eq(lhs, rhs, span) => Self::eq(frame, *lhs, *rhs, span), + UnresolvedExpression::Ge(lhs, rhs, span) => Self::ge(frame, *lhs, *rhs, span), + UnresolvedExpression::Gt(lhs, rhs, span) => Self::gt(frame, *lhs, *rhs, span), + UnresolvedExpression::Le(lhs, rhs, span) => Self::le(frame, *lhs, *rhs, span), + UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(frame, *lhs, *rhs, span), - // // Logical Operations - // UnresolvedExpression::And(lhs, rhs, span) => Self::and(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Or(lhs, rhs, span) => Self::or(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Not(expression, span) => Self::not(variable_table, *expression, span), - // - // // Relational Operations - // UnresolvedExpression::Eq(lhs, rhs, span) => Self::eq(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Ge(lhs, rhs, span) => Self::ge(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Gt(lhs, rhs, span) => Self::gt(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Le(lhs, rhs, span) => Self::le(variable_table, *lhs, *rhs, span), - // UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(variable_table, *lhs, *rhs, span), - // // // Conditionals // UnresolvedExpression::IfElse(cond, first, second, span) => { // Self::conditional(variable_table, *cond, *first, *second, span) diff --git a/dynamic-check/src/ast/expressions/logical/and.rs b/dynamic-check/src/ast/expressions/logical/and.rs index 8b0ed9fcc3..148868e695 100644 --- a/dynamic-check/src/ast/expressions/logical/and.rs +++ b/dynamic-check/src/ast/expressions/logical/and.rs @@ -13,27 +13,25 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; + +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of `lhs && rhs` + /// + /// Returns a new `Expression` applying logical AND `lhs && rhs`. + /// pub(crate) fn and( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { let type_ = Type::Boolean; - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - // Resolve lhs and rhs expressions to boolean type - let boolean_type = Some(type_.clone()); - let (lhs_resolved, rhs_resolved) = Self::binary(table, boolean_type, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; Ok(Expression { type_, diff --git a/dynamic-check/src/ast/expressions/logical/not.rs b/dynamic-check/src/ast/expressions/logical/not.rs index 9d56fc616a..44eae752e0 100644 --- a/dynamic-check/src/ast/expressions/logical/not.rs +++ b/dynamic-check/src/ast/expressions/logical/not.rs @@ -13,26 +13,19 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; +use crate::{Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of `!expression` - pub(crate) fn not( - table: &mut SymbolTable, - expected_type: Option, - expression: UnresolvedExpression, - span: Span, - ) -> Result { + /// + /// Returns a new `Expression` applying a logical NOT `!UnresolvedExpression`. + /// + pub(crate) fn not(table: &Frame, expression: UnresolvedExpression, span: Span) -> Result { let type_ = Type::Boolean; - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - // Resolve lhs and rhs expressions to boolean type - let boolean_type = Some(type_.clone()); - let expression_resolved = Self::resolve(table, (boolean_type, expression))?; + let expression_resolved = Self::new(table, &type_, expression)?; Ok(Expression { type_, diff --git a/dynamic-check/src/ast/expressions/logical/or.rs b/dynamic-check/src/ast/expressions/logical/or.rs index 6e35ab6bf2..a1f218b68c 100644 --- a/dynamic-check/src/ast/expressions/logical/or.rs +++ b/dynamic-check/src/ast/expressions/logical/or.rs @@ -13,31 +13,29 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; + +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of `lhs || rhs` + /// + /// Returns a new `Expression` applying logical OR `lhs || rhs`. + /// pub(crate) fn or( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { let type_ = Type::Boolean; - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - // Resolve lhs and rhs expressions to boolean type - let boolean_type = Some(type_.clone()); - let (lhs_resolved, rhs_resolved) = Self::binary(table, boolean_type, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; Ok(Expression { type_, - value: ExpressionValue::Or(Box::new(lhs_resolved), Box::new(rhs_resolved), span), + value: ExpressionValue::And(Box::new(lhs_resolved), Box::new(rhs_resolved), span), }) } } diff --git a/dynamic-check/src/ast/expressions/relational/eq.rs b/dynamic-check/src/ast/expressions/relational/eq.rs index fbbbd84d3f..47ba5e66bc 100644 --- a/dynamic-check/src/ast/expressions/relational/eq.rs +++ b/dynamic-check/src/ast/expressions/relational/eq.rs @@ -13,27 +13,26 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; + +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of `lhs == rhs` + /// + /// Returns a new `Expression` evaluating `lhs == rhs`. + /// pub(crate) fn eq( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { - // This expression results in a boolean type + // This expression returns a boolean type. let type_ = Type::Boolean; - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(table, None, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; Ok(Expression { type_, diff --git a/dynamic-check/src/ast/expressions/relational/ge.rs b/dynamic-check/src/ast/expressions/relational/ge.rs index 4ea8f90591..2884b6fbc2 100644 --- a/dynamic-check/src/ast/expressions/relational/ge.rs +++ b/dynamic-check/src/ast/expressions/relational/ge.rs @@ -13,34 +13,33 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; + +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; use leo_static_check::{SymbolTable, Type}; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of `lhs >= rhs` + /// + /// Returns a new `Expression` evaluating `lhs >= rhs`. + /// pub(crate) fn ge( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { - // This expression results in a boolean type + // This expression returns a boolean type. let type_ = Type::Boolean; - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(table, None, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; // Check that expressions are integer type lhs_resolved.check_type_integer()?; rhs_resolved.check_type_integer()?; Ok(Expression { - // This expression results in a boolean type + // This expression returns a boolean type. type_, value: ExpressionValue::Ge(Box::new(lhs_resolved), Box::new(rhs_resolved), span), }) diff --git a/dynamic-check/src/ast/expressions/relational/gt.rs b/dynamic-check/src/ast/expressions/relational/gt.rs index 6388f97333..d2b34329a7 100644 --- a/dynamic-check/src/ast/expressions/relational/gt.rs +++ b/dynamic-check/src/ast/expressions/relational/gt.rs @@ -13,34 +13,33 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; + +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of `lhs > rhs` + /// + /// Returns a new `Expression` evaluating `lhs > rhs`. + /// pub(crate) fn gt( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { - // This expression results in a boolean type + // This expression returns a boolean type. let type_ = Type::Boolean; - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(table, None, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; // Check that expressions are integer type lhs_resolved.check_type_integer()?; rhs_resolved.check_type_integer()?; Ok(Expression { - // This expression results in a boolean type + // This expression returns a boolean type. type_: Type::Boolean, value: ExpressionValue::Gt(Box::new(lhs_resolved), Box::new(rhs_resolved), span), }) diff --git a/dynamic-check/src/ast/expressions/relational/le.rs b/dynamic-check/src/ast/expressions/relational/le.rs index 0a1a02b015..ee588fbe6e 100644 --- a/dynamic-check/src/ast/expressions/relational/le.rs +++ b/dynamic-check/src/ast/expressions/relational/le.rs @@ -13,34 +13,33 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; + +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of `lhs <= rhs` + /// + /// Returns a new `Expression` evaluating `lhs <= rhs`. + /// pub(crate) fn le( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { - // This expression results in a boolean type + // This expression returns a boolean type. let type_ = Type::Boolean; - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(table, None, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; // Check that expressions are integer type lhs_resolved.check_type_integer()?; rhs_resolved.check_type_integer()?; Ok(Expression { - // This expression results in a boolean type + // This expression returns a boolean type. type_: Type::Boolean, value: ExpressionValue::Le(Box::new(lhs_resolved), Box::new(rhs_resolved), span), }) diff --git a/dynamic-check/src/ast/expressions/relational/lt.rs b/dynamic-check/src/ast/expressions/relational/lt.rs index 4f874b5e2d..09859be888 100644 --- a/dynamic-check/src/ast/expressions/relational/lt.rs +++ b/dynamic-check/src/ast/expressions/relational/lt.rs @@ -13,34 +13,33 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::{SymbolTable, Type}; + +use crate::{Expression, ExpressionError, ExpressionValue, Frame}; +use leo_static_check::Type; use leo_typed::{Expression as UnresolvedExpression, Span}; impl Expression { - /// Resolve the type of `lhs < rhs` + /// + /// Returns a new `Expression` evaluating `lhs < rhs`. + /// pub(crate) fn lt( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, lhs: UnresolvedExpression, rhs: UnresolvedExpression, span: Span, ) -> Result { - // This expression results in a boolean type + // This expression returns a boolean type. let type_ = Type::Boolean; - // Check the expected type if given - Type::check_type(&expected_type, &type_, span.clone())?; - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(table, None, lhs, rhs, span.clone())?; + let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; // Check that expressions are integer type lhs_resolved.check_type_integer()?; rhs_resolved.check_type_integer()?; Ok(Expression { - // This expression results in a boolean type + // This expression returns a boolean type. type_: Type::Boolean, value: ExpressionValue::Lt(Box::new(lhs_resolved), Box::new(rhs_resolved), span), }) From e50029c4662f8e365fdce3fa5ba8297a52b80d56 Mon Sep 17 00:00:00 2001 From: collin Date: Sun, 18 Oct 2020 23:53:37 -0700 Subject: [PATCH 034/139] fix errors, focus on dynamic checks --- .../src/ast/expressions/array/array.rs | 53 +++--- .../src/ast/expressions/array/array_access.rs | 60 +++--- .../expressions/array/range_or_expression.rs | 48 ++--- .../expressions/array/spread_or_expression.rs | 30 +-- .../src/ast/expressions/circuit/circuit.rs | 127 ++++++------- .../ast/expressions/circuit/circuit_access.rs | 128 ++++++------- .../circuit/circuit_static_access.rs | 102 +++++----- .../expressions/conditional/conditional.rs | 70 +++---- .../src/ast/expressions/expression.rs | 14 +- .../ast/expressions/function/function_call.rs | 112 +++++------ dynamic-check/src/ast/functions/function.rs | 1 + .../src/ast/statements/assign/assign.rs | 137 +++++++------- .../ast/statements/conditional/conditional.rs | 176 +++++++++--------- .../ast/statements/definition/definition.rs | 89 +++++---- .../src/ast/statements/iteration/iteration.rs | 88 ++++----- .../src/ast/statements/return_/return_.rs | 5 +- dynamic-check/src/ast/statements/statement.rs | 82 ++++---- dynamic-check/src/dynamic_check.rs | 20 +- dynamic-check/src/errors/dynamic_check.rs | 35 ++-- dynamic-check/src/errors/expression.rs | 1 + dynamic-check/src/errors/frame.rs | 44 +++++ dynamic-check/src/errors/mod.rs | 39 ++-- dynamic-check/src/lib.rs | 4 +- 23 files changed, 761 insertions(+), 704 deletions(-) create mode 100644 dynamic-check/src/errors/frame.rs diff --git a/dynamic-check/src/ast/expressions/array/array.rs b/dynamic-check/src/ast/expressions/array/array.rs index 792fa25eb4..6b8ae862cf 100644 --- a/dynamic-check/src/ast/expressions/array/array.rs +++ b/dynamic-check/src/ast/expressions/array/array.rs @@ -14,35 +14,42 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ast::expressions::array::SpreadOrExpression, Expression, ExpressionError, ExpressionValue, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; +use crate::{ + ast::expressions::array::SpreadOrExpression, Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode, +}; +use leo_static_check::Type; use leo_typed::{Span, SpreadOrExpression as UnresolvedSpreadOrExpression}; impl Expression { - /// Resolves an array expression + /// + /// Returns a new array `Expression` from a given vector of `UnresolvedSpreadOrExpression`s. + /// + /// Performs a lookup in the given function body's variable table if the expression contains + /// user-defined variables. + /// pub(crate) fn array( - table: &mut SymbolTable, - expected_type: Option, + frame: &Frame, + type_: &Type, expressions: Vec>, span: Span, ) -> Result { - // Expressions should evaluate to array type or array element type - let expected_element_type = if let Some(type_) = expected_type { - let (element_type, dimensions) = type_.get_type_array(span.clone())?; - - if dimensions[0] != expressions.len() { - //throw array dimension mismatch error - return Err(ExpressionError::invalid_length_array( - dimensions[0], - expressions.len(), - span.clone(), - )); - } - - Some(element_type.clone()) - } else { - None - }; + // // Expressions should evaluate to array type or array element type + // let expected_element_type = if let Some(type_) = type_ { + // let (element_type, dimensions) = type_.get_type_array(span.clone())?; + // + // if dimensions[0] != expressions.len() { + // //throw array dimension mismatch error + // return Err(ExpressionError::invalid_length_array( + // dimensions[0], + // expressions.len(), + // span.clone(), + // )); + // } + // + // Some(element_type.clone()) + // } else { + // None + // }; // Store actual array element type let mut actual_element_type = None; @@ -50,7 +57,7 @@ impl Expression { // Resolve all array elements for expression in expressions { - let expression_resolved = SpreadOrExpression::resolve(table, (expected_element_type.clone(), *expression))?; + let expression_resolved = SpreadOrExpression::new(frame, type_, *expression)?; let expression_type = expression_resolved.type_().clone(); array.push(Box::new(expression_resolved)); diff --git a/dynamic-check/src/ast/expressions/array/array_access.rs b/dynamic-check/src/ast/expressions/array/array_access.rs index dfde2506bc..e669d402b2 100644 --- a/dynamic-check/src/ast/expressions/array/array_access.rs +++ b/dynamic-check/src/ast/expressions/array/array_access.rs @@ -13,30 +13,36 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . - -use crate::{ast::expressions::array::RangeOrExpression, Expression, ExpressionError, ExpressionValue, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, RangeOrExpression as UnresolvedRangeOrExpression, Span}; - -impl Expression { - /// Resolves an array access expression - pub(crate) fn array_access( - table: &mut SymbolTable, - expected_type: Option, - array: Box, - range: Box, - span: Span, - ) -> Result { - // Lookup the array in the symbol table. - // We do not know the length from this context so `expected_type = None`. - let array_resolved = Expression::resolve(table, (None, *array))?; - - // Resolve the range or expression - let range_resolved = RangeOrExpression::resolve(table, (expected_type, *range))?; - - Ok(Expression { - type_: range_resolved.type_().clone(), - value: ExpressionValue::ArrayAccess(Box::new(array_resolved), Box::new(range_resolved), span), - }) - } -} +// +// use crate::{ +// ast::expressions::array::RangeOrExpression, Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode, +// }; +// use leo_static_check::Type; +// use leo_typed::{Expression as UnresolvedExpression, RangeOrExpression as UnresolvedRangeOrExpression, Span}; +// +// impl Expression { +// /// +// /// Returns a new array `Expression` from a given array access. +// /// +// /// Performs a lookup in the given function body's variable table if the expression contains +// /// user-defined variables. +// /// +// pub(crate) fn array_access( +// frame: &Frame, +// type_: &Type, +// array: Box, +// range: Box, +// span: Span, +// ) -> Result { +// // Lookup the array in the variable table. +// let array_resolved = Expression::new(frame, type_, *array)?; +// +// // Resolve the range or expression +// let range_resolved = RangeOrExpression::new(frame, type_, *range)?; +// +// Ok(Expression { +// type_: range_resolved.type_().clone(), +// value: ExpressionValue::ArrayAccess(Box::new(array_resolved), Box::new(range_resolved), span), +// }) +// } +// } diff --git a/dynamic-check/src/ast/expressions/array/range_or_expression.rs b/dynamic-check/src/ast/expressions/array/range_or_expression.rs index 788cc56e2a..d3edc64210 100644 --- a/dynamic-check/src/ast/expressions/array/range_or_expression.rs +++ b/dynamic-check/src/ast/expressions/array/range_or_expression.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; +use crate::{Expression, ExpressionError, Frame, ResolvedNode}; +use leo_static_check::Type; use leo_typed::RangeOrExpression as UnresolvedRangeOrExpression; use serde::{Deserialize, Serialize}; @@ -27,33 +27,35 @@ pub enum RangeOrExpression { } impl RangeOrExpression { - /// If this is a range, return an array type. - /// If this is an expression, return a data type. - pub(crate) fn type_(&self) -> &Type { - match self { - RangeOrExpression::Range(expresion, _expression) => expresion.type_(), - RangeOrExpression::Expression(expression) => expression.type_(), - } - } -} + // /// If this is a range, return an array type. + // /// If this is an expression, return a data type. + // pub(crate) fn type_(&self) -> &Type { + // match self { + // RangeOrExpression::Range(expresion, _expression) => expresion.type_(), + // RangeOrExpression::Expression(expression) => expression.type_(), + // } + // } -impl ResolvedNode for RangeOrExpression { - type Error = ExpressionError; - type UnresolvedNode = (Option, UnresolvedRangeOrExpression); - - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let expected_type = unresolved.0; - let r_or_e = unresolved.1; - - Ok(match r_or_e { + /// + /// Returns a new `RangeOrExpression` from a given `UnresolvedRangeOrExpression`. + /// + /// Performs a lookup in the given function body's variable table if the expression contains + /// user-defined variables. + /// + pub fn new( + frame: &Frame, + type_: &Type, + unresolved_expression: UnresolvedRangeOrExpression, + ) -> Result { + Ok(match unresolved_expression { UnresolvedRangeOrExpression::Range(from, to) => { - let resolved_from = Expression::resolve(table, (expected_type.clone(), from.unwrap())).unwrap(); - let resolved_to = Expression::resolve(table, (expected_type, to.unwrap())).unwrap(); + let resolved_from = Expression::new(frame, type_, from.unwrap())?; + let resolved_to = Expression::new(frame, type_, to.unwrap())?; // TODO: add check for range type and array type RangeOrExpression::Range(resolved_from, resolved_to) } UnresolvedRangeOrExpression::Expression(expression) => { - let expression_resolved = Expression::resolve(table, (expected_type, expression)).unwrap(); + let expression_resolved = Expression::new(frame, type_, expression)?; // TODO: add check for array type RangeOrExpression::Expression(expression_resolved) } diff --git a/dynamic-check/src/ast/expressions/array/spread_or_expression.rs b/dynamic-check/src/ast/expressions/array/spread_or_expression.rs index 80fd4e6ea6..b5588d603a 100644 --- a/dynamic-check/src/ast/expressions/array/spread_or_expression.rs +++ b/dynamic-check/src/ast/expressions/array/spread_or_expression.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ExpressionError, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; +use crate::{Expression, ExpressionError, Frame}; +use leo_static_check::Type; use leo_typed::SpreadOrExpression as UnresolvedSpreadOrExpression; use serde::{Deserialize, Serialize}; @@ -33,24 +33,26 @@ impl SpreadOrExpression { SpreadOrExpression::Expression(expression) => expression.type_(), } } -} -impl ResolvedNode for SpreadOrExpression { - type Error = ExpressionError; - type UnresolvedNode = (Option, UnresolvedSpreadOrExpression); - - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let expected_type = unresolved.0; - let s_or_e = unresolved.1; - - Ok(match s_or_e { + /// + /// Returns a new `SpreadOrExpression` from a given `UnresolvedSpreadOrExpression`. + /// + /// Performs a lookup in the given function body's variable table if the expression contains + /// user-defined variables. + /// + pub fn new( + frame: &Frame, + type_: &Type, + unresolved_expression: UnresolvedSpreadOrExpression, + ) -> Result { + Ok(match unresolved_expression { UnresolvedSpreadOrExpression::Spread(spread) => { - let spread_resolved = Expression::resolve(table, (expected_type, spread)).unwrap(); + let spread_resolved = Expression::new(frame, type_, spread)?; // TODO: add check for array type or array element type SpreadOrExpression::Spread(spread_resolved) } UnresolvedSpreadOrExpression::Expression(expression) => { - let expression_resolved = Expression::resolve(table, (expected_type, expression)).unwrap(); + let expression_resolved = Expression::new(frame, type_, expression)?; // TODO: add check for array type or array element type SpreadOrExpression::Expression(expression_resolved) } diff --git a/dynamic-check/src/ast/expressions/circuit/circuit.rs b/dynamic-check/src/ast/expressions/circuit/circuit.rs index 78e544a167..96a319002c 100644 --- a/dynamic-check/src/ast/expressions/circuit/circuit.rs +++ b/dynamic-check/src/ast/expressions/circuit/circuit.rs @@ -13,66 +13,67 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{CircuitVariableDefinition, Expression, ExpressionError, ExpressionValue, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{CircuitVariableDefinition as UnresolvedCircuitVariableDefinition, Identifier, Span}; - -impl Expression { - /// - /// Resolves an inline circuit expression. - /// - pub(crate) fn circuit( - table: &mut SymbolTable, - expected_type: Option, - identifier: Identifier, - variables: Vec, - span: Span, - ) -> Result { - // Check expected type - let type_ = Type::Circuit(identifier.clone()); - Type::check_type(&expected_type, &type_, span.clone())?; - - // Lookup circuit in symbol table - let circuit = table - .get_circuit(&identifier.name) - .ok_or(ExpressionError::undefined_circuit(identifier.clone()))?; - - // Check the number of variables given - let expected_variables = circuit.variables.clone(); - - if variables.len() != expected_variables.len() { - return Err(ExpressionError::invalid_length_circuit_members( - expected_variables.len(), - variables.len(), - span, - )); - } - - // Check the name and type for each circuit variable - let mut variables_resolved = vec![]; - - for variable in variables { - // Find variable by name - let matched_variable = expected_variables - .iter() - .find(|expected| expected.identifier.eq(&variable.identifier)); - - let variable_type = match matched_variable { - Some(variable_type) => variable_type, - None => return Err(ExpressionError::undefined_circuit_variable(variable.identifier)), - }; - - // Resolve the variable expression using the expected variable type - let expected_variable_type = Some(variable_type.type_.clone()); - - let variable_resolved = CircuitVariableDefinition::resolve(table, (expected_variable_type, variable))?; - - variables_resolved.push(variable_resolved); - } - - Ok(Expression { - type_, - value: ExpressionValue::Circuit(identifier, variables_resolved, span), - }) - } -} +// +// use crate::{CircuitVariableDefinition, Expression, ExpressionError, ExpressionValue, ResolvedNode}; +// use leo_static_check::{SymbolTable, Type}; +// use leo_typed::{CircuitVariableDefinition as UnresolvedCircuitVariableDefinition, Identifier, Span}; +// +// impl Expression { +// /// +// /// Resolves an inline circuit expression. +// /// +// pub(crate) fn circuit( +// table: &mut SymbolTable, +// expected_type: Option, +// identifier: Identifier, +// variables: Vec, +// span: Span, +// ) -> Result { +// // Check expected type +// let type_ = Type::Circuit(identifier.clone()); +// Type::check_type(&expected_type, &type_, span.clone())?; +// +// // Lookup circuit in symbol table +// let circuit = table +// .get_circuit(&identifier.name) +// .ok_or(ExpressionError::undefined_circuit(identifier.clone()))?; +// +// // Check the number of variables given +// let expected_variables = circuit.variables.clone(); +// +// if variables.len() != expected_variables.len() { +// return Err(ExpressionError::invalid_length_circuit_members( +// expected_variables.len(), +// variables.len(), +// span, +// )); +// } +// +// // Check the name and type for each circuit variable +// let mut variables_resolved = vec![]; +// +// for variable in variables { +// // Find variable by name +// let matched_variable = expected_variables +// .iter() +// .find(|expected| expected.identifier.eq(&variable.identifier)); +// +// let variable_type = match matched_variable { +// Some(variable_type) => variable_type, +// None => return Err(ExpressionError::undefined_circuit_variable(variable.identifier)), +// }; +// +// // Resolve the variable expression using the expected variable type +// let expected_variable_type = Some(variable_type.type_.clone()); +// +// let variable_resolved = CircuitVariableDefinition::resolve(table, (expected_variable_type, variable))?; +// +// variables_resolved.push(variable_resolved); +// } +// +// Ok(Expression { +// type_, +// value: ExpressionValue::Circuit(identifier, variables_resolved, span), +// }) +// } +// } diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_access.rs b/dynamic-check/src/ast/expressions/circuit/circuit_access.rs index e7e73920be..0733755e8f 100644 --- a/dynamic-check/src/ast/expressions/circuit/circuit_access.rs +++ b/dynamic-check/src/ast/expressions/circuit/circuit_access.rs @@ -13,67 +13,67 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . - -use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; -use leo_static_check::{Attribute, SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, Identifier, Span}; - -impl Expression { - /// Resolve the type of a circuit member - pub(crate) fn circuit_access( - table: &mut SymbolTable, - expected_type: Option, - circuit: Box, - member: Identifier, - span: Span, - ) -> Result { - // Lookup the circuit in the symbol table. - // We do not know the exact circuit type from this context so `expected_type = None`. - let circuit_resolved = Expression::resolve(table, (None, *circuit))?; - let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?; - - // Lookup the circuit type in the symbol table - let circuit_type = table - .get_circuit(&circuit_name.name) - .ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?; - - // Resolve the circuit member as a circuit variable - let matched_variable = circuit_type - .variables - .iter() - .find(|variable| variable.identifier.eq(&member)); - - let type_ = match matched_variable { - // Return variable type - Some(variable) => variable.type_.clone(), - None => { - // Resolve the circuit member as a circuit function - let matched_function = circuit_type - .functions - .iter() - .find(|function| function.function.identifier.eq(&member)); - - match matched_function { - // Return function output type - Some(function) => { - // Check non-static method - if function.attributes.contains(&Attribute::Static) { - return Err(ExpressionError::invalid_static_member_access(member.name.clone(), span)); - } - - function.function.output.type_.clone() - } - None => return Err(ExpressionError::undefined_circuit_function(member, span)), - } - } - }; - - // Check type of circuit member - Type::check_type(&expected_type, &type_, span.clone())?; - - Ok(Expression { - type_, - value: ExpressionValue::CircuitMemberAccess(Box::new(circuit_resolved), member, span), - }) - } -} +// +// use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +// use leo_static_check::{Attribute, SymbolTable, Type}; +// use leo_typed::{Expression as UnresolvedExpression, Identifier, Span}; +// +// impl Expression { +// /// Resolve the type of a circuit member +// pub(crate) fn circuit_access( +// table: &mut SymbolTable, +// expected_type: Option, +// circuit: Box, +// member: Identifier, +// span: Span, +// ) -> Result { +// // Lookup the circuit in the symbol table. +// // We do not know the exact circuit type from this context so `expected_type = None`. +// let circuit_resolved = Expression::resolve(table, (None, *circuit))?; +// let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?; +// +// // Lookup the circuit type in the symbol table +// let circuit_type = table +// .get_circuit(&circuit_name.name) +// .ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?; +// +// // Resolve the circuit member as a circuit variable +// let matched_variable = circuit_type +// .variables +// .iter() +// .find(|variable| variable.identifier.eq(&member)); +// +// let type_ = match matched_variable { +// // Return variable type +// Some(variable) => variable.type_.clone(), +// None => { +// // Resolve the circuit member as a circuit function +// let matched_function = circuit_type +// .functions +// .iter() +// .find(|function| function.function.identifier.eq(&member)); +// +// match matched_function { +// // Return function output type +// Some(function) => { +// // Check non-static method +// if function.attributes.contains(&Attribute::Static) { +// return Err(ExpressionError::invalid_static_member_access(member.name.clone(), span)); +// } +// +// function.function.output.type_.clone() +// } +// None => return Err(ExpressionError::undefined_circuit_function(member, span)), +// } +// } +// }; +// +// // Check type of circuit member +// Type::check_type(&expected_type, &type_, span.clone())?; +// +// Ok(Expression { +// type_, +// value: ExpressionValue::CircuitMemberAccess(Box::new(circuit_resolved), member, span), +// }) +// } +// } diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs b/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs index 9bdd5cc4cc..362eda025d 100644 --- a/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs +++ b/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs @@ -13,54 +13,54 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . - -use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; -use leo_static_check::{Attribute, SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, Identifier, Span}; - -impl Expression { - /// Resolve the type of a static circuit member - pub(crate) fn circuit_static_access( - table: &mut SymbolTable, - expected_type: Option, - circuit: Box, - member: Identifier, - span: Span, - ) -> Result { - // Lookup the circuit in the symbol table. - // We do not know the exact circuit type from this context so `expected_type = None`. - let circuit_resolved = Expression::resolve(table, (None, *circuit))?; - let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?; - - // Lookup the circuit type in the symbol table - let circuit_type = table - .get_circuit(&circuit_name.name) - .ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?; - - // Resolve the circuit member as a circuit function - let matched_function = circuit_type - .functions - .iter() - .find(|function| function.function.identifier.eq(&member)); - - let type_ = match matched_function { - Some(function) => { - // Check static method - if function.attributes.contains(&Attribute::Static) { - function.function.output.type_.clone() - } else { - return Err(ExpressionError::invalid_member_access(member.name, span)); - } - } - None => return Err(ExpressionError::undefined_circuit_function_static(member, span)), - }; - - // Check type of static circuit function output - Type::check_type(&expected_type, &type_, span.clone())?; - - Ok(Expression { - type_, - value: ExpressionValue::CircuitStaticFunctionAccess(Box::new(circuit_resolved), member, span), - }) - } -} +// +// use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +// use leo_static_check::{Attribute, SymbolTable, Type}; +// use leo_typed::{Expression as UnresolvedExpression, Identifier, Span}; +// +// impl Expression { +// /// Resolve the type of a static circuit member +// pub(crate) fn circuit_static_access( +// table: &mut SymbolTable, +// expected_type: Option, +// circuit: Box, +// member: Identifier, +// span: Span, +// ) -> Result { +// // Lookup the circuit in the symbol table. +// // We do not know the exact circuit type from this context so `expected_type = None`. +// let circuit_resolved = Expression::resolve(table, (None, *circuit))?; +// let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?; +// +// // Lookup the circuit type in the symbol table +// let circuit_type = table +// .get_circuit(&circuit_name.name) +// .ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?; +// +// // Resolve the circuit member as a circuit function +// let matched_function = circuit_type +// .functions +// .iter() +// .find(|function| function.function.identifier.eq(&member)); +// +// let type_ = match matched_function { +// Some(function) => { +// // Check static method +// if function.attributes.contains(&Attribute::Static) { +// function.function.output.type_.clone() +// } else { +// return Err(ExpressionError::invalid_member_access(member.name, span)); +// } +// } +// None => return Err(ExpressionError::undefined_circuit_function_static(member, span)), +// }; +// +// // Check type of static circuit function output +// Type::check_type(&expected_type, &type_, span.clone())?; +// +// Ok(Expression { +// type_, +// value: ExpressionValue::CircuitStaticFunctionAccess(Box::new(circuit_resolved), member, span), +// }) +// } +// } diff --git a/dynamic-check/src/ast/expressions/conditional/conditional.rs b/dynamic-check/src/ast/expressions/conditional/conditional.rs index 260f9b0412..48f93bd882 100644 --- a/dynamic-check/src/ast/expressions/conditional/conditional.rs +++ b/dynamic-check/src/ast/expressions/conditional/conditional.rs @@ -13,38 +13,38 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . - -use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// Resolves an `if {cond} ? {first} : {second}` expression - /// `{cond}` should resolve to a boolean type - /// `{first}` and `{second}` should have equal types - pub(crate) fn conditional( - table: &mut SymbolTable, - expected_type: Option, - cond: UnresolvedExpression, - first: UnresolvedExpression, - second: UnresolvedExpression, - span: Span, - ) -> Result { - // Resolve the condition to a boolean type - let cond_type = Some(Type::Boolean); - let cond_resolved = Expression::resolve(table, (cond_type, cond))?; - - // Resolve the first and second expressions to the expected type - let (first_resolved, second_resolved) = Expression::binary(table, expected_type, first, second, span.clone())?; - - Ok(Expression { - type_: first_resolved.type_.clone(), - value: ExpressionValue::IfElse( - Box::new(cond_resolved), - Box::new(first_resolved), - Box::new(second_resolved), - span, - ), - }) - } -} +// +// use crate::{Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode}; +// use leo_static_check::{SymbolTable, Type}; +// use leo_typed::{Expression as UnresolvedExpression, Span}; +// +// impl Expression { +// /// Resolves an `if {cond} ? {first} : {second}` expression +// /// `{cond}` should resolve to a boolean type +// /// `{first}` and `{second}` should have equal types +// pub(crate) fn conditional( +// frame: &Frame, +// type_: &Type, +// cond: UnresolvedExpression, +// first: UnresolvedExpression, +// second: UnresolvedExpression, +// span: Span, +// ) -> Result { +// // Resolve the condition to a boolean type +// let boolean_type = Type::Boolean; +// let cond_resolved = Expression::new(frame, &boolean_type, cond)?; +// +// // Resolve the first and second expressions to the expected type +// let (first_resolved, second_resolved) = Expression::binary(frame, type_, first, second, &span)?; +// +// Ok(Expression { +// type_: type_.clone(), +// value: ExpressionValue::IfElse( +// Box::new(cond_resolved), +// Box::new(first_resolved), +// Box::new(second_resolved), +// span, +// ), +// }) +// } +// } diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs index 9bc5bf8055..ede876fffc 100644 --- a/dynamic-check/src/ast/expressions/expression.rs +++ b/dynamic-check/src/ast/expressions/expression.rs @@ -92,17 +92,17 @@ impl Expression { UnresolvedExpression::Le(lhs, rhs, span) => Self::le(frame, *lhs, *rhs, span), UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(frame, *lhs, *rhs, span), - // // Conditionals + // Conditionals // UnresolvedExpression::IfElse(cond, first, second, span) => { - // Self::conditional(variable_table, *cond, *first, *second, span) + // Self::conditional(variable_table, type_, *cond, *first, *second, span) // } - // - // // Arrays - // UnresolvedExpression::Array(elements, span) => Self::array(variable_table, elements, span), + + // Arrays + UnresolvedExpression::Array(elements, span) => Self::array(frame, type_, elements, span), // UnresolvedExpression::ArrayAccess(array, access, span) => { - // Self::array_access(variable_table, array, access, span) + // Self::array_access(frame, type_, array, access, span) // } - // + // // Tuples // UnresolvedExpression::Tuple(elements, span) => Self::tuple(variable_table, elements, span), // UnresolvedExpression::TupleAccess(tuple, index, span) => { diff --git a/dynamic-check/src/ast/expressions/function/function_call.rs b/dynamic-check/src/ast/expressions/function/function_call.rs index 720d2e05a2..c9b831c663 100644 --- a/dynamic-check/src/ast/expressions/function/function_call.rs +++ b/dynamic-check/src/ast/expressions/function/function_call.rs @@ -13,59 +13,59 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . - -use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// Resolves an inline function call - /// Checks for errors in function name, inputs, and output. - pub(crate) fn function_call( - table: &mut SymbolTable, - expected_type: Option, - function: Box, - inputs: Vec, - span: Span, - ) -> Result { - // Lookup function in symbol table. - // We do not know the exact function type from this context so `expected_type = None`. - let function_resolved = Expression::resolve(table, (None, *function))?; - let function_name = function_resolved.type_().get_type_function(span.clone())?; - - // Lookup the function type in the symbol table - let function_type = table - .get_function(&function_name.name) - .ok_or(ExpressionError::undefined_function(function_name.clone()))?; - - let type_ = function_type.output.type_.clone(); - let expected_inputs = function_type.inputs.clone(); - - // Check the number of inputs given - if inputs.len() != expected_inputs.len() { - return Err(ExpressionError::invalid_length_function_inputs( - expected_inputs.len(), - inputs.len(), - span, - )); - } - - // Check the type for each function input - let mut inputs_resolved = vec![]; - - for (input, function_input_type) in inputs.into_iter().zip(expected_inputs) { - let input_type = function_input_type.type_().clone(); - let input_resolved = Expression::resolve(table, (Some(input_type), input))?; - - inputs_resolved.push(input_resolved) - } - - // Check the function output type - Type::check_type(&expected_type, &type_, span.clone())?; - - Ok(Expression { - type_, - value: ExpressionValue::FunctionCall(Box::new(function_resolved), inputs_resolved, span), - }) - } -} +// +// use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; +// use leo_static_check::{SymbolTable, Type}; +// use leo_typed::{Expression as UnresolvedExpression, Span}; +// +// impl Expression { +// /// Resolves an inline function call +// /// Checks for errors in function name, inputs, and output. +// pub(crate) fn function_call( +// table: &mut SymbolTable, +// expected_type: Option, +// function: Box, +// inputs: Vec, +// span: Span, +// ) -> Result { +// // Lookup function in symbol table. +// // We do not know the exact function type from this context so `expected_type = None`. +// let function_resolved = Expression::resolve(table, (None, *function))?; +// let function_name = function_resolved.type_().get_type_function(span.clone())?; +// +// // Lookup the function type in the symbol table +// let function_type = table +// .get_function(&function_name.name) +// .ok_or(ExpressionError::undefined_function(function_name.clone()))?; +// +// let type_ = function_type.output.type_.clone(); +// let expected_inputs = function_type.inputs.clone(); +// +// // Check the number of inputs given +// if inputs.len() != expected_inputs.len() { +// return Err(ExpressionError::invalid_length_function_inputs( +// expected_inputs.len(), +// inputs.len(), +// span, +// )); +// } +// +// // Check the type for each function input +// let mut inputs_resolved = vec![]; +// +// for (input, function_input_type) in inputs.into_iter().zip(expected_inputs) { +// let input_type = function_input_type.type_().clone(); +// let input_resolved = Expression::resolve(table, (Some(input_type), input))?; +// +// inputs_resolved.push(input_resolved) +// } +// +// // Check the function output type +// Type::check_type(&expected_type, &type_, span.clone())?; +// +// Ok(Expression { +// type_, +// value: ExpressionValue::FunctionCall(Box::new(function_resolved), inputs_resolved, span), +// }) +// } +// } diff --git a/dynamic-check/src/ast/functions/function.rs b/dynamic-check/src/ast/functions/function.rs index 5cb1d003aa..37c87c217d 100644 --- a/dynamic-check/src/ast/functions/function.rs +++ b/dynamic-check/src/ast/functions/function.rs @@ -41,6 +41,7 @@ impl Function { // Create a new `Statement` from every given `UnresolvedStatement`. let statements = function_body .statements + .clone() .into_iter() .map(|unresolved_statement| Statement::new(&function_body, unresolved_statement)) .collect::, StatementError>>()?; diff --git a/dynamic-check/src/ast/statements/assign/assign.rs b/dynamic-check/src/ast/statements/assign/assign.rs index 799e6a0a9a..0b28b92b7c 100644 --- a/dynamic-check/src/ast/statements/assign/assign.rs +++ b/dynamic-check/src/ast/statements/assign/assign.rs @@ -29,74 +29,69 @@ pub struct Assign { pub span: Span, } -impl Statement { - /// - /// Resolves an assign statement - /// - pub(crate) fn assign( - function_body: &Frame, - assignee: Assignee, - expression: UnresolvedExpression, - span: Span, - ) -> Result { - // Lookup variable in symbol table - let key = &assignee.identifier.name; - let variable = function_body.variable_table.get(key, &span)?; - - // Throw an error if this variable is not mutable - if !variable.is_mutable() { - return Err(StatementError::immutable_assign(variable.identifier.name.clone(), span)); - } - - // Get inner assignee type - let type_ = get_inner_assignee_type( - variable_table, - variable.type_.clone(), - assignee.accesses.clone(), - span.clone(), - )?; - - // Resolve the expression based on the assignee type - let expression_resolved = Expression::new(variable_table, (Some(type_), expression))?; - - Ok(Statement::Assign(Assign { - assignee, - expression: expression_resolved, - span, - })) - } -} - -/// -/// Accesses the inner type of an assignee such as an array, tuple, or circuit member. -/// Returns an error for invalid accesses. -/// -fn get_inner_assignee_type( - table: &SymbolTable, - type_: Type, - accesses: Vec, - span: Span, -) -> Result { - match accesses.first() { - None => Ok(type_), - Some(access) => { - // Check that we are correctly accessing the type - let next_type = match (&type_, access) { - (Type::Array(next_type, _), AssigneeAccess::Array(_)) => *next_type.clone(), - (Type::Tuple(types), AssigneeAccess::Tuple(index)) => types[*index].clone(), - (Type::Circuit(identifier), AssigneeAccess::Member(member)) => { - let circuit_type_option = table.get_circuit(&identifier.name); - - let circuit_type = match circuit_type_option { - Some(circuit_type) => circuit_type, - None => return Err(StatementError::undefined_circuit(identifier.clone())), - }; - circuit_type.member_type(member)?.clone() - } - (type_, _) => return Err(StatementError::invalid_assign(type_, span)), - }; - - return get_inner_assignee_type(table, next_type, accesses[1..].to_vec(), span); - } - } -} +// impl Statement { +// /// +// /// Resolves an assign statement +// /// +// pub(crate) fn assign( +// frame: &Frame, +// assignee: Assignee, +// expression: UnresolvedExpression, +// span: Span, +// ) -> Result { +// // Lookup variable in symbol table +// let key = &assignee.identifier.name; +// let variable = frame.variable_table.get(key, &span)?; +// +// // Throw an error if this variable is not mutable +// if !variable.is_mutable() { +// return Err(StatementError::immutable_assign(variable.identifier.name.clone(), span)); +// } +// +// // Get inner assignee type +// let type_ = get_inner_assignee_type(frame, variable.type_.clone(), assignee.accesses.clone(), span.clone())?; +// +// // Resolve the expression based on the assignee type +// let expression_resolved = Expression::new(variable_table, (Some(type_), expression))?; +// +// Ok(Statement::Assign(Assign { +// assignee, +// expression: expression_resolved, +// span, +// })) +// } +// } +// +// /// +// /// Accesses the inner type of an assignee such as an array, tuple, or circuit member. +// /// Returns an error for invalid accesses. +// /// +// fn get_inner_assignee_type( +// frame: &Frame, +// type_: Type, +// accesses: Vec, +// span: Span, +// ) -> Result { +// match accesses.first() { +// None => Ok(type_), +// Some(access) => { +// // Check that we are correctly accessing the type +// let next_type = match (&type_, access) { +// (Type::Array(next_type, _), AssigneeAccess::Array(_)) => *next_type.clone(), +// (Type::Tuple(types), AssigneeAccess::Tuple(index)) => types[*index].clone(), +// (Type::Circuit(identifier), AssigneeAccess::Member(member)) => { +// let circuit_type_option = frame.get_circuit(&identifier.name); +// +// let circuit_type = match circuit_type_option { +// Some(circuit_type) => circuit_type, +// None => return Err(StatementError::undefined_circuit(identifier.clone())), +// }; +// circuit_type.member_type(member)?.clone() +// } +// (type_, _) => return Err(StatementError::invalid_assign(type_, span)), +// }; +// +// return get_inner_assignee_type(frame, next_type, accesses[1..].to_vec(), span); +// } +// } +// } diff --git a/dynamic-check/src/ast/statements/conditional/conditional.rs b/dynamic-check/src/ast/statements/conditional/conditional.rs index 9e5ae0c4ce..7225fa7ea4 100644 --- a/dynamic-check/src/ast/statements/conditional/conditional.rs +++ b/dynamic-check/src/ast/statements/conditional/conditional.rs @@ -14,12 +14,10 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, ResolvedNode, Statement, StatementError}; +use crate::{Expression, Frame, ResolvedNode, Statement, StatementError}; use leo_static_check::{FunctionOutputType, SymbolTable, Type}; use leo_typed::{ - ConditionalNestedOrEndStatement as UnresolvedNestedOrEnd, - ConditionalStatement as UnresolvedConditional, - Span, + ConditionalNestedOrEndStatement as UnresolvedNestedOrEnd, ConditionalStatement as UnresolvedConditional, Span, Statement as UnresolvedStatement, }; @@ -41,90 +39,90 @@ pub struct Conditional { pub span: Span, } -impl Conditional { - /// - /// Resolves a conditional statement. - /// - pub(crate) fn from_unresolved( - table: &mut SymbolTable, - return_type: FunctionOutputType, - conditional: UnresolvedConditional, - span: Span, - ) -> Result { - // Create child symbol table. - let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); +// impl Conditional { +// /// +// /// Resolves a conditional statement. +// /// +// pub(crate) fn from_unresolved( +// table: &mut SymbolTable, +// return_type: FunctionOutputType, +// conditional: UnresolvedConditional, +// span: Span, +// ) -> Result { +// // Create child symbol table. +// let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); +// +// // Resolve the condition to a boolean. +// let type_boolean = Some(Type::Boolean); +// let condition_resolved = Expression::resolve(&mut child_table, (type_boolean, conditional.condition))?; +// +// // Resolve all statements. +// let statements_resolved = resolve_statements(&mut child_table, return_type.clone(), conditional.statements)?; +// +// // Check for an `else if` or `else` clause. +// let nested_or_end = match conditional.next { +// Some(nested_or_end) => nested_or_end, +// None => { +// return Ok(Conditional { +// condition: condition_resolved, +// statements: statements_resolved, +// next: None, +// span, +// }); +// } +// }; +// +// // Evaluate the `else if` or `else` clause. +// let next_resolved = match nested_or_end { +// UnresolvedNestedOrEnd::Nested(conditional) => { +// // Type check the `else if` clause. +// let conditional_resolved = +// Self::from_unresolved(table, return_type.clone(), *conditional, span.clone())?; +// +// ConditionalNestedOrEndStatement::Nested(Box::new(conditional_resolved)) +// } +// UnresolvedNestedOrEnd::End(statements) => { +// // Create child symbol table. +// let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); +// +// // Type check the `else` clause. +// let statements_resolved = resolve_statements(&mut child_table, return_type, statements)?; +// +// ConditionalNestedOrEndStatement::End(statements_resolved) +// } +// }; +// +// Ok(Conditional { +// condition: condition_resolved, +// statements: statements_resolved, +// next: Some(next_resolved), +// span, +// }) +// } +// } - // Resolve the condition to a boolean. - let type_boolean = Some(Type::Boolean); - let condition_resolved = Expression::resolve(&mut child_table, (type_boolean, conditional.condition))?; +// /// Resolve an array of statements. +// fn resolve_statements( +// table: &mut SymbolTable, +// return_type: FunctionOutputType, +// statements: Vec, +// ) -> Result, StatementError> { +// Ok(statements +// .into_iter() +// .map(|statement| Statement::resolve(table, (return_type.clone(), statement))) +// .collect::, _>>()?) +// } - // Resolve all statements. - let statements_resolved = resolve_statements(&mut child_table, return_type.clone(), conditional.statements)?; - - // Check for an `else if` or `else` clause. - let nested_or_end = match conditional.next { - Some(nested_or_end) => nested_or_end, - None => { - return Ok(Conditional { - condition: condition_resolved, - statements: statements_resolved, - next: None, - span, - }); - } - }; - - // Evaluate the `else if` or `else` clause. - let next_resolved = match nested_or_end { - UnresolvedNestedOrEnd::Nested(conditional) => { - // Type check the `else if` clause. - let conditional_resolved = - Self::from_unresolved(table, return_type.clone(), *conditional, span.clone())?; - - ConditionalNestedOrEndStatement::Nested(Box::new(conditional_resolved)) - } - UnresolvedNestedOrEnd::End(statements) => { - // Create child symbol table. - let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); - - // Type check the `else` clause. - let statements_resolved = resolve_statements(&mut child_table, return_type, statements)?; - - ConditionalNestedOrEndStatement::End(statements_resolved) - } - }; - - Ok(Conditional { - condition: condition_resolved, - statements: statements_resolved, - next: Some(next_resolved), - span, - }) - } -} - -/// Resolve an array of statements. -fn resolve_statements( - table: &mut SymbolTable, - return_type: FunctionOutputType, - statements: Vec, -) -> Result, StatementError> { - Ok(statements - .into_iter() - .map(|statement| Statement::resolve(table, (return_type.clone(), statement))) - .collect::, _>>()?) -} - -impl Statement { - /// Resolves a conditional statement. - pub(crate) fn conditional( - function_body: &function_body, - return_type: FunctionOutputType, - conditional: UnresolvedConditional, - span: Span, - ) -> Result { - let conditional = Conditional::from_unresolved(function_body, return_type, conditional, span)?; - - Ok(Statement::Conditional(conditional)) - } -} +// impl Statement { +// /// Resolves a conditional statement. +// pub(crate) fn conditional( +// function_body: &Frame, +// return_type: FunctionOutputType, +// conditional: UnresolvedConditional, +// span: Span, +// ) -> Result { +// let conditional = Conditional::from_unresolved(function_body, return_type, conditional, span)?; +// +// Ok(Statement::Conditional(conditional)) +// } +// } diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs index bba6190e0e..ca4815347f 100644 --- a/dynamic-check/src/ast/statements/definition/definition.rs +++ b/dynamic-check/src/ast/statements/definition/definition.rs @@ -15,14 +15,7 @@ // along with the Leo library. If not, see . use crate::{ - check_tuple_type, - Expression, - ExpressionValue, - Frame, - ResolvedNode, - Statement, - StatementError, - VariableTable, + check_tuple_type, Expression, ExpressionValue, Frame, ResolvedNode, Statement, StatementError, VariableTable, VariableTableError, }; use leo_static_check::{Attribute, ParameterType, SymbolTable, Type}; @@ -106,11 +99,14 @@ impl DefinitionVariables { } // Get the type of each variable. - let variable_types = variables + let variable_types: Vec = variables .names .iter() .map(|variable_name| function_body.variable_table.get(variable_name.name_string(), span)) - .collect::, VariableTableError>>()?; + .collect::, VariableTableError>>()? + .into_iter() + .map(|type_ref| type_ref.clone()) + .collect(); // Create a new vector of `Expression`s from the given vector of `UnresolvedExpression`s. let mut expressions_resolved = vec![]; @@ -135,11 +131,14 @@ impl DefinitionVariables { span: &Span, ) -> Result { // Get the type of each variable. - let variable_types = variables + let variable_types: Vec = variables .names .iter() .map(|variable_name| function_body.variable_table.get(variable_name.name_string(), span)) - .collect::, VariableTableError>>()?; + .collect::, VariableTableError>>()? + .into_iter() + .map(|type_ref| type_ref.clone()) + .collect(); // Create a new tuple type from the vector of variable types. let tuple_type = Type::Tuple(variable_types); @@ -152,39 +151,39 @@ impl DefinitionVariables { } } -/// Inserts a variable definition into the given symbol table -fn insert_defined_variable( - table: &mut SymbolTable, - variable: &VariableName, - type_: &Type, - span: Span, -) -> Result<(), StatementError> { - let attributes = if variable.mutable { - vec![Attribute::Mutable] - } else { - vec![] - }; - - // Insert variable into symbol table - let key = variable.identifier.name.clone(); - let value = ParameterType { - identifier: variable.identifier.clone(), - type_: type_.clone(), - attributes, - }; - - // Check that variable name was not defined twice - let duplicate = table.insert_name(key, value); - - if duplicate.is_some() { - return Err(StatementError::duplicate_variable( - variable.identifier.name.clone(), - span, - )); - } - - Ok(()) -} +// /// Inserts a variable definition into the given symbol table +// fn insert_defined_variable( +// table: &mut SymbolTable, +// variable: &VariableName, +// type_: &Type, +// span: Span, +// ) -> Result<(), StatementError> { +// let attributes = if variable.mutable { +// vec![Attribute::Mutable] +// } else { +// vec![] +// }; +// +// // Insert variable into symbol table +// let key = variable.identifier.name.clone(); +// let value = ParameterType { +// identifier: variable.identifier.clone(), +// type_: type_.clone(), +// attributes, +// }; +// +// // Check that variable name was not defined twice +// let duplicate = table.insert_name(key, value); +// +// if duplicate.is_some() { +// return Err(StatementError::duplicate_variable( +// variable.identifier.name.clone(), +// span, +// )); +// } +// +// Ok(()) +// } impl Statement { /// diff --git a/dynamic-check/src/ast/statements/iteration/iteration.rs b/dynamic-check/src/ast/statements/iteration/iteration.rs index c744bbb40e..9365b7aa9d 100644 --- a/dynamic-check/src/ast/statements/iteration/iteration.rs +++ b/dynamic-check/src/ast/statements/iteration/iteration.rs @@ -29,47 +29,47 @@ pub struct Iteration { pub span: Span, } -impl Statement { - /// Resolve an iteration statement - pub(crate) fn iteration( - table: &mut SymbolTable, - return_type: FunctionOutputType, - index: Identifier, - start: UnresolvedExpression, - stop: UnresolvedExpression, - statements: Vec, - span: Span, - ) -> Result { - // TODO: Create child symbol table and add variables from parent - - // Resolve index numbers to a u32 type - let type_number = Type::IntegerType(IntegerType::U32); - - let start_resolved = Expression::resolve(table, (Some(type_number.clone()), start))?; - let stop_resolved = Expression::resolve(table, (Some(type_number.clone()), stop))?; - - // Add index to symbol table - let key = index.name.clone(); - let value = ParameterType { - identifier: index.clone(), - type_: type_number, - attributes: vec![], - }; - - table.insert_name(key, value); - - // Resolve statements - let statements_resolved = statements - .into_iter() - .map(|statement| Statement::resolve(table, (return_type.clone(), statement))) - .collect::, _>>()?; - - Ok(Statement::Iteration(Iteration { - index, - start: start_resolved, - stop: stop_resolved, - statements: statements_resolved, - span, - })) - } -} +// impl Statement { +// /// Resolve an iteration statement +// pub(crate) fn iteration( +// table: &mut SymbolTable, +// return_type: FunctionOutputType, +// index: Identifier, +// start: UnresolvedExpression, +// stop: UnresolvedExpression, +// statements: Vec, +// span: Span, +// ) -> Result { +// // TODO: Create child symbol table and add variables from parent +// +// // Resolve index numbers to a u32 type +// let type_number = Type::IntegerType(IntegerType::U32); +// +// let start_resolved = Expression::resolve(table, (Some(type_number.clone()), start))?; +// let stop_resolved = Expression::resolve(table, (Some(type_number.clone()), stop))?; +// +// // Add index to symbol table +// let key = index.name.clone(); +// let value = ParameterType { +// identifier: index.clone(), +// type_: type_number, +// attributes: vec![], +// }; +// +// table.insert_name(key, value); +// +// // Resolve statements +// let statements_resolved = statements +// .into_iter() +// .map(|statement| Statement::resolve(table, (return_type.clone(), statement))) +// .collect::, _>>()?; +// +// Ok(Statement::Iteration(Iteration { +// index, +// start: start_resolved, +// stop: stop_resolved, +// statements: statements_resolved, +// span, +// })) +// } +// } diff --git a/dynamic-check/src/ast/statements/return_/return_.rs b/dynamic-check/src/ast/statements/return_/return_.rs index 2ef06d26c1..ef08de01c3 100644 --- a/dynamic-check/src/ast/statements/return_/return_.rs +++ b/dynamic-check/src/ast/statements/return_/return_.rs @@ -29,8 +29,11 @@ impl Statement { unresolved_expression: UnresolvedExpression, span: Span, ) -> Result { + // Get function return type from frame. + let return_type = &function_body.function_type.output.type_; + // Create a new `Expression` from the unresolved return expression - let expression = Expression::new(function_body, unresolved_expression)?; + let expression = Expression::new(function_body, return_type, unresolved_expression)?; Ok(Statement::Return(expression, span)) } diff --git a/dynamic-check/src/ast/statements/statement.rs b/dynamic-check/src/ast/statements/statement.rs index 946761d056..f012b5bc20 100644 --- a/dynamic-check/src/ast/statements/statement.rs +++ b/dynamic-check/src/ast/statements/statement.rs @@ -14,15 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{ - Assign, - Conditional, - Definition, - Expression, - Frame, - Iteration, - ResolvedNode, - StatementError, - VariableTable, + Assign, Conditional, Definition, Expression, Frame, Iteration, ResolvedNode, StatementError, VariableTable, }; use leo_static_check::{FunctionOutputType, FunctionType, SymbolTable}; use leo_typed::{ConsoleFunctionCall, Span, Statement as UnresolvedStatement}; @@ -54,17 +46,18 @@ impl Statement { UnresolvedStatement::Definition(declare, variables, expressions, span) => { Self::definition(frame, declare, variables, expressions, span) } - UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(frame, assignee, expression, span), - UnresolvedStatement::Conditional(conditional, span) => { - Self::conditional(frame, return_type, conditional, span) - } - UnresolvedStatement::Iteration(index, start, stop, statements, span) => { - Self::iteration(frame, return_type, index, start, stop, statements, span) - } - UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)), - UnresolvedStatement::Expression(expression, span) => { - Ok(Statement::Expression(Expression::new(frame, expression)?, span)) - } + // UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(frame, assignee, expression, span), + // UnresolvedStatement::Conditional(conditional, span) => { + // Self::conditional(frame, return_type, conditional, span) + // } + // UnresolvedStatement::Iteration(index, start, stop, statements, span) => { + // Self::iteration(frame, return_type, index, start, stop, statements, span) + // } + // UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)), + // UnresolvedStatement::Expression(expression, span) => { + // Ok(Statement::Expression(Expression::new(frame, expression)?, span)) + // } + _ => unimplemented!("statement not implemented"), } } } @@ -74,29 +67,30 @@ impl ResolvedNode for Statement { type UnresolvedNode = (FunctionOutputType, UnresolvedStatement); /// Type check a statement inside a program AST - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let return_type = unresolved.0; - let statement = unresolved.1; - - match statement { - UnresolvedStatement::Return(expression, span) => { - Self::resolve_return(table, return_type.type_, expression, span) - } - UnresolvedStatement::Definition(declare, variables, expressions, span) => { - Self::definition(table, declare, variables, expressions, span) - } - UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(table, assignee, expression, span), - UnresolvedStatement::Conditional(conditional, span) => { - Self::conditional(table, return_type, conditional, span) - } - UnresolvedStatement::Iteration(index, start, stop, statements, span) => { - Self::iteration(table, return_type, index, start, stop, statements, span) - } - UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)), - UnresolvedStatement::Expression(expression, span) => Ok(Statement::Expression( - Expression::resolve(table, (None, expression))?, - span, - )), - } + fn resolve(_table: &mut SymbolTable, _unresolved: Self::UnresolvedNode) -> Result { + // let return_type = unresolved.0; + // let statement = unresolved.1; + // + // match statement { + // // UnresolvedStatement::Return(expression, span) => { + // // Self::resolve_return(table, return_type.type_, expression, span) + // // } + // // UnresolvedStatement::Definition(declare, variables, expressions, span) => { + // // Self::definition(table, declare, variables, expressions, span) + // // } + // // UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(table, assignee, expression, span), + // // UnresolvedStatement::Conditional(conditional, span) => { + // // Self::conditional(table, return_type, conditional, span) + // // } + // // UnresolvedStatement::Iteration(index, start, stop, statements, span) => { + // // Self::iteration(table, return_type, index, start, stop, statements, span) + // // } + // // UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)), + // // UnresolvedStatement::Expression(expression, span) => Ok(Statement::Expression( + // // Expression::resolve(table, (None, expression))?, + // // span, + // // )), + // } + unimplemented!("statement resolve deprecated"); } } diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 9687dba02f..4e370e9f4e 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{DynamicCheckError, Function, FunctionError, LeoResolvedAst, VariableTableError}; +use crate::{DynamicCheckError, FrameError, VariableTableError}; use leo_static_check::{FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; use leo_typed::{ Expression, @@ -26,7 +26,7 @@ use leo_typed::{ }; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use std::{collections::HashMap, path::PathBuf}; /// Performs a dynamic type inference check over a program. pub struct DynamicCheck { @@ -87,12 +87,12 @@ impl DynamicCheck { /// Returns a `LeoResolvedAst` if all `TypeAssertion` predicates are true. /// Returns ERROR if a `TypeAssertion` predicate is false or a solution does not exist. /// - pub fn solve(self) -> Result { + pub fn solve(self) -> Result<(), DynamicCheckError> { for function_body in self.functions { - function_body.solve(); + function_body.solve()?; } - Ok(LeoResolvedAst::new()) + Ok(()) } } @@ -142,8 +142,8 @@ impl Frame { /// Collects a vector of `TypeAssertion` predicates from a vector of statements. /// fn parse_statements(&mut self) { - for statement in &self.statements { - self.parse_statement(statement); + for statement in self.statements.clone() { + self.parse_statement(&statement); } } @@ -309,7 +309,7 @@ impl Frame { /// /// Returns a new `Function` if all `TypeAssertions` can be solved successfully. /// - fn solve(self) -> Result { + fn solve(self) -> Result<(), FrameError> { let mut unsolved = self.type_assertions.clone(); while !unsolved.is_empty() { @@ -337,7 +337,9 @@ impl Frame { // } // Return a new resolved function struct. - Function::new(self) + // Function::new(self) + + Ok(()) } } diff --git a/dynamic-check/src/errors/dynamic_check.rs b/dynamic-check/src/errors/dynamic_check.rs index 841264c84e..8d2054a743 100644 --- a/dynamic-check/src/errors/dynamic_check.rs +++ b/dynamic-check/src/errors/dynamic_check.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ExpressionError, FunctionError, ProgramError, StatementError}; +// use crate::{ExpressionError, FunctionError, ProgramError, StatementError}; +use crate::FrameError; use leo_typed::Error as FormattedError; use std::path::PathBuf; @@ -26,16 +27,19 @@ pub enum DynamicCheckError { Error(#[from] FormattedError), #[error("{}", _0)] - ExpressionError(#[from] ExpressionError), - - #[error("{}", _0)] - FunctionError(#[from] FunctionError), - - #[error("{}", _0)] - StatementError(#[from] StatementError), - - #[error("{}", _0)] - ProgramError(#[from] ProgramError), + FrameError(#[from] FrameError), + // + // #[error("{}", _0)] + // ExpressionError(#[from] ExpressionError), + // + // #[error("{}", _0)] + // FunctionError(#[from] FunctionError), + // + // #[error("{}", _0)] + // StatementError(#[from] StatementError), + // + // #[error("{}", _0)] + // ProgramError(#[from] ProgramError), } impl DynamicCheckError { @@ -43,10 +47,11 @@ impl DynamicCheckError { pub fn set_path(&mut self, path: PathBuf) { match self { DynamicCheckError::Error(error) => error.set_path(path), - DynamicCheckError::ExpressionError(error) => error.set_path(path), - DynamicCheckError::FunctionError(error) => error.set_path(path), - DynamicCheckError::StatementError(error) => error.set_path(path), - DynamicCheckError::ProgramError(error) => error.set_path(path), + DynamicCheckError::FrameError(error) => error.set_path(path), + // DynamicCheckError::ExpressionError(error) => error.set_path(path), + // DynamicCheckError::FunctionError(error) => error.set_path(path), + // DynamicCheckError::StatementError(error) => error.set_path(path), + // DynamicCheckError::ProgramError(error) => error.set_path(path), } } } diff --git a/dynamic-check/src/errors/expression.rs b/dynamic-check/src/errors/expression.rs index 84df4f4635..3c8f896ac0 100644 --- a/dynamic-check/src/errors/expression.rs +++ b/dynamic-check/src/errors/expression.rs @@ -41,6 +41,7 @@ impl ExpressionError { match self { ExpressionError::Error(error) => error.set_path(path), ExpressionError::TypeError(error) => error.set_path(path), + ExpressionError::VariableTableError(error) => error.set_path(path), } } diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs new file mode 100644 index 0000000000..49ee06adba --- /dev/null +++ b/dynamic-check/src/errors/frame.rs @@ -0,0 +1,44 @@ +// 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 . + +use leo_typed::{Error as FormattedError, Span}; + +use std::path::PathBuf; + +/// Errors encountered when tracking variable names in a program. +#[derive(Debug, Error)] +pub enum FrameError { + #[error("{}", _0)] + Error(#[from] FormattedError), +} + +impl FrameError { + /// + /// Set the filepath for the error stacktrace + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + FrameError::Error(error) => error.set_path(path), + } + } + + /// + /// Return a new formatted error with a given message and span information + /// + fn new_from_span(message: String, span: Span) -> Self { + FrameError::Error(FormattedError::new_from_span(message, span)) + } +} diff --git a/dynamic-check/src/errors/mod.rs b/dynamic-check/src/errors/mod.rs index e80b09f007..8787321ab2 100644 --- a/dynamic-check/src/errors/mod.rs +++ b/dynamic-check/src/errors/mod.rs @@ -14,32 +14,29 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -pub mod circuit; -pub use self::circuit::*; +// pub mod circuit; +// pub use self::circuit::*; pub mod dynamic_check; pub use self::dynamic_check::*; -pub mod expression; -pub use self::expression::*; +pub mod frame; +pub use self::frame::*; -pub mod function; -pub use self::function::*; - -pub mod program; -pub use self::program::*; - -pub mod resolver; -pub use self::resolver::*; - -pub mod statement; -pub use self::statement::*; +// pub mod expression; +// pub use self::expression::*; +// +// pub mod function; +// pub use self::function::*; +// +// pub mod program; +// pub use self::program::*; +// +// pub mod resolver; +// pub use self::resolver::*; +// +// pub mod statement; +// pub use self::statement::*; pub mod variable_table; pub use self::variable_table::*; - -// pub mod symbol_table; -// pub use self::symbol_table::*; - -// pub mod type_; -// pub use self::type_::*; diff --git a/dynamic-check/src/lib.rs b/dynamic-check/src/lib.rs index 5e2064d95f..930adca205 100644 --- a/dynamic-check/src/lib.rs +++ b/dynamic-check/src/lib.rs @@ -17,8 +17,8 @@ #[macro_use] extern crate thiserror; -pub mod ast; -pub use self::ast::*; +// pub mod ast; +// pub use self::ast::*; pub mod dynamic_check; pub use self::dynamic_check::*; From d8075c14e247d984f21a74d34cb826a65307e5fe Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 19 Oct 2020 01:40:36 -0700 Subject: [PATCH 035/139] add scope for loop and non-loop variables --- dynamic-check/src/dynamic_check.rs | 100 ++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 15 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 4e370e9f4e..fbca5ca8fe 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{DynamicCheckError, FrameError, VariableTableError}; -use leo_static_check::{FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; +use leo_static_check::{CircuitType, FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; use leo_typed::{ Expression, Function as UnresolvedFunction, @@ -75,9 +75,9 @@ impl DynamicCheck { /// Collects a vector of `TypeAssertion` predicates from a function. /// fn parse_function(&mut self, function: &UnresolvedFunction) { - let function_body = Frame::new(function.clone(), self.table.clone()); + let frame = Frame::new(function.clone(), self.table.clone()); - self.functions.push(function_body); + self.functions.push(frame); } /// @@ -88,8 +88,8 @@ impl DynamicCheck { /// Returns ERROR if a `TypeAssertion` predicate is false or a solution does not exist. /// pub fn solve(self) -> Result<(), DynamicCheckError> { - for function_body in self.functions { - function_body.solve()?; + for frame in self.functions { + frame.solve()?; } Ok(()) @@ -100,10 +100,11 @@ impl DynamicCheck { #[derive(Clone)] pub struct Frame { pub function_type: FunctionType, + // pub self_type: Option, pub statements: Vec, pub user_defined_types: SymbolTable, pub type_assertions: Vec, - pub variable_table: VariableTable, + pub scopes: Vec, } impl Frame { @@ -116,26 +117,43 @@ impl Frame { // Get function type from symbol table. let function_type = symbol_table.get_function(name).unwrap().clone(); - // Create a new mapping of variables to types. - let mut variable_table = VariableTable::new(); + // Create a new scope for the function variables. + let mut scope = Scope::new(None); // Initialize function inputs as variables. - variable_table.parse_function_inputs(&function_type.inputs); + scope.parse_function_inputs(&function_type.inputs); - // Create new function body struct. + // Create new list of scopes for frame. + let scopes = vec![scope]; + + // Create new frame struct. // Update variables when encountering let/const variable definitions. - let mut function_body = Self { + let mut frame = Self { statements: function.statements, function_type, user_defined_types: symbol_table, type_assertions: vec![], - variable_table, + scopes, }; // Create type assertions for function statements - function_body.parse_statements(); + frame.parse_statements(); - function_body + frame + } + + /// + /// Pushes a new variable `Scope` to the list of scopes in the current `Frame`. + /// + fn push_scope(&mut self, scope: Scope) { + self.scopes.push(scope) + } + + /// + /// Removes and returns the most recent `Scope` from the list of scopes in the current `Frame`. + /// + fn pop_scope(&mut self) -> Option { + self.scopes.pop() } /// @@ -343,7 +361,59 @@ impl Frame { } } -/// A structure for tracking the types of user defined variables in a program. +/// A structure for tracking the types of defined variables in a block of code. +#[derive(Clone)] +pub struct Scope { + pub loop_variables: VariableTable, + pub variables: VariableTable, +} + +impl Scope { + /// + /// Returns a new `Scope` from an optional given `Scope`. + /// + /// The new scope will contain the variables of the optional given `Scope`. + /// + pub fn new(parent: Option) -> Self { + match parent { + Some(scope) => scope.clone(), + None => Self::empty(), + } + } + + /// + /// Returns a new `Scope` with no variables. + /// + fn empty() -> Self { + Self { + loop_variables: VariableTable::new(), + variables: VariableTable::new(), + } + } + + /// + /// Inserts a variable name -> type mapping into the loop variable table. + /// + pub fn insert_loop_variable(&mut self, name: String, type_: Type) -> Option { + self.loop_variables.insert(name, type_) + } + + /// + /// Inserts a variable name -> type mapping into the variable table. + /// + pub fn insert_variable(&mut self, name: String, type_: Type) -> Option { + self.variables.insert(name, type_) + } + + /// + /// Inserts a vector of function input types into the `Scope` variable table. + /// + pub fn parse_function_inputs(&mut self, function_inputs: &Vec) { + self.variables.parse_function_inputs(function_inputs) + } +} + +/// Mapping of variable names to types #[derive(Clone)] pub struct VariableTable(pub HashMap); From a8967298ea5d2a197c9a4485874fcf8beb91b5ea Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 19 Oct 2020 10:46:10 -0700 Subject: [PATCH 036/139] dynamic check parse array expressions --- dynamic-check/src/dynamic_check.rs | 62 ++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index fbca5ca8fe..102c2be027 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -22,6 +22,7 @@ use leo_typed::{ Identifier, Program, Span, + SpreadOrExpression, Statement as UnresolvedStatement, }; @@ -235,6 +236,9 @@ impl Frame { self.parse_conditional_expression(condition, first, second, span) } + // Arrays + Expression::Array(expressions, span) => self.parse_array(expressions, span), + expression => unimplemented!("expression {} not implemented", expression), } } @@ -324,6 +328,64 @@ impl Frame { self.parse_binary_expression(first, second, _span) } + /// + /// Returns the type of the array expression. + /// + fn parse_array(&mut self, expressions: &Vec>, _span: &Span) -> Type { + // Store actual array element type. + let mut actual_element_type = None; + let mut count = 0usize; + + // Parse all array elements. + for expression in expressions { + // Get the type and count of elements in each spread or expression. + let (type_, element_count) = self.parse_spread_or_expression(expression); + + actual_element_type = Some(type_); + count += element_count; + } + + // Return an error for empty arrays. + let type_ = match actual_element_type { + Some(type_) => type_, + None => unimplemented!("return empty array error"), + }; + + Type::Array(Box::new(type_), vec![count]) + } + + /// + /// Returns the type and count of elements in a spread or expression. + /// + fn parse_spread_or_expression(&mut self, s_or_e: &SpreadOrExpression) -> (Type, usize) { + match s_or_e { + SpreadOrExpression::Spread(expression) => { + // Parse the type of the spread array expression. + let array_type = self.parse_expression(expression); + + // Check that the type is an array. + let (element_type, mut dimensions) = match array_type { + Type::Array(element_type, dimensions) => (element_type, dimensions), + _ => unimplemented!("Spread type must be an array"), + }; + + // A spread copies the elements of an array. + // If the array has elements of type array, we must return a new array type with proper dimensions. + // If the array has elements of any other type, we can return the type and count directly. + let count = dimensions.pop().unwrap(); + + let type_ = if dimensions.is_empty() { + *element_type + } else { + Type::Array(element_type, dimensions) + }; + + (type_, count) + } + SpreadOrExpression::Expression(expression) => (self.parse_expression(expression), 1), + } + } + /// /// Returns a new `Function` if all `TypeAssertions` can be solved successfully. /// From 0c6a72c35f0902290b9e47721e68a65860df90cd Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 19 Oct 2020 12:38:14 -0700 Subject: [PATCH 037/139] dynamic check parse tuple expressions --- dynamic-check/src/dynamic_check.rs | 196 +++++++++++++++++++++-------- 1 file changed, 141 insertions(+), 55 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 102c2be027..ff61e03d3a 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -157,6 +157,28 @@ impl Frame { self.scopes.pop() } + /// + /// Insert a variable into the symbol table in the current scope. + /// + fn insert_variable(&mut self, name: String, type_: Type) -> Option { + // Modify the current scope. + let scope = self.scopes.last_mut().unwrap(); + + // Insert the variable name -> type. + scope.variables.insert(name, type_) + } + + /// + /// Get a variable's type from the symbol table in the current scope. + /// + fn get_variable(&self, name: &String) -> &Type { + // Lookup in the current scope. + let scope = self.scopes.last().unwrap(); + + // Get the variable by name. + scope.get_variable(name).unwrap() + } + /// /// Collects a vector of `TypeAssertion` predicates from a vector of statements. /// @@ -204,7 +226,7 @@ impl Frame { fn parse_expression(&mut self, expression: &Expression) -> Type { match expression { // Type variables - Expression::Identifier(identifier) => Self::parse_identifier(&identifier), + Expression::Identifier(identifier) => self.parse_identifier(identifier), Expression::Implicit(name, _) => Self::parse_implicit(name), // Explicit types @@ -237,17 +259,23 @@ impl Frame { } // Arrays - Expression::Array(expressions, span) => self.parse_array(expressions, span), + // Expression::Array(expressions, span) => self.parse_array(expressions, span), + // Expression::ArrayAccess(array, access, span) => self.parse_array_access(array, access, span), + + // Tuples + Expression::Tuple(expressions, span) => self.parse_tuple(expressions, span), + Expression::TupleAccess(tuple, index, span) => self.parse_tuple_access(tuple, *index, span), expression => unimplemented!("expression {} not implemented", expression), } } /// - /// Returns a new type variable from a given identifier + /// Returns the type of the identifier in the symbol table. /// - fn parse_identifier(identifier: &Identifier) -> Type { - Type::TypeVariable(TypeVariable::from(identifier.name.clone())) + fn parse_identifier(&self, identifier: &Identifier) -> Type { + // TODO (collinc97) throw an error if identifier is not present. + self.get_variable(&identifier.name).clone() } /// @@ -329,62 +357,103 @@ impl Frame { } /// - /// Returns the type of the array expression. + /// Returns the type of the tuple expression. /// - fn parse_array(&mut self, expressions: &Vec>, _span: &Span) -> Type { - // Store actual array element type. - let mut actual_element_type = None; - let mut count = 0usize; + fn parse_tuple(&mut self, expressions: &Vec, _span: &Span) -> Type { + let mut types = vec![]; - // Parse all array elements. + // Parse all tuple expressions. for expression in expressions { - // Get the type and count of elements in each spread or expression. - let (type_, element_count) = self.parse_spread_or_expression(expression); + let type_ = self.parse_expression(expression); - actual_element_type = Some(type_); - count += element_count; + types.push(type_) } - // Return an error for empty arrays. - let type_ = match actual_element_type { - Some(type_) => type_, - None => unimplemented!("return empty array error"), + Type::Tuple(types) + } + + /// + /// Returns the type of the accessed tuple element. + /// + fn parse_tuple_access(&mut self, expression: &Expression, index: usize, _span: &Span) -> Type { + // Parse the tuple expression which could be a variable with type tuple. + let type_ = self.parse_expression(expression); + + // Check the type is a tuple. + let elements = match type_ { + Type::Tuple(elements) => elements, + _ => unimplemented!("expected a tuple type"), }; - Type::Array(Box::new(type_), vec![count]) + let element_type = elements[index].clone(); + + element_type } - /// - /// Returns the type and count of elements in a spread or expression. - /// - fn parse_spread_or_expression(&mut self, s_or_e: &SpreadOrExpression) -> (Type, usize) { - match s_or_e { - SpreadOrExpression::Spread(expression) => { - // Parse the type of the spread array expression. - let array_type = self.parse_expression(expression); - - // Check that the type is an array. - let (element_type, mut dimensions) = match array_type { - Type::Array(element_type, dimensions) => (element_type, dimensions), - _ => unimplemented!("Spread type must be an array"), - }; - - // A spread copies the elements of an array. - // If the array has elements of type array, we must return a new array type with proper dimensions. - // If the array has elements of any other type, we can return the type and count directly. - let count = dimensions.pop().unwrap(); - - let type_ = if dimensions.is_empty() { - *element_type - } else { - Type::Array(element_type, dimensions) - }; - - (type_, count) - } - SpreadOrExpression::Expression(expression) => (self.parse_expression(expression), 1), - } - } + // /// + // /// Returns the type of the array expression. + // /// + // fn parse_array(&mut self, expressions: &Vec>, _span: &Span) -> Type { + // // Store actual array element type. + // let mut actual_element_type = None; + // let mut count = 0usize; + // + // // Parse all array elements. + // for expression in expressions { + // // Get the type and count of elements in each spread or expression. + // let (type_, element_count) = self.parse_spread_or_expression(expression); + // + // actual_element_type = Some(type_); + // count += element_count; + // } + // + // // Return an error for empty arrays. + // let type_ = match actual_element_type { + // Some(type_) => type_, + // None => unimplemented!("return empty array error"), + // }; + // + // Type::Array(Box::new(type_), vec![count]) + // } + // + // /// + // /// Returns the type and count of elements in a spread or expression. + // /// + // fn parse_spread_or_expression(&mut self, s_or_e: &SpreadOrExpression) -> (Type, usize) { + // match s_or_e { + // SpreadOrExpression::Spread(expression) => { + // // Parse the type of the spread array expression. + // let array_type = self.parse_expression(expression); + // + // // Check that the type is an array. + // let (element_type, mut dimensions) = match array_type { + // Type::Array(element_type, dimensions) => (element_type, dimensions), + // _ => unimplemented!("Spread type must be an array"), + // }; + // + // // A spread copies the elements of an array. + // // If the array has elements of type array, we must return a new array type with proper dimensions. + // // If the array has elements of any other type, we can return the type and count directly. + // let count = dimensions.pop().unwrap(); + // + // let type_ = if dimensions.is_empty() { + // *element_type + // } else { + // Type::Array(element_type, dimensions) + // }; + // + // (type_, count) + // } + // SpreadOrExpression::Expression(expression) => (self.parse_expression(expression), 1), + // } + // } + // + // /// + // /// Returns the type of the accessed array element. + // /// + // fn parse_array_access(&mut self, array: &Expression, r_or_e: &RangeOrExpression, span: &Span) -> Type { + // // + // } /// /// Returns a new `Function` if all `TypeAssertions` can be solved successfully. @@ -467,6 +536,25 @@ impl Scope { self.variables.insert(name, type_) } + /// + /// Returns a reference to the type corresponding to the loop variable name. + /// + pub fn get_loop_variable(&self, name: &String) -> Option<&Type> { + self.loop_variables.get(name) + } + + /// + /// Returns a reference to the type corresponding to the variable name. + /// + /// Checks loop variables first, then non-loop variables. + /// + pub fn get_variable(&self, name: &String) -> Option<&Type> { + match self.get_loop_variable(name) { + Some(loop_variable_type) => Some(loop_variable_type), + None => self.variables.get(name), + } + } + /// /// Inserts a vector of function input types into the `Scope` variable table. /// @@ -505,10 +593,8 @@ impl VariableTable { /// If the variable table did not have this key present, throw an undefined variable error /// using the given span. /// - pub fn get(&self, name: &String, span: &Span) -> Result<&Type, VariableTableError> { - self.0 - .get(name) - .ok_or(VariableTableError::undefined_variable_name(name, span)) + pub fn get(&self, name: &String) -> Option<&Type> { + self.0.get(name) } /// From 22bc8911720bbe1a996f7f625f975a822f6e1fdb Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 19 Oct 2020 14:11:39 -0700 Subject: [PATCH 038/139] dynamic check parse array access expressions --- dynamic-check/src/dynamic_check.rs | 185 +++++++++++++++++++---------- 1 file changed, 119 insertions(+), 66 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index ff61e03d3a..ae22219b1b 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -21,11 +21,13 @@ use leo_typed::{ Function as UnresolvedFunction, Identifier, Program, + RangeOrExpression, Span, SpreadOrExpression, Statement as UnresolvedStatement, }; +use leo_typed::integer_type::IntegerType; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, path::PathBuf}; @@ -259,8 +261,8 @@ impl Frame { } // Arrays - // Expression::Array(expressions, span) => self.parse_array(expressions, span), - // Expression::ArrayAccess(array, access, span) => self.parse_array_access(array, access, span), + Expression::Array(expressions, span) => self.parse_array(expressions, span), + Expression::ArrayAccess(array, access, span) => self.parse_array_access(array, access, span), // Tuples Expression::Tuple(expressions, span) => self.parse_tuple(expressions, span), @@ -390,70 +392,121 @@ impl Frame { element_type } - // /// - // /// Returns the type of the array expression. - // /// - // fn parse_array(&mut self, expressions: &Vec>, _span: &Span) -> Type { - // // Store actual array element type. - // let mut actual_element_type = None; - // let mut count = 0usize; - // - // // Parse all array elements. - // for expression in expressions { - // // Get the type and count of elements in each spread or expression. - // let (type_, element_count) = self.parse_spread_or_expression(expression); - // - // actual_element_type = Some(type_); - // count += element_count; - // } - // - // // Return an error for empty arrays. - // let type_ = match actual_element_type { - // Some(type_) => type_, - // None => unimplemented!("return empty array error"), - // }; - // - // Type::Array(Box::new(type_), vec![count]) - // } - // - // /// - // /// Returns the type and count of elements in a spread or expression. - // /// - // fn parse_spread_or_expression(&mut self, s_or_e: &SpreadOrExpression) -> (Type, usize) { - // match s_or_e { - // SpreadOrExpression::Spread(expression) => { - // // Parse the type of the spread array expression. - // let array_type = self.parse_expression(expression); - // - // // Check that the type is an array. - // let (element_type, mut dimensions) = match array_type { - // Type::Array(element_type, dimensions) => (element_type, dimensions), - // _ => unimplemented!("Spread type must be an array"), - // }; - // - // // A spread copies the elements of an array. - // // If the array has elements of type array, we must return a new array type with proper dimensions. - // // If the array has elements of any other type, we can return the type and count directly. - // let count = dimensions.pop().unwrap(); - // - // let type_ = if dimensions.is_empty() { - // *element_type - // } else { - // Type::Array(element_type, dimensions) - // }; - // - // (type_, count) - // } - // SpreadOrExpression::Expression(expression) => (self.parse_expression(expression), 1), - // } - // } - // - // /// - // /// Returns the type of the accessed array element. - // /// - // fn parse_array_access(&mut self, array: &Expression, r_or_e: &RangeOrExpression, span: &Span) -> Type { - // // - // } + /// + /// Returns the type of the array expression. + /// + fn parse_array(&mut self, expressions: &Vec>, _span: &Span) -> Type { + // Store actual array element type. + let mut actual_element_type = None; + let mut count = 0usize; + + // Parse all array elements. + for expression in expressions { + // Get the type and count of elements in each spread or expression. + let (type_, element_count) = self.parse_spread_or_expression(expression); + + actual_element_type = Some(type_); + count += element_count; + } + + // Return an error for empty arrays. + let type_ = match actual_element_type { + Some(type_) => type_, + None => unimplemented!("return empty array error"), + }; + + Type::Array(Box::new(type_), vec![count]) + } + + /// + /// Returns the type and count of elements in a spread or expression. + /// + fn parse_spread_or_expression(&mut self, s_or_e: &SpreadOrExpression) -> (Type, usize) { + match s_or_e { + SpreadOrExpression::Spread(expression) => { + // Parse the type of the spread array expression. + let array_type = self.parse_expression(expression); + + // Check that the type is an array. + let (element_type, mut dimensions) = match array_type { + Type::Array(element_type, dimensions) => (element_type, dimensions), + _ => unimplemented!("Spread type must be an array"), + }; + + // A spread copies the elements of an array. + // If the array has elements of type array, we must return a new array type with proper dimensions. + // If the array has elements of any other type, we can return the type and count directly. + let count = dimensions.pop().unwrap(); + + let type_ = if dimensions.is_empty() { + *element_type + } else { + Type::Array(element_type, dimensions) + }; + + (type_, count) + } + SpreadOrExpression::Expression(expression) => (self.parse_expression(expression), 1), + } + } + + /// + /// Returns the type of the accessed array element. + /// + fn parse_array_access(&mut self, expression: &Expression, r_or_e: &RangeOrExpression, span: &Span) -> Type { + // Parse the array expression which could be a variable with type array. + let type_ = self.parse_expression(expression); + + // Check the type is an array. + let (element_type, dimensions) = match type_ { + Type::Array(type_, dimensions) => (type_, dimensions), + _ => unimplemented!("expected an array type"), + }; + + // Get the length of the array. + let length = *dimensions.last().unwrap(); + + // Evaluate the range as an array type or the expression as the element type. + match r_or_e { + RangeOrExpression::Range(from, to) => { + if let Some(expression) = from { + self.parse_index(expression); + } + + if let Some(expression) = to { + self.parse_index(expression); + } + } + RangeOrExpression::Expression(expression) => { + self.parse_index(expression); + } + } + + *element_type + } + + /// + /// Returns the constant integer value of the index. + /// + /// Returns an error if the index is not a constant u8, u16, u32. + /// + fn parse_index(&mut self, expression: &Expression) { + let type_ = self.parse_expression(expression); + + let integer_type = match type_ { + Type::IntegerType(integer_type) => integer_type, + _ => unimplemented!("index must be an integer type"), + }; + + match integer_type { + IntegerType::U8 => {} + IntegerType::U16 => {} + IntegerType::U32 => {} + _ => unimplemented!("index must be u8, u16, u32"), + } + + //TODO (collinc97) perform deeper check in solving + } /// /// Returns a new `Function` if all `TypeAssertions` can be solved successfully. From 65437d3c05afbebc8bd27fe5aaae8ba02b92c223 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 19 Oct 2020 16:03:45 -0700 Subject: [PATCH 039/139] dynamic check parse circuit and circuit access expressions --- dynamic-check/src/dynamic_check.rs | 84 +++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index ae22219b1b..37192428d4 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -17,6 +17,7 @@ use crate::{DynamicCheckError, FrameError, VariableTableError}; use leo_static_check::{CircuitType, FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; use leo_typed::{ + CircuitVariableDefinition, Expression, Function as UnresolvedFunction, Identifier, @@ -103,11 +104,11 @@ impl DynamicCheck { #[derive(Clone)] pub struct Frame { pub function_type: FunctionType, - // pub self_type: Option, - pub statements: Vec, - pub user_defined_types: SymbolTable, - pub type_assertions: Vec, + pub self_type: Option, pub scopes: Vec, + pub statements: Vec, + pub type_assertions: Vec, + pub user_defined_types: SymbolTable, } impl Frame { @@ -132,11 +133,12 @@ impl Frame { // Create new frame struct. // Update variables when encountering let/const variable definitions. let mut frame = Self { - statements: function.statements, function_type, - user_defined_types: symbol_table, - type_assertions: vec![], + self_type: None, scopes, + statements: function.statements, + type_assertions: vec![], + user_defined_types: symbol_table, }; // Create type assertions for function statements @@ -268,6 +270,15 @@ impl Frame { Expression::Tuple(expressions, span) => self.parse_tuple(expressions, span), Expression::TupleAccess(tuple, index, span) => self.parse_tuple_access(tuple, *index, span), + // Circuits + Expression::Circuit(identifier, members, span) => self.parse_circuit(identifier, members, span), + Expression::CircuitMemberAccess(expression, identifier, span) => { + self.parse_circuit_member_access(expression, identifier, span) + } + Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { + self.parse_circuit_static_function_access(expression, identifier, span) + } + expression => unimplemented!("expression {} not implemented", expression), } } @@ -505,7 +516,64 @@ impl Frame { _ => unimplemented!("index must be u8, u16, u32"), } - //TODO (collinc97) perform deeper check in solving + //TODO (collinc97) perform deeper check during solving + } + + /// + /// Returns the type of inline circuit expression. + /// + fn parse_circuit( + &mut self, + identifier: &Identifier, + _members: &Vec, + _span: &Span, + ) -> Type { + Type::Circuit(identifier.clone()) + } + + /// + /// Returns the type of the accessed circuit member. + /// + fn parse_circuit_member_access(&mut self, expression: &Expression, identifier: &Identifier, _span: &Span) -> Type { + // Parse circuit name. + let type_ = self.parse_expression(expression); + + // Check that type is a circuit type. + let circuit_type = match type_ { + Type::Circuit(identifier) => { + // Lookup circuit. + self.user_defined_types.get_circuit(&identifier.name).unwrap() + } + _ => unimplemented!("expected circuit type to access member"), + }; + + // Look for member with matching name. + circuit_type.member_type(&identifier).unwrap().clone() + } + + /// + /// Returns the type returned by calling the static circuit function. + /// + fn parse_circuit_static_function_access( + &mut self, + expression: &Expression, + identifier: &Identifier, + _span: &Span, + ) -> Type { + // Parse the circuit name. + let type_ = self.parse_expression(expression); + + // Check that type is a circuit type. + let circuit_type = match type_ { + Type::Circuit(identifier) => { + // Lookup circuit. + self.user_defined_types.get_circuit(&identifier.name).unwrap() + } + _ => unimplemented!("expected circuit type to access static member"), + }; + + // Look for member with matching name. + circuit_type.member_type(&identifier).unwrap().clone() } /// From d8fd17fb4168cd8b81a858223e74d28d9aa82310 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 19 Oct 2020 17:18:31 -0700 Subject: [PATCH 040/139] impl dynamic checker set membership type assertions --- dynamic-check/src/dynamic_check.rs | 232 +++++++++++++++++++++++++---- static-check/src/types/type_.rs | 49 ++++++ 2 files changed, 255 insertions(+), 26 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 37192428d4..c16c2c8c7e 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -183,6 +183,51 @@ impl Frame { scope.get_variable(name).unwrap() } + /// + /// Creates a new equality type assertion between the given types. + /// + fn create_equality_type_assertion(&mut self, left: Type, right: Type) { + let type_assertion = TypeAssertion::new_equality(left, right); + + self.type_assertions.push(type_assertion); + } + + /// + /// Creates a new membership type assertion between a given and set of types. + /// + fn create_membership_type_assertion(&mut self, given: Type, set: Vec) { + let type_assertion = TypeAssertion::new_membership(given, set); + + self.type_assertions.push(type_assertion); + } + + /// + /// Creates a new membership type assertion between a given and the set of negative integer types. + /// + fn create_negative_membership_type_assertion(&mut self, given: &Type) { + let negative_integer_types = Type::negative_integer_types(); + + self.create_membership_type_assertion(given.clone(), negative_integer_types) + } + + /// + /// Creates a new membership type assertion between a given and the set of all integer types. + /// + fn create_integer_membership_type_assertion(&mut self, given: &Type) { + let integer_types = Type::integer_types(); + + self.create_membership_type_assertion(given.clone(), integer_types) + } + + /// + /// Creates a new membership type assertion between a given and the set of index types. + /// + fn create_index_membership_type_assertion(&mut self, given: &Type) { + let index_types = Type::index_types(); + + self.create_membership_type_assertion(given.clone(), index_types) + } + /// /// Collects a vector of `TypeAssertion` predicates from a vector of statements. /// @@ -218,7 +263,7 @@ impl Frame { let right = self.parse_expression(expression); // Create a new type assertion for the statement return. - let type_assertion = TypeAssertion::new(left, right); + let type_assertion = TypeAssertion::new_equality(left, right); // Push the new type assertion to this function's list of type assertions. self.type_assertions.push(type_assertion) @@ -231,22 +276,22 @@ impl Frame { match expression { // Type variables Expression::Identifier(identifier) => self.parse_identifier(identifier), - Expression::Implicit(name, _) => Self::parse_implicit(name), // Explicit types Expression::Boolean(_, _) => Type::Boolean, Expression::Address(_, _) => Type::Address, Expression::Field(_, _) => Type::Field, Expression::Group(_) => Type::Group, + Expression::Implicit(name, _) => Self::parse_implicit(name), Expression::Integer(integer_type, _, _) => Type::IntegerType(integer_type.clone()), // Number operations - Expression::Add(left, right, span) => self.parse_binary_expression(left, right, span), - Expression::Sub(left, right, span) => self.parse_binary_expression(left, right, span), - Expression::Mul(left, right, span) => self.parse_binary_expression(left, right, span), - Expression::Div(left, right, span) => self.parse_binary_expression(left, right, span), - Expression::Pow(left, right, span) => self.parse_binary_expression(left, right, span), - Expression::Negate(expression, _span) => self.parse_expression(expression), + Expression::Add(left, right, span) => self.parse_integer_binary_expression(left, right, span), + Expression::Sub(left, right, span) => self.parse_integer_binary_expression(left, right, span), + Expression::Mul(left, right, span) => self.parse_integer_binary_expression(left, right, span), + Expression::Div(left, right, span) => self.parse_integer_binary_expression(left, right, span), + Expression::Pow(left, right, span) => self.parse_integer_binary_expression(left, right, span), + Expression::Negate(expression, _span) => self.parse_negate_expression(expression), // Boolean operations Expression::Not(expression, _span) => self.parse_boolean_expression(expression), @@ -254,6 +299,7 @@ impl Frame { Expression::And(left, right, span) => self.parse_boolean_binary_expression(left, right, span), Expression::Eq(left, right, span) => self.parse_boolean_binary_expression(left, right, span), Expression::Ge(left, right, span) => self.parse_boolean_binary_expression(left, right, span), + Expression::Gt(left, right, span) => self.parse_boolean_binary_expression(left, right, span), Expression::Le(left, right, span) => self.parse_boolean_binary_expression(left, right, span), Expression::Lt(left, right, span) => self.parse_boolean_binary_expression(left, right, span), @@ -279,7 +325,9 @@ impl Frame { self.parse_circuit_static_function_access(expression, identifier, span) } - expression => unimplemented!("expression {} not implemented", expression), + // Functions + Expression::FunctionCall(name, arguments, span) => self.parse_function_call(name, arguments, span), + Expression::CoreFunctionCall(name, arguments, span) => self.parse_core_function_call(name, arguments, span), } } @@ -308,14 +356,26 @@ impl Frame { // Get the right expression type. let right_type = self.parse_expression(right); - // TODO (collinc97) throw an error if left type does not match right type - if left_type.ne(&right_type) { - unimplemented!("Mismatched types parse_binary_expression") - } + // Create a type assertion left_type == right_type. + self.create_equality_type_assertion(left_type.clone(), right_type); left_type } + /// + /// Returns the `Type` of the expression after the binary operation. + /// + /// Asserts that the `Type` is an integer. + /// + fn parse_integer_binary_expression(&mut self, left: &Expression, right: &Expression, _span: &Span) -> Type { + let type_ = self.parse_binary_expression(left, right, _span); + + // Assert that the type is an integer. + self.create_integer_membership_type_assertion(&type_); + + type_ + } + /// /// Returns the `Boolean` type if the expression is a `Boolean` type. /// @@ -326,14 +386,25 @@ impl Frame { // Get the type of the expression let expression_type = self.parse_expression(expression); - // TODO (collinc97) throw an error if the expression is not a `Boolean` type. - if expression_type.ne(&boolean_type) { - unimplemented!("Mismatched types parse_boolean_expression") - } + // Assert that the type is a boolean. + self.create_equality_type_assertion(boolean_type.clone(), expression_type); boolean_type } + /// + /// Returns the `Type` of the expression being negated. Must be a negative integer type. + /// + fn parse_negate_expression(&mut self, expression: &Expression) -> Type { + // Parse the expression type. + let type_ = self.parse_expression(expression); + + // Assert that this integer can be negated. + self.create_negative_membership_type_assertion(&type_); + + type_ + } + /// /// Returns the `Boolean` type if the binary expression is a `Boolean` type. /// @@ -344,10 +415,8 @@ impl Frame { // Get the type of the binary expression. let binary_expression_type = self.parse_binary_expression(left, right, _span); - // TODO (collinc97) throw an error if the binary expression is not a `Boolean` type. - if binary_expression_type.ne(&boolean_type) { - unimplemented!("Mismatched types parse_boolean_binary_expression") - } + // Create a type assertion boolean_type == expression_type. + self.create_equality_type_assertion(boolean_type.clone(), binary_expression_type); boolean_type } @@ -576,6 +645,33 @@ impl Frame { circuit_type.member_type(&identifier).unwrap().clone() } + /// + /// Returns the type returned by calling the function. + /// + fn parse_function_call(&mut self, expression: &Expression, _arguments: &Vec, _span: &Span) -> Type { + // Parse the function name. + let type_ = self.parse_expression(expression); + + // Check that type is a function type. + let function_type = match type_ { + Type::Function(identifier) => { + // Lookup function. + self.user_defined_types.get_function(&identifier.name).unwrap() + } + _ => unimplemented!("expected function type for function call"), + }; + + // Return the function output type. + function_type.output.type_.clone() + } + + /// + /// Returns the type returned by calling the core function. + /// + fn parse_core_function_call(&mut self, _name: &String, _arguments: &Vec, _span: &Span) -> Type { + unimplemented!("type checks for core function calls not implemented") + } + /// /// Returns a new `Function` if all `TypeAssertions` can be solved successfully. /// @@ -734,21 +830,105 @@ impl VariableTable { /// A predicate that evaluates equality between two `Types`s. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct TypeAssertion { - left: Type, - right: Type, +pub enum TypeAssertion { + Equality(TypeEquality), + Membership(TypeMembership), } impl TypeAssertion { /// - /// Returns a `TypeAssertion` predicate from given left and right `Types`s + /// Returns a `TypeAssertion::Equality` predicate from given left and right `Types`s. + /// + pub fn new_equality(left: Type, right: Type) -> Self { + Self::Equality(TypeEquality::new(left, right)) + } + + /// + /// Returns a `TypeAssertion::Membership` predicate from given and set `Type`s. + /// + pub fn new_membership(given: Type, set: Vec) -> Self { + Self::Membership(TypeMembership::new(given, set)) + } + + pub fn substitute(&mut self, _variable: &TypeVariable, _type: &Type) { + unimplemented!("substitution not impl") + } + + /// + /// Returns true if the given type assertion outputs true. + /// + pub fn evaluate(&self) -> bool { + match self { + TypeAssertion::Equality(equality) => equality.evaluate(), + TypeAssertion::Membership(membership) => membership.evaluate(), + } + } + + pub fn get_pair(&self) -> Option<(TypeVariable, Type)> { + unimplemented!("pair resolution not impl") + } +} + +/// A predicate that evaluates to true if the given type is equal to a member in the set vector of types. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct TypeMembership { + given: Type, + set: Vec, +} + +impl TypeMembership { + /// + /// Returns a `TypeMembership` predicate from given and set `Type`s. + /// + pub fn new(given: Type, set: Vec) -> Self { + Self { given, set } + } + + /// + /// Substitutes the given `TypeVariable` for each `Type` in the `TypeMembership`. + /// + pub fn substitute(&mut self, _variable: &TypeVariable, _type_: &Type) { + // self.left.substitute(variable, type_); + // self.right.substitute(variable, type_); + } + + /// + /// Returns true if the given type is equal to a member of the set. + /// + pub fn evaluate(&self) -> bool { + self.set.contains(&self.given) + } + + /// + /// Returns the (type variable, type) pair from this assertion. + /// + pub fn get_pair(&self) -> Option<(TypeVariable, Type)> { + // match (&self.left, &self.right) { + // (Type::TypeVariable(variable), type_) => Some((variable.clone(), type_.clone())), + // (type_, Type::TypeVariable(variable)) => Some((variable.clone(), type_.clone())), + // (_type1, _type2) => None, // No (type variable, type) pair can be returned from two types + // } + unimplemented!("pair resolution not impl") + } +} + +/// A predicate that evaluates equality between two `Type`s. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct TypeEquality { + left: Type, + right: Type, +} + +impl TypeEquality { + /// + /// Returns a `TypeEquality` predicate from given left and right `Types`s /// pub fn new(left: Type, right: Type) -> Self { Self { left, right } } /// - /// Substitutes the given `TypeVariable` for each `Types` in the `TypeAssertion`. + /// Substitutes the given `TypeVariable` for each `Types` in the `TypeEquality`. /// pub fn substitute(&mut self, _variable: &TypeVariable, _type_: &Type) { // self.left.substitute(variable, type_); diff --git a/static-check/src/types/type_.rs b/static-check/src/types/type_.rs index 085bed6274..968cc427a1 100644 --- a/static-check/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -181,6 +181,55 @@ impl Type { type_ => Err(TypeError::invalid_function(type_, span)), } } + + /// Returns a list of signed integer types. + pub fn signed_integer_types() -> Vec { + vec![ + Type::IntegerType(IntegerType::I8), + Type::IntegerType(IntegerType::I16), + Type::IntegerType(IntegerType::I32), + Type::IntegerType(IntegerType::I64), + Type::IntegerType(IntegerType::I128), + ] + } + + /// Returns a list of unsigned integer types. + pub fn unsigned_integer_types() -> Vec { + vec![ + Type::IntegerType(IntegerType::U8), + Type::IntegerType(IntegerType::U16), + Type::IntegerType(IntegerType::U32), + Type::IntegerType(IntegerType::U64), + Type::IntegerType(IntegerType::U128), + ] + } + + /// Returns a list of positive integer types. + pub fn negative_integer_types() -> Vec { + let mut types = vec![Type::Field, Type::Group]; + + types.append(&mut Self::signed_integer_types()); + + types + } + + /// Returns a list of integer types. + pub fn integer_types() -> Vec { + let mut types = Self::negative_integer_types(); + + types.append(&mut Self::unsigned_integer_types()); + + types + } + + /// Returns a list of possible index types (u8, u16, u32). + pub fn index_types() -> Vec { + vec![ + Type::IntegerType(IntegerType::U8), + Type::IntegerType(IntegerType::U16), + Type::IntegerType(IntegerType::U32), + ] + } } impl fmt::Display for Type { From f30f61565565afefc4f4979f337e07a768929b22 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 20 Oct 2020 13:14:16 -0700 Subject: [PATCH 041/139] impl dynamic checker definition statements --- ast/src/statements/definition_statement.rs | 11 +- .../src/statement/definition/definition.rs | 54 +---- dynamic-check/src/dynamic_check.rs | 191 +++++++++++++----- typed/src/statements/statement.rs | 25 +-- 4 files changed, 155 insertions(+), 126 deletions(-) diff --git a/ast/src/statements/definition_statement.rs b/ast/src/statements/definition_statement.rs index 6c78a6ffe3..a8637cd0c1 100644 --- a/ast/src/statements/definition_statement.rs +++ b/ast/src/statements/definition_statement.rs @@ -31,7 +31,7 @@ use std::fmt; pub struct DefinitionStatement<'ast> { pub declare: Declare, pub variables: Variables<'ast>, - pub expressions: Vec>, + pub expression: Expression<'ast>, pub line_end: LineEnd, #[pest_ast(outer())] #[serde(with = "SpanDef")] @@ -40,13 +40,6 @@ pub struct DefinitionStatement<'ast> { impl<'ast> fmt::Display for DefinitionStatement<'ast> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let expressions = self - .expressions - .iter() - .map(|x| format!("{}", x)) - .collect::>() - .join(","); - - write!(f, "let {} = {};", self.variables, expressions) + write!(f, "let {} = {};", self.variables, self.expression) } } diff --git a/compiler/src/statement/definition/definition.rs b/compiler/src/statement/definition/definition.rs index 76da259ba2..1a54214a35 100644 --- a/compiler/src/statement/definition/definition.rs +++ b/compiler/src/statement/definition/definition.rs @@ -142,67 +142,35 @@ impl> ConstrainedProgram { function_scope: String, declare: Declare, variables: Variables, - expressions: Vec, + expression: Expression, span: Span, ) -> Result<(), StatementError> { let num_variables = variables.names.len(); - let num_values = expressions.len(); let is_constant = match declare { Declare::Let => false, Declare::Const => true, }; + let expression = self.enforce_expression( + cs, + file_scope.clone(), + function_scope.clone(), + variables.type_.clone(), + expression, + )?; - if num_variables == 1 && num_values == 1 { + if num_variables == 1 { // Define a single variable with a single value let variable = variables.names[0].clone(); - let expression = self.enforce_expression( - cs, - file_scope.clone(), - function_scope.clone(), - variables.type_, - expressions[0].clone(), - )?; self.enforce_single_definition(cs, function_scope, is_constant, variable, expression, span) - } else if num_variables == 1 && num_values > 1 { - // Define a tuple (single variable with multiple values) - - self.enforce_tuple_definition( - cs, - file_scope, - function_scope, - is_constant, - variables, - expressions, - span, - ) - } else if num_variables > 1 && num_values == 1 { + } else { // Define multiple variables for an expression that returns multiple results (multiple definition) - - let values = match self.enforce_expression( - cs, - file_scope.clone(), - function_scope.clone(), - variables.type_.clone(), - expressions[0].clone(), - )? { + let values = match expression { // ConstrainedValue::Return(values) => values, ConstrainedValue::Tuple(values) => values, value => return Err(StatementError::multiple_definition(value.to_string(), span.clone())), }; - self.enforce_multiple_definition(cs, function_scope, is_constant, variables, values, span) - } else { - // Define multiple variables for multiple expressions - let values = self.enforce_expressions( - cs, - file_scope, - function_scope.clone(), - variables.type_.clone(), - expressions, - span.clone(), - )?; - self.enforce_multiple_definition(cs, function_scope, is_constant, variables, values, span) } } diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index c16c2c8c7e..83e50bb466 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -18,6 +18,7 @@ use crate::{DynamicCheckError, FrameError, VariableTableError}; use leo_static_check::{CircuitType, FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; use leo_typed::{ CircuitVariableDefinition, + Declare, Expression, Function as UnresolvedFunction, Identifier, @@ -26,6 +27,7 @@ use leo_typed::{ Span, SpreadOrExpression, Statement as UnresolvedStatement, + Variables, }; use leo_typed::integer_type::IntegerType; @@ -186,7 +188,7 @@ impl Frame { /// /// Creates a new equality type assertion between the given types. /// - fn create_equality_type_assertion(&mut self, left: Type, right: Type) { + fn assert_equal(&mut self, left: Type, right: Type) { let type_assertion = TypeAssertion::new_equality(left, right); self.type_assertions.push(type_assertion); @@ -195,7 +197,7 @@ impl Frame { /// /// Creates a new membership type assertion between a given and set of types. /// - fn create_membership_type_assertion(&mut self, given: Type, set: Vec) { + fn assert_membership(&mut self, given: Type, set: Vec) { let type_assertion = TypeAssertion::new_membership(given, set); self.type_assertions.push(type_assertion); @@ -204,28 +206,28 @@ impl Frame { /// /// Creates a new membership type assertion between a given and the set of negative integer types. /// - fn create_negative_membership_type_assertion(&mut self, given: &Type) { + fn assert_negative_integer(&mut self, given: &Type) { let negative_integer_types = Type::negative_integer_types(); - self.create_membership_type_assertion(given.clone(), negative_integer_types) + self.assert_membership(given.clone(), negative_integer_types) } /// /// Creates a new membership type assertion between a given and the set of all integer types. /// - fn create_integer_membership_type_assertion(&mut self, given: &Type) { + fn assert_integer(&mut self, given: &Type) { let integer_types = Type::integer_types(); - self.create_membership_type_assertion(given.clone(), integer_types) + self.assert_membership(given.clone(), integer_types) } /// /// Creates a new membership type assertion between a given and the set of index types. /// - fn create_index_membership_type_assertion(&mut self, given: &Type) { + fn assert_index(&mut self, given: &Type) { let index_types = Type::index_types(); - self.create_membership_type_assertion(given.clone(), index_types) + self.assert_membership(given.clone(), index_types) } /// @@ -243,16 +245,19 @@ impl Frame { fn parse_statement(&mut self, statement: &UnresolvedStatement) { match statement { UnresolvedStatement::Return(expression, span) => { - self.parse_statement_return(expression, span); + self.parse_return(expression, span); + } + UnresolvedStatement::Definition(declare, variables, expression, span) => { + self.parse_definition(declare, variables, expression, span) } statement => unimplemented!("statement {} not implemented", statement), } } /// - /// Collects a `TypeAssertion` predicate from a statement return. + /// Collects `TypeAssertion` predicates from a return statement. /// - fn parse_statement_return(&mut self, expression: &Expression, _span: &Span) { + fn parse_return(&mut self, expression: &Expression, _span: &Span) { // Get the function output type. let output_type = &self.function_type.output.type_; @@ -263,10 +268,56 @@ impl Frame { let right = self.parse_expression(expression); // Create a new type assertion for the statement return. - let type_assertion = TypeAssertion::new_equality(left, right); + self.assert_equal(left, right); + } - // Push the new type assertion to this function's list of type assertions. - self.type_assertions.push(type_assertion) + /// + /// Collects `Type Assertion` predicates from a definition statement. + /// + fn parse_definition(&mut self, _declare: &Declare, variables: &Variables, expression: &Expression, span: &Span) { + // Parse the definition expression. + let actual_type = self.parse_expression(expression); + + // Check if an explicit type is given. + if let Some(type_) = variables.type_.clone() { + // Convert the expected type into a dynamic check type. + let expected_type = match self.self_type.clone() { + Some(circuit_type) => { + Type::new_from_circuit(&self.user_defined_types, type_, circuit_type.identifier, span.clone()) + .unwrap() + } + None => Type::new(&self.user_defined_types, type_, span.clone()).unwrap(), + }; + + // Assert that the expected type is equal to the actual type. + self.assert_equal(expected_type.clone(), actual_type.clone()) + } + + // Check for multiple defined variables. + if variables.names.len() == 1 { + // Insert variable into symbol table + let variable = variables.names[0].clone(); + + // TODO (collinc97) throw error for duplicate variable definitions. + self.insert_variable(variable.identifier.name, actual_type).unwrap(); + } else { + // Expect a tuple type. + let types = match actual_type { + Type::Tuple(types) => types, + _ => unimplemented!("expected a tuple type for multiple defined variables"), + }; + + // Check number of variables == number of types. + if types.len() != variables.names.len() { + unimplemented!("Incorrect number of defined variables") + } + + // Insert variables into symbol table + for (variable, type_) in variables.names.iter().zip(types) { + // TODO (collinc97) throw error for duplicate variable definitions. + self.insert_variable(variable.identifier.name.clone(), type_).unwrap(); + } + } } /// @@ -357,7 +408,7 @@ impl Frame { let right_type = self.parse_expression(right); // Create a type assertion left_type == right_type. - self.create_equality_type_assertion(left_type.clone(), right_type); + self.assert_equal(left_type.clone(), right_type); left_type } @@ -371,7 +422,7 @@ impl Frame { let type_ = self.parse_binary_expression(left, right, _span); // Assert that the type is an integer. - self.create_integer_membership_type_assertion(&type_); + self.assert_integer(&type_); type_ } @@ -387,7 +438,7 @@ impl Frame { let expression_type = self.parse_expression(expression); // Assert that the type is a boolean. - self.create_equality_type_assertion(boolean_type.clone(), expression_type); + self.assert_equal(boolean_type.clone(), expression_type); boolean_type } @@ -400,7 +451,7 @@ impl Frame { let type_ = self.parse_expression(expression); // Assert that this integer can be negated. - self.create_negative_membership_type_assertion(&type_); + self.assert_negative_integer(&type_); type_ } @@ -416,7 +467,7 @@ impl Frame { let binary_expression_type = self.parse_binary_expression(left, right, _span); // Create a type assertion boolean_type == expression_type. - self.create_equality_type_assertion(boolean_type.clone(), binary_expression_type); + self.assert_equal(boolean_type.clone(), binary_expression_type); boolean_type } @@ -476,8 +527,8 @@ impl Frame { /// Returns the type of the array expression. /// fn parse_array(&mut self, expressions: &Vec>, _span: &Span) -> Type { - // Store actual array element type. - let mut actual_element_type = None; + // Store array element type. + let mut element_type = None; let mut count = 0usize; // Parse all array elements. @@ -485,12 +536,20 @@ impl Frame { // Get the type and count of elements in each spread or expression. let (type_, element_count) = self.parse_spread_or_expression(expression); - actual_element_type = Some(type_); + // Assert that array element types are the same. + if let Some(prev_type) = element_type { + self.assert_equal(prev_type, type_.clone()) + } + + // Update array element type. + element_type = Some(type_); + + // Update number of array elements. count += element_count; } // Return an error for empty arrays. - let type_ = match actual_element_type { + let type_ = match element_type { Some(type_) => type_, None => unimplemented!("return empty array error"), }; @@ -544,59 +603,71 @@ impl Frame { }; // Get the length of the array. - let length = *dimensions.last().unwrap(); + // let length = *dimensions.last().unwrap(); // Evaluate the range as an array type or the expression as the element type. match r_or_e { RangeOrExpression::Range(from, to) => { if let Some(expression) = from { - self.parse_index(expression); + // Parse the expression type. + let type_ = self.parse_expression(expression); + + self.assert_index(&type_); } if let Some(expression) = to { - self.parse_index(expression); + // Parse the expression type. + let type_ = self.parse_expression(expression); + + self.assert_index(&type_); } } RangeOrExpression::Expression(expression) => { - self.parse_index(expression); + // Parse the expression type. + let type_ = self.parse_expression(expression); + + // Assert the type is an index. + self.assert_index(&type_); } } *element_type } - /// - /// Returns the constant integer value of the index. - /// - /// Returns an error if the index is not a constant u8, u16, u32. - /// - fn parse_index(&mut self, expression: &Expression) { - let type_ = self.parse_expression(expression); - - let integer_type = match type_ { - Type::IntegerType(integer_type) => integer_type, - _ => unimplemented!("index must be an integer type"), - }; - - match integer_type { - IntegerType::U8 => {} - IntegerType::U16 => {} - IntegerType::U32 => {} - _ => unimplemented!("index must be u8, u16, u32"), - } - - //TODO (collinc97) perform deeper check during solving - } - /// /// Returns the type of inline circuit expression. /// fn parse_circuit( &mut self, identifier: &Identifier, - _members: &Vec, + members: &Vec, _span: &Span, ) -> Type { + // Check if identifier is Self circuit type. + let circuit_type = if identifier.is_self() { + self.self_type.clone() + } else { + // Get circuit type. + self.user_defined_types + .get_circuit(&identifier.name) + .map(|circuit_type| circuit_type.clone()) + } + .unwrap(); + + // Check the length of the circuit members. + if circuit_type.variables.len() != members.len() { + unimplemented!("Number of circuit arguments invalid") + } + + // Assert members are circuit type member types. + for (expected_variable, actual_variable) in circuit_type.variables.iter().zip(members) { + // Parse actual variable expression. + let actual_type = self.parse_expression(&actual_variable.expression); + + // Assert expected variable type == actual variable type. + self.assert_equal(expected_variable.type_.clone(), actual_type) + } + Type::Circuit(identifier.clone()) } @@ -648,7 +719,7 @@ impl Frame { /// /// Returns the type returned by calling the function. /// - fn parse_function_call(&mut self, expression: &Expression, _arguments: &Vec, _span: &Span) -> Type { + fn parse_function_call(&mut self, expression: &Expression, inputs: &Vec, _span: &Span) -> Type { // Parse the function name. let type_ = self.parse_expression(expression); @@ -656,11 +727,25 @@ impl Frame { let function_type = match type_ { Type::Function(identifier) => { // Lookup function. - self.user_defined_types.get_function(&identifier.name).unwrap() + self.user_defined_types.get_function(&identifier.name).unwrap().clone() } _ => unimplemented!("expected function type for function call"), }; + // Check the length of arguments + if function_type.inputs.len() != inputs.len() { + unimplemented!("Number of function arguments invalid") + } + + // Assert function inputs are correct types. + for (expected_input, actual_input) in function_type.inputs.iter().zip(inputs) { + // Parse actual input expression. + let actual_type = self.parse_expression(actual_input); + + // Assert expected input type == actual input type. + self.assert_equal(expected_input.type_().clone(), actual_type); + } + // Return the function output type. function_type.output.type_.clone() } diff --git a/typed/src/statements/statement.rs b/typed/src/statements/statement.rs index b56defbc27..c6696ad8ca 100644 --- a/typed/src/statements/statement.rs +++ b/typed/src/statements/statement.rs @@ -35,7 +35,7 @@ use std::fmt; #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum Statement { Return(Expression, Span), - Definition(Declare, Variables, Vec, Span), + Definition(Declare, Variables, Expression, Span), Assign(Assignee, Expression, Span), Conditional(ConditionalStatement, Span), Iteration(Identifier, Expression, Expression, Vec, Span), @@ -53,21 +53,10 @@ impl<'ast> From> for Statement { fn from(statement: DefinitionStatement<'ast>) -> Self { let span = Span::from(statement.span); - let expressions = statement - .expressions - .into_iter() - .map(|e| { - let mut expression = Expression::from(e); - expression.set_span(&span); - - expression - }) - .collect::>(); - Statement::Definition( Declare::from(statement.declare), Variables::from(statement.variables), - expressions, + Expression::from(statement.expression), span, ) } @@ -192,14 +181,8 @@ impl fmt::Display for Statement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Statement::Return(ref expression, ref _span) => write!(f, "return {}", expression), - Statement::Definition(ref declare, ref variable, ref expressions, ref _span) => { - let formatted_expressions = expressions - .iter() - .map(|x| format!("{}", x)) - .collect::>() - .join(","); - - write!(f, "{} {} = {};", declare, variable, formatted_expressions) + Statement::Definition(ref declare, ref variable, ref expression, ref _span) => { + write!(f, "{} {} = {};", declare, variable, expression) } Statement::Assign(ref variable, ref statement, ref _span) => write!(f, "{} = {};", variable, statement), Statement::Conditional(ref statement, ref _span) => write!(f, "{}", statement), From 07a17e28460fea7e64bf11e5c660fea7b798facb Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 20 Oct 2020 20:36:15 -0700 Subject: [PATCH 042/139] impl dynamic checker assign statement wip --- dynamic-check/src/dynamic_check.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 83e50bb466..8ebcb7cb06 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -17,6 +17,7 @@ use crate::{DynamicCheckError, FrameError, VariableTableError}; use leo_static_check::{CircuitType, FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; use leo_typed::{ + Assignee, CircuitVariableDefinition, Declare, Expression, @@ -250,6 +251,7 @@ impl Frame { UnresolvedStatement::Definition(declare, variables, expression, span) => { self.parse_definition(declare, variables, expression, span) } + UnresolvedStatement::Assign(assignee, expression, span) => self.parse_assign(assignee, expression, span), statement => unimplemented!("statement {} not implemented", statement), } } @@ -320,6 +322,13 @@ impl Frame { } } + /// + /// Collects `TypeAssertion` predicates from an assignment statement. + /// + fn parse_assign(&mut self, assignee: &Assignee, expression: &Expression, span: &Span) { + // + } + /// /// Returns the type of an expression. /// From 71d3969ac5e3aa8e0bf68274681e5ce2dd6ff5b8 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 21 Oct 2020 16:13:52 -0700 Subject: [PATCH 043/139] impl dynamic checker expression statement --- dynamic-check/src/dynamic_check.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 8ebcb7cb06..235db7b49e 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -252,6 +252,7 @@ impl Frame { self.parse_definition(declare, variables, expression, span) } UnresolvedStatement::Assign(assignee, expression, span) => self.parse_assign(assignee, expression, span), + UnresolvedStatement::Expression(expression, span) => self.parse_statement_expression(expression, span), statement => unimplemented!("statement {} not implemented", statement), } } @@ -325,8 +326,21 @@ impl Frame { /// /// Collects `TypeAssertion` predicates from an assignment statement. /// - fn parse_assign(&mut self, assignee: &Assignee, expression: &Expression, span: &Span) { - // + fn parse_assign(&mut self, _assignee: &Assignee, _expression: &Expression, _span: &Span) { + // TODO (collinc97) impl locations. + } + + /// + /// Asserts that the statement `UnresolvedExpression` returns an empty tuple. + /// + fn parse_statement_expression(&mut self, expression: &Expression, _span: &Span) { + // Create empty tuple type. + let expected_type = Type::Tuple(Vec::with_capacity(0)); + + // Parse the actual type of the expression. + let actual_type = self.parse_expression(expression); + + self.assert_equal(expected_type, actual_type); } /// From cfb5e1b5f743522a67d974ac00c15ddd758a4f91 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 21 Oct 2020 20:15:08 -0700 Subject: [PATCH 044/139] impl dynamic checker conditional statement --- dynamic-check/src/dynamic_check.rs | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 235db7b49e..d9109986fa 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -19,6 +19,8 @@ use leo_static_check::{CircuitType, FunctionInputType, FunctionType, SymbolTable use leo_typed::{ Assignee, CircuitVariableDefinition, + ConditionalNestedOrEndStatement, + ConditionalStatement, Declare, Expression, Function as UnresolvedFunction, @@ -252,6 +254,7 @@ impl Frame { self.parse_definition(declare, variables, expression, span) } UnresolvedStatement::Assign(assignee, expression, span) => self.parse_assign(assignee, expression, span), + UnresolvedStatement::Conditional(conditional, span) => self.parse_statement_conditional(conditional, span), UnresolvedStatement::Expression(expression, span) => self.parse_statement_expression(expression, span), statement => unimplemented!("statement {} not implemented", statement), } @@ -330,6 +333,58 @@ impl Frame { // TODO (collinc97) impl locations. } + /// + /// Collects `TypeAssertion` predicates from a conditional statement. + /// + /// Creates a new scope for each code block in the conditional. + /// + fn parse_statement_conditional(&mut self, conditional: &ConditionalStatement, span: &Span) { + // Parse the condition expression. + let condition = self.parse_expression(&conditional.condition); + + // Assert that the condition is a boolean type. + let boolean_type = Type::Boolean; + self.assert_equal(boolean_type, condition); + + // Parse conditional statements. + self.parse_block(&conditional.statements, span); + + // Parse conditional or end. + match &conditional.next { + Some(cond_or_end) => self.parse_conditional_nested_or_end(cond_or_end, span), + None => {} + } + } + + /// + /// Collects `TypeAssertion` predicates from a conditional statement. + /// + fn parse_conditional_nested_or_end(&mut self, cond_or_end: &ConditionalNestedOrEndStatement, span: &Span) { + match cond_or_end { + ConditionalNestedOrEndStatement::Nested(nested) => { + self.parse_statement_conditional(nested, span); + } + ConditionalNestedOrEndStatement::End(statements) => self.parse_block(statements, span), + } + } + + /// + /// Collects `TypeAssertion` predicates from a block of statements. + /// + fn parse_block(&mut self, statements: &Vec, _span: &Span) { + // Push new scope. + let scope = Scope::new(self.scopes.last().map(|scope| scope.clone())); + self.push_scope(scope); + + // Parse all statements. + for statement in statements.iter() { + self.parse_statement(statement); + } + + // Pop out of scope. + let _scope = self.pop_scope(); + } + /// /// Asserts that the statement `UnresolvedExpression` returns an empty tuple. /// From e5015ccce783fc18caf23639713f8e33752f27e4 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 21 Oct 2020 20:50:14 -0700 Subject: [PATCH 045/139] impl dynamic checker iteration statement --- dynamic-check/src/dynamic_check.rs | 52 +++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index d9109986fa..76dfc0df74 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -255,6 +255,9 @@ impl Frame { } UnresolvedStatement::Assign(assignee, expression, span) => self.parse_assign(assignee, expression, span), UnresolvedStatement::Conditional(conditional, span) => self.parse_statement_conditional(conditional, span), + UnresolvedStatement::Iteration(identifier, from, to, statements, span) => { + self.parse_iteration(identifier, from, to, statements, span) + } UnresolvedStatement::Expression(expression, span) => self.parse_statement_expression(expression, span), statement => unimplemented!("statement {} not implemented", statement), } @@ -333,6 +336,23 @@ impl Frame { // TODO (collinc97) impl locations. } + /// + /// Collects `TypeAssertion` predicates from a block of statements. + /// + fn parse_block(&mut self, statements: &Vec, _span: &Span) { + // Push new scope. + let scope = Scope::new(self.scopes.last().map(|scope| scope.clone())); + self.push_scope(scope); + + // Parse all statements. + for statement in statements.iter() { + self.parse_statement(statement); + } + + // Pop out of scope. + let _scope = self.pop_scope(); + } + /// /// Collects `TypeAssertion` predicates from a conditional statement. /// @@ -369,20 +389,30 @@ impl Frame { } /// - /// Collects `TypeAssertion` predicates from a block of statements. + /// Collects `TypeAssertion` predicates from an iteration statement. /// - fn parse_block(&mut self, statements: &Vec, _span: &Span) { - // Push new scope. - let scope = Scope::new(self.scopes.last().map(|scope| scope.clone())); - self.push_scope(scope); + fn parse_iteration( + &mut self, + identifier: &Identifier, + from: &Expression, + to: &Expression, + statements: &Vec, + span: &Span, + ) { + // Insert variable into symbol table with u32 type. + let u32_type = Type::IntegerType(IntegerType::U32); + self.insert_variable(identifier.name.to_owned(), u32_type.clone()); - // Parse all statements. - for statement in statements.iter() { - self.parse_statement(statement); - } + // Parse `from` and `to` expressions. + let from_type = self.parse_expression(from); + let to_type = self.parse_expression(to); - // Pop out of scope. - let _scope = self.pop_scope(); + // Assert `from` and `to` types are a u32 or implicit. + self.assert_equal(u32_type.clone(), from_type); + self.assert_equal(u32_type, to_type); + + // Parse block of statements. + self.parse_block(statements, span); } /// From 31ace3168f5abb0be5313bf047aa60908660a051 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 21 Oct 2020 20:59:25 -0700 Subject: [PATCH 046/139] handle console function call statement --- dynamic-check/src/dynamic_check.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 76dfc0df74..a028c51295 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -21,6 +21,7 @@ use leo_typed::{ CircuitVariableDefinition, ConditionalNestedOrEndStatement, ConditionalStatement, + ConsoleFunctionCall, Declare, Expression, Function as UnresolvedFunction, @@ -35,7 +36,7 @@ use leo_typed::{ use leo_typed::integer_type::IntegerType; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, path::PathBuf}; +use std::collections::HashMap; /// Performs a dynamic type inference check over a program. pub struct DynamicCheck { @@ -259,7 +260,7 @@ impl Frame { self.parse_iteration(identifier, from, to, statements, span) } UnresolvedStatement::Expression(expression, span) => self.parse_statement_expression(expression, span), - statement => unimplemented!("statement {} not implemented", statement), + UnresolvedStatement::Console(console_call) => self.parse_console_function_call(console_call), } } @@ -428,6 +429,13 @@ impl Frame { self.assert_equal(expected_type, actual_type); } + /// + /// Collects `TypeAssertion` predicates from a console statement. + /// + fn parse_console_function_call(&mut self, _console_function_call: &ConsoleFunctionCall) { + // TODO (collinc97) find a way to fetch console function call types here + } + /// /// Returns the type of an expression. /// @@ -700,7 +708,7 @@ impl Frame { /// /// Returns the type of the accessed array element. /// - fn parse_array_access(&mut self, expression: &Expression, r_or_e: &RangeOrExpression, span: &Span) -> Type { + fn parse_array_access(&mut self, expression: &Expression, r_or_e: &RangeOrExpression, _span: &Span) -> Type { // Parse the array expression which could be a variable with type array. let type_ = self.parse_expression(expression); From ff62d9db7eb3a467e71395dda93d05c75382f942 Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 22 Oct 2020 12:40:35 -0700 Subject: [PATCH 047/139] impl dynamic check solving for equality checks --- dynamic-check/src/dynamic_check.rs | 137 +++++++++++++++++++++++------ dynamic-check/tests/empty.leo | 7 ++ dynamic-check/tests/mod.rs | 2 +- static-check/src/types/type_.rs | 11 +++ 4 files changed, 129 insertions(+), 28 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index a028c51295..e2bf663d70 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -18,6 +18,7 @@ use crate::{DynamicCheckError, FrameError, VariableTableError}; use leo_static_check::{CircuitType, FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; use leo_typed::{ Assignee, + AssigneeAccess, CircuitVariableDefinition, ConditionalNestedOrEndStatement, ConditionalStatement, @@ -309,7 +310,7 @@ impl Frame { let variable = variables.names[0].clone(); // TODO (collinc97) throw error for duplicate variable definitions. - self.insert_variable(variable.identifier.name, actual_type).unwrap(); + let _expect_none = self.insert_variable(variable.identifier.name, actual_type); } else { // Expect a tuple type. let types = match actual_type { @@ -325,16 +326,44 @@ impl Frame { // Insert variables into symbol table for (variable, type_) in variables.names.iter().zip(types) { // TODO (collinc97) throw error for duplicate variable definitions. - self.insert_variable(variable.identifier.name.clone(), type_).unwrap(); + let _expect_none = self.insert_variable(variable.identifier.name.clone(), type_); } } } /// - /// Collects `TypeAssertion` predicates from an assignment statement. + /// Asserts that the assignee's type is equal to the `Expression` type. /// - fn parse_assign(&mut self, _assignee: &Assignee, _expression: &Expression, _span: &Span) { - // TODO (collinc97) impl locations. + fn parse_assign(&mut self, assignee: &Assignee, expression: &Expression, span: &Span) { + // Parse assignee type. + let assignee_type = self.parse_assignee(assignee, span); + + // Parse expression type. + let expression_type = self.parse_expression(expression); + + // Assert that the assignee_type == expression_type. + self.assert_equal(assignee_type, expression_type); + } + + /// + /// Returns the type of the assignee. + /// + fn parse_assignee(&mut self, assignee: &Assignee, span: &Span) -> Type { + // Get the type of the assignee variable. + let mut type_ = self.get_variable(&assignee.identifier.name).to_owned(); + + // Iteratively evaluate assignee access types. + for access in &assignee.accesses { + let access_type = match access { + AssigneeAccess::Array(r_or_e) => self.parse_array_access(type_, r_or_e, span), + AssigneeAccess::Tuple(index) => self.parse_tuple_access(type_, *index, span), + AssigneeAccess::Member(identifier) => self.parse_circuit_member_access(type_, identifier, span), + }; + + type_ = access_type; + } + + type_ } /// @@ -402,7 +431,7 @@ impl Frame { ) { // Insert variable into symbol table with u32 type. let u32_type = Type::IntegerType(IntegerType::U32); - self.insert_variable(identifier.name.to_owned(), u32_type.clone()); + let _expect_none = self.insert_variable(identifier.name.to_owned(), u32_type.clone()); // Parse `from` and `to` expressions. let from_type = self.parse_expression(from); @@ -477,16 +506,16 @@ impl Frame { // Arrays Expression::Array(expressions, span) => self.parse_array(expressions, span), - Expression::ArrayAccess(array, access, span) => self.parse_array_access(array, access, span), + Expression::ArrayAccess(array, access, span) => self.parse_expression_array_access(array, access, span), // Tuples Expression::Tuple(expressions, span) => self.parse_tuple(expressions, span), - Expression::TupleAccess(tuple, index, span) => self.parse_tuple_access(tuple, *index, span), + Expression::TupleAccess(tuple, index, span) => self.parse_expression_tuple_access(tuple, *index, span), // Circuits Expression::Circuit(identifier, members, span) => self.parse_circuit(identifier, members, span), Expression::CircuitMemberAccess(expression, identifier, span) => { - self.parse_circuit_member_access(expression, identifier, span) + self.parse_expression_circuit_member_access(expression, identifier, span) } Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { self.parse_circuit_static_function_access(expression, identifier, span) @@ -622,12 +651,20 @@ impl Frame { } /// - /// Returns the type of the accessed tuple element. + /// Returns the type of the accessed tuple element when called as an expression. /// - fn parse_tuple_access(&mut self, expression: &Expression, index: usize, _span: &Span) -> Type { + fn parse_expression_tuple_access(&mut self, expression: &Expression, index: usize, span: &Span) -> Type { // Parse the tuple expression which could be a variable with type tuple. let type_ = self.parse_expression(expression); + // Parse the tuple access. + self.parse_tuple_access(type_, index, span) + } + + /// + /// Returns the type of the accessed tuple element. + /// + fn parse_tuple_access(&mut self, type_: Type, index: usize, _span: &Span) -> Type { // Check the type is a tuple. let elements = match type_ { Type::Tuple(elements) => elements, @@ -706,14 +743,27 @@ impl Frame { } /// - /// Returns the type of the accessed array element. + /// Returns the type of the accessed array element when called as an expression. /// - fn parse_array_access(&mut self, expression: &Expression, r_or_e: &RangeOrExpression, _span: &Span) -> Type { + fn parse_expression_array_access( + &mut self, + expression: &Expression, + r_or_e: &RangeOrExpression, + span: &Span, + ) -> Type { // Parse the array expression which could be a variable with type array. let type_ = self.parse_expression(expression); + // Parse the array access. + self.parse_array_access(type_, r_or_e, span) + } + + /// + /// Returns the type of the accessed array element. + /// + fn parse_array_access(&mut self, type_: Type, r_or_e: &RangeOrExpression, _span: &Span) -> Type { // Check the type is an array. - let (element_type, dimensions) = match type_ { + let (element_type, _dimensions) = match type_ { Type::Array(type_, dimensions) => (type_, dimensions), _ => unimplemented!("expected an array type"), }; @@ -788,12 +838,25 @@ impl Frame { } /// - /// Returns the type of the accessed circuit member. + /// Returns the type of the accessed circuit member when called as an expression. /// - fn parse_circuit_member_access(&mut self, expression: &Expression, identifier: &Identifier, _span: &Span) -> Type { + fn parse_expression_circuit_member_access( + &mut self, + expression: &Expression, + identifier: &Identifier, + span: &Span, + ) -> Type { // Parse circuit name. let type_ = self.parse_expression(expression); + // Parse the circuit member access. + self.parse_circuit_member_access(type_, identifier, span) + } + + /// + /// Returns the type of the accessed circuit member. + /// + fn parse_circuit_member_access(&mut self, type_: Type, identifier: &Identifier, _span: &Span) -> Type { // Check that type is a circuit type. let circuit_type = match type_ { Type::Circuit(identifier) => { @@ -835,6 +898,8 @@ impl Frame { /// /// Returns the type returned by calling the function. /// + /// Does not attempt to evaluate the function call. We are just checking types at this step. + /// fn parse_function_call(&mut self, expression: &Expression, inputs: &Vec, _span: &Span) -> Type { // Parse the function name. let type_ = self.parse_expression(expression); @@ -886,11 +951,13 @@ impl Frame { println!("assertion: {:?}", type_assertion); // Get type variable and type - if let Some((type_variable, type_)) = type_assertion.get_pair() { + if let Some((type_variable, type_)) = type_assertion.solve() { // Substitute type variable for type in unsolved for original in &mut unsolved { original.substitute(&type_variable, &type_) } + } else { + // Evaluate the type assertion. } } @@ -1051,8 +1118,13 @@ impl TypeAssertion { Self::Membership(TypeMembership::new(given, set)) } - pub fn substitute(&mut self, _variable: &TypeVariable, _type: &Type) { - unimplemented!("substitution not impl") + /// + /// Substitutes the given type for self if self is equal to the type variable. + pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { + match self { + TypeAssertion::Equality(equality) => equality.substitute(variable, type_), + TypeAssertion::Membership(_) => unimplemented!(), + } } /// @@ -1065,8 +1137,11 @@ impl TypeAssertion { } } - pub fn get_pair(&self) -> Option<(TypeVariable, Type)> { - unimplemented!("pair resolution not impl") + pub fn solve(&self) -> Option<(TypeVariable, Type)> { + match self { + TypeAssertion::Equality(equality) => equality.solve(), + TypeAssertion::Membership(_) => unimplemented!(), + } } } @@ -1109,7 +1184,7 @@ impl TypeMembership { // (type_, Type::TypeVariable(variable)) => Some((variable.clone(), type_.clone())), // (_type1, _type2) => None, // No (type variable, type) pair can be returned from two types // } - unimplemented!("pair resolution not impl") + unimplemented!() } } @@ -1131,9 +1206,9 @@ impl TypeEquality { /// /// Substitutes the given `TypeVariable` for each `Types` in the `TypeEquality`. /// - pub fn substitute(&mut self, _variable: &TypeVariable, _type_: &Type) { - // self.left.substitute(variable, type_); - // self.right.substitute(variable, type_); + pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { + self.left.substitute(variable, type_); + self.right.substitute(variable, type_); } /// @@ -1146,11 +1221,19 @@ impl TypeEquality { /// /// Returns the (type variable, type) pair from this assertion. /// - pub fn get_pair(&self) -> Option<(TypeVariable, Type)> { + pub fn solve(&self) -> Option<(TypeVariable, Type)> { match (&self.left, &self.right) { (Type::TypeVariable(variable), type_) => Some((variable.clone(), type_.clone())), (type_, Type::TypeVariable(variable)) => Some((variable.clone(), type_.clone())), - (_type1, _type2) => None, // No (type variable, type) pair can be returned from two types + (type1, type2) => { + // Compare types. + if type1.eq(type2) { + // Return None if the two types are equal (the equality is satisfied). + None + } else { + unimplemented!("ERROR type equality `{} == {}` failed", type1, type2) + } + } } } } diff --git a/dynamic-check/tests/empty.leo b/dynamic-check/tests/empty.leo index e69de29bb2..87881eff6d 100644 --- a/dynamic-check/tests/empty.leo +++ b/dynamic-check/tests/empty.leo @@ -0,0 +1,7 @@ +function main() -> u8 { + let mut a = (1, 2); + + a.0 = 3u32; + + return a.1 +} \ No newline at end of file diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 0a2eca61f1..5805073f25 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -54,7 +54,7 @@ impl TestDynamicCheck { } pub fn solve(self) { - self.dynamic_check.solve(); + self.dynamic_check.solve().unwrap(); } } diff --git a/static-check/src/types/type_.rs b/static-check/src/types/type_.rs index 968cc427a1..05a444b13c 100644 --- a/static-check/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -230,6 +230,17 @@ impl Type { Type::IntegerType(IntegerType::U32), ] } + + /// + /// Replaces self with the given type if self is equal to the given `TypeVariable`. + /// + pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { + if let Type::TypeVariable(self_variable) = self { + if self_variable == variable { + *self = type_.to_owned() + } + } + } } impl fmt::Display for Type { From d41e6779c7a0835d95e101e60d9244fa6dd5105f Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 22 Oct 2020 15:36:35 -0700 Subject: [PATCH 048/139] impl dynamic check function and circuit lookups --- dynamic-check/src/dynamic_check.rs | 38 ++++++++++++++++++++++++++---- dynamic-check/tests/empty.leo | 12 ++++++---- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index e2bf663d70..6dadae02b5 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -182,12 +182,26 @@ impl Frame { /// /// Get a variable's type from the symbol table in the current scope. /// - fn get_variable(&self, name: &String) -> &Type { + fn get_variable(&self, name: &String) -> Option<&Type> { // Lookup in the current scope. let scope = self.scopes.last().unwrap(); // Get the variable by name. - scope.get_variable(name).unwrap() + scope.get_variable(name) + } + + /// + /// Get a function's type from the user defined types in the current scope. + /// + fn get_function(&self, name: &String) -> Option<&FunctionType> { + self.user_defined_types.get_function(name) + } + + /// + /// Get a circuit's type from the user defined types in the current scope. + /// + fn get_circuit(&self, name: &String) -> Option<&CircuitType> { + self.user_defined_types.get_circuit(name) } /// @@ -195,6 +209,7 @@ impl Frame { /// fn assert_equal(&mut self, left: Type, right: Type) { let type_assertion = TypeAssertion::new_equality(left, right); + println!("TYPE ASSERTION: {:?}", type_assertion); self.type_assertions.push(type_assertion); } @@ -350,7 +365,7 @@ impl Frame { /// fn parse_assignee(&mut self, assignee: &Assignee, span: &Span) -> Type { // Get the type of the assignee variable. - let mut type_ = self.get_variable(&assignee.identifier.name).to_owned(); + let mut type_ = self.get_variable(&assignee.identifier.name).unwrap().to_owned(); // Iteratively evaluate assignee access types. for access in &assignee.accesses { @@ -531,8 +546,21 @@ impl Frame { /// Returns the type of the identifier in the symbol table. /// fn parse_identifier(&self, identifier: &Identifier) -> Type { - // TODO (collinc97) throw an error if identifier is not present. - self.get_variable(&identifier.name).clone() + // Check variable symbol table. + if let Some(type_) = self.get_variable(&identifier.name) { + return type_.to_owned(); + }; + + // Check function symbol table. + if let Some(function_type) = self.get_function(&identifier.name) { + return Type::Function(function_type.identifier.to_owned()); + }; + + // Check circuit symbol table. + match self.get_circuit(&identifier.name) { + Some(circuit_type) => Type::Circuit(circuit_type.identifier.to_owned()), + None => unimplemented!("ERROR identifier not found"), + } } /// diff --git a/dynamic-check/tests/empty.leo b/dynamic-check/tests/empty.leo index 87881eff6d..85feabd262 100644 --- a/dynamic-check/tests/empty.leo +++ b/dynamic-check/tests/empty.leo @@ -1,7 +1,9 @@ -function main() -> u8 { - let mut a = (1, 2); +function one() -> u8 { + return 1 +} - a.0 = 3u32; - - return a.1 +function main(mut a: u8) -> bool { + a = one(); + let b = true; + return b } \ No newline at end of file From 3331ee77c4cf6612223b864cf35480fdcaec8b1d Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 22 Oct 2020 22:31:07 -0700 Subject: [PATCH 049/139] impl dynamic check circuits --- dynamic-check/src/dynamic_check.rs | 318 +++++++++++++++++---- dynamic-check/tests/empty.leo | 11 +- static-check/src/types/circuits/circuit.rs | 20 +- 3 files changed, 283 insertions(+), 66 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 6dadae02b5..eca287b9d0 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -15,23 +15,34 @@ // along with the Leo library. If not, see . use crate::{DynamicCheckError, FrameError, VariableTableError}; -use leo_static_check::{CircuitType, FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable}; +use leo_static_check::{ + Attribute, + CircuitFunctionType, + CircuitType, + FunctionInputType, + FunctionType, + SymbolTable, + Type, + TypeVariable, +}; use leo_typed::{ Assignee, AssigneeAccess, + Circuit, + CircuitMember, CircuitVariableDefinition, ConditionalNestedOrEndStatement, ConditionalStatement, ConsoleFunctionCall, Declare, Expression, - Function as UnresolvedFunction, + Function, Identifier, Program, RangeOrExpression, Span, SpreadOrExpression, - Statement as UnresolvedStatement, + Statement, Variables, }; @@ -42,9 +53,11 @@ use std::collections::HashMap; /// Performs a dynamic type inference check over a program. pub struct DynamicCheck { table: SymbolTable, - functions: Vec, + frames: Vec, } +pub struct VariableEnvironment {} + impl DynamicCheck { /// /// Returns a new `DynamicCheck` from a given program and symbol table. @@ -52,7 +65,7 @@ impl DynamicCheck { pub fn new(program: &Program, symbol_table: SymbolTable) -> Self { let mut dynamic_check = Self { table: symbol_table, - functions: vec![], + frames: vec![], }; dynamic_check.parse_program(program); @@ -64,6 +77,14 @@ impl DynamicCheck { /// Collects a vector of `TypeAssertion` predicates from a program. /// fn parse_program(&mut self, program: &Program) { + let circuits = program + .circuits + .iter() + .map(|(_identifier, circuit)| circuit) + .collect::>(); + + self.parse_circuits(circuits); + let functions = program .functions .iter() @@ -76,19 +97,79 @@ impl DynamicCheck { /// /// Collects a vector of `TypeAssertion` predicates from a vector of functions. /// - fn parse_functions(&mut self, functions: Vec<&UnresolvedFunction>) { + fn parse_functions(&mut self, functions: Vec<&Function>) { for function in functions { - self.parse_function(function) + self.parse_function(function); } } /// /// Collects a vector of `TypeAssertion` predicates from a function. /// - fn parse_function(&mut self, function: &UnresolvedFunction) { - let frame = Frame::new(function.clone(), self.table.clone()); + fn parse_function(&mut self, function: &Function) { + let frame = Frame::new_function(function.to_owned(), None, None, self.table.clone()); - self.functions.push(frame); + self.frames.push(frame); + } + + /// + /// Collects a vector of `Frames`s from a vector of circuit functions. + /// + fn parse_circuits(&mut self, circuits: Vec<&Circuit>) { + for circuit in circuits { + self.parse_circuit(circuit); + } + } + + /// + /// Collects a vector of `Frames`s from a circuit function. + /// + /// Each frame collects a vector of `TypeAssertion` predicates from each function. + /// + fn parse_circuit(&mut self, circuit: &Circuit) { + let name = &circuit.circuit_name.name; + + // Get circuit type from circuit symbol table. + let circuit_type = self.table.get_circuit(name).unwrap().clone(); + + // Insert circuit member variable types into variable table. + let variable_table = Scope::empty(); + + // for circuit_variable in &circuit_type.variables { + // // Get name and type from circuit variables. + // let name = circuit_variable.identifier.name.to_owned(); + // let type_ = circuit_variable.type_.to_owned(); + // + // variable_table.insert_variable(name, type_); + // } + // + // // Insert circuit member function types into function table. + let user_defined_types = self.table.clone(); + // + // for circuit_function in &circuit_type.functions { + // // Get the name and type from circuit functions. + // let identifier = circuit_function.function.identifier.to_owned(); + // let function_type = circuit_function.function.to_owned(); + // + // user_defined_types.insert_function(identifier, function_type); + // } + + // Create a new function for each circuit member function. + for circuit_member in &circuit.members { + // ignore circuit member variables + if let CircuitMember::CircuitFunction(_, function) = circuit_member { + // Collect `TypeAssertion` predicates from the function. + // Pass down circuit self type and circuit variable types to each function. + let frame = Frame::new_circuit_function( + function.to_owned(), + circuit_type.clone(), + variable_table.clone(), + user_defined_types.clone(), + ); + + self.frames.push(frame) + } + } } /// @@ -99,7 +180,7 @@ impl DynamicCheck { /// Returns ERROR if a `TypeAssertion` predicate is false or a solution does not exist. /// pub fn solve(self) -> Result<(), DynamicCheckError> { - for frame in self.functions { + for frame in self.frames { frame.solve()?; } @@ -113,7 +194,7 @@ pub struct Frame { pub function_type: FunctionType, pub self_type: Option, pub scopes: Vec, - pub statements: Vec, + pub statements: Vec, pub type_assertions: Vec, pub user_defined_types: SymbolTable, } @@ -122,14 +203,19 @@ impl Frame { /// /// Collects a vector of `TypeAssertion` predicates from a function. /// - pub fn new(function: UnresolvedFunction, symbol_table: SymbolTable) -> Self { + pub fn new_function( + function: Function, + self_type: Option, + parent_scope: Option, + user_defined_types: SymbolTable, + ) -> Self { let name = &function.identifier.name; // Get function type from symbol table. - let function_type = symbol_table.get_function(name).unwrap().clone(); + let function_type = user_defined_types.get_function(name).unwrap().clone(); // Create a new scope for the function variables. - let mut scope = Scope::new(None); + let mut scope = Scope::new(parent_scope); // Initialize function inputs as variables. scope.parse_function_inputs(&function_type.inputs); @@ -141,11 +227,51 @@ impl Frame { // Update variables when encountering let/const variable definitions. let mut frame = Self { function_type, - self_type: None, + self_type, scopes, statements: function.statements, type_assertions: vec![], - user_defined_types: symbol_table, + user_defined_types, + }; + + // Create type assertions for function statements + frame.parse_statements(); + + frame + } + + /// + /// Collects vector of `TypeAssertion` predicates from a circuit function. + /// + pub fn new_circuit_function( + function: Function, + self_type: CircuitType, + parent_scope: Scope, + user_defined_types: SymbolTable, + ) -> Self { + let identifier = &function.identifier; + + // Find function name in circuit members. + let circuit_function_type = self_type.member_function_type(identifier).unwrap().to_owned(); + + // Create a new scope for the function variables. + let mut scope = Scope::new(Some(parent_scope)); + + // Initialize function inputs as variables. + scope.parse_function_inputs(&circuit_function_type.function.inputs); + + // Create new list of scopes for frame. + let scopes = vec![scope]; + + // Create new frame struct. + // Update variables when encountering let/const variable definitions. + let mut frame = Self { + function_type: circuit_function_type.function, + self_type: Some(self_type), + scopes, + statements: function.statements, + type_assertions: Vec::new(), + user_defined_types, }; // Create type assertions for function statements @@ -262,21 +388,21 @@ impl Frame { /// /// Collects a vector of `TypeAssertion` predicates from a statement. /// - fn parse_statement(&mut self, statement: &UnresolvedStatement) { + fn parse_statement(&mut self, statement: &Statement) { match statement { - UnresolvedStatement::Return(expression, span) => { + Statement::Return(expression, span) => { self.parse_return(expression, span); } - UnresolvedStatement::Definition(declare, variables, expression, span) => { + Statement::Definition(declare, variables, expression, span) => { self.parse_definition(declare, variables, expression, span) } - UnresolvedStatement::Assign(assignee, expression, span) => self.parse_assign(assignee, expression, span), - UnresolvedStatement::Conditional(conditional, span) => self.parse_statement_conditional(conditional, span), - UnresolvedStatement::Iteration(identifier, from, to, statements, span) => { + Statement::Assign(assignee, expression, span) => self.parse_assign(assignee, expression, span), + Statement::Conditional(conditional, span) => self.parse_statement_conditional(conditional, span), + Statement::Iteration(identifier, from, to, statements, span) => { self.parse_iteration(identifier, from, to, statements, span) } - UnresolvedStatement::Expression(expression, span) => self.parse_statement_expression(expression, span), - UnresolvedStatement::Console(console_call) => self.parse_console_function_call(console_call), + Statement::Expression(expression, span) => self.parse_statement_expression(expression, span), + Statement::Console(console_call) => self.parse_console_function_call(console_call), } } @@ -384,7 +510,7 @@ impl Frame { /// /// Collects `TypeAssertion` predicates from a block of statements. /// - fn parse_block(&mut self, statements: &Vec, _span: &Span) { + fn parse_block(&mut self, statements: &Vec, _span: &Span) { // Push new scope. let scope = Scope::new(self.scopes.last().map(|scope| scope.clone())); self.push_scope(scope); @@ -441,7 +567,7 @@ impl Frame { identifier: &Identifier, from: &Expression, to: &Expression, - statements: &Vec, + statements: &Vec, span: &Span, ) { // Insert variable into symbol table with u32 type. @@ -533,7 +659,7 @@ impl Frame { self.parse_expression_circuit_member_access(expression, identifier, span) } Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { - self.parse_circuit_static_function_access(expression, identifier, span) + self.parse_static_circuit_function_access(expression, identifier, span) } // Functions @@ -884,43 +1010,131 @@ impl Frame { /// /// Returns the type of the accessed circuit member. /// - fn parse_circuit_member_access(&mut self, type_: Type, identifier: &Identifier, _span: &Span) -> Type { + fn parse_circuit_member_access(&mut self, type_: Type, identifier: &Identifier, span: &Span) -> Type { // Check that type is a circuit type. - let circuit_type = match type_ { - Type::Circuit(identifier) => { - // Lookup circuit. - self.user_defined_types.get_circuit(&identifier.name).unwrap() - } - _ => unimplemented!("expected circuit type to access member"), - }; + let circuit_type = self.parse_circuit_name(type_, span); // Look for member with matching name. - circuit_type.member_type(&identifier).unwrap().clone() + circuit_type.member_type(&identifier).unwrap() } /// /// Returns the type returned by calling the static circuit function. /// - fn parse_circuit_static_function_access( + fn parse_static_circuit_function_access( &mut self, expression: &Expression, identifier: &Identifier, - _span: &Span, + span: &Span, ) -> Type { // Parse the circuit name. let type_ = self.parse_expression(expression); + self.parse_circuit_member_access(type_, identifier, span) + } + + /// + /// Returns a `CircuitType` given a circuit expression. + /// + fn parse_circuit_name(&mut self, type_: Type, _span: &Span) -> &CircuitType { // Check that type is a circuit type. - let circuit_type = match type_ { + match type_ { Type::Circuit(identifier) => { - // Lookup circuit. + // Lookup circuit identifier. self.user_defined_types.get_circuit(&identifier.name).unwrap() } - _ => unimplemented!("expected circuit type to access static member"), - }; + _ => unimplemented!("expected circuit type"), + } + } - // Look for member with matching name. - circuit_type.member_type(&identifier).unwrap().clone() + /// + /// Returns a `FunctionType` given a function expression. + /// + fn parse_function_name(&mut self, expression: &Expression, span: &Span) -> FunctionType { + // Case 1: Call a function defined in the program file. + // Case 2: Call a circuit function. + // Case 3: Call a static circuit function. + // Return an Error in any other case. + match expression { + Expression::Identifier(identifier) => self.parse_program_function(identifier, span), + Expression::CircuitMemberAccess(expression, identifier, span) => { + self.parse_circuit_function(expression, identifier, span) + } + Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { + self.parse_static_circuit_function(expression, identifier, span) + } + _ => unimplemented!("Invalid function name"), + } + } + + /// + /// Returns a `FunctionType` given a function identifier. + /// + fn parse_program_function(&mut self, identifier: &Identifier, _span: &Span) -> FunctionType { + self.user_defined_types + .get_function(&identifier.name) + .unwrap() + .to_owned() + } + + /// + /// Returns a `CircuitFunctionType` given a circuit expression and function identifier. + /// + fn parse_circuit_function_type( + &mut self, + expression: &Expression, + identifier: &Identifier, + span: &Span, + ) -> &CircuitFunctionType { + // Parse circuit name. + let type_ = self.parse_expression(expression); + + // Get circuit type. + let circuit_type = self.parse_circuit_name(type_, span); + + // Find circuit function by identifier. + circuit_type.member_function_type(identifier).unwrap() + } + + /// + /// Returns a `FunctionType` given a circuit expression and non-static function identifier. + /// + fn parse_circuit_function( + &mut self, + expression: &Expression, + identifier: &Identifier, + span: &Span, + ) -> FunctionType { + // Find circuit function type. + let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span); + + // Check that the function is non-static. + if circuit_function_type.attributes.contains(&Attribute::Static) { + unimplemented!("Called static function using dot syntax") + } + + // Return the function type. + circuit_function_type.function.to_owned() + } + + /// + /// Returns a `FunctionType` given a circuit expression and static function identifier. + /// + fn parse_static_circuit_function( + &mut self, + expression: &Expression, + identifier: &Identifier, + span: &Span, + ) -> FunctionType { + // Find circuit function type. + let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span); + + // Check that the function is static. + if !circuit_function_type.attributes.contains(&Attribute::Static) { + unimplemented!("Called non-static function using double colon syntax") + } + + circuit_function_type.function.to_owned() } /// @@ -928,18 +1142,10 @@ impl Frame { /// /// Does not attempt to evaluate the function call. We are just checking types at this step. /// - fn parse_function_call(&mut self, expression: &Expression, inputs: &Vec, _span: &Span) -> Type { + fn parse_function_call(&mut self, expression: &Expression, inputs: &Vec, span: &Span) -> Type { // Parse the function name. - let type_ = self.parse_expression(expression); - - // Check that type is a function type. - let function_type = match type_ { - Type::Function(identifier) => { - // Lookup function. - self.user_defined_types.get_function(&identifier.name).unwrap().clone() - } - _ => unimplemented!("expected function type for function call"), - }; + println!("expression {}", expression); + let function_type = self.parse_function_name(expression, span); // Check the length of arguments if function_type.inputs.len() != inputs.len() { diff --git a/dynamic-check/tests/empty.leo b/dynamic-check/tests/empty.leo index 85feabd262..41ed588476 100644 --- a/dynamic-check/tests/empty.leo +++ b/dynamic-check/tests/empty.leo @@ -1,9 +1,14 @@ -function one() -> u8 { - return 1 +circuit Foo { + a: u8, + b: u8, + + static function one() -> u8 { + return 1 + } } function main(mut a: u8) -> bool { - a = one(); + a = Foo::one(); let b = true; return b } \ No newline at end of file diff --git a/static-check/src/types/circuits/circuit.rs b/static-check/src/types/circuits/circuit.rs index eb191ceb96..7968ced1d6 100644 --- a/static-check/src/types/circuits/circuit.rs +++ b/static-check/src/types/circuits/circuit.rs @@ -106,13 +106,22 @@ impl CircuitType { }) } + /// + /// Returns the function type of a circuit member given an identifier. + /// + pub fn member_function_type(&self, identifier: &Identifier) -> Option<&CircuitFunctionType> { + self.functions + .iter() + .find(|function| function.function.identifier.eq(identifier)) + } + /// /// Returns the type of a circuit member. /// /// If the member is a circuit variable, then the type of the variable is returned. /// If the member is a circuit function, then the return type of the function is returned. /// - pub fn member_type(&self, identifier: &Identifier) -> Result<&Type, TypeError> { + pub fn member_type(&self, identifier: &Identifier) -> Result { // Check if the circuit member is a circuit variable. let matched_variable = self .variables @@ -120,16 +129,13 @@ impl CircuitType { .find(|variable| variable.identifier.eq(identifier)); match matched_variable { - Some(variable) => Ok(&variable.type_), + Some(variable) => Ok(variable.type_.to_owned()), None => { // Check if the circuit member is a circuit function. - let matched_function = self - .functions - .iter() - .find(|function| function.function.identifier.eq(identifier)); + let matched_function = self.member_function_type(identifier); match matched_function { - Some(function) => Ok(&function.function.output.type_), + Some(function) => Ok(Type::Function(function.function.identifier.to_owned())), None => Err(TypeError::undefined_circuit_member(identifier.clone())), } } From f1490a994b00da4802912d0ec02bec9fb1218936 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 23 Oct 2020 15:23:48 -0700 Subject: [PATCH 050/139] impl dynamic check errors --- Cargo.lock | 2 + compiler/Cargo.toml | 8 + compiler/src/compiler.rs | 9 + dynamic-check/src/dynamic_check.rs | 392 +++++++++++++--------- dynamic-check/src/errors/dynamic_check.rs | 5 +- dynamic-check/src/errors/frame.rs | 10 + dynamic-check/src/errors/mod.rs | 3 + dynamic-check/src/errors/scope.rs | 42 +++ 8 files changed, 302 insertions(+), 169 deletions(-) create mode 100644 dynamic-check/src/errors/scope.rs diff --git a/Cargo.lock b/Cargo.lock index 7c3d37aa70..e7998c227c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1235,11 +1235,13 @@ dependencies = [ "hex", "leo-ast", "leo-core", + "leo-dynamic-check", "leo-gadgets", "leo-imports", "leo-input", "leo-package", "leo-state", + "leo-static-check", "leo-typed", "num-bigint", "pest", diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index a3b641e65d..25e05398bb 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -25,6 +25,10 @@ version = "1.0.3" path = "../core" version = "1.0.3" +[dependencies.leo-dynamic-check] +path = "../dynamic-check" +version = "1.0.3" + [dependencies.leo-gadgets] path = "../gadgets" version = "1.0.3" @@ -49,6 +53,10 @@ version = "1.0.3" path = "../state" version = "1.0.3" +[dependencies.leo-static-check] +path = "../static-check" +version = "1.0.3" + [dependencies.snarkos-curves] version = "1.1.3" default-features = false diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 0abf3ec47b..604ea96985 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -24,10 +24,12 @@ use crate::{ OutputFile, }; use leo_ast::LeoAst; +use leo_dynamic_check::DynamicCheck; use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; use leo_state::verify_local_data_commitment; +use leo_static_check::StaticCheck; use leo_typed::{Input, LeoTypedAst, MainInput, Program}; use snarkos_dpc::{base_dpc::instantiated::Components, SystemParameters}; @@ -160,6 +162,13 @@ impl> Compiler { let typed_tree = LeoTypedAst::new(&package_name, &ast); self.program = typed_tree.into_repr(); + + let symbol_table = StaticCheck::run(&self.program).unwrap(); + + let dynamic_check = DynamicCheck::new(&self.program, symbol_table).unwrap(); + + dynamic_check.solve().unwrap(); + self.imported_programs = ImportParser::parse(&self.program)?; tracing::debug!("Program parsing complete\n{:#?}", self.program); diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index eca287b9d0..05cee53c34 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{DynamicCheckError, FrameError, VariableTableError}; +use crate::{DynamicCheckError, FrameError, ScopeError, VariableTableError}; use leo_static_check::{ Attribute, CircuitFunctionType, @@ -62,28 +62,28 @@ impl DynamicCheck { /// /// Returns a new `DynamicCheck` from a given program and symbol table. /// - pub fn new(program: &Program, symbol_table: SymbolTable) -> Self { + pub fn new(program: &Program, symbol_table: SymbolTable) -> Result { let mut dynamic_check = Self { table: symbol_table, - frames: vec![], + frames: Vec::new(), }; - dynamic_check.parse_program(program); + dynamic_check.parse_program(program)?; - dynamic_check + Ok(dynamic_check) } /// /// Collects a vector of `TypeAssertion` predicates from a program. /// - fn parse_program(&mut self, program: &Program) { + fn parse_program(&mut self, program: &Program) -> Result<(), DynamicCheckError> { let circuits = program .circuits .iter() .map(|(_identifier, circuit)| circuit) .collect::>(); - self.parse_circuits(circuits); + self.parse_circuits(circuits)?; let functions = program .functions @@ -91,34 +91,40 @@ impl DynamicCheck { .map(|(_identifier, function)| function) .collect::>(); - self.parse_functions(functions); + self.parse_functions(functions) } /// /// Collects a vector of `TypeAssertion` predicates from a vector of functions. /// - fn parse_functions(&mut self, functions: Vec<&Function>) { + fn parse_functions(&mut self, functions: Vec<&Function>) -> Result<(), DynamicCheckError> { for function in functions { - self.parse_function(function); + self.parse_function(function)?; } + + Ok(()) } /// /// Collects a vector of `TypeAssertion` predicates from a function. /// - fn parse_function(&mut self, function: &Function) { - let frame = Frame::new_function(function.to_owned(), None, None, self.table.clone()); + fn parse_function(&mut self, function: &Function) -> Result<(), DynamicCheckError> { + let frame = Frame::new_function(function.to_owned(), None, None, self.table.clone())?; self.frames.push(frame); + + Ok(()) } /// /// Collects a vector of `Frames`s from a vector of circuit functions. /// - fn parse_circuits(&mut self, circuits: Vec<&Circuit>) { + fn parse_circuits(&mut self, circuits: Vec<&Circuit>) -> Result<(), DynamicCheckError> { for circuit in circuits { - self.parse_circuit(circuit); + self.parse_circuit(circuit)?; } + + Ok(()) } /// @@ -126,34 +132,12 @@ impl DynamicCheck { /// /// Each frame collects a vector of `TypeAssertion` predicates from each function. /// - fn parse_circuit(&mut self, circuit: &Circuit) { + fn parse_circuit(&mut self, circuit: &Circuit) -> Result<(), DynamicCheckError> { let name = &circuit.circuit_name.name; // Get circuit type from circuit symbol table. let circuit_type = self.table.get_circuit(name).unwrap().clone(); - // Insert circuit member variable types into variable table. - let variable_table = Scope::empty(); - - // for circuit_variable in &circuit_type.variables { - // // Get name and type from circuit variables. - // let name = circuit_variable.identifier.name.to_owned(); - // let type_ = circuit_variable.type_.to_owned(); - // - // variable_table.insert_variable(name, type_); - // } - // - // // Insert circuit member function types into function table. - let user_defined_types = self.table.clone(); - // - // for circuit_function in &circuit_type.functions { - // // Get the name and type from circuit functions. - // let identifier = circuit_function.function.identifier.to_owned(); - // let function_type = circuit_function.function.to_owned(); - // - // user_defined_types.insert_function(identifier, function_type); - // } - // Create a new function for each circuit member function. for circuit_member in &circuit.members { // ignore circuit member variables @@ -163,13 +147,15 @@ impl DynamicCheck { let frame = Frame::new_circuit_function( function.to_owned(), circuit_type.clone(), - variable_table.clone(), - user_defined_types.clone(), - ); + Scope::empty(), + self.table.clone(), + )?; self.frames.push(frame) } } + + Ok(()) } /// @@ -208,7 +194,7 @@ impl Frame { self_type: Option, parent_scope: Option, user_defined_types: SymbolTable, - ) -> Self { + ) -> Result { let name = &function.identifier.name; // Get function type from symbol table. @@ -218,7 +204,7 @@ impl Frame { let mut scope = Scope::new(parent_scope); // Initialize function inputs as variables. - scope.parse_function_inputs(&function_type.inputs); + scope.parse_function_inputs(&function_type.inputs)?; // Create new list of scopes for frame. let scopes = vec![scope]; @@ -235,9 +221,9 @@ impl Frame { }; // Create type assertions for function statements - frame.parse_statements(); + frame.parse_statements()?; - frame + Ok(frame) } /// @@ -248,7 +234,7 @@ impl Frame { self_type: CircuitType, parent_scope: Scope, user_defined_types: SymbolTable, - ) -> Self { + ) -> Result { let identifier = &function.identifier; // Find function name in circuit members. @@ -258,7 +244,7 @@ impl Frame { let mut scope = Scope::new(Some(parent_scope)); // Initialize function inputs as variables. - scope.parse_function_inputs(&circuit_function_type.function.inputs); + scope.parse_function_inputs(&circuit_function_type.function.inputs)?; // Create new list of scopes for frame. let scopes = vec![scope]; @@ -275,9 +261,9 @@ impl Frame { }; // Create type assertions for function statements - frame.parse_statements(); + frame.parse_statements()?; - frame + Ok(frame) } /// @@ -379,20 +365,20 @@ impl Frame { /// /// Collects a vector of `TypeAssertion` predicates from a vector of statements. /// - fn parse_statements(&mut self) { + fn parse_statements(&mut self) -> Result<(), FrameError> { for statement in self.statements.clone() { - self.parse_statement(&statement); + self.parse_statement(&statement)?; } + + Ok(()) } /// /// Collects a vector of `TypeAssertion` predicates from a statement. /// - fn parse_statement(&mut self, statement: &Statement) { + fn parse_statement(&mut self, statement: &Statement) -> Result<(), FrameError> { match statement { - Statement::Return(expression, span) => { - self.parse_return(expression, span); - } + Statement::Return(expression, span) => self.parse_return(expression, span), Statement::Definition(declare, variables, expression, span) => { self.parse_definition(declare, variables, expression, span) } @@ -409,7 +395,7 @@ impl Frame { /// /// Collects `TypeAssertion` predicates from a return statement. /// - fn parse_return(&mut self, expression: &Expression, _span: &Span) { + fn parse_return(&mut self, expression: &Expression, _span: &Span) -> Result<(), FrameError> { // Get the function output type. let output_type = &self.function_type.output.type_; @@ -417,18 +403,26 @@ impl Frame { let left = output_type.clone(); // Create the right hand side from the statement return expression. - let right = self.parse_expression(expression); + let right = self.parse_expression(expression)?; // Create a new type assertion for the statement return. self.assert_equal(left, right); + + Ok(()) } /// /// Collects `Type Assertion` predicates from a definition statement. /// - fn parse_definition(&mut self, _declare: &Declare, variables: &Variables, expression: &Expression, span: &Span) { + fn parse_definition( + &mut self, + _declare: &Declare, + variables: &Variables, + expression: &Expression, + span: &Span, + ) -> Result<(), FrameError> { // Parse the definition expression. - let actual_type = self.parse_expression(expression); + let actual_type = self.parse_expression(expression)?; // Check if an explicit type is given. if let Some(type_) = variables.type_.clone() { @@ -470,26 +464,30 @@ impl Frame { let _expect_none = self.insert_variable(variable.identifier.name.clone(), type_); } } + + Ok(()) } /// /// Asserts that the assignee's type is equal to the `Expression` type. /// - fn parse_assign(&mut self, assignee: &Assignee, expression: &Expression, span: &Span) { + fn parse_assign(&mut self, assignee: &Assignee, expression: &Expression, span: &Span) -> Result<(), FrameError> { // Parse assignee type. - let assignee_type = self.parse_assignee(assignee, span); + let assignee_type = self.parse_assignee(assignee, span)?; // Parse expression type. - let expression_type = self.parse_expression(expression); + let expression_type = self.parse_expression(expression)?; // Assert that the assignee_type == expression_type. self.assert_equal(assignee_type, expression_type); + + Ok(()) } /// /// Returns the type of the assignee. /// - fn parse_assignee(&mut self, assignee: &Assignee, span: &Span) -> Type { + fn parse_assignee(&mut self, assignee: &Assignee, span: &Span) -> Result { // Get the type of the assignee variable. let mut type_ = self.get_variable(&assignee.identifier.name).unwrap().to_owned(); @@ -499,29 +497,31 @@ impl Frame { AssigneeAccess::Array(r_or_e) => self.parse_array_access(type_, r_or_e, span), AssigneeAccess::Tuple(index) => self.parse_tuple_access(type_, *index, span), AssigneeAccess::Member(identifier) => self.parse_circuit_member_access(type_, identifier, span), - }; + }?; type_ = access_type; } - type_ + Ok(type_) } /// /// Collects `TypeAssertion` predicates from a block of statements. /// - fn parse_block(&mut self, statements: &Vec, _span: &Span) { + fn parse_block(&mut self, statements: &Vec, _span: &Span) -> Result<(), FrameError> { // Push new scope. let scope = Scope::new(self.scopes.last().map(|scope| scope.clone())); self.push_scope(scope); // Parse all statements. for statement in statements.iter() { - self.parse_statement(statement); + self.parse_statement(statement)?; } // Pop out of scope. let _scope = self.pop_scope(); + + Ok(()) } /// @@ -529,32 +529,40 @@ impl Frame { /// /// Creates a new scope for each code block in the conditional. /// - fn parse_statement_conditional(&mut self, conditional: &ConditionalStatement, span: &Span) { + fn parse_statement_conditional( + &mut self, + conditional: &ConditionalStatement, + span: &Span, + ) -> Result<(), FrameError> { // Parse the condition expression. - let condition = self.parse_expression(&conditional.condition); + let condition = self.parse_expression(&conditional.condition)?; // Assert that the condition is a boolean type. let boolean_type = Type::Boolean; self.assert_equal(boolean_type, condition); // Parse conditional statements. - self.parse_block(&conditional.statements, span); + self.parse_block(&conditional.statements, span)?; // Parse conditional or end. match &conditional.next { - Some(cond_or_end) => self.parse_conditional_nested_or_end(cond_or_end, span), + Some(cond_or_end) => self.parse_conditional_nested_or_end(cond_or_end, span)?, None => {} } + + Ok(()) } /// /// Collects `TypeAssertion` predicates from a conditional statement. /// - fn parse_conditional_nested_or_end(&mut self, cond_or_end: &ConditionalNestedOrEndStatement, span: &Span) { + fn parse_conditional_nested_or_end( + &mut self, + cond_or_end: &ConditionalNestedOrEndStatement, + span: &Span, + ) -> Result<(), FrameError> { match cond_or_end { - ConditionalNestedOrEndStatement::Nested(nested) => { - self.parse_statement_conditional(nested, span); - } + ConditionalNestedOrEndStatement::Nested(nested) => self.parse_statement_conditional(nested, span), ConditionalNestedOrEndStatement::End(statements) => self.parse_block(statements, span), } } @@ -569,58 +577,61 @@ impl Frame { to: &Expression, statements: &Vec, span: &Span, - ) { + ) -> Result<(), FrameError> { // Insert variable into symbol table with u32 type. let u32_type = Type::IntegerType(IntegerType::U32); let _expect_none = self.insert_variable(identifier.name.to_owned(), u32_type.clone()); // Parse `from` and `to` expressions. - let from_type = self.parse_expression(from); - let to_type = self.parse_expression(to); + let from_type = self.parse_expression(from)?; + let to_type = self.parse_expression(to)?; // Assert `from` and `to` types are a u32 or implicit. self.assert_equal(u32_type.clone(), from_type); self.assert_equal(u32_type, to_type); // Parse block of statements. - self.parse_block(statements, span); + self.parse_block(statements, span) } /// /// Asserts that the statement `UnresolvedExpression` returns an empty tuple. /// - fn parse_statement_expression(&mut self, expression: &Expression, _span: &Span) { + fn parse_statement_expression(&mut self, expression: &Expression, _span: &Span) -> Result<(), FrameError> { // Create empty tuple type. let expected_type = Type::Tuple(Vec::with_capacity(0)); // Parse the actual type of the expression. - let actual_type = self.parse_expression(expression); + let actual_type = self.parse_expression(expression)?; self.assert_equal(expected_type, actual_type); + + Ok(()) } /// /// Collects `TypeAssertion` predicates from a console statement. /// - fn parse_console_function_call(&mut self, _console_function_call: &ConsoleFunctionCall) { + fn parse_console_function_call(&mut self, _console_function_call: &ConsoleFunctionCall) -> Result<(), FrameError> { // TODO (collinc97) find a way to fetch console function call types here + Ok(()) } /// /// Returns the type of an expression. /// - fn parse_expression(&mut self, expression: &Expression) -> Type { + fn parse_expression(&mut self, expression: &Expression) -> Result { match expression { // Type variables Expression::Identifier(identifier) => self.parse_identifier(identifier), // Explicit types - Expression::Boolean(_, _) => Type::Boolean, - Expression::Address(_, _) => Type::Address, - Expression::Field(_, _) => Type::Field, - Expression::Group(_) => Type::Group, - Expression::Implicit(name, _) => Self::parse_implicit(name), - Expression::Integer(integer_type, _, _) => Type::IntegerType(integer_type.clone()), + Expression::Boolean(_, _) => Ok(Type::Boolean), + Expression::Address(_, _) => Ok(Type::Address), + Expression::Field(_, _) => Ok(Type::Field), + Expression::Group(_) => Ok(Type::Group), + Expression::Implicit(name, _) => Ok(Self::parse_implicit(name)), + Expression::Integer(integer_type, _, _) => Ok(Type::IntegerType(integer_type.clone())), // Number operations Expression::Add(left, right, span) => self.parse_integer_binary_expression(left, right, span), @@ -671,20 +682,20 @@ impl Frame { /// /// Returns the type of the identifier in the symbol table. /// - fn parse_identifier(&self, identifier: &Identifier) -> Type { + fn parse_identifier(&self, identifier: &Identifier) -> Result { // Check variable symbol table. if let Some(type_) = self.get_variable(&identifier.name) { - return type_.to_owned(); + return Ok(type_.to_owned()); }; // Check function symbol table. if let Some(function_type) = self.get_function(&identifier.name) { - return Type::Function(function_type.identifier.to_owned()); + return Ok(Type::Function(function_type.identifier.to_owned())); }; // Check circuit symbol table. match self.get_circuit(&identifier.name) { - Some(circuit_type) => Type::Circuit(circuit_type.identifier.to_owned()), + Some(circuit_type) => Ok(Type::Circuit(circuit_type.identifier.to_owned())), None => unimplemented!("ERROR identifier not found"), } } @@ -699,17 +710,22 @@ impl Frame { /// /// Returns the type of a binary expression. /// - fn parse_binary_expression(&mut self, left: &Expression, right: &Expression, _span: &Span) -> Type { + fn parse_binary_expression( + &mut self, + left: &Expression, + right: &Expression, + _span: &Span, + ) -> Result { // Get the left expression type. - let left_type = self.parse_expression(left); + let left_type = self.parse_expression(left)?; // Get the right expression type. - let right_type = self.parse_expression(right); + let right_type = self.parse_expression(right)?; // Create a type assertion left_type == right_type. self.assert_equal(left_type.clone(), right_type); - left_type + Ok(left_type) } /// @@ -717,58 +733,68 @@ impl Frame { /// /// Asserts that the `Type` is an integer. /// - fn parse_integer_binary_expression(&mut self, left: &Expression, right: &Expression, _span: &Span) -> Type { - let type_ = self.parse_binary_expression(left, right, _span); + fn parse_integer_binary_expression( + &mut self, + left: &Expression, + right: &Expression, + _span: &Span, + ) -> Result { + let type_ = self.parse_binary_expression(left, right, _span)?; // Assert that the type is an integer. self.assert_integer(&type_); - type_ + Ok(type_) } /// /// Returns the `Boolean` type if the expression is a `Boolean` type. /// - fn parse_boolean_expression(&mut self, expression: &Expression) -> Type { + fn parse_boolean_expression(&mut self, expression: &Expression) -> Result { // Return the `Boolean` type let boolean_type = Type::Boolean; // Get the type of the expression - let expression_type = self.parse_expression(expression); + let expression_type = self.parse_expression(expression)?; // Assert that the type is a boolean. self.assert_equal(boolean_type.clone(), expression_type); - boolean_type + Ok(boolean_type) } /// /// Returns the `Type` of the expression being negated. Must be a negative integer type. /// - fn parse_negate_expression(&mut self, expression: &Expression) -> Type { + fn parse_negate_expression(&mut self, expression: &Expression) -> Result { // Parse the expression type. - let type_ = self.parse_expression(expression); + let type_ = self.parse_expression(expression)?; // Assert that this integer can be negated. self.assert_negative_integer(&type_); - type_ + Ok(type_) } /// /// Returns the `Boolean` type if the binary expression is a `Boolean` type. /// - fn parse_boolean_binary_expression(&mut self, left: &Expression, right: &Expression, _span: &Span) -> Type { + fn parse_boolean_binary_expression( + &mut self, + left: &Expression, + right: &Expression, + _span: &Span, + ) -> Result { // Return the `Boolean` type. let boolean_type = Type::Boolean; // Get the type of the binary expression. - let binary_expression_type = self.parse_binary_expression(left, right, _span); + let binary_expression_type = self.parse_binary_expression(left, right, _span)?; // Create a type assertion boolean_type == expression_type. self.assert_equal(boolean_type.clone(), binary_expression_type); - boolean_type + Ok(boolean_type) } /// @@ -780,9 +806,9 @@ impl Frame { first: &Expression, second: &Expression, _span: &Span, - ) -> Type { + ) -> Result { // Check that the type of the condition expression is a boolean. - let _condition_type = self.parse_boolean_expression(condition); + let _condition_type = self.parse_boolean_expression(condition)?; // Check that the types of the first and second expression are equal. self.parse_binary_expression(first, second, _span) @@ -791,25 +817,30 @@ impl Frame { /// /// Returns the type of the tuple expression. /// - fn parse_tuple(&mut self, expressions: &Vec, _span: &Span) -> Type { + fn parse_tuple(&mut self, expressions: &Vec, _span: &Span) -> Result { let mut types = vec![]; // Parse all tuple expressions. for expression in expressions { - let type_ = self.parse_expression(expression); + let type_ = self.parse_expression(expression)?; types.push(type_) } - Type::Tuple(types) + Ok(Type::Tuple(types)) } /// /// Returns the type of the accessed tuple element when called as an expression. /// - fn parse_expression_tuple_access(&mut self, expression: &Expression, index: usize, span: &Span) -> Type { + fn parse_expression_tuple_access( + &mut self, + expression: &Expression, + index: usize, + span: &Span, + ) -> Result { // Parse the tuple expression which could be a variable with type tuple. - let type_ = self.parse_expression(expression); + let type_ = self.parse_expression(expression)?; // Parse the tuple access. self.parse_tuple_access(type_, index, span) @@ -818,7 +849,7 @@ impl Frame { /// /// Returns the type of the accessed tuple element. /// - fn parse_tuple_access(&mut self, type_: Type, index: usize, _span: &Span) -> Type { + fn parse_tuple_access(&mut self, type_: Type, index: usize, _span: &Span) -> Result { // Check the type is a tuple. let elements = match type_ { Type::Tuple(elements) => elements, @@ -827,13 +858,13 @@ impl Frame { let element_type = elements[index].clone(); - element_type + Ok(element_type) } /// /// Returns the type of the array expression. /// - fn parse_array(&mut self, expressions: &Vec>, _span: &Span) -> Type { + fn parse_array(&mut self, expressions: &Vec>, _span: &Span) -> Result { // Store array element type. let mut element_type = None; let mut count = 0usize; @@ -841,7 +872,7 @@ impl Frame { // Parse all array elements. for expression in expressions { // Get the type and count of elements in each spread or expression. - let (type_, element_count) = self.parse_spread_or_expression(expression); + let (type_, element_count) = self.parse_spread_or_expression(expression)?; // Assert that array element types are the same. if let Some(prev_type) = element_type { @@ -861,17 +892,17 @@ impl Frame { None => unimplemented!("return empty array error"), }; - Type::Array(Box::new(type_), vec![count]) + Ok(Type::Array(Box::new(type_), vec![count])) } /// /// Returns the type and count of elements in a spread or expression. /// - fn parse_spread_or_expression(&mut self, s_or_e: &SpreadOrExpression) -> (Type, usize) { - match s_or_e { + fn parse_spread_or_expression(&mut self, s_or_e: &SpreadOrExpression) -> Result<(Type, usize), FrameError> { + Ok(match s_or_e { SpreadOrExpression::Spread(expression) => { // Parse the type of the spread array expression. - let array_type = self.parse_expression(expression); + let array_type = self.parse_expression(expression)?; // Check that the type is an array. let (element_type, mut dimensions) = match array_type { @@ -892,8 +923,8 @@ impl Frame { (type_, count) } - SpreadOrExpression::Expression(expression) => (self.parse_expression(expression), 1), - } + SpreadOrExpression::Expression(expression) => (self.parse_expression(expression)?, 1), + }) } /// @@ -904,9 +935,9 @@ impl Frame { expression: &Expression, r_or_e: &RangeOrExpression, span: &Span, - ) -> Type { + ) -> Result { // Parse the array expression which could be a variable with type array. - let type_ = self.parse_expression(expression); + let type_ = self.parse_expression(expression)?; // Parse the array access. self.parse_array_access(type_, r_or_e, span) @@ -915,7 +946,12 @@ impl Frame { /// /// Returns the type of the accessed array element. /// - fn parse_array_access(&mut self, type_: Type, r_or_e: &RangeOrExpression, _span: &Span) -> Type { + fn parse_array_access( + &mut self, + type_: Type, + r_or_e: &RangeOrExpression, + _span: &Span, + ) -> Result { // Check the type is an array. let (element_type, _dimensions) = match type_ { Type::Array(type_, dimensions) => (type_, dimensions), @@ -930,28 +966,28 @@ impl Frame { RangeOrExpression::Range(from, to) => { if let Some(expression) = from { // Parse the expression type. - let type_ = self.parse_expression(expression); + let type_ = self.parse_expression(expression)?; self.assert_index(&type_); } if let Some(expression) = to { // Parse the expression type. - let type_ = self.parse_expression(expression); + let type_ = self.parse_expression(expression)?; self.assert_index(&type_); } } RangeOrExpression::Expression(expression) => { // Parse the expression type. - let type_ = self.parse_expression(expression); + let type_ = self.parse_expression(expression)?; // Assert the type is an index. self.assert_index(&type_); } } - *element_type + Ok(*element_type) } /// @@ -962,7 +998,7 @@ impl Frame { identifier: &Identifier, members: &Vec, _span: &Span, - ) -> Type { + ) -> Result { // Check if identifier is Self circuit type. let circuit_type = if identifier.is_self() { self.self_type.clone() @@ -982,13 +1018,13 @@ impl Frame { // Assert members are circuit type member types. for (expected_variable, actual_variable) in circuit_type.variables.iter().zip(members) { // Parse actual variable expression. - let actual_type = self.parse_expression(&actual_variable.expression); + let actual_type = self.parse_expression(&actual_variable.expression)?; // Assert expected variable type == actual variable type. self.assert_equal(expected_variable.type_.clone(), actual_type) } - Type::Circuit(identifier.clone()) + Ok(Type::Circuit(identifier.to_owned())) } /// @@ -999,9 +1035,9 @@ impl Frame { expression: &Expression, identifier: &Identifier, span: &Span, - ) -> Type { + ) -> Result { // Parse circuit name. - let type_ = self.parse_expression(expression); + let type_ = self.parse_expression(expression)?; // Parse the circuit member access. self.parse_circuit_member_access(type_, identifier, span) @@ -1010,12 +1046,17 @@ impl Frame { /// /// Returns the type of the accessed circuit member. /// - fn parse_circuit_member_access(&mut self, type_: Type, identifier: &Identifier, span: &Span) -> Type { + fn parse_circuit_member_access( + &mut self, + type_: Type, + identifier: &Identifier, + span: &Span, + ) -> Result { // Check that type is a circuit type. - let circuit_type = self.parse_circuit_name(type_, span); + let circuit_type = self.parse_circuit_name(type_, span)?; // Look for member with matching name. - circuit_type.member_type(&identifier).unwrap() + Ok(circuit_type.member_type(&identifier).unwrap()) } /// @@ -1026,9 +1067,9 @@ impl Frame { expression: &Expression, identifier: &Identifier, span: &Span, - ) -> Type { + ) -> Result { // Parse the circuit name. - let type_ = self.parse_expression(expression); + let type_ = self.parse_expression(expression)?; self.parse_circuit_member_access(type_, identifier, span) } @@ -1036,21 +1077,21 @@ impl Frame { /// /// Returns a `CircuitType` given a circuit expression. /// - fn parse_circuit_name(&mut self, type_: Type, _span: &Span) -> &CircuitType { + fn parse_circuit_name(&mut self, type_: Type, _span: &Span) -> Result<&CircuitType, FrameError> { // Check that type is a circuit type. - match type_ { + Ok(match type_ { Type::Circuit(identifier) => { // Lookup circuit identifier. self.user_defined_types.get_circuit(&identifier.name).unwrap() } _ => unimplemented!("expected circuit type"), - } + }) } /// /// Returns a `FunctionType` given a function expression. /// - fn parse_function_name(&mut self, expression: &Expression, span: &Span) -> FunctionType { + fn parse_function_name(&mut self, expression: &Expression, span: &Span) -> Result { // Case 1: Call a function defined in the program file. // Case 2: Call a circuit function. // Case 3: Call a static circuit function. @@ -1070,11 +1111,12 @@ impl Frame { /// /// Returns a `FunctionType` given a function identifier. /// - fn parse_program_function(&mut self, identifier: &Identifier, _span: &Span) -> FunctionType { - self.user_defined_types + fn parse_program_function(&mut self, identifier: &Identifier, _span: &Span) -> Result { + Ok(self + .user_defined_types .get_function(&identifier.name) .unwrap() - .to_owned() + .to_owned()) } /// @@ -1085,15 +1127,15 @@ impl Frame { expression: &Expression, identifier: &Identifier, span: &Span, - ) -> &CircuitFunctionType { + ) -> Result<&CircuitFunctionType, FrameError> { // Parse circuit name. - let type_ = self.parse_expression(expression); + let type_ = self.parse_expression(expression)?; // Get circuit type. - let circuit_type = self.parse_circuit_name(type_, span); + let circuit_type = self.parse_circuit_name(type_, span)?; // Find circuit function by identifier. - circuit_type.member_function_type(identifier).unwrap() + Ok(circuit_type.member_function_type(identifier).unwrap()) } /// @@ -1104,9 +1146,9 @@ impl Frame { expression: &Expression, identifier: &Identifier, span: &Span, - ) -> FunctionType { + ) -> Result { // Find circuit function type. - let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span); + let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; // Check that the function is non-static. if circuit_function_type.attributes.contains(&Attribute::Static) { @@ -1114,7 +1156,7 @@ impl Frame { } // Return the function type. - circuit_function_type.function.to_owned() + Ok(circuit_function_type.function.to_owned()) } /// @@ -1125,16 +1167,16 @@ impl Frame { expression: &Expression, identifier: &Identifier, span: &Span, - ) -> FunctionType { + ) -> Result { // Find circuit function type. - let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span); + let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; // Check that the function is static. if !circuit_function_type.attributes.contains(&Attribute::Static) { unimplemented!("Called non-static function using double colon syntax") } - circuit_function_type.function.to_owned() + Ok(circuit_function_type.function.to_owned()) } /// @@ -1142,10 +1184,15 @@ impl Frame { /// /// Does not attempt to evaluate the function call. We are just checking types at this step. /// - fn parse_function_call(&mut self, expression: &Expression, inputs: &Vec, span: &Span) -> Type { + fn parse_function_call( + &mut self, + expression: &Expression, + inputs: &Vec, + span: &Span, + ) -> Result { // Parse the function name. println!("expression {}", expression); - let function_type = self.parse_function_name(expression, span); + let function_type = self.parse_function_name(expression, span)?; // Check the length of arguments if function_type.inputs.len() != inputs.len() { @@ -1155,20 +1202,25 @@ impl Frame { // Assert function inputs are correct types. for (expected_input, actual_input) in function_type.inputs.iter().zip(inputs) { // Parse actual input expression. - let actual_type = self.parse_expression(actual_input); + let actual_type = self.parse_expression(actual_input)?; // Assert expected input type == actual input type. self.assert_equal(expected_input.type_().clone(), actual_type); } // Return the function output type. - function_type.output.type_.clone() + Ok(function_type.output.type_.clone()) } /// /// Returns the type returned by calling the core function. /// - fn parse_core_function_call(&mut self, _name: &String, _arguments: &Vec, _span: &Span) -> Type { + fn parse_core_function_call( + &mut self, + _name: &String, + _arguments: &Vec, + _span: &Span, + ) -> Result { unimplemented!("type checks for core function calls not implemented") } @@ -1277,8 +1329,10 @@ impl Scope { /// /// Inserts a vector of function input types into the `Scope` variable table. /// - pub fn parse_function_inputs(&mut self, function_inputs: &Vec) { - self.variables.parse_function_inputs(function_inputs) + pub fn parse_function_inputs(&mut self, function_inputs: &Vec) -> Result<(), ScopeError> { + self.variables + .parse_function_inputs(function_inputs) + .map_err(|err| ScopeError::VariableTableError(err)) } } @@ -1319,7 +1373,10 @@ impl VariableTable { /// /// Inserts a vector of function input types into the variable table. /// - pub fn parse_function_inputs(&mut self, function_inputs: &Vec) { + pub fn parse_function_inputs( + &mut self, + function_inputs: &Vec, + ) -> Result<(), VariableTableError> { for input in function_inputs { let input_name = input.identifier().name.clone(); let input_type = input.type_().clone(); @@ -1327,6 +1384,7 @@ impl VariableTable { // TODO (collinc97) throw an error for duplicate function input names. self.insert(input_name, input_type); } + Ok(()) } } diff --git a/dynamic-check/src/errors/dynamic_check.rs b/dynamic-check/src/errors/dynamic_check.rs index 8d2054a743..bbcfffe457 100644 --- a/dynamic-check/src/errors/dynamic_check.rs +++ b/dynamic-check/src/errors/dynamic_check.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -// use crate::{ExpressionError, FunctionError, ProgramError, StatementError}; use crate::FrameError; use leo_typed::Error as FormattedError; @@ -43,7 +42,9 @@ pub enum DynamicCheckError { } impl DynamicCheckError { - /// Set the filepath for the error stacktrace + /// + /// Set the filepath for the error stacktrace. + /// pub fn set_path(&mut self, path: PathBuf) { match self { DynamicCheckError::Error(error) => error.set_path(path), diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index 49ee06adba..a247fa6e5d 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +use crate::ScopeError; +use leo_static_check::TypeError; use leo_typed::{Error as FormattedError, Span}; use std::path::PathBuf; @@ -23,6 +25,12 @@ use std::path::PathBuf; pub enum FrameError { #[error("{}", _0)] Error(#[from] FormattedError), + + #[error("{}", _0)] + ScopeError(#[from] ScopeError), + + #[error("{}", _0)] + TypeError(#[from] TypeError), } impl FrameError { @@ -32,6 +40,8 @@ impl FrameError { pub fn set_path(&mut self, path: PathBuf) { match self { FrameError::Error(error) => error.set_path(path), + FrameError::ScopeError(error) => error.set_path(path), + FrameError::TypeError(error) => error.set_path(path), } } diff --git a/dynamic-check/src/errors/mod.rs b/dynamic-check/src/errors/mod.rs index 8787321ab2..a41469c2b2 100644 --- a/dynamic-check/src/errors/mod.rs +++ b/dynamic-check/src/errors/mod.rs @@ -38,5 +38,8 @@ pub use self::frame::*; // pub mod statement; // pub use self::statement::*; +pub mod scope; +pub use self::scope::*; + pub mod variable_table; pub use self::variable_table::*; diff --git a/dynamic-check/src/errors/scope.rs b/dynamic-check/src/errors/scope.rs new file mode 100644 index 0000000000..0701021c41 --- /dev/null +++ b/dynamic-check/src/errors/scope.rs @@ -0,0 +1,42 @@ +// 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 . + +use crate::VariableTableError; +use leo_typed::Error as FormattedError; + +use std::path::PathBuf; + +/// Errors encountered when evaluating variables in a scope. +#[derive(Debug, Error)] +pub enum ScopeError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + VariableTableError(#[from] VariableTableError), +} + +impl ScopeError { + /// + /// Set the filepath for the error stacktrace. + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + ScopeError::Error(error) => error.set_path(path), + ScopeError::VariableTableError(error) => error.set_path(path), + } + } +} From 4aab804148ca2ea6c79e5f60f5ca423258592ee0 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 23 Oct 2020 15:52:43 -0700 Subject: [PATCH 051/139] add type variable for implicit addresses --- compiler/src/compiler.rs | 8 ++++---- compiler/src/errors/compiler.rs | 8 ++++++++ dynamic-check/src/dynamic_check.rs | 18 +++++++++++++++--- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 604ea96985..86bbf6aa03 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -163,11 +163,11 @@ impl> Compiler { self.program = typed_tree.into_repr(); - let symbol_table = StaticCheck::run(&self.program).unwrap(); + // Run static check on program. + let symbol_table = StaticCheck::run(&self.program)?; - let dynamic_check = DynamicCheck::new(&self.program, symbol_table).unwrap(); - - dynamic_check.solve().unwrap(); + // Run dynamic check on program. + DynamicCheck::run(&self.program, symbol_table)?; self.imported_programs = ImportParser::parse(&self.program)?; diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index 576b1218a9..1e1573fdf6 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -21,10 +21,15 @@ use leo_input::InputParserError; use leo_state::LocalDataVerificationError; use bincode::Error as SerdeError; +use leo_dynamic_check::DynamicCheckError; +use leo_static_check::StaticCheckError; use std::path::PathBuf; #[derive(Debug, Error)] pub enum CompilerError { + #[error("{}", _0)] + DynamicCheckError(#[from] DynamicCheckError), + #[error("{}", _0)] ImportError(#[from] ImportError), @@ -66,6 +71,9 @@ pub enum CompilerError { #[error("{}", _0)] SerdeError(#[from] SerdeError), + + #[error("{}", _0)] + StaticCheckError(#[from] StaticCheckError), } impl CompilerError { diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 05cee53c34..1daddae891 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -59,6 +59,17 @@ pub struct DynamicCheck { pub struct VariableEnvironment {} impl DynamicCheck { + /// + /// Creates a new `DynamicCheck` from a given program and symbol table. + /// + /// Evaluates all `TypeAssertion` predicates. + /// + pub fn run(program: &Program, symbol_table: SymbolTable) -> Result<(), DynamicCheckError> { + let dynamic_check = Self::new(program, symbol_table)?; + + dynamic_check.solve() + } + /// /// Returns a new `DynamicCheck` from a given program and symbol table. /// @@ -694,10 +705,11 @@ impl Frame { }; // Check circuit symbol table. - match self.get_circuit(&identifier.name) { - Some(circuit_type) => Ok(Type::Circuit(circuit_type.identifier.to_owned())), - None => unimplemented!("ERROR identifier not found"), + if let Some(circuit_type) = self.get_circuit(&identifier.name) { + return Ok(Type::Circuit(circuit_type.identifier.to_owned())); } + + Ok(Self::parse_implicit(&identifier.name)) } /// From dbade1f4fe092b3de735a2af7cc696a8651b26b3 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 23 Oct 2020 17:00:11 -0700 Subject: [PATCH 052/139] fix mismatched types test --- compiler/tests/syntax/mod.rs | 13 +- dynamic-check/src/dynamic_check.rs | 135 ++++++++++----------- dynamic-check/src/errors/frame.rs | 18 +-- dynamic-check/src/errors/mod.rs | 3 + dynamic-check/src/errors/type_assertion.rs | 54 +++++++++ dynamic-check/tests/empty.leo | 14 --- dynamic-check/tests/mod.rs | 2 +- 7 files changed, 146 insertions(+), 93 deletions(-) create mode 100644 dynamic-check/src/errors/type_assertion.rs diff --git a/compiler/tests/syntax/mod.rs b/compiler/tests/syntax/mod.rs index 2472df4f87..94e351da9f 100644 --- a/compiler/tests/syntax/mod.rs +++ b/compiler/tests/syntax/mod.rs @@ -17,6 +17,7 @@ use crate::{expect_compiler_error, parse_input, parse_program}; use leo_ast::ParserError; use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError}; +use leo_dynamic_check::errors::{DynamicCheckError, FrameError, TypeAssertionError}; use leo_input::InputParserError; pub mod identifiers; @@ -67,6 +68,7 @@ fn input_syntax_error() { let bytes = include_bytes!("input_semicolon.leo"); let error = parse_input(bytes).err().unwrap(); + // Expect an input parser error. match error { CompilerError::InputParserError(InputParserError::SyntaxError(_)) => {} _ => panic!("input syntax error should be a ParserError"), @@ -76,8 +78,13 @@ fn input_syntax_error() { #[test] fn test_compare_mismatched_types() { let bytes = include_bytes!("compare_mismatched_types.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - // previously this bug caused a stack overflow - expect_compiler_error(program); + // Expect a dynamic check error. + match error { + CompilerError::DynamicCheckError(DynamicCheckError::FrameError(FrameError::TypeAssertionError( + TypeAssertionError::Error(_), + ))) => {} + error => panic!("Expected dynamic check error, found {}", error), + } } diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 1daddae891..a126ff999a 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{DynamicCheckError, FrameError, ScopeError, VariableTableError}; +use crate::{DynamicCheckError, FrameError, ScopeError, TypeAssertionError, VariableTableError}; use leo_static_check::{ Attribute, CircuitFunctionType, @@ -330,9 +330,10 @@ impl Frame { /// /// Creates a new equality type assertion between the given types. /// - fn assert_equal(&mut self, left: Type, right: Type) { - let type_assertion = TypeAssertion::new_equality(left, right); - println!("TYPE ASSERTION: {:?}", type_assertion); + fn assert_equal(&mut self, left: Type, right: Type, span: &Span) { + let type_assertion = TypeAssertion::new_equality(left, right, span); + + println!("equality: {:?}", type_assertion); self.type_assertions.push(type_assertion); } @@ -406,7 +407,7 @@ impl Frame { /// /// Collects `TypeAssertion` predicates from a return statement. /// - fn parse_return(&mut self, expression: &Expression, _span: &Span) -> Result<(), FrameError> { + fn parse_return(&mut self, expression: &Expression, span: &Span) -> Result<(), FrameError> { // Get the function output type. let output_type = &self.function_type.output.type_; @@ -417,7 +418,7 @@ impl Frame { let right = self.parse_expression(expression)?; // Create a new type assertion for the statement return. - self.assert_equal(left, right); + self.assert_equal(left, right, span); Ok(()) } @@ -447,7 +448,7 @@ impl Frame { }; // Assert that the expected type is equal to the actual type. - self.assert_equal(expected_type.clone(), actual_type.clone()) + self.assert_equal(expected_type.clone(), actual_type.clone(), span) } // Check for multiple defined variables. @@ -490,7 +491,7 @@ impl Frame { let expression_type = self.parse_expression(expression)?; // Assert that the assignee_type == expression_type. - self.assert_equal(assignee_type, expression_type); + self.assert_equal(assignee_type, expression_type, span); Ok(()) } @@ -550,7 +551,7 @@ impl Frame { // Assert that the condition is a boolean type. let boolean_type = Type::Boolean; - self.assert_equal(boolean_type, condition); + self.assert_equal(boolean_type, condition, span); // Parse conditional statements. self.parse_block(&conditional.statements, span)?; @@ -598,8 +599,8 @@ impl Frame { let to_type = self.parse_expression(to)?; // Assert `from` and `to` types are a u32 or implicit. - self.assert_equal(u32_type.clone(), from_type); - self.assert_equal(u32_type, to_type); + self.assert_equal(u32_type.clone(), from_type, span); + self.assert_equal(u32_type, to_type, span); // Parse block of statements. self.parse_block(statements, span) @@ -608,14 +609,14 @@ impl Frame { /// /// Asserts that the statement `UnresolvedExpression` returns an empty tuple. /// - fn parse_statement_expression(&mut self, expression: &Expression, _span: &Span) -> Result<(), FrameError> { + fn parse_statement_expression(&mut self, expression: &Expression, span: &Span) -> Result<(), FrameError> { // Create empty tuple type. let expected_type = Type::Tuple(Vec::with_capacity(0)); // Parse the actual type of the expression. let actual_type = self.parse_expression(expression)?; - self.assert_equal(expected_type, actual_type); + self.assert_equal(expected_type, actual_type, span); Ok(()) } @@ -650,10 +651,10 @@ impl Frame { Expression::Mul(left, right, span) => self.parse_integer_binary_expression(left, right, span), Expression::Div(left, right, span) => self.parse_integer_binary_expression(left, right, span), Expression::Pow(left, right, span) => self.parse_integer_binary_expression(left, right, span), - Expression::Negate(expression, _span) => self.parse_negate_expression(expression), + Expression::Negate(expression, span) => self.parse_negate_expression(expression, span), // Boolean operations - Expression::Not(expression, _span) => self.parse_boolean_expression(expression), + Expression::Not(expression, span) => self.parse_boolean_expression(expression, span), Expression::Or(left, right, span) => self.parse_boolean_binary_expression(left, right, span), Expression::And(left, right, span) => self.parse_boolean_binary_expression(left, right, span), Expression::Eq(left, right, span) => self.parse_boolean_binary_expression(left, right, span), @@ -726,8 +727,9 @@ impl Frame { &mut self, left: &Expression, right: &Expression, - _span: &Span, + span: &Span, ) -> Result { + println!("left {}, right {}", left, right); // Get the left expression type. let left_type = self.parse_expression(left)?; @@ -735,7 +737,7 @@ impl Frame { let right_type = self.parse_expression(right)?; // Create a type assertion left_type == right_type. - self.assert_equal(left_type.clone(), right_type); + self.assert_equal(left_type.clone(), right_type, span); Ok(left_type) } @@ -762,7 +764,7 @@ impl Frame { /// /// Returns the `Boolean` type if the expression is a `Boolean` type. /// - fn parse_boolean_expression(&mut self, expression: &Expression) -> Result { + fn parse_boolean_expression(&mut self, expression: &Expression, span: &Span) -> Result { // Return the `Boolean` type let boolean_type = Type::Boolean; @@ -770,7 +772,7 @@ impl Frame { let expression_type = self.parse_expression(expression)?; // Assert that the type is a boolean. - self.assert_equal(boolean_type.clone(), expression_type); + self.assert_equal(boolean_type.clone(), expression_type, span); Ok(boolean_type) } @@ -778,7 +780,7 @@ impl Frame { /// /// Returns the `Type` of the expression being negated. Must be a negative integer type. /// - fn parse_negate_expression(&mut self, expression: &Expression) -> Result { + fn parse_negate_expression(&mut self, expression: &Expression, _span: &Span) -> Result { // Parse the expression type. let type_ = self.parse_expression(expression)?; @@ -795,17 +797,15 @@ impl Frame { &mut self, left: &Expression, right: &Expression, - _span: &Span, + span: &Span, ) -> Result { - // Return the `Boolean` type. + // Create the `Boolean` type. let boolean_type = Type::Boolean; - // Get the type of the binary expression. - let binary_expression_type = self.parse_binary_expression(left, right, _span)?; - - // Create a type assertion boolean_type == expression_type. - self.assert_equal(boolean_type.clone(), binary_expression_type); + // Create a new type assertion for the binary expression + let _binary_expression_type = self.parse_binary_expression(left, right, span)?; + // Return the `Boolean` type. Ok(boolean_type) } @@ -817,13 +817,13 @@ impl Frame { condition: &Expression, first: &Expression, second: &Expression, - _span: &Span, + span: &Span, ) -> Result { // Check that the type of the condition expression is a boolean. - let _condition_type = self.parse_boolean_expression(condition)?; + let _condition_type = self.parse_boolean_expression(condition, span)?; // Check that the types of the first and second expression are equal. - self.parse_binary_expression(first, second, _span) + self.parse_binary_expression(first, second, span) } /// @@ -876,7 +876,7 @@ impl Frame { /// /// Returns the type of the array expression. /// - fn parse_array(&mut self, expressions: &Vec>, _span: &Span) -> Result { + fn parse_array(&mut self, expressions: &Vec>, span: &Span) -> Result { // Store array element type. let mut element_type = None; let mut count = 0usize; @@ -888,7 +888,7 @@ impl Frame { // Assert that array element types are the same. if let Some(prev_type) = element_type { - self.assert_equal(prev_type, type_.clone()) + self.assert_equal(prev_type, type_.clone(), span); } // Update array element type. @@ -1009,7 +1009,7 @@ impl Frame { &mut self, identifier: &Identifier, members: &Vec, - _span: &Span, + span: &Span, ) -> Result { // Check if identifier is Self circuit type. let circuit_type = if identifier.is_self() { @@ -1033,7 +1033,7 @@ impl Frame { let actual_type = self.parse_expression(&actual_variable.expression)?; // Assert expected variable type == actual variable type. - self.assert_equal(expected_variable.type_.clone(), actual_type) + self.assert_equal(expected_variable.type_.clone(), actual_type, span) } Ok(Type::Circuit(identifier.to_owned())) @@ -1217,7 +1217,7 @@ impl Frame { let actual_type = self.parse_expression(actual_input)?; // Assert expected input type == actual input type. - self.assert_equal(expected_input.type_().clone(), actual_type); + self.assert_equal(expected_input.type_().clone(), actual_type, span); } // Return the function output type. @@ -1248,15 +1248,17 @@ impl Frame { println!("assertion: {:?}", type_assertion); - // Get type variable and type - if let Some((type_variable, type_)) = type_assertion.solve() { - // Substitute type variable for type in unsolved + // Solve the `TypeAssertion`. + // + // If the `TypeAssertion` has a solution, then continue the loop. + // If the `TypeAssertion` returns a `TypeVariablePair`, then substitute the `TypeVariable` + // for it's paired `Type` in all `TypeAssertion`s. + if let Some(pair) = type_assertion.solve()? { + // Substitute the `TypeVariable` for it's paired `Type` in all `TypeAssertion`s. for original in &mut unsolved { - original.substitute(&type_variable, &type_) + original.substitute(&pair.0, &pair.1) } - } else { - // Evaluate the type assertion. - } + }; } // for type_assertion in unsolved.pop() { @@ -1400,6 +1402,9 @@ impl VariableTable { } } +/// A type variable -> type pair. +pub struct TypeVariablePair(TypeVariable, Type); + /// A predicate that evaluates equality between two `Types`s. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub enum TypeAssertion { @@ -1411,8 +1416,8 @@ impl TypeAssertion { /// /// Returns a `TypeAssertion::Equality` predicate from given left and right `Types`s. /// - pub fn new_equality(left: Type, right: Type) -> Self { - Self::Equality(TypeEquality::new(left, right)) + pub fn new_equality(left: Type, right: Type, span: &Span) -> Self { + Self::Equality(TypeEquality::new(left, right, span)) } /// @@ -1432,16 +1437,12 @@ impl TypeAssertion { } /// - /// Returns true if the given type assertion outputs true. + /// Returns `None` if the `TypeAssertion` is solvable. /// - pub fn evaluate(&self) -> bool { - match self { - TypeAssertion::Equality(equality) => equality.evaluate(), - TypeAssertion::Membership(membership) => membership.evaluate(), - } - } - - pub fn solve(&self) -> Option<(TypeVariable, Type)> { + /// If the `TypeAssertion` is not solvable, throw a `TypeAssertionError`. + /// If the `TypeAssertion` contains a `TypeVariable`, then return `Some(TypeVariable, Type)`. + /// + pub fn solve(&self) -> Result, TypeAssertionError> { match self { TypeAssertion::Equality(equality) => equality.solve(), TypeAssertion::Membership(_) => unimplemented!(), @@ -1497,14 +1498,19 @@ impl TypeMembership { pub struct TypeEquality { left: Type, right: Type, + span: Span, } impl TypeEquality { /// /// Returns a `TypeEquality` predicate from given left and right `Types`s /// - pub fn new(left: Type, right: Type) -> Self { - Self { left, right } + pub fn new(left: Type, right: Type, span: &Span) -> Self { + Self { + left, + right, + span: span.to_owned(), + } } /// @@ -1515,29 +1521,22 @@ impl TypeEquality { self.right.substitute(variable, type_); } - /// - /// Returns true if the left `Types` is equal to the right `Types`. - /// - pub fn evaluate(&self) -> bool { - self.left.eq(&self.right) - } - /// /// Returns the (type variable, type) pair from this assertion. /// - pub fn solve(&self) -> Option<(TypeVariable, Type)> { - match (&self.left, &self.right) { - (Type::TypeVariable(variable), type_) => Some((variable.clone(), type_.clone())), - (type_, Type::TypeVariable(variable)) => Some((variable.clone(), type_.clone())), + pub fn solve(&self) -> Result, TypeAssertionError> { + Ok(match (&self.left, &self.right) { + (Type::TypeVariable(variable), type_) => Some(TypeVariablePair(variable.clone(), type_.clone())), + (type_, Type::TypeVariable(variable)) => Some(TypeVariablePair(variable.clone(), type_.clone())), (type1, type2) => { // Compare types. if type1.eq(type2) { // Return None if the two types are equal (the equality is satisfied). None } else { - unimplemented!("ERROR type equality `{} == {}` failed", type1, type2) + return Err(TypeAssertionError::assertion_failed(type1, type2, &self.span)); } } - } + }) } } diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index a247fa6e5d..b6ff758e55 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::ScopeError; +use crate::{ScopeError, TypeAssertionError}; use leo_static_check::TypeError; use leo_typed::{Error as FormattedError, Span}; @@ -29,6 +29,9 @@ pub enum FrameError { #[error("{}", _0)] ScopeError(#[from] ScopeError), + #[error("{}", _0)] + TypeAssertionError(#[from] TypeAssertionError), + #[error("{}", _0)] TypeError(#[from] TypeError), } @@ -41,14 +44,15 @@ impl FrameError { match self { FrameError::Error(error) => error.set_path(path), FrameError::ScopeError(error) => error.set_path(path), + FrameError::TypeAssertionError(error) => error.set_path(path), FrameError::TypeError(error) => error.set_path(path), } } - /// - /// Return a new formatted error with a given message and span information - /// - fn new_from_span(message: String, span: Span) -> Self { - FrameError::Error(FormattedError::new_from_span(message, span)) - } + // /// + // /// Return a new formatted error with a given message and span information + // /// + // fn new_from_span(message: String, span: Span) -> Self { + // FrameError::Error(FormattedError::new_from_span(message, span)) + // } } diff --git a/dynamic-check/src/errors/mod.rs b/dynamic-check/src/errors/mod.rs index a41469c2b2..5cf3d1a478 100644 --- a/dynamic-check/src/errors/mod.rs +++ b/dynamic-check/src/errors/mod.rs @@ -41,5 +41,8 @@ pub use self::frame::*; pub mod scope; pub use self::scope::*; +pub mod type_assertion; +pub use self::type_assertion::*; + pub mod variable_table; pub use self::variable_table::*; diff --git a/dynamic-check/src/errors/type_assertion.rs b/dynamic-check/src/errors/type_assertion.rs new file mode 100644 index 0000000000..656bb8fc9c --- /dev/null +++ b/dynamic-check/src/errors/type_assertion.rs @@ -0,0 +1,54 @@ +// 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 . + +use leo_static_check::Type; +use leo_typed::{Error as FormattedError, Span}; + +use std::path::PathBuf; + +/// Errors encountered when attempting to solve a type assertion. +#[derive(Debug, Error)] +pub enum TypeAssertionError { + #[error("{}", _0)] + Error(#[from] FormattedError), +} + +impl TypeAssertionError { + /// + /// Set the filepath for the error stacktrace. + /// + pub fn set_path(&mut self, path: PathBuf) { + match self { + TypeAssertionError::Error(error) => error.set_path(path), + } + } + + /// + /// Returns a new formatted error with a given message and span information. + /// + fn new_from_span(message: String, span: Span) -> Self { + TypeAssertionError::Error(FormattedError::new_from_span(message, span)) + } + + /// + /// Found mismatched types during program parsing. + /// + pub fn assertion_failed(left: &Type, right: &Type, span: &Span) -> Self { + let message = format!("Mismatched types expected type `{}`, found type `{}`", left, right); + + Self::new_from_span(message, span.to_owned()) + } +} diff --git a/dynamic-check/tests/empty.leo b/dynamic-check/tests/empty.leo index 41ed588476..e69de29bb2 100644 --- a/dynamic-check/tests/empty.leo +++ b/dynamic-check/tests/empty.leo @@ -1,14 +0,0 @@ -circuit Foo { - a: u8, - b: u8, - - static function one() -> u8 { - return 1 - } -} - -function main(mut a: u8) -> bool { - a = Foo::one(); - let b = true; - return b -} \ No newline at end of file diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 5805073f25..ffac91f162 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -48,7 +48,7 @@ impl TestDynamicCheck { let symbol_table = StaticCheck::run(&program).unwrap(); // Create dynamic check - let dynamic_check = DynamicCheck::new(&program, symbol_table); + let dynamic_check = DynamicCheck::new(&program, symbol_table).unwrap(); Self { dynamic_check } } From f2a808cbe741a4f33f2f18a0bb9566e1150f7b70 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 23 Oct 2020 17:31:41 -0700 Subject: [PATCH 053/139] impl membership type assertion error handling --- compiler/tests/boolean/mod.rs | 18 ++---- compiler/tests/mod.rs | 9 +++ dynamic-check/src/dynamic_check.rs | 72 +++++++++++++--------- dynamic-check/src/errors/type_assertion.rs | 16 ++++- 4 files changed, 70 insertions(+), 45 deletions(-) diff --git a/compiler/tests/boolean/mod.rs b/compiler/tests/boolean/mod.rs index 72ca91f215..7d9fcd9d08 100644 --- a/compiler/tests/boolean/mod.rs +++ b/compiler/tests/boolean/mod.rs @@ -17,6 +17,7 @@ use crate::{ assert_satisfied, expect_compiler_error, + expect_dynamic_check_error, get_output, parse_program, parse_program_with_input, @@ -38,15 +39,6 @@ pub fn output_false(program: EdwardsTestCompiler) { assert_eq!(expected, actual.bytes().as_slice()); } -fn fail_boolean_statement(program: EdwardsTestCompiler) { - match expect_compiler_error(program) { - CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( - ExpressionError::BooleanError(BooleanError::Error(_)), - ))) => {} - _ => panic!("Expected boolean error, got {}"), - } -} - #[test] fn test_input_pass() { let program_bytes = include_bytes!("assert_eq_input.leo"); @@ -139,9 +131,9 @@ fn test_false_or_false() { #[test] fn test_true_or_u32() { let bytes = include_bytes!("true_or_u32.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - fail_boolean_statement(program); + expect_dynamic_check_error(error); } // Boolean and && @@ -173,9 +165,9 @@ fn test_false_and_false() { #[test] fn test_true_and_u32() { let bytes = include_bytes!("true_and_u32.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - fail_boolean_statement(program); + expect_dynamic_check_error(error); } // All diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index 015c2e272a..ac6d042a87 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -178,6 +178,15 @@ pub(crate) fn expect_compiler_error(program: EdwardsTestCompiler) -> CompilerErr program.generate_constraints_helper(&mut cs).unwrap_err() } +pub(crate) fn expect_dynamic_check_error(error: CompilerError) { + let is_dynamic_check = match error { + CompilerError::DynamicCheckError(_) => true, + _ => false, + }; + + assert!(is_dynamic_check) +} + // pub(crate) fn expect_synthesis_error(program: EdwardsTestCompiler) { // let mut cs = TestConstraintSystem::::new(); // let _output = program.generate_constraints_helper(&mut cs).unwrap(); diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index a126ff999a..819b5a570d 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -341,8 +341,8 @@ impl Frame { /// /// Creates a new membership type assertion between a given and set of types. /// - fn assert_membership(&mut self, given: Type, set: Vec) { - let type_assertion = TypeAssertion::new_membership(given, set); + fn assert_membership(&mut self, given: Type, set: Vec, span: &Span) { + let type_assertion = TypeAssertion::new_membership(given, set, span); self.type_assertions.push(type_assertion); } @@ -350,28 +350,28 @@ impl Frame { /// /// Creates a new membership type assertion between a given and the set of negative integer types. /// - fn assert_negative_integer(&mut self, given: &Type) { + fn assert_negative_integer(&mut self, given: &Type, span: &Span) { let negative_integer_types = Type::negative_integer_types(); - self.assert_membership(given.clone(), negative_integer_types) + self.assert_membership(given.clone(), negative_integer_types, span) } /// /// Creates a new membership type assertion between a given and the set of all integer types. /// - fn assert_integer(&mut self, given: &Type) { + fn assert_integer(&mut self, given: &Type, span: &Span) { let integer_types = Type::integer_types(); - self.assert_membership(given.clone(), integer_types) + self.assert_membership(given.clone(), integer_types, span) } /// /// Creates a new membership type assertion between a given and the set of index types. /// - fn assert_index(&mut self, given: &Type) { + fn assert_index(&mut self, given: &Type, span: &Span) { let index_types = Type::index_types(); - self.assert_membership(given.clone(), index_types) + self.assert_membership(given.clone(), index_types, span) } /// @@ -751,12 +751,12 @@ impl Frame { &mut self, left: &Expression, right: &Expression, - _span: &Span, + span: &Span, ) -> Result { - let type_ = self.parse_binary_expression(left, right, _span)?; + let type_ = self.parse_binary_expression(left, right, span)?; // Assert that the type is an integer. - self.assert_integer(&type_); + self.assert_integer(&type_, span); Ok(type_) } @@ -780,12 +780,12 @@ impl Frame { /// /// Returns the `Type` of the expression being negated. Must be a negative integer type. /// - fn parse_negate_expression(&mut self, expression: &Expression, _span: &Span) -> Result { + fn parse_negate_expression(&mut self, expression: &Expression, span: &Span) -> Result { // Parse the expression type. let type_ = self.parse_expression(expression)?; // Assert that this integer can be negated. - self.assert_negative_integer(&type_); + self.assert_negative_integer(&type_, span); Ok(type_) } @@ -958,12 +958,7 @@ impl Frame { /// /// Returns the type of the accessed array element. /// - fn parse_array_access( - &mut self, - type_: Type, - r_or_e: &RangeOrExpression, - _span: &Span, - ) -> Result { + fn parse_array_access(&mut self, type_: Type, r_or_e: &RangeOrExpression, span: &Span) -> Result { // Check the type is an array. let (element_type, _dimensions) = match type_ { Type::Array(type_, dimensions) => (type_, dimensions), @@ -980,14 +975,14 @@ impl Frame { // Parse the expression type. let type_ = self.parse_expression(expression)?; - self.assert_index(&type_); + self.assert_index(&type_, span); } if let Some(expression) = to { // Parse the expression type. let type_ = self.parse_expression(expression)?; - self.assert_index(&type_); + self.assert_index(&type_, span); } } RangeOrExpression::Expression(expression) => { @@ -995,7 +990,7 @@ impl Frame { let type_ = self.parse_expression(expression)?; // Assert the type is an index. - self.assert_index(&type_); + self.assert_index(&type_, span); } } @@ -1423,8 +1418,8 @@ impl TypeAssertion { /// /// Returns a `TypeAssertion::Membership` predicate from given and set `Type`s. /// - pub fn new_membership(given: Type, set: Vec) -> Self { - Self::Membership(TypeMembership::new(given, set)) + pub fn new_membership(given: Type, set: Vec, span: &Span) -> Self { + Self::Membership(TypeMembership::new(given, set, span)) } /// @@ -1445,7 +1440,11 @@ impl TypeAssertion { pub fn solve(&self) -> Result, TypeAssertionError> { match self { TypeAssertion::Equality(equality) => equality.solve(), - TypeAssertion::Membership(_) => unimplemented!(), + TypeAssertion::Membership(membership) => { + membership.solve()?; + + Ok(None) + } } } } @@ -1455,14 +1454,19 @@ impl TypeAssertion { pub struct TypeMembership { given: Type, set: Vec, + span: Span, } impl TypeMembership { /// /// Returns a `TypeMembership` predicate from given and set `Type`s. /// - pub fn new(given: Type, set: Vec) -> Self { - Self { given, set } + pub fn new(given: Type, set: Vec, span: &Span) -> Self { + Self { + given, + set, + span: span.to_owned(), + } } /// @@ -1476,8 +1480,16 @@ impl TypeMembership { /// /// Returns true if the given type is equal to a member of the set. /// - pub fn evaluate(&self) -> bool { - self.set.contains(&self.given) + pub fn solve(&self) -> Result<(), TypeAssertionError> { + if self.set.contains(&self.given) { + Ok(()) + } else { + Err(TypeAssertionError::membership_failed( + &self.given, + &self.set, + &self.span, + )) + } } /// @@ -1534,7 +1546,7 @@ impl TypeEquality { // Return None if the two types are equal (the equality is satisfied). None } else { - return Err(TypeAssertionError::assertion_failed(type1, type2, &self.span)); + return Err(TypeAssertionError::equality_failed(type1, type2, &self.span)); } } }) diff --git a/dynamic-check/src/errors/type_assertion.rs b/dynamic-check/src/errors/type_assertion.rs index 656bb8fc9c..22b1090714 100644 --- a/dynamic-check/src/errors/type_assertion.rs +++ b/dynamic-check/src/errors/type_assertion.rs @@ -46,8 +46,20 @@ impl TypeAssertionError { /// /// Found mismatched types during program parsing. /// - pub fn assertion_failed(left: &Type, right: &Type, span: &Span) -> Self { - let message = format!("Mismatched types expected type `{}`, found type `{}`", left, right); + pub fn equality_failed(left: &Type, right: &Type, span: &Span) -> Self { + let message = format!("Mismatched types. Expected type `{}`, found type `{}`.", left, right); + + Self::new_from_span(message, span.to_owned()) + } + + /// + /// Given type is not a member of the set of expected types. + /// + pub fn membership_failed(given: &Type, set: &Vec, span: &Span) -> Self { + let message = format!( + "Mismatched types. Given type `{}` is not in the expected type set `{:?}`.", + given, set + ); Self::new_from_span(message, span.to_owned()) } From d55bd0d2af56cd57979bb15aa3b587f7c867f4d9 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 23 Oct 2020 17:59:34 -0700 Subject: [PATCH 054/139] enforce order on solving type assertions --- dynamic-check/src/dynamic_check.rs | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 819b5a570d..7dfe816090 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -1237,10 +1237,20 @@ impl Frame { fn solve(self) -> Result<(), FrameError> { let mut unsolved = self.type_assertions.clone(); + // Solve all type equality assertions first. + let mut unsolved_membership = Vec::new(); + while !unsolved.is_empty() { // Pop type assertion from list let type_assertion = unsolved.pop().unwrap(); + // If it is a membership assertion, then skip it for now. + if let TypeAssertion::Membership(membership) = type_assertion { + unsolved_membership.push(membership); + + continue; + } + println!("assertion: {:?}", type_assertion); // Solve the `TypeAssertion`. @@ -1253,9 +1263,22 @@ impl Frame { for original in &mut unsolved { original.substitute(&pair.0, &pair.1) } + + for original in &mut unsolved_membership { + original.substitute(&pair.0, &pair.1) + } }; } + // Solve all type membership assertions. + while !unsolved_membership.is_empty() { + // Pop type assertion from list + let type_assertion = unsolved_membership.pop().unwrap(); + + // Solve the membership assertion. + type_assertion.solve()?; + } + // for type_assertion in unsolved.pop() { // if let Some((type_variable, type_)) = type_assertion.get_substitute() { // // Substitute type variable in unsolved type assertions @@ -1427,7 +1450,7 @@ impl TypeAssertion { pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { match self { TypeAssertion::Equality(equality) => equality.substitute(variable, type_), - TypeAssertion::Membership(_) => unimplemented!(), + TypeAssertion::Membership(membership) => membership.substitute(variable, type_), } } @@ -1472,9 +1495,8 @@ impl TypeMembership { /// /// Substitutes the given `TypeVariable` for each `Type` in the `TypeMembership`. /// - pub fn substitute(&mut self, _variable: &TypeVariable, _type_: &Type) { - // self.left.substitute(variable, type_); - // self.right.substitute(variable, type_); + pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { + self.given.substitute(variable, type_) } /// From 8e75e3653263638be9bd5106cc029256c74de621 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 23 Oct 2020 21:54:19 -0700 Subject: [PATCH 055/139] manually impl PartialEq for array types --- compiler/tests/array/mod.rs | 53 +++++++++++++++++---------------- static-check/src/types/type_.rs | 50 +++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 28 deletions(-) diff --git a/compiler/tests/array/mod.rs b/compiler/tests/array/mod.rs index 62a18bd541..a4e37b66cb 100644 --- a/compiler/tests/array/mod.rs +++ b/compiler/tests/array/mod.rs @@ -17,6 +17,7 @@ use crate::{ assert_satisfied, expect_compiler_error, + expect_dynamic_check_error, get_output, parse_program, parse_program_with_input, @@ -150,17 +151,17 @@ fn test_input_tuple_3x2_fail() { #[test] fn test_multi_fail_initializer() { let program_bytes = include_bytes!("multi_fail_initializer.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] fn test_multi_inline_fail() { let program_bytes = include_bytes!("multi_fail_inline.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -174,9 +175,9 @@ fn test_multi_initializer() { #[test] fn test_multi_initializer_fail() { let program_bytes = include_bytes!("multi_initializer_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let err = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(err); } #[test] @@ -190,9 +191,9 @@ fn test_nested_3x2_value() { #[test] fn test_nested_3x2_value_fail() { let program_bytes = include_bytes!("nested_3x2_value_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -206,9 +207,9 @@ fn test_tuple_3x2_value() { #[test] fn test_tuple_3x2_value_fail() { let program_bytes = include_bytes!("tuple_3x2_value_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -250,9 +251,9 @@ fn test_type_nested_value_nested_3x2() { #[test] fn test_type_nested_value_nested_3x2_fail() { let program_bytes = include_bytes!("type_nested_value_nested_3x2_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -266,9 +267,9 @@ fn test_type_nested_value_nested_4x3x2() { #[test] fn test_type_nested_value_nested_4x3x2_fail() { let program_bytes = include_bytes!("type_nested_value_nested_4x3x2_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -282,9 +283,9 @@ fn test_type_nested_value_tuple_3x2() { #[test] fn test_type_nested_value_tuple_3x2_fail() { let program_bytes = include_bytes!("type_nested_value_tuple_3x2_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -298,9 +299,9 @@ fn test_type_nested_value_tuple_4x3x2() { #[test] fn test_type_nested_value_tuple_4x3x2_fail() { let program_bytes = include_bytes!("type_nested_value_tuple_4x3x2_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -314,9 +315,9 @@ fn test_type_tuple_value_nested_3x2() { #[test] fn test_type_tuple_value_nested_3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_nested_3x2_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -330,9 +331,9 @@ fn test_type_tuple_value_nested_4x3x2() { #[test] fn test_type_tuple_value_nested_4x3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_nested_4x3x2_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -346,9 +347,9 @@ fn test_type_tuple_value_tuple_3x2() { #[test] fn test_type_tuple_value_tuple_3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_tuple_3x2_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -362,9 +363,9 @@ fn test_type_tuple_value_tuple_4x3x2() { #[test] fn test_type_tuple_value_tuple_4x3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_tuple_4x3x2_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } // Tests for nested multi-dimensional arrays as input to the program diff --git a/static-check/src/types/type_.rs b/static-check/src/types/type_.rs index 05a444b13c..03b94ba50e 100644 --- a/static-check/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -17,10 +17,13 @@ use crate::{SymbolTable, TypeError, TypeVariable}; use leo_typed::{Identifier, IntegerType, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::{ + cmp::{Eq, PartialEq}, + fmt, +}; /// A type in a Leo program. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Hash, Serialize, Deserialize)] pub enum Type { // Data types Address, @@ -273,3 +276,46 @@ impl fmt::Display for Type { } } } + +impl PartialEq for Type { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Type::Address, Type::Address) => true, + (Type::Boolean, Type::Boolean) => true, + (Type::Field, Type::Field) => true, + (Type::Group, Type::Group) => true, + (Type::IntegerType(integer_type1), Type::IntegerType(integer_type2)) => integer_type1.eq(integer_type2), + + (Type::Array(type1, dimensions1), Type::Array(type2, dimensions2)) => { + // Flatten both array types before comparison. + let (type1_flat, dimensions1_flat) = flatten_array_type(type1, dimensions1.to_owned()); + let (type2_flat, dimensions2_flat) = flatten_array_type(type2, dimensions2.to_owned()); + + // Element types and dimensions must match + type1_flat.eq(type2_flat) && dimensions1_flat.eq(&dimensions2_flat) + } + + (Type::Tuple(types1), Type::Tuple(types2)) => types1.eq(types2), + (Type::Circuit(identifier1), Type::Circuit(identifier2)) => identifier1.eq(identifier2), + (Type::Function(identifier1), Type::Function(identifier2)) => identifier1.eq(identifier2), + (Type::TypeVariable(variable1), Type::TypeVariable(variable2)) => variable1.eq(variable2), + _ => false, + } + } +} + +impl Eq for Type {} + +/// +/// Returns the data type of the array element and vector of dimensions. +/// +/// Will flatten an array type `[[[u8; 1]; 2]; 3]` into `[u8; (3, 2, 1)]`. +/// +fn flatten_array_type(type_: &Type, mut dimensions: Vec) -> (&Type, Vec) { + if let Type::Array(element_type, element_dimensions) = type_ { + dimensions.append(&mut element_dimensions.to_owned()); + flatten_array_type(element_type, dimensions) + } else { + (type_, dimensions) + } +} From 40d26dce7f4b58008290c81087c8a7e3cb05afd1 Mon Sep 17 00:00:00 2001 From: collin Date: Sat, 24 Oct 2020 00:51:04 -0700 Subject: [PATCH 056/139] refactor type assertion solving --- dynamic-check/src/dynamic_check.rs | 201 +++++++++++++++++---- dynamic-check/src/errors/type_assertion.rs | 12 ++ static-check/src/types/type_.rs | 2 +- 3 files changed, 174 insertions(+), 41 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 7dfe816090..61308fa892 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -16,6 +16,7 @@ use crate::{DynamicCheckError, FrameError, ScopeError, TypeAssertionError, VariableTableError}; use leo_static_check::{ + flatten_array_type, Attribute, CircuitFunctionType, CircuitType, @@ -1253,21 +1254,42 @@ impl Frame { println!("assertion: {:?}", type_assertion); + // Collect `TypeVariablePairs` from the `TypeAssertion`. + let pairs = type_assertion.pairs()?; + + // If no pairs are found, attempt to evaluate the `TypeAssertion`. + if pairs.is_empty() { + // Evaluate the `TypeAssertion`. + type_assertion.evaluate()? + } else { + // Iterate over each `TypeVariable` -> `Type` pair. + for pair in pairs.get_pairs() { + // Substitute the `TypeVariable` for it's paired `Type` in all `TypeAssertion`s. + for original in &mut unsolved { + original.substitute(&pair.0, &pair.1) + } + + for original in &mut unsolved_membership { + original.substitute(&pair.0, &pair.1) + } + } + } + // Solve the `TypeAssertion`. // // If the `TypeAssertion` has a solution, then continue the loop. // If the `TypeAssertion` returns a `TypeVariablePair`, then substitute the `TypeVariable` // for it's paired `Type` in all `TypeAssertion`s. - if let Some(pair) = type_assertion.solve()? { - // Substitute the `TypeVariable` for it's paired `Type` in all `TypeAssertion`s. - for original in &mut unsolved { - original.substitute(&pair.0, &pair.1) - } - - for original in &mut unsolved_membership { - original.substitute(&pair.0, &pair.1) - } - }; + // if let Some(pair) = type_assertion.solve()? { + // // Substitute the `TypeVariable` for it's paired `Type` in all `TypeAssertion`s. + // for original in &mut unsolved { + // original.substitute(&pair.0, &pair.1) + // } + // + // for original in &mut unsolved_membership { + // original.substitute(&pair.0, &pair.1) + // } + // }; } // Solve all type membership assertions. @@ -1276,7 +1298,7 @@ impl Frame { let type_assertion = unsolved_membership.pop().unwrap(); // Solve the membership assertion. - type_assertion.solve()?; + type_assertion.evaluate()?; } // for type_assertion in unsolved.pop() { @@ -1420,9 +1442,6 @@ impl VariableTable { } } -/// A type variable -> type pair. -pub struct TypeVariablePair(TypeVariable, Type); - /// A predicate that evaluates equality between two `Types`s. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub enum TypeAssertion { @@ -1445,8 +1464,19 @@ impl TypeAssertion { Self::Membership(TypeMembership::new(given, set, span)) } + /// + /// Returns one or more `TypeVariablePairs` generated by the given `TypeAssertion`. + /// + pub fn pairs(&self) -> Result { + match self { + TypeAssertion::Equality(equality) => equality.pairs(), + TypeAssertion::Membership(_) => unimplemented!("Cannot generate pairs from type membership"), + } + } + /// /// Substitutes the given type for self if self is equal to the type variable. + /// pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { match self { TypeAssertion::Equality(equality) => equality.substitute(variable, type_), @@ -1455,19 +1485,12 @@ impl TypeAssertion { } /// - /// Returns `None` if the `TypeAssertion` is solvable. + /// Checks if the `TypeAssertion` is satisfied. /// - /// If the `TypeAssertion` is not solvable, throw a `TypeAssertionError`. - /// If the `TypeAssertion` contains a `TypeVariable`, then return `Some(TypeVariable, Type)`. - /// - pub fn solve(&self) -> Result, TypeAssertionError> { + pub fn evaluate(&self) -> Result<(), TypeAssertionError> { match self { - TypeAssertion::Equality(equality) => equality.solve(), - TypeAssertion::Membership(membership) => { - membership.solve()?; - - Ok(None) - } + TypeAssertion::Equality(equality) => equality.evaluate(), + TypeAssertion::Membership(membership) => membership.evaluate(), } } } @@ -1502,7 +1525,7 @@ impl TypeMembership { /// /// Returns true if the given type is equal to a member of the set. /// - pub fn solve(&self) -> Result<(), TypeAssertionError> { + pub fn evaluate(&self) -> Result<(), TypeAssertionError> { if self.set.contains(&self.given) { Ok(()) } else { @@ -1555,22 +1578,120 @@ impl TypeEquality { self.right.substitute(variable, type_); } + /// + /// Checks if the `self.left` == `self.right`. + /// + pub fn evaluate(&self) -> Result<(), TypeAssertionError> { + if self.left.eq(&self.right) { + Ok(()) + } else { + Err(TypeAssertionError::equality_failed(&self.left, &self.right, &self.span)) + } + } + /// /// Returns the (type variable, type) pair from this assertion. /// - pub fn solve(&self) -> Result, TypeAssertionError> { - Ok(match (&self.left, &self.right) { - (Type::TypeVariable(variable), type_) => Some(TypeVariablePair(variable.clone(), type_.clone())), - (type_, Type::TypeVariable(variable)) => Some(TypeVariablePair(variable.clone(), type_.clone())), - (type1, type2) => { - // Compare types. - if type1.eq(type2) { - // Return None if the two types are equal (the equality is satisfied). - None - } else { - return Err(TypeAssertionError::equality_failed(type1, type2, &self.span)); - } - } - }) + pub fn pairs(&self) -> Result { + TypeVariablePairs::new(&self.left, &self.right, &self.span) + } +} + +/// A type variable -> type pair. +pub struct TypeVariablePair(TypeVariable, Type); + +/// A vector of `TypeVariablePair`s. +pub struct TypeVariablePairs(Vec); + +impl Default for TypeVariablePairs { + fn default() -> Self { + Self(Vec::new()) + } +} + +impl TypeVariablePairs { + /// + /// Returns a new `TypeVariablePairs` struct from the given left and right types. + /// + pub fn new(left: &Type, right: &Type, span: &Span) -> Result { + let mut pairs = Self::default(); + + // Push all `TypeVariablePair`s. + pairs.push_pairs(left, right, span)?; + + Ok(pairs) + } + + /// + /// Returns true if the self vector has no pairs. + /// + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// + /// Returns the self vector of pairs. + /// + pub fn get_pairs(&self) -> &Vec { + &self.0 + } + + /// + /// Pushes a new `TypeVariablePair` struct to self. + /// + pub fn push(&mut self, variable: &TypeVariable, type_: &Type) { + // Create a new type variable -> type pair. + let pair = TypeVariablePair(variable.clone(), type_.clone()); + + // Push the pair to the self vector. + self.0.push(pair); + } + + /// + /// Checks if the given left or right type contains a `TypeVariable`. + /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left + /// and right type. + /// + pub fn push_pairs(&mut self, left: &Type, right: &Type, span: &Span) -> Result<(), TypeAssertionError> { + match (left, right) { + (Type::TypeVariable(variable), type_) => Ok(self.push(variable, type_)), + (type_, Type::TypeVariable(variable)) => Ok(self.push(variable, type_)), + (Type::Array(type1, dimensions1), Type::Array(type2, dimensions2)) => { + self.push_pairs_array(type1, dimensions1, type2, dimensions2, span) + } + (_, _) => Ok(()), // No `TypeVariable` found so we do not push any pairs. + } + } + + /// + /// Checks if the given left or right array type contains a `TypeVariable`. + /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left + /// and right type. + /// + fn push_pairs_array( + &mut self, + left_type: &Type, + left_dimensions: &Vec, + right_type: &Type, + right_dimensions: &Vec, + span: &Span, + ) -> Result<(), TypeAssertionError> { + // Flatten the array types to get the element types. + let (left_type_flat, left_dimensions_flat) = flatten_array_type(left_type, left_dimensions.to_owned()); + let (right_type_flat, right_dimensions_flat) = flatten_array_type(right_type, right_dimensions.to_owned()); + + // If the dimensions do not match, then throw an error. + if left_dimensions_flat.ne(&right_dimensions_flat) { + return Err(TypeAssertionError::array_dimensions( + left_dimensions_flat, + right_dimensions_flat, + span, + )); + } + + // Compare the array element types. + self.push_pairs(left_type_flat, right_type_flat, span); + + Ok(()) } } diff --git a/dynamic-check/src/errors/type_assertion.rs b/dynamic-check/src/errors/type_assertion.rs index 22b1090714..da61010947 100644 --- a/dynamic-check/src/errors/type_assertion.rs +++ b/dynamic-check/src/errors/type_assertion.rs @@ -63,4 +63,16 @@ impl TypeAssertionError { Self::new_from_span(message, span.to_owned()) } + + /// + /// Mismatched array type dimensions. + /// + pub fn array_dimensions(dimensions1: Vec, dimensions2: Vec, span: &Span) -> Self { + let message = format!( + "Expected array with dimensions `{:?}`, found array with dimensions `{:?}`.", + dimensions1, dimensions2 + ); + + Self::new_from_span(message, span.to_owned()) + } } diff --git a/static-check/src/types/type_.rs b/static-check/src/types/type_.rs index 03b94ba50e..69c7a346da 100644 --- a/static-check/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -311,7 +311,7 @@ impl Eq for Type {} /// /// Will flatten an array type `[[[u8; 1]; 2]; 3]` into `[u8; (3, 2, 1)]`. /// -fn flatten_array_type(type_: &Type, mut dimensions: Vec) -> (&Type, Vec) { +pub fn flatten_array_type(type_: &Type, mut dimensions: Vec) -> (&Type, Vec) { if let Type::Array(element_type, element_dimensions) = type_ { dimensions.append(&mut element_dimensions.to_owned()); flatten_array_type(element_type, dimensions) From 973e2a6afc5e95209ad539cfe613bd22e7f2a1bc Mon Sep 17 00:00:00 2001 From: collin Date: Sat, 24 Oct 2020 02:53:09 -0700 Subject: [PATCH 057/139] add dynamic check errors for circuits 1 --- compiler/tests/circuits/mod.rs | 41 ++++++++----------- dynamic-check/src/dynamic_check.rs | 65 ++++++++++++++++++++++++------ dynamic-check/src/errors/frame.rs | 59 +++++++++++++++++++++++---- typed/src/common/identifier.rs | 6 ++- 4 files changed, 126 insertions(+), 45 deletions(-) diff --git a/compiler/tests/circuits/mod.rs b/compiler/tests/circuits/mod.rs index 4c9c8665e9..f192067104 100644 --- a/compiler/tests/circuits/mod.rs +++ b/compiler/tests/circuits/mod.rs @@ -14,18 +14,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_compiler_error, parse_program, EdwardsTestCompiler}; +use crate::{assert_satisfied, expect_compiler_error, expect_dynamic_check_error, parse_program, EdwardsTestCompiler}; use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError}; -fn expect_fail(program: EdwardsTestCompiler) { - match expect_compiler_error(program) { - CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( - ExpressionError::Error(_string), - ))) => {} - error => panic!("Expected invalid circuit member error, got {}", error), - } -} - // Expressions #[test] @@ -41,15 +32,15 @@ fn test_inline_fail() { let bytes = include_bytes!("inline_fail.leo"); let program = parse_program(bytes).unwrap(); - expect_fail(program); + expect_compiler_error(program); } #[test] fn test_inline_undefined() { let bytes = include_bytes!("inline_undefined.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_fail(program); + expect_dynamic_check_error(error); } // Members @@ -65,9 +56,9 @@ fn test_member_variable() { #[test] fn test_member_variable_fail() { let bytes = include_bytes!("member_variable_fail.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_fail(program); + expect_dynamic_check_error(error); } #[test] @@ -89,17 +80,17 @@ fn test_member_function() { #[test] fn test_member_function_fail() { let bytes = include_bytes!("member_function_fail.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_fail(program); + expect_dynamic_check_error(error); } #[test] fn test_member_function_invalid() { let bytes = include_bytes!("member_function_invalid.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_fail(program); + expect_dynamic_check_error(error); } #[test] @@ -129,17 +120,17 @@ fn test_member_static_function_nested() { #[test] fn test_member_static_function_invalid() { let bytes = include_bytes!("member_static_function_invalid.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_fail(program) + expect_dynamic_check_error(error) } #[test] fn test_member_static_function_undefined() { let bytes = include_bytes!("member_static_function_undefined.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_fail(program) + expect_dynamic_check_error(error) } // Mutability @@ -213,9 +204,9 @@ fn test_mutate_variable_fail() { #[test] fn test_self_fail() { let bytes = include_bytes!("self_fail.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 61308fa892..a3fab01667 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -696,6 +696,15 @@ impl Frame { /// Returns the type of the identifier in the symbol table. /// fn parse_identifier(&self, identifier: &Identifier) -> Result { + // Check Self type. + if identifier.is_self_type() { + // Check for frame circuit self type. + let circuit_type = self.self_type_or_error(&identifier.span)?; + + // Return new type with circuit identifier. + return Ok(Type::Circuit(circuit_type.identifier)); + } + // Check variable symbol table. if let Some(type_) = self.get_variable(&identifier.name) { return Ok(type_.to_owned()); @@ -730,7 +739,6 @@ impl Frame { right: &Expression, span: &Span, ) -> Result { - println!("left {}, right {}", left, right); // Get the left expression type. let left_type = self.parse_expression(left)?; @@ -998,6 +1006,16 @@ impl Frame { Ok(*element_type) } + /// + /// Returns the Self type of the frame or an error if it does not exist. + /// + fn self_type_or_error(&self, span: &Span) -> Result { + self.self_type + .as_ref() + .map(|circuit_type| circuit_type.clone()) + .ok_or_else(|| FrameError::circuit_self(span)) + } + /// /// Returns the type of inline circuit expression. /// @@ -1009,14 +1027,15 @@ impl Frame { ) -> Result { // Check if identifier is Self circuit type. let circuit_type = if identifier.is_self() { - self.self_type.clone() + // Get the Self type of the frame. + self.self_type_or_error(span)? } else { // Get circuit type. self.user_defined_types .get_circuit(&identifier.name) .map(|circuit_type| circuit_type.clone()) - } - .unwrap(); + .ok_or_else(|| FrameError::undefined_circuit(identifier))? + }; // Check the length of the circuit members. if circuit_type.variables.len() != members.len() { @@ -1064,7 +1083,7 @@ impl Frame { let circuit_type = self.parse_circuit_name(type_, span)?; // Look for member with matching name. - Ok(circuit_type.member_type(&identifier).unwrap()) + Ok(circuit_type.member_type(&identifier)?) } /// @@ -1092,7 +1111,7 @@ impl Frame { // Lookup circuit identifier. self.user_defined_types.get_circuit(&identifier.name).unwrap() } - _ => unimplemented!("expected circuit type"), + type_ => unimplemented!("expected circuit type {:?}", type_), }) } @@ -1143,7 +1162,9 @@ impl Frame { let circuit_type = self.parse_circuit_name(type_, span)?; // Find circuit function by identifier. - Ok(circuit_type.member_function_type(identifier).unwrap()) + circuit_type + .member_function_type(identifier) + .ok_or_else(|| FrameError::undefined_circuit_function(identifier)) } /// @@ -1160,7 +1181,7 @@ impl Frame { // Check that the function is non-static. if circuit_function_type.attributes.contains(&Attribute::Static) { - unimplemented!("Called static function using dot syntax") + return Err(FrameError::invalid_static_access(identifier)); } // Return the function type. @@ -1181,7 +1202,7 @@ impl Frame { // Check that the function is static. if !circuit_function_type.attributes.contains(&Attribute::Static) { - unimplemented!("Called non-static function using double colon syntax") + return Err(FrameError::invalid_member_access(identifier)); } Ok(circuit_function_type.function.to_owned()) @@ -1199,7 +1220,6 @@ impl Frame { span: &Span, ) -> Result { // Parse the function name. - println!("expression {}", expression); let function_type = self.parse_function_name(expression, span)?; // Check the length of arguments @@ -1656,9 +1676,10 @@ impl TypeVariablePairs { match (left, right) { (Type::TypeVariable(variable), type_) => Ok(self.push(variable, type_)), (type_, Type::TypeVariable(variable)) => Ok(self.push(variable, type_)), - (Type::Array(type1, dimensions1), Type::Array(type2, dimensions2)) => { - self.push_pairs_array(type1, dimensions1, type2, dimensions2, span) + (Type::Array(left_type, left_dimensions), Type::Array(right_type, right_dimensions)) => { + self.push_pairs_array(left_type, left_dimensions, right_type, right_dimensions, span) } + (Type::Tuple(left_types), Type::Tuple(right_types)) => self.push_pairs_tuple(left_types, right_types, span), (_, _) => Ok(()), // No `TypeVariable` found so we do not push any pairs. } } @@ -1694,4 +1715,24 @@ impl TypeVariablePairs { Ok(()) } + + /// + /// Checks if any given left or right tuple type contains a `TypeVariable`. + /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left + /// and right type. + /// + fn push_pairs_tuple( + &mut self, + left_types: &Vec, + right_types: &Vec, + span: &Span, + ) -> Result<(), TypeAssertionError> { + // Iterate over each left == right pair of types. + for (left, right) in left_types.iter().zip(right_types) { + // Check for `TypeVariablePair`s. + self.push_pairs(left, right, span)?; + } + + Ok(()) + } } diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index b6ff758e55..0bf5f2e961 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -16,7 +16,7 @@ use crate::{ScopeError, TypeAssertionError}; use leo_static_check::TypeError; -use leo_typed::{Error as FormattedError, Span}; +use leo_typed::{Error as FormattedError, Identifier, Span}; use std::path::PathBuf; @@ -49,10 +49,55 @@ impl FrameError { } } - // /// - // /// Return a new formatted error with a given message and span information - // /// - // fn new_from_span(message: String, span: Span) -> Self { - // FrameError::Error(FormattedError::new_from_span(message, span)) - // } + /// + /// Return a new formatted error with a given message and span information + /// + fn new_from_span(message: String, span: Span) -> Self { + FrameError::Error(FormattedError::new_from_span(message, span)) + } + + /// + /// Attempted to access the `Self` type outside of a circuit context. + /// + pub fn circuit_self(span: &Span) -> Self { + let message = "The `Self` keyword is only valid inside a circuit context.".to_string(); + + Self::new_from_span(message, span.to_owned()) + } + + /// + /// Attempted to call non-static member using `::`. + /// + pub fn invalid_member_access(identifier: &Identifier) -> Self { + let message = format!("non-static member `{}` must be accessed using `.` syntax", identifier); + + Self::new_from_span(message, identifier.span.to_owned()) + } + + /// + /// Attempted to call static member using `.`. + /// + pub fn invalid_static_access(identifier: &Identifier) -> Self { + let message = format!("static member `{}` must be accessed using `::` syntax", identifier); + + Self::new_from_span(message, identifier.span.to_owned()) + } + + /// + /// Attempted to call a circuit type that is not defined in the current context. + /// + pub fn undefined_circuit(identifier: &Identifier) -> Self { + let message = format!("The circuit `{}` is not defined.", identifier); + + Self::new_from_span(message, identifier.span.to_owned()) + } + + /// + /// Attempted to call a circuit function that is not defined in the current context. + /// + pub fn undefined_circuit_function(identifier: &Identifier) -> Self { + let message = format!("The circuit function `{}` is not defined.", identifier); + + Self::new_from_span(message, identifier.span.to_owned()) + } } diff --git a/typed/src/common/identifier.rs b/typed/src/common/identifier.rs index c10474e62c..6b08d8b58b 100644 --- a/typed/src/common/identifier.rs +++ b/typed/src/common/identifier.rs @@ -46,8 +46,12 @@ pub struct Identifier { } impl Identifier { + pub fn is_self_type(&self) -> bool { + self.name == "Self" + } + pub fn is_self(&self) -> bool { - self.name == "Self" || self.name == "self" + self.is_self_type() || self.name == "self" } } From e19616b4e5010ada58507ec71ead6a889a669bcb Mon Sep 17 00:00:00 2001 From: collin Date: Sat, 24 Oct 2020 13:07:27 -0700 Subject: [PATCH 058/139] add dynamic check errors for circuits 2 --- compiler/tests/circuits/mod.rs | 8 +++--- compiler/tests/circuits/mut_function_fail.leo | 2 ++ dynamic-check/src/dynamic_check.rs | 8 ++++-- dynamic-check/src/errors/frame.rs | 25 +++++++++++++++++-- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/compiler/tests/circuits/mod.rs b/compiler/tests/circuits/mod.rs index f192067104..3935fd8dcc 100644 --- a/compiler/tests/circuits/mod.rs +++ b/compiler/tests/circuits/mod.rs @@ -138,9 +138,9 @@ fn test_member_static_function_undefined() { #[test] fn test_mutate_function_fail() { let bytes = include_bytes!("mut_function_fail.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -178,9 +178,9 @@ fn test_mutate_self_static_function_fail() { #[test] fn test_mutate_static_function_fail() { let bytes = include_bytes!("mut_static_function_fail.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] diff --git a/compiler/tests/circuits/mut_function_fail.leo b/compiler/tests/circuits/mut_function_fail.leo index ed3092c656..3469f97627 100644 --- a/compiler/tests/circuits/mut_function_fail.leo +++ b/compiler/tests/circuits/mut_function_fail.leo @@ -1,4 +1,6 @@ circuit Foo { + a: u8, + function bar() {} } diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index a3fab01667..b0109b3a6b 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -1039,7 +1039,11 @@ impl Frame { // Check the length of the circuit members. if circuit_type.variables.len() != members.len() { - unimplemented!("Number of circuit arguments invalid") + return Err(FrameError::num_variables( + circuit_type.variables.len(), + members.len(), + span, + )); } // Assert members are circuit type member types. @@ -1224,7 +1228,7 @@ impl Frame { // Check the length of arguments if function_type.inputs.len() != inputs.len() { - unimplemented!("Number of function arguments invalid") + return Err(FrameError::num_inputs(function_type.inputs.len(), inputs.len(), span)); } // Assert function inputs are correct types. diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index 0bf5f2e961..07d1e98e0d 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -69,7 +69,7 @@ impl FrameError { /// Attempted to call non-static member using `::`. /// pub fn invalid_member_access(identifier: &Identifier) -> Self { - let message = format!("non-static member `{}` must be accessed using `.` syntax", identifier); + let message = format!("non-static member `{}` must be accessed using `.` syntax.", identifier); Self::new_from_span(message, identifier.span.to_owned()) } @@ -78,11 +78,32 @@ impl FrameError { /// Attempted to call static member using `.`. /// pub fn invalid_static_access(identifier: &Identifier) -> Self { - let message = format!("static member `{}` must be accessed using `::` syntax", identifier); + let message = format!("static member `{}` must be accessed using `::` syntax.", identifier); Self::new_from_span(message, identifier.span.to_owned()) } + /// + /// Attempted to call a function with the incorrect number of inputs. + /// + pub fn num_inputs(expected: usize, actual: usize, span: &Span) -> Self { + let message = format!( + "Function expected {} input variables, found {} inputs.", + expected, actual + ); + + Self::new_from_span(message, span.clone()) + } + + /// + /// Attempted to create a circuit with the incorrect number of member variables. + /// + pub fn num_variables(expected: usize, actual: usize, span: &Span) -> Self { + let message = format!("Circuit expected {} variables, found {} variables.", expected, actual); + + Self::new_from_span(message, span.clone()) + } + /// /// Attempted to call a circuit type that is not defined in the current context. /// From 22d6c98c77213e5d9ef53de0275f8fdcfcf0532c Mon Sep 17 00:00:00 2001 From: collin Date: Sat, 24 Oct 2020 16:50:07 -0700 Subject: [PATCH 059/139] add dynamic check errors for functions --- compiler/tests/boolean/mod.rs | 1 - compiler/tests/circuits/mod.rs | 3 +-- compiler/tests/function/mod.rs | 23 +++++++---------------- compiler/tests/mutability/mod.rs | 10 +++++----- dynamic-check/src/dynamic_check.rs | 11 ++++------- dynamic-check/src/errors/frame.rs | 9 +++++++++ 6 files changed, 26 insertions(+), 31 deletions(-) diff --git a/compiler/tests/boolean/mod.rs b/compiler/tests/boolean/mod.rs index 7d9fcd9d08..6901c2a15b 100644 --- a/compiler/tests/boolean/mod.rs +++ b/compiler/tests/boolean/mod.rs @@ -23,7 +23,6 @@ use crate::{ parse_program_with_input, EdwardsTestCompiler, }; -use leo_compiler::errors::{BooleanError, CompilerError, ExpressionError, FunctionError, StatementError}; pub fn output_true(program: EdwardsTestCompiler) { let expected = include_bytes!("output/registers_true.out"); diff --git a/compiler/tests/circuits/mod.rs b/compiler/tests/circuits/mod.rs index 3935fd8dcc..79cb5bc1c2 100644 --- a/compiler/tests/circuits/mod.rs +++ b/compiler/tests/circuits/mod.rs @@ -14,8 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_compiler_error, expect_dynamic_check_error, parse_program, EdwardsTestCompiler}; -use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError}; +use crate::{assert_satisfied, expect_compiler_error, expect_dynamic_check_error, parse_program}; // Expressions diff --git a/compiler/tests/function/mod.rs b/compiler/tests/function/mod.rs index d5a3c3548b..69e9d1b980 100644 --- a/compiler/tests/function/mod.rs +++ b/compiler/tests/function/mod.rs @@ -17,22 +17,13 @@ use crate::{ assert_satisfied, expect_compiler_error, + expect_dynamic_check_error, get_output, parse_program, parse_program_with_input, - EdwardsTestCompiler, }; use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError}; -fn expect_undefined_identifier(program: EdwardsTestCompiler) { - match expect_compiler_error(program) { - CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( - ExpressionError::Error(_), - ))) => {} - error => panic!("Expected function undefined, got {}", error), - } -} - #[test] fn test_empty() { let bytes = include_bytes!("empty.leo"); @@ -129,9 +120,9 @@ fn test_scope_fail() { #[test] fn test_undefined() { let bytes = include_bytes!("undefined.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_undefined_identifier(program); + expect_dynamic_check_error(error); } #[test] @@ -147,9 +138,9 @@ fn test_value_unchanged() { #[test] fn test_return_array_nested_fail() { let bytes = include_bytes!("return_array_nested_fail.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -163,9 +154,9 @@ fn test_return_array_nested_pass() { #[test] fn test_return_array_tuple_fail() { let bytes = include_bytes!("return_array_tuple_fail.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] diff --git a/compiler/tests/mutability/mod.rs b/compiler/tests/mutability/mod.rs index ea380447bf..c36cd10b14 100644 --- a/compiler/tests/mutability/mod.rs +++ b/compiler/tests/mutability/mod.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program}; +use crate::{assert_satisfied, expect_compiler_error, expect_dynamic_check_error, generate_main_input, parse_program}; use leo_typed::InputValue; #[test] @@ -92,17 +92,17 @@ fn test_circuit_variable_mut() { #[test] fn test_circuit_function_mut() { let bytes = include_bytes!("circuit_function_mut.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] fn test_circuit_static_function_mut() { let bytes = include_bytes!("circuit_static_function_mut.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index b0109b3a6b..4aa6a2654f 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -1143,11 +1143,10 @@ impl Frame { /// Returns a `FunctionType` given a function identifier. /// fn parse_program_function(&mut self, identifier: &Identifier, _span: &Span) -> Result { - Ok(self - .user_defined_types + self.user_defined_types .get_function(&identifier.name) - .unwrap() - .to_owned()) + .map(|function_type| function_type.to_owned()) + .ok_or_else(|| FrameError::undefined_function(identifier)) } /// @@ -1715,9 +1714,7 @@ impl TypeVariablePairs { } // Compare the array element types. - self.push_pairs(left_type_flat, right_type_flat, span); - - Ok(()) + self.push_pairs(left_type_flat, right_type_flat, span) } /// diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index 07d1e98e0d..5bc248a47a 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -121,4 +121,13 @@ impl FrameError { Self::new_from_span(message, identifier.span.to_owned()) } + + /// + /// Attempted to call a function that is not defined in the current context. + /// + pub fn undefined_function(identifier: &Identifier) -> Self { + let message = format!("The function `{}` is not defined.", identifier); + + Self::new_from_span(message, identifier.span.to_owned()) + } } From 6e124e52ff29519fef77d786e2d993ad1187816f Mon Sep 17 00:00:00 2001 From: collin Date: Sat, 24 Oct 2020 17:01:40 -0700 Subject: [PATCH 060/139] add dynamic check errors for statements --- compiler/tests/statements/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/tests/statements/mod.rs b/compiler/tests/statements/mod.rs index 3180c6fa30..cb6efc3552 100644 --- a/compiler/tests/statements/mod.rs +++ b/compiler/tests/statements/mod.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program}; +use crate::{assert_satisfied, expect_dynamic_check_error, generate_main_input, parse_program}; use leo_typed::InputValue; pub mod conditional; @@ -60,7 +60,7 @@ fn test_iteration_basic() { #[test] fn test_num_returns_fail() { let bytes = include_bytes!("num_returns_fail.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } From 17a65fe54a49627f9a1d0b145e7769300065e50b Mon Sep 17 00:00:00 2001 From: collin Date: Sat, 24 Oct 2020 19:27:30 -0700 Subject: [PATCH 061/139] add dynamic check errors for circuits 3 --- compiler/tests/circuits/mod.rs | 12 ++++----- dynamic-check/src/dynamic_check.rs | 29 ++++++++++++++++------ dynamic-check/src/errors/frame.rs | 9 +++++++ static-check/src/types/circuits/circuit.rs | 11 +++++++- typed/src/input/input.rs | 2 +- 5 files changed, 48 insertions(+), 15 deletions(-) diff --git a/compiler/tests/circuits/mod.rs b/compiler/tests/circuits/mod.rs index 79cb5bc1c2..4790c5fff2 100644 --- a/compiler/tests/circuits/mod.rs +++ b/compiler/tests/circuits/mod.rs @@ -161,17 +161,17 @@ fn test_mutate_self_variable_fail() { #[test] fn test_mutate_self_function_fail() { let bytes = include_bytes!("mut_self_function_fail.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] fn test_mutate_self_static_function_fail() { let bytes = include_bytes!("mut_self_static_function_fail.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] @@ -227,9 +227,9 @@ fn test_self_member_invalid() { #[test] fn test_self_member_undefined() { let bytes = include_bytes!("self_member_undefined.leo"); - let program = parse_program(bytes).unwrap(); + let error = parse_program(bytes).err().unwrap(); - let _err = expect_compiler_error(program); + expect_dynamic_check_error(error); } // All diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 4aa6a2654f..d549258f51 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -57,8 +57,6 @@ pub struct DynamicCheck { frames: Vec, } -pub struct VariableEnvironment {} - impl DynamicCheck { /// /// Creates a new `DynamicCheck` from a given program and symbol table. @@ -89,20 +87,27 @@ impl DynamicCheck { /// Collects a vector of `TypeAssertion` predicates from a program. /// fn parse_program(&mut self, program: &Program) -> Result<(), DynamicCheckError> { + // Parse program input keyword as a circuit type. + // let input_type = CircuitType::from_input() + + // Iterate over circuit types. let circuits = program .circuits .iter() .map(|(_identifier, circuit)| circuit) .collect::>(); + // Parse circuit types in program context. self.parse_circuits(circuits)?; + // Iterate over functions. let functions = program .functions .iter() .map(|(_identifier, function)| function) .collect::>(); + // Parse functions in program context. self.parse_functions(functions) } @@ -334,8 +339,6 @@ impl Frame { fn assert_equal(&mut self, left: Type, right: Type, span: &Span) { let type_assertion = TypeAssertion::new_equality(left, right, span); - println!("equality: {:?}", type_assertion); - self.type_assertions.push(type_assertion); } @@ -502,7 +505,17 @@ impl Frame { /// fn parse_assignee(&mut self, assignee: &Assignee, span: &Span) -> Result { // Get the type of the assignee variable. - let mut type_ = self.get_variable(&assignee.identifier.name).unwrap().to_owned(); + let mut type_ = if assignee.identifier.is_self() { + // If the variable is the self keyword, then return the self.circuit_type + let self_type = self.self_type_or_error(span)?; + + Type::Circuit(self_type.identifier) + } else { + // Otherwise, lookup the variable by name in the symbol table. + self.get_variable(&assignee.identifier.name) + .map(|type_| type_.to_owned()) + .ok_or_else(|| FrameError::undefined_variable(&assignee.identifier))? + }; // Iteratively evaluate assignee access types. for access in &assignee.accesses { @@ -697,7 +710,7 @@ impl Frame { /// fn parse_identifier(&self, identifier: &Identifier) -> Result { // Check Self type. - if identifier.is_self_type() { + if identifier.is_self() { // Check for frame circuit self type. let circuit_type = self.self_type_or_error(&identifier.span)?; @@ -1037,6 +1050,8 @@ impl Frame { .ok_or_else(|| FrameError::undefined_circuit(identifier))? }; + println!("circuit_type: {:?}", circuit_type); + // Check the length of the circuit members. if circuit_type.variables.len() != members.len() { return Err(FrameError::num_variables( @@ -1055,7 +1070,7 @@ impl Frame { self.assert_equal(expected_variable.type_.clone(), actual_type, span) } - Ok(Type::Circuit(identifier.to_owned())) + Ok(Type::Circuit(circuit_type.identifier)) } /// diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index 5bc248a47a..0b9c6a7fee 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -130,4 +130,13 @@ impl FrameError { Self::new_from_span(message, identifier.span.to_owned()) } + + /// + /// Attempted to call a variable that is not defined in the current context. + /// + pub fn undefined_variable(identifier: &Identifier) -> Self { + let message = format!("The variable `{}` is not defined.", identifier); + + Self::new_from_span(message, identifier.span.to_owned()) + } } diff --git a/static-check/src/types/circuits/circuit.rs b/static-check/src/types/circuits/circuit.rs index 7968ced1d6..ef9dddd828 100644 --- a/static-check/src/types/circuits/circuit.rs +++ b/static-check/src/types/circuits/circuit.rs @@ -22,7 +22,7 @@ use crate::{ Type, TypeError, }; -use leo_typed::{Circuit, CircuitMember, Identifier}; +use leo_typed::{Circuit, CircuitMember, Identifier, Input}; use serde::{Deserialize, Serialize}; @@ -141,4 +141,13 @@ impl CircuitType { } } } + + // /// + // /// Returns a new `CircuitType` from a given `Input` struct. + // /// + // pub fn from_input(input: &Input) -> Self { + // // Get definitions for each input variable. + // + // // Create a new `CircuitType` for each + // } } diff --git a/typed/src/input/input.rs b/typed/src/input/input.rs index 0ed2bdbf1c..9da128d58d 100644 --- a/typed/src/input/input.rs +++ b/typed/src/input/input.rs @@ -73,7 +73,7 @@ impl Input { Ok(()) } - /// Parse all input variables included in a file and store them in `self`. + /// Parse all state variables included in a file and store them in `self`. pub fn parse_state(&mut self, file: File) -> Result<(), InputParserError> { for entry in file.entries.into_iter() { match entry { From 54bf6ca42d4cb9a1fdcf102a1c88219a4f656757 Mon Sep 17 00:00:00 2001 From: collin Date: Sat, 24 Oct 2020 23:57:38 -0700 Subject: [PATCH 062/139] load program input type into symbol table --- compiler/src/compiler.rs | 2 +- dynamic-check/src/dynamic_check.rs | 17 ++++--- static-check/src/static_check.rs | 16 +++++- static-check/src/symbol_table.rs | 51 ++++++++++++++++++- static-check/src/types/circuits/circuit.rs | 42 +++++++++++---- .../src/types/circuits/circuit_variable.rs | 12 ++++- .../src/types/functions/function_input.rs | 6 +-- typed/src/common/identifier.rs | 7 +++ typed/src/common/span.rs | 11 ++++ 9 files changed, 140 insertions(+), 24 deletions(-) diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 86bbf6aa03..8d07925ce6 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -164,7 +164,7 @@ impl> Compiler { self.program = typed_tree.into_repr(); // Run static check on program. - let symbol_table = StaticCheck::run(&self.program)?; + let symbol_table = StaticCheck::run(&self.program, &self.program_input)?; // Run dynamic check on program. DynamicCheck::run(&self.program, symbol_table)?; diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index d549258f51..82a9cd191c 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -1125,13 +1125,15 @@ impl Frame { /// fn parse_circuit_name(&mut self, type_: Type, _span: &Span) -> Result<&CircuitType, FrameError> { // Check that type is a circuit type. - Ok(match type_ { + match type_ { Type::Circuit(identifier) => { // Lookup circuit identifier. - self.user_defined_types.get_circuit(&identifier.name).unwrap() + self.user_defined_types + .get_circuit(&identifier.name) + .ok_or_else(|| FrameError::undefined_circuit(&identifier)) } type_ => unimplemented!("expected circuit type {:?}", type_), - }) + } } /// @@ -1247,11 +1249,14 @@ impl Frame { // Assert function inputs are correct types. for (expected_input, actual_input) in function_type.inputs.iter().zip(inputs) { - // Parse actual input expression. + // Parse expected input type. + let expected_type = expected_input.type_(); + + // Parse actual input type. let actual_type = self.parse_expression(actual_input)?; // Assert expected input type == actual input type. - self.assert_equal(expected_input.type_().clone(), actual_type, span); + self.assert_equal(expected_type, actual_type, span); } // Return the function output type. @@ -1471,7 +1476,7 @@ impl VariableTable { ) -> Result<(), VariableTableError> { for input in function_inputs { let input_name = input.identifier().name.clone(); - let input_type = input.type_().clone(); + let input_type = input.type_(); // TODO (collinc97) throw an error for duplicate function input names. self.insert(input_name, input_type); diff --git a/static-check/src/static_check.rs b/static-check/src/static_check.rs index fb24d1673a..e00293760d 100644 --- a/static-check/src/static_check.rs +++ b/static-check/src/static_check.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{StaticCheckError, SymbolTable}; -use leo_typed::Program; +use leo_typed::{Input, Program}; /// Performs a static type check over a program. pub struct StaticCheck { @@ -35,9 +35,12 @@ impl StaticCheck { /// /// Returns a new `SymbolTable` from a given program. /// - pub fn run(program: &Program) -> Result { + pub fn run(program: &Program, input: &Input) -> Result { let mut check = Self::new(); + // Load program input types. + check.load_input(input)?; + // Run pass one checks check.pass_one(program)?; @@ -47,6 +50,15 @@ impl StaticCheck { Ok(check.table) } + /// + /// Loads the program input types into the symbol table. + /// + pub fn load_input(&mut self, input: &Input) -> Result<(), StaticCheckError> { + self.table + .load_input(input) + .map_err(|err| StaticCheckError::SymbolTableError(err)) + } + /// /// Checks for duplicate circuit and function names given an unresolved program. /// diff --git a/static-check/src/symbol_table.rs b/static-check/src/symbol_table.rs index 9d36f80447..5cccf4eeb2 100644 --- a/static-check/src/symbol_table.rs +++ b/static-check/src/symbol_table.rs @@ -14,12 +14,18 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{CircuitType, FunctionType, ParameterType, SymbolTableError}; -use leo_typed::{Circuit, Function, Identifier}; +use crate::{CircuitType, CircuitVariableType, FunctionType, ParameterType, SymbolTableError}; +use leo_typed::{Circuit, Function, Identifier, Input}; use leo_imports::ImportParser; use std::collections::HashMap; +pub const INPUT_VARIABLE_NAME: &str = "input"; +pub const RECORD_VARIABLE_NAME: &str = "record"; +pub const REGISTERS_VARIABLE_NAME: &str = "registers"; +pub const STATE_VARIABLE_NAME: &str = "state"; +pub const STATE_LEAF_VARIABLE_NAME: &str = "state_leaf"; + /// A abstract data type that builds symbol tables for functions and circuits /// /// A symbol table has access to all function and circuit names in its @@ -142,6 +148,47 @@ impl SymbolTable { } } + /// + /// Loads function input types into symbol table. + /// + pub fn load_input(&mut self, input: &Input) -> Result<(), SymbolTableError> { + // Get values for each input section. + let registers_values = input.get_registers().values(); + let record_values = input.get_record().values(); + let state_values = input.get_state().values(); + let state_leaf_values = input.get_state_leaf().values(); + + // Create a new `CircuitType` for each input section. + let registers_type = + CircuitType::from_input_section(&self, REGISTERS_VARIABLE_NAME.to_string(), registers_values)?; + let record_type = CircuitType::from_input_section(&self, RECORD_VARIABLE_NAME.to_string(), record_values)?; + let state_type = CircuitType::from_input_section(&self, STATE_VARIABLE_NAME.to_string(), state_values)?; + let state_leaf_type = + CircuitType::from_input_section(&self, STATE_LEAF_VARIABLE_NAME.to_string(), state_leaf_values)?; + + // Create a new `CircuitVariableType` for each type. + let registers_variable = CircuitVariableType::from(®isters_type); + let record_variable = CircuitVariableType::from(&record_type); + let state_variable = CircuitVariableType::from(&state_type); + let state_leaf_variable = CircuitVariableType::from(&state_leaf_type); + + // Create new `CircuitType` for input keyword. + let input_type = CircuitType { + identifier: Identifier::new(INPUT_VARIABLE_NAME.to_string()), + variables: vec![registers_variable, record_variable, state_variable, state_leaf_variable], + functions: Vec::new(), + }; + + // Insert each circuit type into the symbol table. + self.insert_circuit(registers_type.identifier.clone(), registers_type); + self.insert_circuit(record_type.identifier.clone(), record_type); + self.insert_circuit(state_type.identifier.clone(), state_type); + self.insert_circuit(state_leaf_type.identifier.clone(), state_leaf_type); + self.insert_circuit(input_type.identifier.clone(), input_type); + + Ok(()) + } + /// /// Inserts all imported identifiers for a given list of imported programs. /// diff --git a/static-check/src/types/circuits/circuit.rs b/static-check/src/types/circuits/circuit.rs index ef9dddd828..16ba130f6d 100644 --- a/static-check/src/types/circuits/circuit.rs +++ b/static-check/src/types/circuits/circuit.rs @@ -22,9 +22,10 @@ use crate::{ Type, TypeError, }; -use leo_typed::{Circuit, CircuitMember, Identifier, Input}; +use leo_typed::{Circuit, CircuitMember, Identifier, InputValue, Parameter, Span}; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; /// Stores circuit definition details. /// @@ -142,12 +143,35 @@ impl CircuitType { } } - // /// - // /// Returns a new `CircuitType` from a given `Input` struct. - // /// - // pub fn from_input(input: &Input) -> Self { - // // Get definitions for each input variable. - // - // // Create a new `CircuitType` for each - // } + /// + /// Returns a new `CircuitType` from a given `Input` struct. + /// + pub fn from_input_section( + table: &SymbolTable, + name: String, + section: HashMap>, + ) -> Result { + // Create a new `CircuitVariableType` for each section pair. + let mut variables = Vec::new(); + + for (parameter, _option) in section.into_iter() { + let variable = CircuitVariableType { + identifier: parameter.variable, + type_: Type::new(table, parameter.type_, Span::default())?, + attributes: Vec::new(), + }; + + variables.push(variable); + } + + // Create a new `Identifier` for the input section. + let identifier = Identifier::new(name); + + // Return a new `CircuitType` with the given name. + Ok(Self { + identifier, + variables, + functions: Vec::new(), + }) + } } diff --git a/static-check/src/types/circuits/circuit_variable.rs b/static-check/src/types/circuits/circuit_variable.rs index 55b8326b8a..e471f3a752 100644 --- a/static-check/src/types/circuits/circuit_variable.rs +++ b/static-check/src/types/circuits/circuit_variable.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Attribute, Type}; +use crate::{Attribute, CircuitType, Type}; use leo_typed::Identifier; use serde::{Deserialize, Serialize}; @@ -28,3 +28,13 @@ pub struct CircuitVariableType { /// The attributes of the circuit variable pub attributes: Vec, } + +impl From<&CircuitType> for CircuitVariableType { + fn from(type_: &CircuitType) -> Self { + Self { + identifier: type_.identifier.clone(), + type_: Type::Circuit(type_.identifier.clone()), + attributes: Vec::new(), + } + } +} diff --git a/static-check/src/types/functions/function_input.rs b/static-check/src/types/functions/function_input.rs index 6edc20e9ec..f801a04afa 100644 --- a/static-check/src/types/functions/function_input.rs +++ b/static-check/src/types/functions/function_input.rs @@ -39,10 +39,10 @@ impl FunctionInputType { /// /// Return the `Type` of the current function input. /// - pub fn type_(&self) -> &Type { + pub fn type_(&self) -> Type { match self { - FunctionInputType::InputKeyword(_) => unimplemented!("ERROR: input type not implemented"), - FunctionInputType::Variable(variable) => &variable.type_, + FunctionInputType::InputKeyword(identifier) => Type::Circuit(identifier.to_owned()), + FunctionInputType::Variable(variable) => variable.type_.to_owned(), } } diff --git a/typed/src/common/identifier.rs b/typed/src/common/identifier.rs index 6b08d8b58b..638c5229b5 100644 --- a/typed/src/common/identifier.rs +++ b/typed/src/common/identifier.rs @@ -46,6 +46,13 @@ pub struct Identifier { } impl Identifier { + pub fn new(name: String) -> Self { + Self { + name, + span: Span::default(), + } + } + pub fn is_self_type(&self) -> bool { self.name == "Self" } diff --git a/typed/src/common/span.rs b/typed/src/common/span.rs index b5af258eb2..78a805e48c 100644 --- a/typed/src/common/span.rs +++ b/typed/src/common/span.rs @@ -45,3 +45,14 @@ impl<'ast> From> for Span { } } } + +impl Default for Span { + fn default() -> Self { + Self { + text: String::new(), + line: 0, + start: 0, + end: 0, + } + } +} From 9933b8e3367371d9106fc76e181b4352de90b373 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 12:24:24 -0700 Subject: [PATCH 063/139] impl dynamic checks for core packages --- Cargo.lock | 1 + compiler/src/compiler.rs | 5 +- compiler/src/import/store/import.rs | 15 ++-- imports/src/parser/import_parser.rs | 9 +++ static-check/Cargo.toml | 4 + static-check/src/errors/symbol_table.rs | 9 +++ static-check/src/static_check.rs | 30 +++++-- static-check/src/symbol_table.rs | 103 ++++++++++++++++++++---- 8 files changed, 140 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e7998c227c..cacc1e9a1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1415,6 +1415,7 @@ name = "leo-static-check" version = "1.0.3" dependencies = [ "leo-ast", + "leo-core", "leo-imports", "leo-typed", "serde", diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 8d07925ce6..c2d2a90ef9 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -162,15 +162,14 @@ impl> Compiler { let typed_tree = LeoTypedAst::new(&package_name, &ast); self.program = typed_tree.into_repr(); + self.imported_programs = ImportParser::parse(&self.program)?; // Run static check on program. - let symbol_table = StaticCheck::run(&self.program, &self.program_input)?; + let symbol_table = StaticCheck::run(&self.program, &self.program_input, &self.imported_programs)?; // Run dynamic check on program. DynamicCheck::run(&self.program, symbol_table)?; - self.imported_programs = ImportParser::parse(&self.program)?; - tracing::debug!("Program parsing complete\n{:#?}", self.program); Ok(()) diff --git a/compiler/src/import/store/import.rs b/compiler/src/import/store/import.rs index 833e60c98e..d25175d877 100644 --- a/compiler/src/import/store/import.rs +++ b/compiler/src/import/store/import.rs @@ -27,13 +27,10 @@ impl> ConstrainedProgram { import: &Import, imported_programs: &ImportParser, ) -> Result<(), ImportError> { - // Fetch core dependencies - let core_dependency = imported_programs - .core_packages() - .iter() - .find(|package| import.package.eq(package)); + // Fetch core packages + let core_package = imported_programs.get_core_package(&import.package); - if let Some(package) = core_dependency { + if let Some(package) = core_package { self.store_core_package(scope.clone(), package.clone())?; return Ok(()); @@ -42,17 +39,17 @@ impl> ConstrainedProgram { // Fetch dependencies for the current import let imported_symbols = ImportedSymbols::from(import); - for (package, symbol) in imported_symbols.symbols { + for (name, symbol) in imported_symbols.symbols { // Find imported program let program = imported_programs - .get_import(&package) + .get_import(&name) .ok_or(ImportError::unknown_package(import.package.name.clone()))?; // Parse imported program self.store_definitions(program.clone(), imported_programs)?; // Store the imported symbol - self.store_symbol(scope.clone(), package, &symbol, program)?; + self.store_symbol(scope.clone(), name, &symbol, program)?; } Ok(()) diff --git a/imports/src/parser/import_parser.rs b/imports/src/parser/import_parser.rs index 05bd601bc0..c8e3b41eae 100644 --- a/imports/src/parser/import_parser.rs +++ b/imports/src/parser/import_parser.rs @@ -90,6 +90,15 @@ impl ImportParser { self.imports.get(file_name) } + /// + /// Returns a reference to the core package corresponding to the given package. + /// + pub fn get_core_package(&self, package: &Package) -> Option<&Package> { + self.core_packages() + .iter() + .find(|core_package| core_package.eq(&package)) + } + /// /// Returns a reference to the vector of core packages. /// diff --git a/static-check/Cargo.toml b/static-check/Cargo.toml index b1d204b109..c79a458702 100644 --- a/static-check/Cargo.toml +++ b/static-check/Cargo.toml @@ -21,6 +21,10 @@ edition = "2018" path = "../ast" version = "1.0.3" +[dependencies.leo-core] +path = "../core" +version = "1.0.3" + [dependencies.leo-imports] path = "../imports" version = "1.0.3" diff --git a/static-check/src/errors/symbol_table.rs b/static-check/src/errors/symbol_table.rs index 59c722c1a1..36505648a5 100644 --- a/static-check/src/errors/symbol_table.rs +++ b/static-check/src/errors/symbol_table.rs @@ -15,6 +15,7 @@ // along with the Leo library. If not, see . use crate::TypeError; +use leo_core::{CorePackageListError, LeoCoreError}; use leo_typed::{Error as FormattedError, Identifier, Span}; use std::path::PathBuf; @@ -22,9 +23,15 @@ use std::path::PathBuf; /// Errors encountered when tracking variable, function, and circuit names in a program. #[derive(Debug, Error)] pub enum SymbolTableError { + #[error("{}", _0)] + CorePackageListError(#[from] CorePackageListError), + #[error("{}", _0)] Error(#[from] FormattedError), + #[error("{}", _0)] + LeoCoreError(#[from] LeoCoreError), + #[error("{}", _0)] TypeError(#[from] TypeError), } @@ -35,7 +42,9 @@ impl SymbolTableError { /// pub fn set_path(&mut self, path: PathBuf) { match self { + SymbolTableError::CorePackageListError(error) => error.set_path(path), SymbolTableError::Error(error) => error.set_path(path), + SymbolTableError::LeoCoreError(error) => error.set_path(path), SymbolTableError::TypeError(error) => error.set_path(path), } } diff --git a/static-check/src/static_check.rs b/static-check/src/static_check.rs index e00293760d..b9144edb05 100644 --- a/static-check/src/static_check.rs +++ b/static-check/src/static_check.rs @@ -15,6 +15,7 @@ // along with the Leo library. If not, see . use crate::{StaticCheckError, SymbolTable}; +use leo_imports::ImportParser; use leo_typed::{Input, Program}; /// Performs a static type check over a program. @@ -35,14 +36,21 @@ impl StaticCheck { /// /// Returns a new `SymbolTable` from a given program. /// - pub fn run(program: &Program, input: &Input) -> Result { + pub fn run( + program: &Program, + input: &Input, + import_parser: &ImportParser, + ) -> Result { let mut check = Self::new(); // Load program input types. - check.load_input(input)?; + check.insert_input(input)?; + + // // Load the program imports into the symbol table. + // check.insert_imports()?; // Run pass one checks - check.pass_one(program)?; + check.pass_one(program, import_parser)?; // Run pass two checks check.pass_two(program)?; @@ -51,21 +59,29 @@ impl StaticCheck { } /// - /// Loads the program input types into the symbol table. + /// Inserts the program input types into the symbol table. /// - pub fn load_input(&mut self, input: &Input) -> Result<(), StaticCheckError> { + pub fn insert_input(&mut self, input: &Input) -> Result<(), StaticCheckError> { self.table - .load_input(input) + .insert_input(input) .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. /// /// 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 pass_one(&mut self, program: &Program) -> Result<(), StaticCheckError> { + 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)?; diff --git a/static-check/src/symbol_table.rs b/static-check/src/symbol_table.rs index 5cccf4eeb2..985339de95 100644 --- a/static-check/src/symbol_table.rs +++ b/static-check/src/symbol_table.rs @@ -15,9 +15,10 @@ // along with the Leo library. If not, see . use crate::{CircuitType, CircuitVariableType, FunctionType, ParameterType, SymbolTableError}; -use leo_typed::{Circuit, Function, Identifier, Input}; - +use leo_core::CorePackageList; use leo_imports::ImportParser; +use leo_typed::{Circuit, Function, Identifier, Import, Input, Package}; + use std::collections::HashMap; pub const INPUT_VARIABLE_NAME: &str = "input"; @@ -149,9 +150,13 @@ impl SymbolTable { } /// - /// Loads function input types into symbol table. + /// Inserts function input types into symbol table. /// - pub fn load_input(&mut self, input: &Input) -> Result<(), SymbolTableError> { + /// Creates a new `CircuitType` to represent the input values. + /// The 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> { // Get values for each input section. let registers_values = input.get_registers().values(); let record_values = input.get_record().values(); @@ -194,13 +199,77 @@ impl SymbolTable { /// /// No type resolution performed at this step. /// - pub fn insert_imports(&mut self, _imports: ImportParser) {} + // pub fn insert_imports(&mut self, imports: ImportParser) -> Result<(), SymbolTableError> { + // // Iterate over each imported program. + // + // // Store separate symbol table for each program. + // + // // + // } /// - /// Checks for duplicate circuit names given a hashmap of unresolved circuits. + /// Inserts core package name and type information into the symbol table. + /// + pub fn insert_core_package(&mut self, package: &Package) -> Result<(), SymbolTableError> { + // Create list of imported core packages. + let list = CorePackageList::from_package_access(package.access.to_owned())?; + + // Fetch core package symbols from `leo-core`. + let symbol_list = list.to_symbols()?; + + // 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())); + + // Create new circuit type for symbol. + let circuit_type = CircuitType::new(&self, circuit)?; + + // Insert circuit type of symbol. + self.insert_circuit(circuit_type.identifier.clone(), circuit_type); + } + + Ok(()) + } + + /// + /// Checks that all given imported names 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_imports( + &mut self, + imports: &Vec, + 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") + } + } + } + + Ok(()) + } + + /// + /// Checks for duplicate circuit names given a hashmap of circuits. /// /// If a circuit name has no duplicates, then it is inserted into the symbol table. - /// Variables defined later in the unresolved program cannot have the same name. + /// Types defined later in the program cannot have the same name. /// pub fn check_duplicate_circuits( &mut self, @@ -224,10 +293,10 @@ impl SymbolTable { } /// - /// Checks for duplicate function names given a hashmap of unresolved functions. + /// Checks for duplicate function names given a hashmap of functions. /// /// If a 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. + /// Types defined later in the program cannot have the same name. /// pub fn check_duplicate_functions( &mut self, @@ -251,10 +320,10 @@ impl SymbolTable { } /// - /// Checks for unknown types in a circuit given a hashmap of unresolved circuits. + /// Checks for unknown types in a circuit given a hashmap of circuits. /// /// If a circuit definition only contains known types, then it is inserted into the - /// symbol table. Variables defined later in the unresolved program can lookup the definition + /// symbol table. Variables defined later in the program can lookup the definition /// and refer to its expected types /// pub fn check_unknown_types_circuits( @@ -263,10 +332,10 @@ impl SymbolTable { ) -> Result<(), SymbolTableError> { // Iterate over circuit names and definitions. for (_, circuit) in circuits.iter() { - // Get the identifier of the unresolved circuit. + // Get the identifier of the circuit. let identifier = circuit.circuit_name.clone(); - // Resolve unknown types in the unresolved circuit definition. + // Resolve unknown types in the circuit definition. let circuit_type = CircuitType::new(self, circuit.clone())?; // Attempt to insert the circuit definition into the symbol table. @@ -277,10 +346,10 @@ impl SymbolTable { } /// - /// Checks for unknown types in a function given a hashmap of unresolved functions. + /// Checks for unknown types in a function given a hashmap of functions. /// /// If a function definition only contains known types, then it is inserted into the - /// symbol table. Variables defined later in the unresolved program can lookup the definition + /// symbol table. Variables defined later in the program can lookup the definition /// and refer to its expected types /// pub fn check_unknown_types_functions( @@ -289,10 +358,10 @@ impl SymbolTable { ) -> Result<(), SymbolTableError> { // Iterate over function names and definitions. for (_, function) in functions.iter() { - // Get the identifier of the unresolved function. + // Get the identifier of the function. let identifier = function.identifier.clone(); - // Resolve unknown types in the unresolved function definition. + // Resolve unknown types in the function definition. let function_type = FunctionType::new(&self, function.clone())?; // Attempt to insert the function definition into the symbol table. From 9bae1037f74a8a4bc846f2a620adcb1e68249cfa Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 12:55:00 -0700 Subject: [PATCH 064/139] fix core package tests --- compiler/tests/core/mod.rs | 18 +++++++++--------- .../core/packages/unstable/blake2s/mod.rs | 5 +++-- compiler/tests/mod.rs | 9 +++++++++ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/compiler/tests/core/mod.rs b/compiler/tests/core/mod.rs index a520d60ac5..6a7728361e 100644 --- a/compiler/tests/core/mod.rs +++ b/compiler/tests/core/mod.rs @@ -16,38 +16,38 @@ pub mod packages; -use crate::{assert_satisfied, expect_compiler_error, parse_program}; +use crate::{assert_satisfied, expect_static_check_error, parse_program}; #[test] fn test_core_circuit_invalid() { let program_bytes = include_bytes!("core_package_invalid.leo"); - let program = parse_program(program_bytes).unwrap(); + let program = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_static_check_error(program); } #[test] fn test_core_circuit_star_fail() { let program_bytes = include_bytes!("core_circuit_star_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_static_check_error(error); } #[test] fn test_core_package_invalid() { let program_bytes = include_bytes!("core_package_invalid.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_static_check_error(error); } #[test] fn test_core_unstable_package_invalid() { let program_bytes = include_bytes!("core_unstable_package_invalid.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_static_check_error(error); } #[test] diff --git a/compiler/tests/core/packages/unstable/blake2s/mod.rs b/compiler/tests/core/packages/unstable/blake2s/mod.rs index 13de62b45a..3cf5e54993 100644 --- a/compiler/tests/core/packages/unstable/blake2s/mod.rs +++ b/compiler/tests/core/packages/unstable/blake2s/mod.rs @@ -17,6 +17,7 @@ use crate::{ assert_satisfied, expect_compiler_error, + expect_dynamic_check_error, generate_main_input, get_output, parse_program, @@ -33,9 +34,9 @@ use snarkos_models::algorithms::PRF; #[test] fn test_arguments_length_fail() { let program_bytes = include_bytes!("arguments_length_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index ac6d042a87..f601c2cb0b 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -187,6 +187,15 @@ pub(crate) fn expect_dynamic_check_error(error: CompilerError) { assert!(is_dynamic_check) } +pub(crate) fn expect_static_check_error(error: CompilerError) { + let is_static_check = match error { + CompilerError::StaticCheckError(_) => true, + _ => false, + }; + + assert!(is_static_check) +} + // pub(crate) fn expect_synthesis_error(program: EdwardsTestCompiler) { // let mut cs = TestConstraintSystem::::new(); // let _output = program.generate_constraints_helper(&mut cs).unwrap(); From b3c140d5bbae66648e4206fbd3497fed175b1f9f Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 13:14:36 -0700 Subject: [PATCH 065/139] fix array function input bug --- .../tests/core/packages/unstable/blake2s/mod.rs | 5 ++--- compiler/tests/function/array_input.leo | 6 ++++++ compiler/tests/function/mod.rs | 8 ++++++++ dynamic-check/src/dynamic_check.rs | 2 -- static-check/src/types/type_.rs | 15 ++++++++++++--- 5 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 compiler/tests/function/array_input.leo diff --git a/compiler/tests/core/packages/unstable/blake2s/mod.rs b/compiler/tests/core/packages/unstable/blake2s/mod.rs index 3cf5e54993..83ec7d15a1 100644 --- a/compiler/tests/core/packages/unstable/blake2s/mod.rs +++ b/compiler/tests/core/packages/unstable/blake2s/mod.rs @@ -16,7 +16,6 @@ use crate::{ assert_satisfied, - expect_compiler_error, expect_dynamic_check_error, generate_main_input, get_output, @@ -42,9 +41,9 @@ fn test_arguments_length_fail() { #[test] fn test_arguments_type_fail() { let program_bytes = include_bytes!("arguments_type_fail.leo"); - let program = parse_program(program_bytes).unwrap(); + let error = parse_program(program_bytes).err().unwrap(); - expect_compiler_error(program); + expect_dynamic_check_error(error); } #[test] diff --git a/compiler/tests/function/array_input.leo b/compiler/tests/function/array_input.leo new file mode 100644 index 0000000000..a70483cae7 --- /dev/null +++ b/compiler/tests/function/array_input.leo @@ -0,0 +1,6 @@ +function foo(a: [u8; 1]) {} + +function main() { + let a: [u16; 1] = [1; 1]; + foo(a); +} \ No newline at end of file diff --git a/compiler/tests/function/mod.rs b/compiler/tests/function/mod.rs index 69e9d1b980..7b9cfdd750 100644 --- a/compiler/tests/function/mod.rs +++ b/compiler/tests/function/mod.rs @@ -133,6 +133,14 @@ fn test_value_unchanged() { assert_satisfied(program); } +#[test] +fn test_array_input() { + let bytes = include_bytes!("array_input.leo"); + let error = parse_program(bytes).err().unwrap(); + + expect_dynamic_check_error(error) +} + // Test return multidimensional arrays #[test] diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 82a9cd191c..2ebdb0b551 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -1050,8 +1050,6 @@ impl Frame { .ok_or_else(|| FrameError::undefined_circuit(identifier))? }; - println!("circuit_type: {:?}", circuit_type); - // Check the length of the circuit members. if circuit_type.variables.len() != members.len() { return Err(FrameError::num_variables( diff --git a/static-check/src/types/type_.rs b/static-check/src/types/type_.rs index 69c7a346da..11fb31e280 100644 --- a/static-check/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -238,10 +238,19 @@ impl Type { /// Replaces self with the given type if self is equal to the given `TypeVariable`. /// pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { - if let Type::TypeVariable(self_variable) = self { - if self_variable == variable { - *self = type_.to_owned() + match self { + Type::TypeVariable(self_variable) => { + if self_variable == variable { + *self = type_.to_owned() + } } + Type::Array(self_type, _) => { + self_type.substitute(variable, type_); + } + Type::Tuple(types) => types + .iter_mut() + .for_each(|tuple_type| tuple_type.substitute(variable, type_)), + _ => {} } } } From d5bc0d2b7f9cbe3093e721cbd67df010c2546c90 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 13:31:34 -0700 Subject: [PATCH 066/139] make type variables more unique --- dynamic-check/src/dynamic_check.rs | 8 ++++---- static-check/src/types/type_variable.rs | 23 +++++++++++++---------- typed/src/common/identifier.rs | 7 +++++++ 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 2ebdb0b551..cf2b4f6f0b 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -656,7 +656,7 @@ impl Frame { Expression::Address(_, _) => Ok(Type::Address), Expression::Field(_, _) => Ok(Type::Field), Expression::Group(_) => Ok(Type::Group), - Expression::Implicit(name, _) => Ok(Self::parse_implicit(name)), + Expression::Implicit(name, span) => Ok(Self::parse_implicit(Identifier::new_with_span(name, span))), Expression::Integer(integer_type, _, _) => Ok(Type::IntegerType(integer_type.clone())), // Number operations @@ -733,14 +733,14 @@ impl Frame { return Ok(Type::Circuit(circuit_type.identifier.to_owned())); } - Ok(Self::parse_implicit(&identifier.name)) + Ok(Self::parse_implicit(identifier.to_owned())) } /// /// Returns a new type variable from a given identifier /// - fn parse_implicit(name: &String) -> Type { - Type::TypeVariable(TypeVariable::from(name.clone())) + fn parse_implicit(identifier: Identifier) -> Type { + Type::TypeVariable(TypeVariable::from(identifier)) } /// diff --git a/static-check/src/types/type_variable.rs b/static-check/src/types/type_variable.rs index d38cd402c2..5a07795030 100644 --- a/static-check/src/types/type_variable.rs +++ b/static-check/src/types/type_variable.rs @@ -19,25 +19,28 @@ use serde::{Deserialize, Serialize}; use std::fmt; /// An unknown type in a Leo program. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Hash, Serialize, Deserialize)] pub struct TypeVariable { - name: String, + identifier: Identifier, } impl fmt::Display for TypeVariable { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.name) - } -} - -impl From for TypeVariable { - fn from(name: String) -> Self { - Self { name } + write!(f, "{}", self.identifier) } } impl From for TypeVariable { fn from(identifier: Identifier) -> Self { - Self::from(identifier.name) + Self { identifier } } } + +/// Compare the type variable `Identifier` and `Span`. +impl PartialEq for TypeVariable { + fn eq(&self, other: &Self) -> bool { + self.identifier.name.eq(&other.identifier.name) || self.identifier.span.eq(&other.identifier.span) + } +} + +impl Eq for TypeVariable {} diff --git a/typed/src/common/identifier.rs b/typed/src/common/identifier.rs index 638c5229b5..33f0a9f9fd 100644 --- a/typed/src/common/identifier.rs +++ b/typed/src/common/identifier.rs @@ -53,6 +53,13 @@ impl Identifier { } } + pub fn new_with_span(name: &String, span: &Span) -> Self { + Self { + name: name.to_owned(), + span: span.to_owned(), + } + } + pub fn is_self_type(&self) -> bool { self.name == "Self" } From 09d86576ea727af864a61bbba425fba592feea6a Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 15:51:46 -0700 Subject: [PATCH 067/139] add import parsing to first pass of static check --- compiler/src/compiler.rs | 2 +- compiler/src/import/store/import.rs | 7 +- compiler/src/import/store/imported_symbols.rs | 110 ++++----- compiler/src/import/store/mod.rs | 2 +- dynamic-check/tests/mod.rs | 2 +- imports/src/parser/import_parser.rs | 25 +- imports/src/parser/parse_symbol.rs | 4 +- static-check/src/errors/symbol_table.rs | 40 +++- static-check/src/imports/imported_symbols.rs | 55 +++++ static-check/src/imports/mod.rs | 18 ++ static-check/src/lib.rs | 3 + static-check/src/static_check.rs | 57 +++-- static-check/src/symbol_table.rs | 222 ++++++++++++++---- static-check/tests/mod.rs | 2 +- typed/src/annotation.rs | 4 +- typed/src/imports/import.rs | 24 +- typed/src/program.rs | 6 +- 17 files changed, 407 insertions(+), 176 deletions(-) create mode 100644 static-check/src/imports/imported_symbols.rs create mode 100644 static-check/src/imports/mod.rs diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index c2d2a90ef9..2cc1ca660b 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -165,7 +165,7 @@ impl> Compiler { 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)?; diff --git a/compiler/src/import/store/import.rs b/compiler/src/import/store/import.rs index d25175d877..a332e54cd7 100644 --- a/compiler/src/import/store/import.rs +++ b/compiler/src/import/store/import.rs @@ -14,9 +14,10 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -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> ConstrainedProgram { pub(crate) fn store_import( &mut self, scope: String, - import: &Import, + import: &ImportStatement, imported_programs: &ImportParser, ) -> Result<(), ImportError> { // Fetch core packages diff --git a/compiler/src/import/store/imported_symbols.rs b/compiler/src/import/store/imported_symbols.rs index 80545e01f4..c9196c4310 100644 --- a/compiler/src/import/store/imported_symbols.rs +++ b/compiler/src/import/store/imported_symbols.rs @@ -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 . - -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 . +// +// 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)), +// } +// } +// } diff --git a/compiler/src/import/store/mod.rs b/compiler/src/import/store/mod.rs index 7633655956..fee7b3a914 100644 --- a/compiler/src/import/store/mod.rs +++ b/compiler/src/import/store/mod.rs @@ -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::*; diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index ffac91f162..63441b4496 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -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(); diff --git a/imports/src/parser/import_parser.rs b/imports/src/parser/import_parser.rs index c8e3b41eae..66322776dc 100644 --- a/imports/src/parser/import_parser.rs +++ b/imports/src/parser/import_parser.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . 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) } diff --git a/imports/src/parser/parse_symbol.rs b/imports/src/parser/parse_symbol.rs index c5638d00ef..811cf7b087 100644 --- a/imports/src/parser/parse_symbol.rs +++ b/imports/src/parser/parse_symbol.rs @@ -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(()) } diff --git a/static-check/src/errors/symbol_table.rs b/static-check/src/errors/symbol_table.rs index 36505648a5..bae3ed451c 100644 --- a/static-check/src/errors/symbol_table.rs +++ b/static-check/src/errors/symbol_table.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -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()) } } diff --git a/static-check/src/imports/imported_symbols.rs b/static-check/src/imports/imported_symbols.rs new file mode 100644 index 0000000000..8ee3c747c3 --- /dev/null +++ b/static-check/src/imports/imported_symbols.rs @@ -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 . + +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)), + } + } +} diff --git a/static-check/src/imports/mod.rs b/static-check/src/imports/mod.rs new file mode 100644 index 0000000000..000a0a4885 --- /dev/null +++ b/static-check/src/imports/mod.rs @@ -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 . + +pub mod imported_symbols; +pub use self::imported_symbols::*; diff --git a/static-check/src/lib.rs b/static-check/src/lib.rs index b985aab375..22815db239 100644 --- a/static-check/src/lib.rs +++ b/static-check/src/lib.rs @@ -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::*; diff --git a/static-check/src/static_check.rs b/static-check/src/static_check.rs index b9144edb05..4775c94900 100644 --- a/static-check/src/static_check.rs +++ b/static-check/src/static_check.rs @@ -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 { + 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 { 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)) } /// diff --git a/static-check/src/symbol_table.rs b/static-check/src/symbol_table.rs index 985339de95..75c87da921 100644 --- a/static-check/src/symbol_table.rs +++ b/static-check/src/symbol_table.rs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -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 { + 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, + imports: &Vec, 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(()) diff --git a/static-check/tests/mod.rs b/static-check/tests/mod.rs index b748415e6b..155b8665ae 100644 --- a/static-check/tests/mod.rs +++ b/static-check/tests/mod.rs @@ -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(); } /// diff --git a/typed/src/annotation.rs b/typed/src/annotation.rs index 6ffa0fad8c..67439869b2 100644 --- a/typed/src/annotation.rs +++ b/typed/src/annotation.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -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, + _imports: &mut Vec, _circuits: &mut HashMap, _functions: &mut HashMap, tests: &mut HashMap, diff --git a/typed/src/imports/import.rs b/typed/src/imports/import.rs index aeac7f0d3b..3c47d204ab 100644 --- a/typed/src/imports/import.rs +++ b/typed/src/imports/import.rs @@ -14,42 +14,50 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -//! 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> 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> 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) } diff --git a/typed/src/program.rs b/typed/src/program.rs index 90cfb41fc4..6dd3339ea6 100644 --- a/typed/src/program.rs +++ b/typed/src/program.rs @@ -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, - pub imports: Vec, + pub imports: Vec, pub circuits: HashMap, pub functions: HashMap, pub tests: HashMap, @@ -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)); } From 020773fb2a180f3eb2a09f8079fe17fb5568cb97 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 16:05:02 -0700 Subject: [PATCH 068/139] impl dynamic checks for imports. all tests pass --- compiler/src/import/store/imported_symbols.rs | 55 ------------------- compiler/src/import/store/mod.rs | 2 - dynamic-check/src/dynamic_check.rs | 2 - static-check/src/static_check.rs | 10 +--- static-check/src/symbol_table.rs | 34 +++++++----- 5 files changed, 24 insertions(+), 79 deletions(-) delete mode 100644 compiler/src/import/store/imported_symbols.rs diff --git a/compiler/src/import/store/imported_symbols.rs b/compiler/src/import/store/imported_symbols.rs deleted file mode 100644 index c9196c4310..0000000000 --- a/compiler/src/import/store/imported_symbols.rs +++ /dev/null @@ -1,55 +0,0 @@ -// // 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 . -// -// 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)), -// } -// } -// } diff --git a/compiler/src/import/store/mod.rs b/compiler/src/import/store/mod.rs index fee7b3a914..6b881f6016 100644 --- a/compiler/src/import/store/mod.rs +++ b/compiler/src/import/store/mod.rs @@ -21,7 +21,5 @@ pub use self::core_package::*; pub mod import; pub use self::import::*; -// pub mod imported_symbols; - pub mod symbol; pub use self::symbol::*; diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index cf2b4f6f0b..8790d86534 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -1293,8 +1293,6 @@ impl Frame { continue; } - println!("assertion: {:?}", type_assertion); - // Collect `TypeVariablePairs` from the `TypeAssertion`. let pairs = type_assertion.pairs()?; diff --git a/static-check/src/static_check.rs b/static-check/src/static_check.rs index 4775c94900..ca7162a5a8 100644 --- a/static-check/src/static_check.rs +++ b/static-check/src/static_check.rs @@ -104,12 +104,8 @@ impl StaticCheck { /// refer to its expected types. /// pub fn pass_two(&mut self, program: &Program) -> Result<(), StaticCheckError> { - // Check unresolved program circuit definitions. - self.table.check_unknown_types_circuits(&program.circuits)?; - - // Check unresolved program function definitions. - self.table.check_unknown_types_functions(&program.functions)?; - - Ok(()) + self.table + .check_unknown_types_program(program) + .map_err(|err| StaticCheckError::SymbolTableError(err)) } } diff --git a/static-check/src/symbol_table.rs b/static-check/src/symbol_table.rs index 75c87da921..9d089b9ed0 100644 --- a/static-check/src/symbol_table.rs +++ b/static-check/src/symbol_table.rs @@ -69,7 +69,6 @@ impl SymbolTable { /// variable type is returned. /// pub fn insert_name(&mut self, name: String, variable_type: ParameterType) -> Option { - println!("name: {}", name); self.names.insert(name, variable_type) } @@ -296,9 +295,12 @@ impl SymbolTable { .get_import(&name) .ok_or_else(|| SymbolTableError::unknown_package(&name, &symbol.span))?; - // Check the imported program. + // Check the imported program for duplicate types. self.check_duplicate_program(program, import_parser)?; + // Check the imported program for undefined types. + self.check_unknown_types_program(program)?; + // Push the imported file's name to checked import files. checked.push(name); @@ -354,17 +356,6 @@ impl SymbolTable { 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) } @@ -449,6 +440,23 @@ impl SymbolTable { Ok(()) } + /// + /// Checks for unknown types in circuit and function definitions given an unresolved program. + /// + /// If a circuit or function definition only contains known types, then it is inserted into the + /// symbol table. Variables defined later in the unresolved program can lookup the definition and + /// refer to its expected types. + /// + pub fn check_unknown_types_program(&mut self, program: &Program) -> Result<(), SymbolTableError> { + // Check unresolved program circuit definitions. + self.check_unknown_types_circuits(&program.circuits)?; + + // Check unresolved program function definitions. + self.check_unknown_types_functions(&program.functions)?; + + Ok(()) + } + /// /// Checks for unknown types in a circuit given a hashmap of circuits. /// From b6d0f9daca887bf2cdbeba2cb898af1a822bcb20 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 16:46:11 -0700 Subject: [PATCH 069/139] fix static and dynamic check test runners --- dynamic-check/tests/mod.rs | 11 ++++++++-- .../src/types/functions/function_input.rs | 16 +------------- static-check/tests/mod.rs | 21 +++++++++++++++---- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 63441b4496..96eac2b74e 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -17,8 +17,9 @@ use leo_ast::LeoAst; use leo_dynamic_check::DynamicCheck; +use leo_imports::ImportParser; use leo_static_check::StaticCheck; -use leo_typed::LeoTypedAst; +use leo_typed::{Input, LeoTypedAst}; use std::path::PathBuf; const TEST_PROGRAM_PATH: &str = ""; @@ -44,8 +45,14 @@ impl TestDynamicCheck { let typed = LeoTypedAst::new(TEST_PROGRAM_NAME, &ast); let program = typed.into_repr(); + // Create empty import parser. + let import_parser = ImportParser::new(); + + // Create empty input. + let input = Input::new(); + // Create static check. - let symbol_table = StaticCheck::run_with_input(&program).unwrap(); + let symbol_table = StaticCheck::run_with_input(&program, &import_parser, &input).unwrap(); // Create dynamic check let dynamic_check = DynamicCheck::new(&program, symbol_table).unwrap(); diff --git a/static-check/src/types/functions/function_input.rs b/static-check/src/types/functions/function_input.rs index f801a04afa..4062abe8ef 100644 --- a/static-check/src/types/functions/function_input.rs +++ b/static-check/src/types/functions/function_input.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{FunctionInputVariableType, ParameterType, SymbolTable, Type, TypeError}; +use crate::{FunctionInputVariableType, SymbolTable, Type, TypeError}; use leo_typed::{FunctionInput, Identifier}; use serde::{Deserialize, Serialize}; @@ -87,18 +87,4 @@ impl FunctionInputType { } }) } - - /// - /// Insert the current function input type into the given symbol table. - /// - /// If the symbol table did not have this name present, `None` is returned. - /// - pub fn insert(&self, table: &mut SymbolTable) -> Option { - match self { - FunctionInputType::Variable(variable) => variable.insert(table), - FunctionInputType::InputKeyword(_identifier) => { - unimplemented!("uncomment when support for input types is added") - } - } - } } diff --git a/static-check/tests/mod.rs b/static-check/tests/mod.rs index 155b8665ae..631b9ca6a0 100644 --- a/static-check/tests/mod.rs +++ b/static-check/tests/mod.rs @@ -18,8 +18,9 @@ pub mod symbol_table; use leo_ast::LeoAst; use leo_static_check::{StaticCheck, StaticCheckError, SymbolTableError}; -use leo_typed::LeoTypedAst; +use leo_typed::{Input, LeoTypedAst}; +use leo_imports::ImportParser; use std::path::PathBuf; const TEST_PROGRAM_PATH: &str = ""; @@ -58,8 +59,14 @@ impl TestStaticCheck { // Get program. let program = self.typed.into_repr(); + // Create empty import parser. + let import_parser = ImportParser::new(); + + // Create empty input. + let input = Input::new(); + // Create new symbol table. - let _symbol_table = StaticCheck::run_with_input(&program).unwrap(); + let _symbol_table = StaticCheck::run_with_input(&program, &import_parser, &input).unwrap(); } /// @@ -74,8 +81,11 @@ impl TestStaticCheck { // Create new symbol table. let static_check = &mut StaticCheck::new(); + // Create empty import parser. + let import_parser = ImportParser::new(); + // Run pass one and expect an error. - let error = static_check.pass_one(&program).unwrap_err(); + let error = static_check.pass_one(&program, &import_parser).unwrap_err(); match error { StaticCheckError::SymbolTableError(SymbolTableError::Error(_)) => {} // Ok @@ -95,8 +105,11 @@ impl TestStaticCheck { // Create a new symbol table. let static_check = &mut StaticCheck::new(); + // Create empty import parser. + let import_parser = ImportParser::new(); + // Run the pass one and expect no errors. - static_check.pass_one(&program).unwrap(); + static_check.pass_one(&program, &import_parser).unwrap(); // Run the pass two and expect and error. let error = static_check.pass_two(&program).unwrap_err(); From c87ee5e63296c9c7522a65ff8682e7d6537e022e Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 17:46:42 -0700 Subject: [PATCH 070/139] fix serialization test --- typed/tests/serialization/expected_typed_ast.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typed/tests/serialization/expected_typed_ast.json b/typed/tests/serialization/expected_typed_ast.json index 59417f2fe3..471f2a3cc5 100644 --- a/typed/tests/serialization/expected_typed_ast.json +++ b/typed/tests/serialization/expected_typed_ast.json @@ -7,7 +7,7 @@ "{\"name\":\"main\",\"span\":\"{\\\"text\\\":\\\" function main() {\\\",\\\"line\\\":1,\\\"start\\\":10,\\\"end\\\":14}\"}": { "identifier": "{\"name\":\"main\",\"span\":\"{\\\"text\\\":\\\" function main() {\\\",\\\"line\\\":1,\\\"start\\\":10,\\\"end\\\":14}\"}", "input": [], - "returns": null, + "output": null, "statements": [ { "Return": [ From 9024fb0968b2fab31514fc01f919fcbe9d6a83a8 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 17:52:32 -0700 Subject: [PATCH 071/139] remove unused code --- .../src/statement/definition/definition.rs | 68 +---- dynamic-check/src/ast/ast.rs | 116 --------- dynamic-check/src/ast/circuits/circuit.rs | 84 ------- dynamic-check/src/ast/circuits/mod.rs | 18 -- dynamic-check/src/ast/console/mod.rs | 15 -- .../src/ast/expressions/arithmetic/add.rs | 40 --- .../src/ast/expressions/arithmetic/div.rs | 40 --- .../src/ast/expressions/arithmetic/mod.rs | 33 --- .../src/ast/expressions/arithmetic/mul.rs | 40 --- .../src/ast/expressions/arithmetic/negate.rs | 38 --- .../src/ast/expressions/arithmetic/pow.rs | 40 --- .../src/ast/expressions/arithmetic/sub.rs | 40 --- .../src/ast/expressions/array/array.rs | 78 ------ .../src/ast/expressions/array/array_access.rs | 48 ---- .../src/ast/expressions/array/mod.rs | 27 -- .../expressions/array/range_or_expression.rs | 64 ----- .../expressions/array/spread_or_expression.rs | 61 ----- .../src/ast/expressions/binary/binary.rs | 38 --- .../src/ast/expressions/binary/mod.rs | 18 -- .../src/ast/expressions/circuit/circuit.rs | 79 ------ .../ast/expressions/circuit/circuit_access.rs | 79 ------ .../circuit/circuit_static_access.rs | 66 ----- .../circuit/circuit_variable_definition.rs | 47 ---- .../src/ast/expressions/circuit/mod.rs | 27 -- .../expressions/conditional/conditional.rs | 50 ---- .../src/ast/expressions/conditional/mod.rs | 18 -- .../src/ast/expressions/expression.rs | 219 ---------------- .../src/ast/expressions/expression_value.rs | 133 ---------- .../ast/expressions/function/core_circuit.rs | 32 --- .../ast/expressions/function/function_call.rs | 71 ------ .../src/ast/expressions/function/mod.rs | 21 -- .../ast/expressions/identifier/identifier.rs | 36 --- .../src/ast/expressions/identifier/mod.rs | 18 -- .../src/ast/expressions/logical/and.rs | 41 --- .../src/ast/expressions/logical/mod.rs | 24 -- .../src/ast/expressions/logical/not.rs | 35 --- .../src/ast/expressions/logical/or.rs | 41 --- dynamic-check/src/ast/expressions/mod.rs | 54 ---- .../src/ast/expressions/relational/eq.rs | 42 ---- .../src/ast/expressions/relational/ge.rs | 47 ---- .../src/ast/expressions/relational/gt.rs | 47 ---- .../src/ast/expressions/relational/le.rs | 47 ---- .../src/ast/expressions/relational/lt.rs | 47 ---- .../src/ast/expressions/relational/mod.rs | 30 --- .../src/ast/expressions/tuple/mod.rs | 21 -- .../src/ast/expressions/tuple/tuple.rs | 69 ----- .../src/ast/expressions/tuple/tuple_access.rs | 56 ----- .../src/ast/expressions/values/address.rs | 31 --- .../src/ast/expressions/values/boolean.rs | 31 --- .../src/ast/expressions/values/field.rs | 31 --- .../src/ast/expressions/values/group.rs | 31 --- .../src/ast/expressions/values/implicit.rs | 44 ---- .../src/ast/expressions/values/integer.rs | 31 --- .../src/ast/expressions/values/mod.rs | 33 --- dynamic-check/src/ast/functions/function.rs | 104 -------- dynamic-check/src/ast/functions/mod.rs | 21 -- .../src/ast/functions/test_function.rs | 47 ---- dynamic-check/src/ast/imports/import.rs | 39 --- dynamic-check/src/ast/imports/mod.rs | 18 -- dynamic-check/src/ast/mod.rs | 39 --- dynamic-check/src/ast/programs/mod.rs | 18 -- dynamic-check/src/ast/programs/program.rs | 95 ------- .../src/ast/statements/assign/assign.rs | 97 ------- .../src/ast/statements/assign/mod.rs | 18 -- .../ast/statements/conditional/conditional.rs | 128 ---------- .../src/ast/statements/conditional/mod.rs | 18 -- .../ast/statements/definition/definition.rs | 238 ------------------ .../src/ast/statements/definition/mod.rs | 18 -- .../src/ast/statements/iteration/iteration.rs | 75 ------ .../src/ast/statements/iteration/mod.rs | 18 -- dynamic-check/src/ast/statements/mod.rs | 33 --- .../src/ast/statements/return_/mod.rs | 18 -- .../src/ast/statements/return_/return_.rs | 40 --- dynamic-check/src/ast/statements/statement.rs | 96 ------- dynamic-check/src/lib.rs | 3 - 75 files changed, 1 insertion(+), 3815 deletions(-) delete mode 100644 dynamic-check/src/ast/ast.rs delete mode 100644 dynamic-check/src/ast/circuits/circuit.rs delete mode 100644 dynamic-check/src/ast/circuits/mod.rs delete mode 100644 dynamic-check/src/ast/console/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/arithmetic/add.rs delete mode 100644 dynamic-check/src/ast/expressions/arithmetic/div.rs delete mode 100644 dynamic-check/src/ast/expressions/arithmetic/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/arithmetic/mul.rs delete mode 100644 dynamic-check/src/ast/expressions/arithmetic/negate.rs delete mode 100644 dynamic-check/src/ast/expressions/arithmetic/pow.rs delete mode 100644 dynamic-check/src/ast/expressions/arithmetic/sub.rs delete mode 100644 dynamic-check/src/ast/expressions/array/array.rs delete mode 100644 dynamic-check/src/ast/expressions/array/array_access.rs delete mode 100644 dynamic-check/src/ast/expressions/array/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/array/range_or_expression.rs delete mode 100644 dynamic-check/src/ast/expressions/array/spread_or_expression.rs delete mode 100644 dynamic-check/src/ast/expressions/binary/binary.rs delete mode 100644 dynamic-check/src/ast/expressions/binary/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/circuit/circuit.rs delete mode 100644 dynamic-check/src/ast/expressions/circuit/circuit_access.rs delete mode 100644 dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs delete mode 100644 dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs delete mode 100644 dynamic-check/src/ast/expressions/circuit/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/conditional/conditional.rs delete mode 100644 dynamic-check/src/ast/expressions/conditional/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/expression.rs delete mode 100644 dynamic-check/src/ast/expressions/expression_value.rs delete mode 100644 dynamic-check/src/ast/expressions/function/core_circuit.rs delete mode 100644 dynamic-check/src/ast/expressions/function/function_call.rs delete mode 100644 dynamic-check/src/ast/expressions/function/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/identifier/identifier.rs delete mode 100644 dynamic-check/src/ast/expressions/identifier/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/logical/and.rs delete mode 100644 dynamic-check/src/ast/expressions/logical/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/logical/not.rs delete mode 100644 dynamic-check/src/ast/expressions/logical/or.rs delete mode 100644 dynamic-check/src/ast/expressions/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/relational/eq.rs delete mode 100644 dynamic-check/src/ast/expressions/relational/ge.rs delete mode 100644 dynamic-check/src/ast/expressions/relational/gt.rs delete mode 100644 dynamic-check/src/ast/expressions/relational/le.rs delete mode 100644 dynamic-check/src/ast/expressions/relational/lt.rs delete mode 100644 dynamic-check/src/ast/expressions/relational/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/tuple/mod.rs delete mode 100644 dynamic-check/src/ast/expressions/tuple/tuple.rs delete mode 100644 dynamic-check/src/ast/expressions/tuple/tuple_access.rs delete mode 100644 dynamic-check/src/ast/expressions/values/address.rs delete mode 100644 dynamic-check/src/ast/expressions/values/boolean.rs delete mode 100644 dynamic-check/src/ast/expressions/values/field.rs delete mode 100644 dynamic-check/src/ast/expressions/values/group.rs delete mode 100644 dynamic-check/src/ast/expressions/values/implicit.rs delete mode 100644 dynamic-check/src/ast/expressions/values/integer.rs delete mode 100644 dynamic-check/src/ast/expressions/values/mod.rs delete mode 100644 dynamic-check/src/ast/functions/function.rs delete mode 100644 dynamic-check/src/ast/functions/mod.rs delete mode 100644 dynamic-check/src/ast/functions/test_function.rs delete mode 100644 dynamic-check/src/ast/imports/import.rs delete mode 100644 dynamic-check/src/ast/imports/mod.rs delete mode 100644 dynamic-check/src/ast/mod.rs delete mode 100644 dynamic-check/src/ast/programs/mod.rs delete mode 100644 dynamic-check/src/ast/programs/program.rs delete mode 100644 dynamic-check/src/ast/statements/assign/assign.rs delete mode 100644 dynamic-check/src/ast/statements/assign/mod.rs delete mode 100644 dynamic-check/src/ast/statements/conditional/conditional.rs delete mode 100644 dynamic-check/src/ast/statements/conditional/mod.rs delete mode 100644 dynamic-check/src/ast/statements/definition/definition.rs delete mode 100644 dynamic-check/src/ast/statements/definition/mod.rs delete mode 100644 dynamic-check/src/ast/statements/iteration/iteration.rs delete mode 100644 dynamic-check/src/ast/statements/iteration/mod.rs delete mode 100644 dynamic-check/src/ast/statements/mod.rs delete mode 100644 dynamic-check/src/ast/statements/return_/mod.rs delete mode 100644 dynamic-check/src/ast/statements/return_/return_.rs delete mode 100644 dynamic-check/src/ast/statements/statement.rs diff --git a/compiler/src/statement/definition/definition.rs b/compiler/src/statement/definition/definition.rs index 1a54214a35..558568614c 100644 --- a/compiler/src/statement/definition/definition.rs +++ b/compiler/src/statement/definition/definition.rs @@ -17,7 +17,7 @@ //! Enforces a definition statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_typed::{Declare, Expression, Span, Type, VariableName, Variables}; +use leo_typed::{Declare, Expression, Span, VariableName, Variables}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -45,72 +45,6 @@ impl> ConstrainedProgram { Ok(()) } - fn enforce_expressions>( - &mut self, - cs: &mut CS, - file_scope: String, - function_scope: String, - type_: Option, - expressions: Vec, - span: Span, - ) -> Result>, StatementError> { - let types = match type_ { - Some(Type::Tuple(types)) => types, - Some(type_) => return Err(StatementError::tuple_type(type_.to_string(), span.clone())), - None => vec![], - }; - - let implicit_types = types.is_empty(); - let mut expected_types = vec![]; - - for i in 0..expressions.len() { - let expected_type = if implicit_types { None } else { Some(types[i].clone()) }; - - expected_types.push(expected_type); - } - - let mut values = vec![]; - - for (expression, expected_type) in expressions.into_iter().zip(expected_types.into_iter()) { - let value = self.enforce_expression( - cs, - file_scope.clone(), - function_scope.clone(), - expected_type, - expression, - )?; - - values.push(value); - } - - Ok(values) - } - - fn enforce_tuple_definition>( - &mut self, - cs: &mut CS, - file_scope: String, - function_scope: String, - is_constant: bool, - variables: Variables, - expressions: Vec, - span: Span, - ) -> Result<(), StatementError> { - let values = self.enforce_expressions( - cs, - file_scope, - function_scope.clone(), - variables.type_.clone(), - expressions, - span.clone(), - )?; - - let tuple = ConstrainedValue::Tuple(values); - let variable = variables.names[0].clone(); - - self.enforce_single_definition(cs, function_scope, is_constant, variable, tuple, span) - } - fn enforce_multiple_definition>( &mut self, cs: &mut CS, diff --git a/dynamic-check/src/ast/ast.rs b/dynamic-check/src/ast/ast.rs deleted file mode 100644 index 704a6762c3..0000000000 --- a/dynamic-check/src/ast/ast.rs +++ /dev/null @@ -1,116 +0,0 @@ -// 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 . - -use crate::{Program, ResolverError}; -use leo_imports::ImportParser; -use leo_static_check::SymbolTable; -use leo_typed::LeoTypedAst; - -use serde_json; -use std::path::PathBuf; - -/// A program abstract syntax tree without implicit types. -#[derive(Debug, Eq, PartialEq)] -pub struct LeoResolvedAst { - pub resolved_ast: Program, -} - -impl LeoResolvedAst { - /// - /// Creates a new `LeoResolvedAst` resolved syntax tree from a given `LeoTypedAst` - /// typed syntax tree and main file path. - /// - pub fn new(ast: LeoTypedAst, _path: PathBuf) -> Result<(), ResolverError> { - // Get program typed syntax tree representation. - let program = ast.into_repr(); - - // Get imported program typed syntax tree representations. - let _imported_programs = ImportParser::parse(&program)?; - - // TODO (collinc97): Get input and state file typed syntax tree representations. - // - // // Create a new symbol table to track of program variables, circuits, and functions by name. - // let mut symbol_table = SymbolTable::new(None); - // - // // Pass 1: Check for circuit and function name collisions. - // symbol_table.pass_one(&program).map_err(|mut e| { - // // Set the filepath for the error stacktrace. - // e.set_path(path.clone()); - // - // e - // })?; - // - // // Pass 2: Check circuit and function definitions for unknown types. - // symbol_table.pass_two(&program).map_err(|mut e| { - // // Set the filepath for the error stacktrace. - // e.set_path(path.clone()); - // - // e - // })?; - // - // // Pass 3: Check statements for type errors. - // let resolved_ast = Program::resolve(&mut symbol_table, program).map_err(|mut e| { - // // Set the filepath for the error stacktrace. - // e.set_path(path); - // - // e - // })?; - - // Ok(Self { resolved_ast }) - - Ok(()) - } - - /// - /// Returns a reference to the inner resolved syntax tree representation. - /// - pub fn into_repr(self) -> Program { - self.resolved_ast - } - - /// - /// Serializes the resolved syntax tree into a JSON string. - /// - pub fn to_json_string(&self) -> Result { - Ok(serde_json::to_string_pretty(&self.resolved_ast)?) - } - - /// - /// Deserializes the JSON string into a resolved syntax tree. - /// - pub fn from_json_string(json: &str) -> Result { - let resolved_ast: Program = serde_json::from_str(json)?; - Ok(Self { resolved_ast }) - } -} - -/// A node in the `LeoResolvedAST`. -/// -/// This node and all of its children should not contain any implicit types. -pub trait ResolvedNode { - /// The expected error type if the type resolution fails. - type Error; - - /// The `leo-typed` AST node that is being type checked. - type UnresolvedNode; - - /// - /// Returns a resolved AST representation given an unresolved AST representation and symbol table. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result - where - Self: std::marker::Sized; -} diff --git a/dynamic-check/src/ast/circuits/circuit.rs b/dynamic-check/src/ast/circuits/circuit.rs deleted file mode 100644 index 96d0574694..0000000000 --- a/dynamic-check/src/ast/circuits/circuit.rs +++ /dev/null @@ -1,84 +0,0 @@ -// 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 . - -use crate::{CircuitError, Function, ResolvedNode}; -use leo_static_check::{Attribute, CircuitType, ParameterType, SymbolTable, Type}; -use leo_typed::{circuit::Circuit as UnresolvedCircuit, identifier::Identifier, CircuitMember}; - -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; - -/// A circuit in the resolved syntax tree. -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct Circuit { - /// The user-defined type of this circuit. - pub type_: CircuitType, - - /// The circuit member functions. - pub functions: HashMap, -} - -impl ResolvedNode for Circuit { - type Error = CircuitError; - type UnresolvedNode = UnresolvedCircuit; - - /// - /// Return a new `Circuit` from a given `UnresolvedCircuit`. - /// - /// Performs a lookup in the given symbol table if the circuit contains user-defined types. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let identifier = unresolved.circuit_name; - let type_ = table.get_circuit(&identifier.name).unwrap().clone(); - - // Create circuit context - let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); - - // Create self variable - let self_key = "self".to_owned(); - let self_variable = ParameterType { - identifier: identifier.clone(), - type_: Type::Circuit(identifier.clone()), - attributes: vec![Attribute::Mutable], - }; - child_table.insert_name(self_key, self_variable); - - // Insert circuit functions into symbol table - for function in type_.functions.iter() { - let function_key = function.function.identifier.clone(); - let function_type = function.function.clone(); - - child_table.insert_function(function_key, function_type); - } - - // Resolve all circuit functions - let mut functions = HashMap::new(); - - for member in unresolved.members { - match member { - CircuitMember::CircuitVariable(_, _, _) => {} - CircuitMember::CircuitFunction(_, function) => { - let identifier = function.identifier.clone(); - let function_resolved = Function::resolve(&mut child_table.clone(), function)?; - - functions.insert(identifier, function_resolved); - } - } - } - - Ok(Circuit { type_, functions }) - } -} diff --git a/dynamic-check/src/ast/circuits/mod.rs b/dynamic-check/src/ast/circuits/mod.rs deleted file mode 100644 index 5aa364bd84..0000000000 --- a/dynamic-check/src/ast/circuits/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod circuit; -pub use self::circuit::*; diff --git a/dynamic-check/src/ast/console/mod.rs b/dynamic-check/src/ast/console/mod.rs deleted file mode 100644 index 600f61b496..0000000000 --- a/dynamic-check/src/ast/console/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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 . diff --git a/dynamic-check/src/ast/expressions/arithmetic/add.rs b/dynamic-check/src/ast/expressions/arithmetic/add.rs deleted file mode 100644 index b4409f6d28..0000000000 --- a/dynamic-check/src/ast/expressions/arithmetic/add.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` adding `lhs + rhs`. - /// - pub(crate) fn add( - frame: &Frame, - type_: &Type, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(frame, type_, lhs, rhs, &span)?; - - Ok(Expression { - type_: type_.clone(), - value: ExpressionValue::Add(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/arithmetic/div.rs b/dynamic-check/src/ast/expressions/arithmetic/div.rs deleted file mode 100644 index a52a1790eb..0000000000 --- a/dynamic-check/src/ast/expressions/arithmetic/div.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` dividing `lhs / rhs`. - /// - pub(crate) fn div( - frame: &Frame, - type_: &Type, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(frame, type_, lhs, rhs, &span)?; - - Ok(Expression { - type_: type_.clone(), - value: ExpressionValue::Div(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/arithmetic/mod.rs b/dynamic-check/src/ast/expressions/arithmetic/mod.rs deleted file mode 100644 index 8888661b3d..0000000000 --- a/dynamic-check/src/ast/expressions/arithmetic/mod.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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 . - -pub mod add; -pub use self::add::*; - -pub mod div; -pub use self::div::*; - -pub mod mul; -pub use self::mul::*; - -pub mod negate; -pub use self::negate::*; - -pub mod pow; -pub use self::pow::*; - -pub mod sub; -pub use self::sub::*; diff --git a/dynamic-check/src/ast/expressions/arithmetic/mul.rs b/dynamic-check/src/ast/expressions/arithmetic/mul.rs deleted file mode 100644 index 9e984943ac..0000000000 --- a/dynamic-check/src/ast/expressions/arithmetic/mul.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` multiplying `lhs * rhs`. - /// - pub(crate) fn mul( - frame: &Frame, - type_: &Type, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(frame, type_, lhs, rhs, &span)?; - - Ok(Expression { - type_: type_.clone(), - value: ExpressionValue::Mul(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/arithmetic/negate.rs b/dynamic-check/src/ast/expressions/arithmetic/negate.rs deleted file mode 100644 index af4b77ceaa..0000000000 --- a/dynamic-check/src/ast/expressions/arithmetic/negate.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` negating the `UnresolvedExpression`. - /// - pub(crate) fn negate( - frame: &Frame, - type_: &Type, - unresolved_expression: UnresolvedExpression, - span: Span, - ) -> Result { - let expression_resolved = Self::new(frame, type_, unresolved_expression)?; - - Ok(Expression { - type_: type_.clone(), - value: ExpressionValue::Negate(Box::new(expression_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/arithmetic/pow.rs b/dynamic-check/src/ast/expressions/arithmetic/pow.rs deleted file mode 100644 index 29969d71c4..0000000000 --- a/dynamic-check/src/ast/expressions/arithmetic/pow.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` raising `lhs` to the power of `rhs`. - /// - pub(crate) fn pow( - frame: &Frame, - type_: &Type, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(frame, type_, lhs, rhs, &span)?; - - Ok(Expression { - type_: type_.clone(), - value: ExpressionValue::Pow(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/arithmetic/sub.rs b/dynamic-check/src/ast/expressions/arithmetic/sub.rs deleted file mode 100644 index 8a3b0c5ada..0000000000 --- a/dynamic-check/src/ast/expressions/arithmetic/sub.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` subtracting `lhs - rhs`. - /// - pub(crate) fn sub( - frame: &Frame, - type_: &Type, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(frame, type_, lhs, rhs, &span)?; - - Ok(Expression { - type_: type_.clone(), - value: ExpressionValue::Sub(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/array/array.rs b/dynamic-check/src/ast/expressions/array/array.rs deleted file mode 100644 index 6b8ae862cf..0000000000 --- a/dynamic-check/src/ast/expressions/array/array.rs +++ /dev/null @@ -1,78 +0,0 @@ -// 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 . - -use crate::{ - ast::expressions::array::SpreadOrExpression, Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode, -}; -use leo_static_check::Type; -use leo_typed::{Span, SpreadOrExpression as UnresolvedSpreadOrExpression}; - -impl Expression { - /// - /// Returns a new array `Expression` from a given vector of `UnresolvedSpreadOrExpression`s. - /// - /// Performs a lookup in the given function body's variable table if the expression contains - /// user-defined variables. - /// - pub(crate) fn array( - frame: &Frame, - type_: &Type, - expressions: Vec>, - span: Span, - ) -> Result { - // // Expressions should evaluate to array type or array element type - // let expected_element_type = if let Some(type_) = type_ { - // let (element_type, dimensions) = type_.get_type_array(span.clone())?; - // - // if dimensions[0] != expressions.len() { - // //throw array dimension mismatch error - // return Err(ExpressionError::invalid_length_array( - // dimensions[0], - // expressions.len(), - // span.clone(), - // )); - // } - // - // Some(element_type.clone()) - // } else { - // None - // }; - - // Store actual array element type - let mut actual_element_type = None; - let mut array = vec![]; - - // Resolve all array elements - for expression in expressions { - let expression_resolved = SpreadOrExpression::new(frame, type_, *expression)?; - let expression_type = expression_resolved.type_().clone(); - - array.push(Box::new(expression_resolved)); - actual_element_type = Some(expression_type); - } - - // Define array type for expression - let type_ = match actual_element_type { - Some(type_) => type_, - None => unimplemented!("ERROR: Arrays of size zero are no-op"), - }; - - Ok(Expression { - type_, - value: ExpressionValue::Array(array, span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/array/array_access.rs b/dynamic-check/src/ast/expressions/array/array_access.rs deleted file mode 100644 index e669d402b2..0000000000 --- a/dynamic-check/src/ast/expressions/array/array_access.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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 . -// -// use crate::{ -// ast::expressions::array::RangeOrExpression, Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode, -// }; -// use leo_static_check::Type; -// use leo_typed::{Expression as UnresolvedExpression, RangeOrExpression as UnresolvedRangeOrExpression, Span}; -// -// impl Expression { -// /// -// /// Returns a new array `Expression` from a given array access. -// /// -// /// Performs a lookup in the given function body's variable table if the expression contains -// /// user-defined variables. -// /// -// pub(crate) fn array_access( -// frame: &Frame, -// type_: &Type, -// array: Box, -// range: Box, -// span: Span, -// ) -> Result { -// // Lookup the array in the variable table. -// let array_resolved = Expression::new(frame, type_, *array)?; -// -// // Resolve the range or expression -// let range_resolved = RangeOrExpression::new(frame, type_, *range)?; -// -// Ok(Expression { -// type_: range_resolved.type_().clone(), -// value: ExpressionValue::ArrayAccess(Box::new(array_resolved), Box::new(range_resolved), span), -// }) -// } -// } diff --git a/dynamic-check/src/ast/expressions/array/mod.rs b/dynamic-check/src/ast/expressions/array/mod.rs deleted file mode 100644 index 0c59a9f5d4..0000000000 --- a/dynamic-check/src/ast/expressions/array/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -pub mod array; -pub use self::array::*; - -pub mod array_access; -pub use self::array_access::*; - -pub mod range_or_expression; -pub use self::range_or_expression::*; - -pub mod spread_or_expression; -pub use self::spread_or_expression::*; diff --git a/dynamic-check/src/ast/expressions/array/range_or_expression.rs b/dynamic-check/src/ast/expressions/array/range_or_expression.rs deleted file mode 100644 index d3edc64210..0000000000 --- a/dynamic-check/src/ast/expressions/array/range_or_expression.rs +++ /dev/null @@ -1,64 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, Frame, ResolvedNode}; -use leo_static_check::Type; -use leo_typed::RangeOrExpression as UnresolvedRangeOrExpression; - -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum RangeOrExpression { - Range(Expression, Expression), - Expression(Expression), -} - -impl RangeOrExpression { - // /// If this is a range, return an array type. - // /// If this is an expression, return a data type. - // pub(crate) fn type_(&self) -> &Type { - // match self { - // RangeOrExpression::Range(expresion, _expression) => expresion.type_(), - // RangeOrExpression::Expression(expression) => expression.type_(), - // } - // } - - /// - /// Returns a new `RangeOrExpression` from a given `UnresolvedRangeOrExpression`. - /// - /// Performs a lookup in the given function body's variable table if the expression contains - /// user-defined variables. - /// - pub fn new( - frame: &Frame, - type_: &Type, - unresolved_expression: UnresolvedRangeOrExpression, - ) -> Result { - Ok(match unresolved_expression { - UnresolvedRangeOrExpression::Range(from, to) => { - let resolved_from = Expression::new(frame, type_, from.unwrap())?; - let resolved_to = Expression::new(frame, type_, to.unwrap())?; - // TODO: add check for range type and array type - RangeOrExpression::Range(resolved_from, resolved_to) - } - UnresolvedRangeOrExpression::Expression(expression) => { - let expression_resolved = Expression::new(frame, type_, expression)?; - // TODO: add check for array type - RangeOrExpression::Expression(expression_resolved) - } - }) - } -} diff --git a/dynamic-check/src/ast/expressions/array/spread_or_expression.rs b/dynamic-check/src/ast/expressions/array/spread_or_expression.rs deleted file mode 100644 index b5588d603a..0000000000 --- a/dynamic-check/src/ast/expressions/array/spread_or_expression.rs +++ /dev/null @@ -1,61 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, Frame}; -use leo_static_check::Type; -use leo_typed::SpreadOrExpression as UnresolvedSpreadOrExpression; - -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum SpreadOrExpression { - Spread(Expression), - Expression(Expression), -} - -impl SpreadOrExpression { - pub(crate) fn type_(&self) -> &Type { - match self { - SpreadOrExpression::Spread(expression) => expression.type_(), - SpreadOrExpression::Expression(expression) => expression.type_(), - } - } - - /// - /// Returns a new `SpreadOrExpression` from a given `UnresolvedSpreadOrExpression`. - /// - /// Performs a lookup in the given function body's variable table if the expression contains - /// user-defined variables. - /// - pub fn new( - frame: &Frame, - type_: &Type, - unresolved_expression: UnresolvedSpreadOrExpression, - ) -> Result { - Ok(match unresolved_expression { - UnresolvedSpreadOrExpression::Spread(spread) => { - let spread_resolved = Expression::new(frame, type_, spread)?; - // TODO: add check for array type or array element type - SpreadOrExpression::Spread(spread_resolved) - } - UnresolvedSpreadOrExpression::Expression(expression) => { - let expression_resolved = Expression::new(frame, type_, expression)?; - // TODO: add check for array type or array element type - SpreadOrExpression::Expression(expression_resolved) - } - }) - } -} diff --git a/dynamic-check/src/ast/expressions/binary/binary.rs b/dynamic-check/src/ast/expressions/binary/binary.rs deleted file mode 100644 index 88d1d4c3f6..0000000000 --- a/dynamic-check/src/ast/expressions/binary/binary.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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 . -use crate::{Expression, ExpressionError, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// Resolve a binary expression from left to right. - /// If no expected type is given, then the expression resolves to the lhs type. - pub(crate) fn binary( - frame: &Frame, - type_: &Type, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - _span: &Span, - ) -> Result<(Self, Self), ExpressionError> { - // Resolve lhs with expected type - let lhs_resolved = Expression::new(frame, type_, lhs)?; - - // Resolve the rhs with expected type - let rhs_resolved = Expression::new(frame, type_, rhs)?; - - Ok((lhs_resolved, rhs_resolved)) - } -} diff --git a/dynamic-check/src/ast/expressions/binary/mod.rs b/dynamic-check/src/ast/expressions/binary/mod.rs deleted file mode 100644 index e2c63f7183..0000000000 --- a/dynamic-check/src/ast/expressions/binary/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod binary; -pub use self::binary::*; diff --git a/dynamic-check/src/ast/expressions/circuit/circuit.rs b/dynamic-check/src/ast/expressions/circuit/circuit.rs deleted file mode 100644 index 96a319002c..0000000000 --- a/dynamic-check/src/ast/expressions/circuit/circuit.rs +++ /dev/null @@ -1,79 +0,0 @@ -// 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 . -// -// use crate::{CircuitVariableDefinition, Expression, ExpressionError, ExpressionValue, ResolvedNode}; -// use leo_static_check::{SymbolTable, Type}; -// use leo_typed::{CircuitVariableDefinition as UnresolvedCircuitVariableDefinition, Identifier, Span}; -// -// impl Expression { -// /// -// /// Resolves an inline circuit expression. -// /// -// pub(crate) fn circuit( -// table: &mut SymbolTable, -// expected_type: Option, -// identifier: Identifier, -// variables: Vec, -// span: Span, -// ) -> Result { -// // Check expected type -// let type_ = Type::Circuit(identifier.clone()); -// Type::check_type(&expected_type, &type_, span.clone())?; -// -// // Lookup circuit in symbol table -// let circuit = table -// .get_circuit(&identifier.name) -// .ok_or(ExpressionError::undefined_circuit(identifier.clone()))?; -// -// // Check the number of variables given -// let expected_variables = circuit.variables.clone(); -// -// if variables.len() != expected_variables.len() { -// return Err(ExpressionError::invalid_length_circuit_members( -// expected_variables.len(), -// variables.len(), -// span, -// )); -// } -// -// // Check the name and type for each circuit variable -// let mut variables_resolved = vec![]; -// -// for variable in variables { -// // Find variable by name -// let matched_variable = expected_variables -// .iter() -// .find(|expected| expected.identifier.eq(&variable.identifier)); -// -// let variable_type = match matched_variable { -// Some(variable_type) => variable_type, -// None => return Err(ExpressionError::undefined_circuit_variable(variable.identifier)), -// }; -// -// // Resolve the variable expression using the expected variable type -// let expected_variable_type = Some(variable_type.type_.clone()); -// -// let variable_resolved = CircuitVariableDefinition::resolve(table, (expected_variable_type, variable))?; -// -// variables_resolved.push(variable_resolved); -// } -// -// Ok(Expression { -// type_, -// value: ExpressionValue::Circuit(identifier, variables_resolved, span), -// }) -// } -// } diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_access.rs b/dynamic-check/src/ast/expressions/circuit/circuit_access.rs deleted file mode 100644 index 0733755e8f..0000000000 --- a/dynamic-check/src/ast/expressions/circuit/circuit_access.rs +++ /dev/null @@ -1,79 +0,0 @@ -// 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 . -// -// use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; -// use leo_static_check::{Attribute, SymbolTable, Type}; -// use leo_typed::{Expression as UnresolvedExpression, Identifier, Span}; -// -// impl Expression { -// /// Resolve the type of a circuit member -// pub(crate) fn circuit_access( -// table: &mut SymbolTable, -// expected_type: Option, -// circuit: Box, -// member: Identifier, -// span: Span, -// ) -> Result { -// // Lookup the circuit in the symbol table. -// // We do not know the exact circuit type from this context so `expected_type = None`. -// let circuit_resolved = Expression::resolve(table, (None, *circuit))?; -// let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?; -// -// // Lookup the circuit type in the symbol table -// let circuit_type = table -// .get_circuit(&circuit_name.name) -// .ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?; -// -// // Resolve the circuit member as a circuit variable -// let matched_variable = circuit_type -// .variables -// .iter() -// .find(|variable| variable.identifier.eq(&member)); -// -// let type_ = match matched_variable { -// // Return variable type -// Some(variable) => variable.type_.clone(), -// None => { -// // Resolve the circuit member as a circuit function -// let matched_function = circuit_type -// .functions -// .iter() -// .find(|function| function.function.identifier.eq(&member)); -// -// match matched_function { -// // Return function output type -// Some(function) => { -// // Check non-static method -// if function.attributes.contains(&Attribute::Static) { -// return Err(ExpressionError::invalid_static_member_access(member.name.clone(), span)); -// } -// -// function.function.output.type_.clone() -// } -// None => return Err(ExpressionError::undefined_circuit_function(member, span)), -// } -// } -// }; -// -// // Check type of circuit member -// Type::check_type(&expected_type, &type_, span.clone())?; -// -// Ok(Expression { -// type_, -// value: ExpressionValue::CircuitMemberAccess(Box::new(circuit_resolved), member, span), -// }) -// } -// } diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs b/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs deleted file mode 100644 index 362eda025d..0000000000 --- a/dynamic-check/src/ast/expressions/circuit/circuit_static_access.rs +++ /dev/null @@ -1,66 +0,0 @@ -// 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 . -// -// use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; -// use leo_static_check::{Attribute, SymbolTable, Type}; -// use leo_typed::{Expression as UnresolvedExpression, Identifier, Span}; -// -// impl Expression { -// /// Resolve the type of a static circuit member -// pub(crate) fn circuit_static_access( -// table: &mut SymbolTable, -// expected_type: Option, -// circuit: Box, -// member: Identifier, -// span: Span, -// ) -> Result { -// // Lookup the circuit in the symbol table. -// // We do not know the exact circuit type from this context so `expected_type = None`. -// let circuit_resolved = Expression::resolve(table, (None, *circuit))?; -// let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?; -// -// // Lookup the circuit type in the symbol table -// let circuit_type = table -// .get_circuit(&circuit_name.name) -// .ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?; -// -// // Resolve the circuit member as a circuit function -// let matched_function = circuit_type -// .functions -// .iter() -// .find(|function| function.function.identifier.eq(&member)); -// -// let type_ = match matched_function { -// Some(function) => { -// // Check static method -// if function.attributes.contains(&Attribute::Static) { -// function.function.output.type_.clone() -// } else { -// return Err(ExpressionError::invalid_member_access(member.name, span)); -// } -// } -// None => return Err(ExpressionError::undefined_circuit_function_static(member, span)), -// }; -// -// // Check type of static circuit function output -// Type::check_type(&expected_type, &type_, span.clone())?; -// -// Ok(Expression { -// type_, -// value: ExpressionValue::CircuitStaticFunctionAccess(Box::new(circuit_resolved), member, span), -// }) -// } -// } diff --git a/dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs b/dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs deleted file mode 100644 index 17b69b0f4f..0000000000 --- a/dynamic-check/src/ast/expressions/circuit/circuit_variable_definition.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{CircuitVariableDefinition as UnresolvedCircuitVariableDefinition, Identifier}; - -use serde::{Deserialize, Serialize}; - -/// A circuit variable with an assigned expression. Used when defining an inline circuit expression. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct CircuitVariableDefinition { - identifier: Identifier, - expression: Expression, -} - -impl ResolvedNode for CircuitVariableDefinition { - type Error = ExpressionError; - type UnresolvedNode = (Option, UnresolvedCircuitVariableDefinition); - - /// - /// Type check a circuit variable in an inline circuit expression - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let expected_type = unresolved.0; - let circuit_variable = unresolved.1; - - // Resolve circuit variable expression with expected type - Ok(CircuitVariableDefinition { - identifier: circuit_variable.identifier, - expression: Expression::resolve(table, (expected_type, circuit_variable.expression))?, - }) - } -} diff --git a/dynamic-check/src/ast/expressions/circuit/mod.rs b/dynamic-check/src/ast/expressions/circuit/mod.rs deleted file mode 100644 index a1c5db9a5c..0000000000 --- a/dynamic-check/src/ast/expressions/circuit/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -pub mod circuit; -pub use self::circuit::*; - -pub mod circuit_access; -pub use self::circuit_access::*; - -pub mod circuit_static_access; -pub use self::circuit_static_access::*; - -pub mod circuit_variable_definition; -pub use self::circuit_variable_definition::*; diff --git a/dynamic-check/src/ast/expressions/conditional/conditional.rs b/dynamic-check/src/ast/expressions/conditional/conditional.rs deleted file mode 100644 index 48f93bd882..0000000000 --- a/dynamic-check/src/ast/expressions/conditional/conditional.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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 . -// -// use crate::{Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode}; -// use leo_static_check::{SymbolTable, Type}; -// use leo_typed::{Expression as UnresolvedExpression, Span}; -// -// impl Expression { -// /// Resolves an `if {cond} ? {first} : {second}` expression -// /// `{cond}` should resolve to a boolean type -// /// `{first}` and `{second}` should have equal types -// pub(crate) fn conditional( -// frame: &Frame, -// type_: &Type, -// cond: UnresolvedExpression, -// first: UnresolvedExpression, -// second: UnresolvedExpression, -// span: Span, -// ) -> Result { -// // Resolve the condition to a boolean type -// let boolean_type = Type::Boolean; -// let cond_resolved = Expression::new(frame, &boolean_type, cond)?; -// -// // Resolve the first and second expressions to the expected type -// let (first_resolved, second_resolved) = Expression::binary(frame, type_, first, second, &span)?; -// -// Ok(Expression { -// type_: type_.clone(), -// value: ExpressionValue::IfElse( -// Box::new(cond_resolved), -// Box::new(first_resolved), -// Box::new(second_resolved), -// span, -// ), -// }) -// } -// } diff --git a/dynamic-check/src/ast/expressions/conditional/mod.rs b/dynamic-check/src/ast/expressions/conditional/mod.rs deleted file mode 100644 index e7a9ed3b86..0000000000 --- a/dynamic-check/src/ast/expressions/conditional/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod conditional; -pub use self::conditional::*; diff --git a/dynamic-check/src/ast/expressions/expression.rs b/dynamic-check/src/ast/expressions/expression.rs deleted file mode 100644 index ede876fffc..0000000000 --- a/dynamic-check/src/ast/expressions/expression.rs +++ /dev/null @@ -1,219 +0,0 @@ -// 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 . - -use crate::{ExpressionError, ExpressionValue, Frame, ResolvedNode, VariableTable}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -use serde::{Deserialize, Serialize}; - -/// Stores a type-checked expression -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct Expression { - /// The type this expression evaluates to - pub(crate) type_: Type, - /// The value of this expression - pub(crate) value: ExpressionValue, -} - -impl Expression { - /// Return the type this expression evaluates to - pub fn type_(&self) -> &Type { - &self.type_ - } - - /// Return the span - pub fn span(&self) -> &Span { - self.value.span() - } - - /// Returns `Ok` if this expression resolves to an integer type - pub fn check_type_integer(&self) -> Result<(), ExpressionError> { - self.type_.check_type_integer(self.value.span().clone())?; - - Ok(()) - } - - /// - /// Returns a new `Expression` from a given `UnresolvedExpression`. - /// - /// Performs a lookup in the given function body's variable table if the expression contains - /// user-defined variables. - /// - pub fn new( - frame: &Frame, - type_: &Type, - unresolved_expression: UnresolvedExpression, - ) -> Result { - match unresolved_expression { - // Identifier - UnresolvedExpression::Identifier(identifier) => Self::variable(frame, identifier), - - // Values - UnresolvedExpression::Address(string, span) => Ok(Self::address(type_, string, span)), - UnresolvedExpression::Boolean(string, span) => Ok(Self::boolean(type_, string, span)), - UnresolvedExpression::Field(string, span) => Ok(Self::field(type_, string, span)), - UnresolvedExpression::Group(group_value) => Ok(Self::group(type_, group_value)), - UnresolvedExpression::Integer(integer_type, string, span) => { - Ok(Self::integer(type_, integer_type, string, span)) - } - UnresolvedExpression::Implicit(string, span) => Self::implicit(type_, string, span), - - // Arithmetic Operations - UnresolvedExpression::Add(lhs, rhs, span) => Self::add(frame, type_, *lhs, *rhs, span), - UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(frame, type_, *lhs, *rhs, span), - UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(frame, type_, *lhs, *rhs, span), - UnresolvedExpression::Div(lhs, rhs, span) => Self::div(frame, type_, *lhs, *rhs, span), - UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(frame, type_, *lhs, *rhs, span), - UnresolvedExpression::Negate(expression, span) => Self::negate(frame, type_, *expression, span), - - // Logical Operations - UnresolvedExpression::And(lhs, rhs, span) => Self::and(frame, *lhs, *rhs, span), - UnresolvedExpression::Or(lhs, rhs, span) => Self::or(frame, *lhs, *rhs, span), - UnresolvedExpression::Not(expression, span) => Self::not(frame, *expression, span), - - // Relational Operations - UnresolvedExpression::Eq(lhs, rhs, span) => Self::eq(frame, *lhs, *rhs, span), - UnresolvedExpression::Ge(lhs, rhs, span) => Self::ge(frame, *lhs, *rhs, span), - UnresolvedExpression::Gt(lhs, rhs, span) => Self::gt(frame, *lhs, *rhs, span), - UnresolvedExpression::Le(lhs, rhs, span) => Self::le(frame, *lhs, *rhs, span), - UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(frame, *lhs, *rhs, span), - - // Conditionals - // UnresolvedExpression::IfElse(cond, first, second, span) => { - // Self::conditional(variable_table, type_, *cond, *first, *second, span) - // } - - // Arrays - UnresolvedExpression::Array(elements, span) => Self::array(frame, type_, elements, span), - // UnresolvedExpression::ArrayAccess(array, access, span) => { - // Self::array_access(frame, type_, array, access, span) - // } - - // // Tuples - // UnresolvedExpression::Tuple(elements, span) => Self::tuple(variable_table, elements, span), - // UnresolvedExpression::TupleAccess(tuple, index, span) => { - // Self::tuple_access(variable_table, tuple, index, span) - // } - // - // // Circuits - // UnresolvedExpression::Circuit(identifier, variables, span) => { - // Self::circuit(variable_table, identifier, variables, span) - // } - // UnresolvedExpression::CircuitMemberAccess(circuit, member, span) => { - // Self::circuit_access(variable_table, circuit, member, span) - // } - // UnresolvedExpression::CircuitStaticFunctionAccess(circuit, member, span) => { - // Self::circuit_static_access(variable_table, circuit, member, span) - // } - // - // // Functions - // UnresolvedExpression::FunctionCall(function, inputs, span) => { - // Self::function_call(variable_table, function, inputs, span) - // } - // UnresolvedExpression::CoreFunctionCall(_name, _inputs, _span) => { - // unimplemented!("core function calls not type checked") - // // Self::core_function_call(variable_table, expected_type, function, inputs, span) - // } - _ => unimplemented!("expression not impl yet"), - } - } -} - -impl ResolvedNode for Expression { - type Error = ExpressionError; - /// (expected type, unresolved expression) - type UnresolvedNode = (Option, UnresolvedExpression); - - /// Type check an expression inside a program AST - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - unimplemented!("expression resolve method deprecated") - // let expected_type = unresolved.0; - // let expression = unresolved.1; - // - // match expression { - // // Identifier - // UnresolvedExpression::Identifier(identifier) => Self::identifier(table, expected_type, identifier), - // - // // Values - // UnresolvedExpression::Address(string, span) => Self::address(expected_type, string, span), - // UnresolvedExpression::Boolean(string, span) => Self::boolean(expected_type, string, span), - // UnresolvedExpression::Field(string, span) => Self::field(expected_type, string, span), - // UnresolvedExpression::Group(group_value) => Self::group(expected_type, group_value), - // UnresolvedExpression::Implicit(string, span) => Self::implicit(expected_type, string, span), - // UnresolvedExpression::Integer(integer_type, string, span) => { - // Self::integer(expected_type, integer_type, string, span) - // } - // - // // Arithmetic Operations - // UnresolvedExpression::Add(lhs, rhs, span) => Self::add(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Sub(lhs, rhs, span) => Self::sub(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Mul(lhs, rhs, span) => Self::mul(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Div(lhs, rhs, span) => Self::div(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Pow(lhs, rhs, span) => Self::pow(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Negate(expression, span) => Self::negate(table, expected_type, *expression, span), - // - // // Logical Operations - // UnresolvedExpression::And(lhs, rhs, span) => Self::and(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Or(lhs, rhs, span) => Self::or(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Not(expression, span) => Self::not(table, expected_type, *expression, span), - // - // // Relational Operations - // UnresolvedExpression::Eq(lhs, rhs, span) => Self::eq(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Ge(lhs, rhs, span) => Self::ge(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Gt(lhs, rhs, span) => Self::gt(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Le(lhs, rhs, span) => Self::le(table, expected_type, *lhs, *rhs, span), - // UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(table, expected_type, *lhs, *rhs, span), - // - // // Conditionals - // UnresolvedExpression::IfElse(cond, first, second, span) => { - // Self::conditional(table, expected_type, *cond, *first, *second, span) - // } - // - // // Arrays - // UnresolvedExpression::Array(elements, span) => Self::array(table, expected_type, elements, span), - // UnresolvedExpression::ArrayAccess(array, access, span) => { - // Self::array_access(table, expected_type, array, access, span) - // } - // - // // Tuples - // UnresolvedExpression::Tuple(elements, span) => Self::tuple(table, expected_type, elements, span), - // UnresolvedExpression::TupleAccess(tuple, index, span) => { - // Self::tuple_access(table, expected_type, tuple, index, span) - // } - // - // // Circuits - // UnresolvedExpression::Circuit(identifier, variables, span) => { - // Self::circuit(table, expected_type, identifier, variables, span) - // } - // UnresolvedExpression::CircuitMemberAccess(circuit, member, span) => { - // Self::circuit_access(table, expected_type, circuit, member, span) - // } - // UnresolvedExpression::CircuitStaticFunctionAccess(circuit, member, span) => { - // Self::circuit_static_access(table, expected_type, circuit, member, span) - // } - // - // // Functions - // UnresolvedExpression::FunctionCall(function, inputs, span) => { - // Self::function_call(table, expected_type, function, inputs, span) - // } - // UnresolvedExpression::CoreFunctionCall(_name, _inputs, _span) => { - // unimplemented!("core function calls not type checked") - // // Self::core_function_call(table, expected_type, function, inputs, span) - // } - // } - } -} diff --git a/dynamic-check/src/ast/expressions/expression_value.rs b/dynamic-check/src/ast/expressions/expression_value.rs deleted file mode 100644 index 30b94ad2a2..0000000000 --- a/dynamic-check/src/ast/expressions/expression_value.rs +++ /dev/null @@ -1,133 +0,0 @@ -// 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 . - -use crate::{ - expressions::array::{RangeOrExpression, SpreadOrExpression}, - CircuitVariableDefinition, - Expression, -}; -use leo_typed::{GroupValue, Identifier, IntegerType, Span}; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub enum ExpressionValue { - // Variable - Variable(Identifier), - - // Values - Address(String, Span), - Boolean(String, Span), - Field(String, Span), - Group(GroupValue), - Integer(IntegerType, String, Span), - - // Arithmetic operations - Add(Box, Box, Span), - Sub(Box, Box, Span), - Mul(Box, Box, Span), - Div(Box, Box, Span), - Pow(Box, Box, Span), - Negate(Box, Span), - - // Logical operations - And(Box, Box, Span), - Or(Box, Box, Span), - Not(Box, Span), - - // Relational operations - Eq(Box, Box, Span), - Ge(Box, Box, Span), - Gt(Box, Box, Span), - Le(Box, Box, Span), - Lt(Box, Box, Span), - - // Conditionals - // (conditional, first_value, second_value, span) - IfElse(Box, Box, Box, Span), - - // Arrays - // (array_elements, span) - Array(Vec>, Span), - // (array_name, range, span) - ArrayAccess(Box, Box, Span), - - // Tuples - // (tuple_elements, span) - Tuple(Vec, Span), - // (tuple_name, index, span) - TupleAccess(Box, usize, Span), - - // Circuits - // (defined_circuit_name, circuit_members, span) - Circuit(Identifier, Vec, Span), - // (declared_circuit name, circuit_member_name, span) - CircuitMemberAccess(Box, Identifier, Span), - // (defined_circuit name, circuit_static_function_name, span) - CircuitStaticFunctionAccess(Box, Identifier, Span), - - // Functions - // (declared_function_name, function_arguments, span) - FunctionCall(Box, Vec, Span), - // (core_function_name, function_arguments, span) - CoreFunctionCall(String, Vec, Span), -} - -impl ExpressionValue { - /// Return the span - pub fn span(&self) -> &Span { - match self { - ExpressionValue::Variable(identifier) => &identifier.span, - ExpressionValue::Address(_, span) => span, - ExpressionValue::Boolean(_, span) => span, - ExpressionValue::Field(_, span) => span, - ExpressionValue::Group(group_value) => group_value.span(), - ExpressionValue::Integer(_type, _, span) => span, - - ExpressionValue::Add(_, _, span) => span, - ExpressionValue::Sub(_, _, span) => span, - ExpressionValue::Mul(_, _, span) => span, - ExpressionValue::Div(_, _, span) => span, - ExpressionValue::Pow(_, _, span) => span, - ExpressionValue::Negate(_, span) => span, - - ExpressionValue::And(_, _, span) => span, - ExpressionValue::Or(_, _, span) => span, - ExpressionValue::Not(_, span) => span, - - ExpressionValue::Eq(_, _, span) => span, - ExpressionValue::Ge(_, _, span) => span, - ExpressionValue::Gt(_, _, span) => span, - ExpressionValue::Le(_, _, span) => span, - ExpressionValue::Lt(_, _, span) => span, - - ExpressionValue::IfElse(_, _, _, span) => span, - - ExpressionValue::Array(_, span) => span, - ExpressionValue::ArrayAccess(_, _, span) => span, - - ExpressionValue::Tuple(_, span) => span, - ExpressionValue::TupleAccess(_, _, span) => span, - - ExpressionValue::Circuit(_, _, span) => span, - ExpressionValue::CircuitMemberAccess(_, _, span) => span, - ExpressionValue::CircuitStaticFunctionAccess(_, _, span) => span, - - ExpressionValue::FunctionCall(_, _, span) => span, - ExpressionValue::CoreFunctionCall(_, _, span) => span, - } - } -} diff --git a/dynamic-check/src/ast/expressions/function/core_circuit.rs b/dynamic-check/src/ast/expressions/function/core_circuit.rs deleted file mode 100644 index 89cbfc6477..0000000000 --- a/dynamic-check/src/ast/expressions/function/core_circuit.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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 . - -// use crate::{Expression, ExpressionValue, ResolvedNode, SymbolTable, Type}; -// use leo_typed::{Expression as UnresolvedExpression, Span, Type as UnresolvedType}; -// -// impl Expression { -// /// Resolves inputs for a call to a core circuit. -// pub(crate) fn core_circuit_call( -// table: &mut SymbolTable, -// expected_type: Option, -// function: String, -// inputs: Vec, -// output_type: UnresolvedType, -// span: Span, -// ) -> Result { -// -// } -// } diff --git a/dynamic-check/src/ast/expressions/function/function_call.rs b/dynamic-check/src/ast/expressions/function/function_call.rs deleted file mode 100644 index c9b831c663..0000000000 --- a/dynamic-check/src/ast/expressions/function/function_call.rs +++ /dev/null @@ -1,71 +0,0 @@ -// 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 . -// -// use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; -// use leo_static_check::{SymbolTable, Type}; -// use leo_typed::{Expression as UnresolvedExpression, Span}; -// -// impl Expression { -// /// Resolves an inline function call -// /// Checks for errors in function name, inputs, and output. -// pub(crate) fn function_call( -// table: &mut SymbolTable, -// expected_type: Option, -// function: Box, -// inputs: Vec, -// span: Span, -// ) -> Result { -// // Lookup function in symbol table. -// // We do not know the exact function type from this context so `expected_type = None`. -// let function_resolved = Expression::resolve(table, (None, *function))?; -// let function_name = function_resolved.type_().get_type_function(span.clone())?; -// -// // Lookup the function type in the symbol table -// let function_type = table -// .get_function(&function_name.name) -// .ok_or(ExpressionError::undefined_function(function_name.clone()))?; -// -// let type_ = function_type.output.type_.clone(); -// let expected_inputs = function_type.inputs.clone(); -// -// // Check the number of inputs given -// if inputs.len() != expected_inputs.len() { -// return Err(ExpressionError::invalid_length_function_inputs( -// expected_inputs.len(), -// inputs.len(), -// span, -// )); -// } -// -// // Check the type for each function input -// let mut inputs_resolved = vec![]; -// -// for (input, function_input_type) in inputs.into_iter().zip(expected_inputs) { -// let input_type = function_input_type.type_().clone(); -// let input_resolved = Expression::resolve(table, (Some(input_type), input))?; -// -// inputs_resolved.push(input_resolved) -// } -// -// // Check the function output type -// Type::check_type(&expected_type, &type_, span.clone())?; -// -// Ok(Expression { -// type_, -// value: ExpressionValue::FunctionCall(Box::new(function_resolved), inputs_resolved, span), -// }) -// } -// } diff --git a/dynamic-check/src/ast/expressions/function/mod.rs b/dynamic-check/src/ast/expressions/function/mod.rs deleted file mode 100644 index f5c92c10a4..0000000000 --- a/dynamic-check/src/ast/expressions/function/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 . - -pub mod core_circuit; -pub use self::core_circuit::*; - -pub mod function_call; -pub use self::function_call::*; diff --git a/dynamic-check/src/ast/expressions/identifier/identifier.rs b/dynamic-check/src/ast/expressions/identifier/identifier.rs deleted file mode 100644 index 4e061d64d4..0000000000 --- a/dynamic-check/src/ast/expressions/identifier/identifier.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame, VariableTable}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::Identifier; - -impl Expression { - /// - /// Returns a new variable expression from a given variable. - /// - /// Performs a lookup in the given function body's variable table to find the variable's type. - /// - pub(crate) fn variable(function_body: &Frame, variable: Identifier) -> Result { - // Lookup the type of the given variable. - let type_ = function_body.variable_table.get(&variable.name, &variable.span)?; - - Ok(Expression { - type_: type_.clone(), - value: ExpressionValue::Variable(variable), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/identifier/mod.rs b/dynamic-check/src/ast/expressions/identifier/mod.rs deleted file mode 100644 index 29ea470671..0000000000 --- a/dynamic-check/src/ast/expressions/identifier/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod identifier; -pub use self::identifier::*; diff --git a/dynamic-check/src/ast/expressions/logical/and.rs b/dynamic-check/src/ast/expressions/logical/and.rs deleted file mode 100644 index 148868e695..0000000000 --- a/dynamic-check/src/ast/expressions/logical/and.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` applying logical AND `lhs && rhs`. - /// - pub(crate) fn and( - frame: &Frame, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - let type_ = Type::Boolean; - - // Resolve lhs and rhs expressions to boolean type - let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; - - Ok(Expression { - type_, - value: ExpressionValue::And(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/logical/mod.rs b/dynamic-check/src/ast/expressions/logical/mod.rs deleted file mode 100644 index 56200117ee..0000000000 --- a/dynamic-check/src/ast/expressions/logical/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 . - -pub mod and; -pub use self::and::*; - -pub mod not; -pub use self::not::*; - -pub mod or; -pub use self::or::*; diff --git a/dynamic-check/src/ast/expressions/logical/not.rs b/dynamic-check/src/ast/expressions/logical/not.rs deleted file mode 100644 index 44eae752e0..0000000000 --- a/dynamic-check/src/ast/expressions/logical/not.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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 . -use crate::{Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` applying a logical NOT `!UnresolvedExpression`. - /// - pub(crate) fn not(table: &Frame, expression: UnresolvedExpression, span: Span) -> Result { - let type_ = Type::Boolean; - - // Resolve lhs and rhs expressions to boolean type - let expression_resolved = Self::new(table, &type_, expression)?; - - Ok(Expression { - type_, - value: ExpressionValue::Not(Box::new(expression_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/logical/or.rs b/dynamic-check/src/ast/expressions/logical/or.rs deleted file mode 100644 index a1f218b68c..0000000000 --- a/dynamic-check/src/ast/expressions/logical/or.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` applying logical OR `lhs || rhs`. - /// - pub(crate) fn or( - frame: &Frame, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - let type_ = Type::Boolean; - - // Resolve lhs and rhs expressions to boolean type - let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; - - Ok(Expression { - type_, - value: ExpressionValue::And(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/mod.rs b/dynamic-check/src/ast/expressions/mod.rs deleted file mode 100644 index 6531a18d36..0000000000 --- a/dynamic-check/src/ast/expressions/mod.rs +++ /dev/null @@ -1,54 +0,0 @@ -// 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 . - -pub mod arithmetic; -pub use self::arithmetic::*; - -pub mod array; -pub use self::array::*; - -pub mod binary; -pub use self::binary::*; - -pub mod circuit; -pub use self::circuit::*; - -pub mod conditional; -pub use self::conditional::*; - -pub mod expression; -pub use self::expression::*; - -pub mod expression_value; -pub use self::expression_value::*; - -pub mod function; -pub use self::function::*; - -pub mod identifier; -pub use self::identifier::*; - -pub mod logical; -pub use self::logical::*; - -pub mod relational; -pub use self::relational::*; - -pub mod tuple; -pub use self::tuple::*; - -pub mod values; -pub use self::values::*; diff --git a/dynamic-check/src/ast/expressions/relational/eq.rs b/dynamic-check/src/ast/expressions/relational/eq.rs deleted file mode 100644 index 47ba5e66bc..0000000000 --- a/dynamic-check/src/ast/expressions/relational/eq.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` evaluating `lhs == rhs`. - /// - pub(crate) fn eq( - frame: &Frame, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - // This expression returns a boolean type. - let type_ = Type::Boolean; - - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; - - Ok(Expression { - type_, - value: ExpressionValue::Eq(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/relational/ge.rs b/dynamic-check/src/ast/expressions/relational/ge.rs deleted file mode 100644 index 2884b6fbc2..0000000000 --- a/dynamic-check/src/ast/expressions/relational/ge.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` evaluating `lhs >= rhs`. - /// - pub(crate) fn ge( - frame: &Frame, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - // This expression returns a boolean type. - let type_ = Type::Boolean; - - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; - - // Check that expressions are integer type - lhs_resolved.check_type_integer()?; - rhs_resolved.check_type_integer()?; - - Ok(Expression { - // This expression returns a boolean type. - type_, - value: ExpressionValue::Ge(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/relational/gt.rs b/dynamic-check/src/ast/expressions/relational/gt.rs deleted file mode 100644 index d2b34329a7..0000000000 --- a/dynamic-check/src/ast/expressions/relational/gt.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` evaluating `lhs > rhs`. - /// - pub(crate) fn gt( - frame: &Frame, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - // This expression returns a boolean type. - let type_ = Type::Boolean; - - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; - - // Check that expressions are integer type - lhs_resolved.check_type_integer()?; - rhs_resolved.check_type_integer()?; - - Ok(Expression { - // This expression returns a boolean type. - type_: Type::Boolean, - value: ExpressionValue::Gt(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/relational/le.rs b/dynamic-check/src/ast/expressions/relational/le.rs deleted file mode 100644 index ee588fbe6e..0000000000 --- a/dynamic-check/src/ast/expressions/relational/le.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` evaluating `lhs <= rhs`. - /// - pub(crate) fn le( - frame: &Frame, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - // This expression returns a boolean type. - let type_ = Type::Boolean; - - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; - - // Check that expressions are integer type - lhs_resolved.check_type_integer()?; - rhs_resolved.check_type_integer()?; - - Ok(Expression { - // This expression returns a boolean type. - type_: Type::Boolean, - value: ExpressionValue::Le(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/relational/lt.rs b/dynamic-check/src/ast/expressions/relational/lt.rs deleted file mode 100644 index 09859be888..0000000000 --- a/dynamic-check/src/ast/expressions/relational/lt.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame}; -use leo_static_check::Type; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new `Expression` evaluating `lhs < rhs`. - /// - pub(crate) fn lt( - frame: &Frame, - lhs: UnresolvedExpression, - rhs: UnresolvedExpression, - span: Span, - ) -> Result { - // This expression returns a boolean type. - let type_ = Type::Boolean; - - // Resolve lhs and rhs expressions - let (lhs_resolved, rhs_resolved) = Self::binary(frame, &type_, lhs, rhs, &span)?; - - // Check that expressions are integer type - lhs_resolved.check_type_integer()?; - rhs_resolved.check_type_integer()?; - - Ok(Expression { - // This expression returns a boolean type. - type_: Type::Boolean, - value: ExpressionValue::Lt(Box::new(lhs_resolved), Box::new(rhs_resolved), span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/relational/mod.rs b/dynamic-check/src/ast/expressions/relational/mod.rs deleted file mode 100644 index a912ceaa23..0000000000 --- a/dynamic-check/src/ast/expressions/relational/mod.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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 . - -pub mod eq; -pub use self::eq::*; - -pub mod ge; -pub use self::ge::*; - -pub mod gt; -pub use self::gt::*; - -pub mod le; -pub use self::le::*; - -pub mod lt; -pub use self::lt::*; diff --git a/dynamic-check/src/ast/expressions/tuple/mod.rs b/dynamic-check/src/ast/expressions/tuple/mod.rs deleted file mode 100644 index 9125265b0e..0000000000 --- a/dynamic-check/src/ast/expressions/tuple/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 . - -pub mod tuple; -pub use self::tuple::*; - -pub mod tuple_access; -pub use self::tuple_access::*; diff --git a/dynamic-check/src/ast/expressions/tuple/tuple.rs b/dynamic-check/src/ast/expressions/tuple/tuple.rs deleted file mode 100644 index 028dba221c..0000000000 --- a/dynamic-check/src/ast/expressions/tuple/tuple.rs +++ /dev/null @@ -1,69 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode, VariableTable}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// - /// Returns a new expression that defines a tuple (single variable with multiple values). - /// - /// Performs a lookup in the given variable table if an `UnresolvedExpression` contains user-defined types. - /// - pub(crate) fn tuple( - function_body: &Frame, - type_: &Type, - unresolved_expressions: Vec, - span: Span, - ) -> Result { - // Get the type of each element in the tuple. - // If the type is not a tuple type, throw an error. - let element_types = match type_ { - Type::Tuple(types) => types, - type_ => return Err(ExpressionError::invalid_type_tuple(type_, &span)), - }; - - // Create a new vector of `Expression`s from the given vector of `UnresolvedExpression`s. - let mut tuple = vec![]; - - for (unresolved_expression, element_type) in unresolved_expressions.into_iter().zip(element_types) { - let expression = Expression::new(function_body, element_type, unresolved_expression)?; - - tuple.push(expression); - } - - Ok(Expression { - type_: type_.clone(), - value: ExpressionValue::Tuple(tuple, span), - }) - } -} - -/// Return a tuple of types given some expected type tuple. Otherwise return a tuple of `None` types. -pub fn check_tuple_type( - expected_type: Option, - length: usize, - span: Span, -) -> Result>, ExpressionError> { - Ok(match expected_type { - Some(type_) => { - let types = type_.get_type_tuple(span.clone())?; - types.iter().map(|type_| Some(type_.clone())).collect::>() - } - None => vec![None; length], - }) -} diff --git a/dynamic-check/src/ast/expressions/tuple/tuple_access.rs b/dynamic-check/src/ast/expressions/tuple/tuple_access.rs deleted file mode 100644 index 31f52553a6..0000000000 --- a/dynamic-check/src/ast/expressions/tuple/tuple_access.rs +++ /dev/null @@ -1,56 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Expression { - /// Resolves a tuple access expression - pub(crate) fn tuple_access( - table: &mut SymbolTable, - expected_type: Option, - tuple: Box, - index: usize, - span: Span, - ) -> Result { - // Lookup the tuple in the symbol table. - // We do not know the length from this context so `expected_type = None`. - let tuple_resolved = Expression::resolve(table, (None, *tuple))?; - - // Resolve the tuple index type - let type_tuple = tuple_resolved.type_().get_type_tuple(span.clone())?; - - // Throw a tuple out of bounds error for an index that does not exist - if index > type_tuple.len() { - return Err(ExpressionError::invalid_index_tuple( - index, - type_tuple.len(), - span.clone(), - )); - } - - let type_ = type_tuple[index].clone(); - - // Check that expected type matches - Type::check_type(&expected_type, &type_, span.clone())?; - - Ok(Expression { - type_, - value: ExpressionValue::TupleAccess(Box::new(tuple_resolved), index, span), - }) - } -} diff --git a/dynamic-check/src/ast/expressions/values/address.rs b/dynamic-check/src/ast/expressions/values/address.rs deleted file mode 100644 index 7ae85019e4..0000000000 --- a/dynamic-check/src/ast/expressions/values/address.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::Type; -use leo_typed::Span; - -impl Expression { - /// - /// Returns a new address `Expression` from a given type and address string. - /// - pub(crate) fn address(type_: &Type, address_string: String, span: Span) -> Self { - Expression { - type_: type_.clone(), - value: ExpressionValue::Address(address_string, span), - } - } -} diff --git a/dynamic-check/src/ast/expressions/values/boolean.rs b/dynamic-check/src/ast/expressions/values/boolean.rs deleted file mode 100644 index 8ffd41ae0e..0000000000 --- a/dynamic-check/src/ast/expressions/values/boolean.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::Type; -use leo_typed::Span; - -impl Expression { - /// - /// Returns a new boolean expression from a given type and boolean string. - /// - pub(crate) fn boolean(type_: &Type, boolean_string: String, span: Span) -> Self { - Expression { - type_: type_.clone(), - value: ExpressionValue::Boolean(boolean_string, span), - } - } -} diff --git a/dynamic-check/src/ast/expressions/values/field.rs b/dynamic-check/src/ast/expressions/values/field.rs deleted file mode 100644 index 1f23db1cf4..0000000000 --- a/dynamic-check/src/ast/expressions/values/field.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionValue}; -use leo_static_check::Type; -use leo_typed::Span; - -impl Expression { - /// - /// Returns a new field expression from a given type and field string. - /// - pub(crate) fn field(type_: &Type, field_string: String, span: Span) -> Self { - Expression { - type_: type_.clone(), - value: ExpressionValue::Field(field_string, span), - } - } -} diff --git a/dynamic-check/src/ast/expressions/values/group.rs b/dynamic-check/src/ast/expressions/values/group.rs deleted file mode 100644 index b51db3467a..0000000000 --- a/dynamic-check/src/ast/expressions/values/group.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::Type; -use leo_typed::GroupValue; - -impl Expression { - /// - /// Returns a new group `Expression` from the given type and group value. - /// - pub(crate) fn group(type_: &Type, group_value: GroupValue) -> Self { - Expression { - type_: type_.clone(), - value: ExpressionValue::Group(group_value), - } - } -} diff --git a/dynamic-check/src/ast/expressions/values/implicit.rs b/dynamic-check/src/ast/expressions/values/implicit.rs deleted file mode 100644 index 8c0189281d..0000000000 --- a/dynamic-check/src/ast/expressions/values/implicit.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::Type; -use leo_typed::{GroupValue, Span}; - -impl Expression { - /// - /// Returns a new `Expression` from a given type and implicit number string. - /// - pub(crate) fn implicit(type_: &Type, implicit_string: String, span: Span) -> Result { - let value = match &type_ { - Type::Address => ExpressionValue::Address(implicit_string, span), - Type::Boolean => ExpressionValue::Boolean(implicit_string, span), - Type::Field => ExpressionValue::Field(implicit_string, span), - Type::Group => ExpressionValue::Group(GroupValue::Single(implicit_string, span)), - Type::IntegerType(integer_type) => ExpressionValue::Integer(integer_type.clone(), implicit_string, span), - Type::Array(_type, _dimensions) => unimplemented!("ERROR: Arrays cannot be implicit"), - Type::Tuple(_types) => unimplemented!("ERROR: Tuples cannot be implicit"), - Type::Function(_name) => unimplemented!("ERROR: Functions cannot be implicit"), - Type::Circuit(_name) => unimplemented!("ERROR: Circuits cannot be implicit"), - Type::TypeVariable(_name) => unimplemented!("ERROR: Type variables not implemented"), - }; - - Ok(Expression { - type_: type_.clone(), - value, - }) - } -} diff --git a/dynamic-check/src/ast/expressions/values/integer.rs b/dynamic-check/src/ast/expressions/values/integer.rs deleted file mode 100644 index 57d2c73df7..0000000000 --- a/dynamic-check/src/ast/expressions/values/integer.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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 . - -use crate::{Expression, ExpressionError, ExpressionValue}; -use leo_static_check::Type; -use leo_typed::{IntegerType, Span}; - -impl Expression { - /// - /// Returns a new integer `Expression` from a given type, integer type, and integer string. - /// - pub(crate) fn integer(type_: &Type, integer_type: IntegerType, integer_string: String, span: Span) -> Self { - Expression { - type_: type_.clone(), - value: ExpressionValue::Integer(integer_type, integer_string, span), - } - } -} diff --git a/dynamic-check/src/ast/expressions/values/mod.rs b/dynamic-check/src/ast/expressions/values/mod.rs deleted file mode 100644 index fbc8b53bd0..0000000000 --- a/dynamic-check/src/ast/expressions/values/mod.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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 . - -pub mod address; -pub use self::address::*; - -pub mod boolean; -pub use self::boolean::*; - -pub mod field; -pub use self::field::*; - -pub mod group; -pub use self::group::*; - -pub mod implicit; -pub use self::implicit::*; - -pub mod integer; -pub use self::integer::*; diff --git a/dynamic-check/src/ast/functions/function.rs b/dynamic-check/src/ast/functions/function.rs deleted file mode 100644 index 37c87c217d..0000000000 --- a/dynamic-check/src/ast/functions/function.rs +++ /dev/null @@ -1,104 +0,0 @@ -// 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 . - -use crate::{Frame, FunctionError, ResolvedNode, Statement, StatementError, VariableTable}; -use leo_static_check::{FunctionType, SymbolTable, TypeError}; -use leo_typed::{Function as UnresolvedFunction, Statement as UnresolvedStatement}; - -use serde::{Deserialize, Serialize}; - -/// A function in a resolved syntax tree. -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct Function { - /// The user-defined type of this function. - pub function_type: FunctionType, - - /// The function statements. - pub statements: Vec, -} - -impl Function { - /// - /// Returns a new `Function` from a given `FunctionBody`. - /// - /// Performs a lookup in the given function body's variable table if the statement contains - /// user-defined types.. - /// - pub fn new(function_body: Frame) -> Result { - // Create a new `Statement` from every given `UnresolvedStatement`. - let statements = function_body - .statements - .clone() - .into_iter() - .map(|unresolved_statement| Statement::new(&function_body, unresolved_statement)) - .collect::, StatementError>>()?; - - Ok(Function { - function_type: function_body.function_type, - statements, - }) - } -} - -impl ResolvedNode for Function { - type Error = FunctionError; - type UnresolvedNode = UnresolvedFunction; - - /// - /// Return a new `Function` from a given `UnresolvedFunction`. - /// - /// Performs a lookup in the given symbol table if the function contains user-defined types. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - // Lookup function identifier in symbol table - let identifier = unresolved.identifier; - - // Throw an error if the function does not exist - let type_ = table - .get_function(&identifier.name) - .ok_or(FunctionError::TypeError(TypeError::undefined_function(identifier)))? - .clone(); - - // // Create function context - // let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); - - // Insert function input types into the symbol table - for input in type_.inputs.clone() { - let exists = input.insert(table); - - // Throw an error if two function inputs have been defined with the same name - if exists.is_some() { - return Err(FunctionError::duplicate_input(input.identifier().clone())); - } - } - - // Pass expected function output to resolved statements - let output = type_.output.clone(); - let mut statements = vec![]; - - // Resolve all function statements - for (_i, statement) in unresolved.statements.into_iter().enumerate() { - let statement = Statement::resolve(table, (output.clone(), statement))?; - - statements.push(statement); - } - - Ok(Function { - function_type: type_, - statements, - }) - } -} diff --git a/dynamic-check/src/ast/functions/mod.rs b/dynamic-check/src/ast/functions/mod.rs deleted file mode 100644 index db7036b538..0000000000 --- a/dynamic-check/src/ast/functions/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 . - -pub mod function; -pub use self::function::*; - -pub mod test_function; -pub use self::test_function::*; diff --git a/dynamic-check/src/ast/functions/test_function.rs b/dynamic-check/src/ast/functions/test_function.rs deleted file mode 100644 index 1259a6be43..0000000000 --- a/dynamic-check/src/ast/functions/test_function.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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 . - -use crate::{Function, FunctionError, ResolvedNode}; -use leo_static_check::SymbolTable; -use leo_typed::{Identifier, TestFunction as UnresolvedTestFunction}; - -use serde::{Deserialize, Serialize}; - -/// A test function in a resolved syntax tree. -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct TestFunction { - /// The test function. - pub function: Function, - /// The custom test input file. - pub input_file: Option, -} - -impl ResolvedNode for TestFunction { - type Error = FunctionError; - type UnresolvedNode = UnresolvedTestFunction; - - /// - /// Return a new `TestFunction` from a given `UnresolvedTestFunction`. - /// - /// Performs a lookup in the given symbol table if the test function contains user-defined types. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - Ok(TestFunction { - function: Function::resolve(table, unresolved.function).unwrap(), - input_file: unresolved.input_file, - }) - } -} diff --git a/dynamic-check/src/ast/imports/import.rs b/dynamic-check/src/ast/imports/import.rs deleted file mode 100644 index 8223b64184..0000000000 --- a/dynamic-check/src/ast/imports/import.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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 . - -use crate::ResolvedNode; -use leo_static_check::SymbolTable; -use leo_typed::Import as UnresolvedImport; - -use serde::{Deserialize, Serialize}; - -/// An import in a resolved syntax tree. -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct Import {} - -impl ResolvedNode for Import { - type Error = (); - type UnresolvedNode = UnresolvedImport; - - /// - /// Return a new `Import` from a given `UnresolvedImport`. - /// - /// Performs a lookup in the given symbol table if the import contains user-defined types. - /// - fn resolve(_table: &mut SymbolTable, _resolved: Self::UnresolvedNode) -> Result { - Ok(Import {}) - } -} diff --git a/dynamic-check/src/ast/imports/mod.rs b/dynamic-check/src/ast/imports/mod.rs deleted file mode 100644 index 9f45af0270..0000000000 --- a/dynamic-check/src/ast/imports/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod import; -pub use self::import::*; diff --git a/dynamic-check/src/ast/mod.rs b/dynamic-check/src/ast/mod.rs deleted file mode 100644 index 8195841282..0000000000 --- a/dynamic-check/src/ast/mod.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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 . - -pub mod ast; -pub use self::ast::*; - -pub mod circuits; -pub use self::circuits::*; - -pub mod console; -pub use self::console::*; - -pub mod expressions; -pub use self::expressions::*; - -pub mod functions; -pub use self::functions::*; - -pub mod imports; -pub use self::imports::*; - -pub mod programs; -pub use self::programs::*; - -pub mod statements; -pub use self::statements::*; diff --git a/dynamic-check/src/ast/programs/mod.rs b/dynamic-check/src/ast/programs/mod.rs deleted file mode 100644 index 86fb38e5ab..0000000000 --- a/dynamic-check/src/ast/programs/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod program; -pub use self::program::*; diff --git a/dynamic-check/src/ast/programs/program.rs b/dynamic-check/src/ast/programs/program.rs deleted file mode 100644 index 3d8a18e2b9..0000000000 --- a/dynamic-check/src/ast/programs/program.rs +++ /dev/null @@ -1,95 +0,0 @@ -// 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 . - -use crate::{Circuit, Function, ProgramError, ResolvedNode, TestFunction}; -use leo_static_check::SymbolTable; -use leo_typed::{Identifier, Program as UnresolvedProgram}; - -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; - -pub static MAIN_FUNCTION_NAME: &str = "main"; - -/// The root of the resolved syntax tree. -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct Program { - // pub imports: Vec, - pub circuits: HashMap, - pub functions: HashMap, - pub tests: HashMap, -} - -impl ResolvedNode for Program { - type Error = ProgramError; - type UnresolvedNode = UnresolvedProgram; - - /// - /// Returns a `Program` given an `UnresolvedProgram` AST. - /// - /// At each AST node: - /// 1. Resolve all child AST nodes. - /// 2. Resolve current AST node. - /// - /// Performs a lookup in the given symbol table if the function contains user-defined types. - /// - fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result { - let mut circuits = HashMap::new(); - let mut functions = HashMap::new(); - let mut tests = HashMap::new(); - - // TODO: Resolve import statements - - // Resolve circuit definitions - for (identifier, circuit) in unresolved.circuits { - let resolved_circuit = Circuit::resolve(table, circuit)?; - - circuits.insert(identifier, resolved_circuit); - } - - // Resolve function statements - for (identifier, function) in unresolved.functions { - let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); - let resolved_function = Function::resolve(&mut child_table, function)?; - - functions.insert(identifier, resolved_function); - } - - // Resolve tests - for (identifier, test) in unresolved.tests { - let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); - let resolved_test = TestFunction::resolve(&mut child_table, test)?; - - tests.insert(identifier, resolved_test); - } - - // Look for main function - // let main = unresolved.functions.into_iter().find(|(identifier, _)| { - // identifier.name.eq(MAIN_FUNCTION_NAME) - // }); - // - // //TODO: return no main function error - // let program = match main { - // Some((_identifier, function)) => , - // None => unimplemented!("ERROR: main function not found"), - // } - - Ok(Program { - circuits, - functions, - tests, - }) - } -} diff --git a/dynamic-check/src/ast/statements/assign/assign.rs b/dynamic-check/src/ast/statements/assign/assign.rs deleted file mode 100644 index 0b28b92b7c..0000000000 --- a/dynamic-check/src/ast/statements/assign/assign.rs +++ /dev/null @@ -1,97 +0,0 @@ -// 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 . - -use crate::{Expression, Frame, ResolvedNode, Statement, StatementError, VariableTable}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{Assignee, AssigneeAccess, Expression as UnresolvedExpression, Span}; - -use serde::{Deserialize, Serialize}; - -/// A statement that assigns `Assignee = Expression;`. -/// Checks that the expression resolves to the assignee's type -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct Assign { - pub assignee: Assignee, - pub expression: Expression, - pub span: Span, -} - -// impl Statement { -// /// -// /// Resolves an assign statement -// /// -// pub(crate) fn assign( -// frame: &Frame, -// assignee: Assignee, -// expression: UnresolvedExpression, -// span: Span, -// ) -> Result { -// // Lookup variable in symbol table -// let key = &assignee.identifier.name; -// let variable = frame.variable_table.get(key, &span)?; -// -// // Throw an error if this variable is not mutable -// if !variable.is_mutable() { -// return Err(StatementError::immutable_assign(variable.identifier.name.clone(), span)); -// } -// -// // Get inner assignee type -// let type_ = get_inner_assignee_type(frame, variable.type_.clone(), assignee.accesses.clone(), span.clone())?; -// -// // Resolve the expression based on the assignee type -// let expression_resolved = Expression::new(variable_table, (Some(type_), expression))?; -// -// Ok(Statement::Assign(Assign { -// assignee, -// expression: expression_resolved, -// span, -// })) -// } -// } -// -// /// -// /// Accesses the inner type of an assignee such as an array, tuple, or circuit member. -// /// Returns an error for invalid accesses. -// /// -// fn get_inner_assignee_type( -// frame: &Frame, -// type_: Type, -// accesses: Vec, -// span: Span, -// ) -> Result { -// match accesses.first() { -// None => Ok(type_), -// Some(access) => { -// // Check that we are correctly accessing the type -// let next_type = match (&type_, access) { -// (Type::Array(next_type, _), AssigneeAccess::Array(_)) => *next_type.clone(), -// (Type::Tuple(types), AssigneeAccess::Tuple(index)) => types[*index].clone(), -// (Type::Circuit(identifier), AssigneeAccess::Member(member)) => { -// let circuit_type_option = frame.get_circuit(&identifier.name); -// -// let circuit_type = match circuit_type_option { -// Some(circuit_type) => circuit_type, -// None => return Err(StatementError::undefined_circuit(identifier.clone())), -// }; -// circuit_type.member_type(member)?.clone() -// } -// (type_, _) => return Err(StatementError::invalid_assign(type_, span)), -// }; -// -// return get_inner_assignee_type(frame, next_type, accesses[1..].to_vec(), span); -// } -// } -// } diff --git a/dynamic-check/src/ast/statements/assign/mod.rs b/dynamic-check/src/ast/statements/assign/mod.rs deleted file mode 100644 index 5236b5fc8e..0000000000 --- a/dynamic-check/src/ast/statements/assign/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod assign; -pub use self::assign::*; diff --git a/dynamic-check/src/ast/statements/conditional/conditional.rs b/dynamic-check/src/ast/statements/conditional/conditional.rs deleted file mode 100644 index 7225fa7ea4..0000000000 --- a/dynamic-check/src/ast/statements/conditional/conditional.rs +++ /dev/null @@ -1,128 +0,0 @@ -// 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 . - -use crate::{Expression, Frame, ResolvedNode, Statement, StatementError}; -use leo_static_check::{FunctionOutputType, SymbolTable, Type}; -use leo_typed::{ - ConditionalNestedOrEndStatement as UnresolvedNestedOrEnd, ConditionalStatement as UnresolvedConditional, Span, - Statement as UnresolvedStatement, -}; - -use serde::{Deserialize, Serialize}; - -/// A nested `else if` or an ending `else` clause -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum ConditionalNestedOrEndStatement { - Nested(Box), - End(Vec), -} - -/// An `if else` statement with resolved inner statements -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct Conditional { - pub condition: Expression, - pub statements: Vec, - pub next: Option, - pub span: Span, -} - -// impl Conditional { -// /// -// /// Resolves a conditional statement. -// /// -// pub(crate) fn from_unresolved( -// table: &mut SymbolTable, -// return_type: FunctionOutputType, -// conditional: UnresolvedConditional, -// span: Span, -// ) -> Result { -// // Create child symbol table. -// let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); -// -// // Resolve the condition to a boolean. -// let type_boolean = Some(Type::Boolean); -// let condition_resolved = Expression::resolve(&mut child_table, (type_boolean, conditional.condition))?; -// -// // Resolve all statements. -// let statements_resolved = resolve_statements(&mut child_table, return_type.clone(), conditional.statements)?; -// -// // Check for an `else if` or `else` clause. -// let nested_or_end = match conditional.next { -// Some(nested_or_end) => nested_or_end, -// None => { -// return Ok(Conditional { -// condition: condition_resolved, -// statements: statements_resolved, -// next: None, -// span, -// }); -// } -// }; -// -// // Evaluate the `else if` or `else` clause. -// let next_resolved = match nested_or_end { -// UnresolvedNestedOrEnd::Nested(conditional) => { -// // Type check the `else if` clause. -// let conditional_resolved = -// Self::from_unresolved(table, return_type.clone(), *conditional, span.clone())?; -// -// ConditionalNestedOrEndStatement::Nested(Box::new(conditional_resolved)) -// } -// UnresolvedNestedOrEnd::End(statements) => { -// // Create child symbol table. -// let mut child_table = SymbolTable::new(Some(Box::new(table.clone()))); -// -// // Type check the `else` clause. -// let statements_resolved = resolve_statements(&mut child_table, return_type, statements)?; -// -// ConditionalNestedOrEndStatement::End(statements_resolved) -// } -// }; -// -// Ok(Conditional { -// condition: condition_resolved, -// statements: statements_resolved, -// next: Some(next_resolved), -// span, -// }) -// } -// } - -// /// Resolve an array of statements. -// fn resolve_statements( -// table: &mut SymbolTable, -// return_type: FunctionOutputType, -// statements: Vec, -// ) -> Result, StatementError> { -// Ok(statements -// .into_iter() -// .map(|statement| Statement::resolve(table, (return_type.clone(), statement))) -// .collect::, _>>()?) -// } - -// impl Statement { -// /// Resolves a conditional statement. -// pub(crate) fn conditional( -// function_body: &Frame, -// return_type: FunctionOutputType, -// conditional: UnresolvedConditional, -// span: Span, -// ) -> Result { -// let conditional = Conditional::from_unresolved(function_body, return_type, conditional, span)?; -// -// Ok(Statement::Conditional(conditional)) -// } -// } diff --git a/dynamic-check/src/ast/statements/conditional/mod.rs b/dynamic-check/src/ast/statements/conditional/mod.rs deleted file mode 100644 index e7a9ed3b86..0000000000 --- a/dynamic-check/src/ast/statements/conditional/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod conditional; -pub use self::conditional::*; diff --git a/dynamic-check/src/ast/statements/definition/definition.rs b/dynamic-check/src/ast/statements/definition/definition.rs deleted file mode 100644 index ca4815347f..0000000000 --- a/dynamic-check/src/ast/statements/definition/definition.rs +++ /dev/null @@ -1,238 +0,0 @@ -// 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 . - -use crate::{ - check_tuple_type, Expression, ExpressionValue, Frame, ResolvedNode, Statement, StatementError, VariableTable, - VariableTableError, -}; -use leo_static_check::{Attribute, ParameterType, SymbolTable, Type}; -use leo_typed::{Declare, Expression as UnresolvedExpression, Span, VariableName, Variables}; - -use serde::{Deserialize, Serialize}; - -/// A `let` or `const` definition statement. -/// Defines one or more variables with resolved types. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct Definition { - pub declare: Declare, - pub variables: DefinitionVariables, - pub span: Span, -} - -/// One or more variables with resolved types. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum DefinitionVariables { - Single(VariableName, Expression), - Tuple(VariableName, Expression), - MultipleVariable(Vec, Vec), - MultipleVariableTuple(Vec, Expression), -} - -impl DefinitionVariables { - /// - /// Returns a new statement that defines a single variable with a single expression. - /// - /// Performs a lookup in the given variable table if the `UnresolvedExpression` contains user-defined variables. - /// - fn single( - function_body: &Frame, - variable_name: VariableName, - unresolved_expression: UnresolvedExpression, - span: &Span, - ) -> Result { - // Get the type of the variable. - let type_ = function_body.variable_table.get(variable_name.name_string(), span)?; - - // Create a new `Expression` from the given `UnresolvedExpression`. - let expression = Expression::new(function_body, type_, unresolved_expression)?; - - Ok(DefinitionVariables::Single(variable_name, expression)) - } - - /// - /// Returns a new statement that defines a tuple (single variable with multiple expressions). - /// - /// Performs a lookup in the given variable table if an `UnresolvedExpression` contains user-defined variables. - /// - fn tuple( - function_body: &Frame, - variable: VariableName, - unresolved_expressions: Vec, - span: &Span, - ) -> Result { - // Get the type of the variable. - let type_ = function_body.variable_table.get(variable.name_string(), span)?; - - // Create a new tuple of `Expression`s from the given vector of `UnresolvedExpression's. - let tuple = Expression::tuple(function_body, type_, unresolved_expressions, span.clone())?; - - Ok(DefinitionVariables::Tuple(variable, tuple)) - } - - /// Resolves multiple variables for multiple expressions - fn multiple_variable( - function_body: &Frame, - variables: Variables, - unresolved_expressions: Vec, - span: &Span, - ) -> Result { - // Check number of variables == expressions - if variables.names.len() != unresolved_expressions.len() { - return Err(StatementError::multiple_variable_expressions( - variables.names.len(), - unresolved_expressions.len(), - span, - )); - } - - // Get the type of each variable. - let variable_types: Vec = variables - .names - .iter() - .map(|variable_name| function_body.variable_table.get(variable_name.name_string(), span)) - .collect::, VariableTableError>>()? - .into_iter() - .map(|type_ref| type_ref.clone()) - .collect(); - - // Create a new vector of `Expression`s from the given vector of `UnresolvedExpression`s. - let mut expressions_resolved = vec![]; - - for (unresolved_expression, variable_type) in unresolved_expressions.into_iter().zip(variable_types) { - let expression_resolved = Expression::new(function_body, &variable_type, unresolved_expression)?; - - expressions_resolved.push(expression_resolved); - } - - Ok(DefinitionVariables::MultipleVariable( - variables.names, - expressions_resolved, - )) - } - - /// Resolves multiple variables for an expression that returns a tuple - fn multiple_variable_tuple( - function_body: &Frame, - variables: Variables, - unresolved_expression: UnresolvedExpression, - span: &Span, - ) -> Result { - // Get the type of each variable. - let variable_types: Vec = variables - .names - .iter() - .map(|variable_name| function_body.variable_table.get(variable_name.name_string(), span)) - .collect::, VariableTableError>>()? - .into_iter() - .map(|type_ref| type_ref.clone()) - .collect(); - - // Create a new tuple type from the vector of variable types. - let tuple_type = Type::Tuple(variable_types); - - // Create a new `Expression` from the given `UnresolvedExpression`. - // This expression should return a tuple. - let expression = Expression::new(function_body, &tuple_type, unresolved_expression)?; - - Ok(DefinitionVariables::MultipleVariableTuple(variables.names, expression)) - } -} - -// /// Inserts a variable definition into the given symbol table -// fn insert_defined_variable( -// table: &mut SymbolTable, -// variable: &VariableName, -// type_: &Type, -// span: Span, -// ) -> Result<(), StatementError> { -// let attributes = if variable.mutable { -// vec![Attribute::Mutable] -// } else { -// vec![] -// }; -// -// // Insert variable into symbol table -// let key = variable.identifier.name.clone(); -// let value = ParameterType { -// identifier: variable.identifier.clone(), -// type_: type_.clone(), -// attributes, -// }; -// -// // Check that variable name was not defined twice -// let duplicate = table.insert_name(key, value); -// -// if duplicate.is_some() { -// return Err(StatementError::duplicate_variable( -// variable.identifier.name.clone(), -// span, -// )); -// } -// -// Ok(()) -// } - -impl Statement { - /// - /// Returns a new `let` or `const` definition statement from a given `UnresolvedExpression`. - /// - /// Performs a lookup in the given variable table if the statement contains user-defined variables. - /// - pub(crate) fn definition( - function_body: &Frame, - declare: Declare, - variables: Variables, - unresolved_expressions: Vec, - span: Span, - ) -> Result { - let num_variables = variables.names.len(); - let num_values = unresolved_expressions.len(); - - let variables = if num_variables == 1 && num_values == 1 { - // Define a single variable with a single value - - DefinitionVariables::single( - function_body, - variables.names[0].clone(), - unresolved_expressions[0].clone(), - &span, - ) - } else if num_variables == 1 && num_values > 1 { - // Define a tuple (single variable with multiple values) - - DefinitionVariables::tuple(function_body, variables.names[0].clone(), unresolved_expressions, &span) - } else if num_variables > 1 && num_values == 1 { - // Define multiple variables for an expression that returns a tuple - - DefinitionVariables::multiple_variable_tuple( - function_body, - variables, - unresolved_expressions[0].clone(), - &span, - ) - } else { - // Define multiple variables for multiple expressions - - DefinitionVariables::multiple_variable(function_body, variables, unresolved_expressions, &span) - }?; - - Ok(Statement::Definition(Definition { - declare, - variables, - span, - })) - } -} diff --git a/dynamic-check/src/ast/statements/definition/mod.rs b/dynamic-check/src/ast/statements/definition/mod.rs deleted file mode 100644 index 2b20761620..0000000000 --- a/dynamic-check/src/ast/statements/definition/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod definition; -pub use self::definition::*; diff --git a/dynamic-check/src/ast/statements/iteration/iteration.rs b/dynamic-check/src/ast/statements/iteration/iteration.rs deleted file mode 100644 index 9365b7aa9d..0000000000 --- a/dynamic-check/src/ast/statements/iteration/iteration.rs +++ /dev/null @@ -1,75 +0,0 @@ -// 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 . -use crate::{Expression, ResolvedNode, Statement, StatementError}; -use leo_static_check::{FunctionOutputType, ParameterType, SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, Identifier, IntegerType, Span, Statement as UnresolvedStatement}; - -use serde::{Deserialize, Serialize}; - -/// A resolved iteration statement -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct Iteration { - pub index: Identifier, - pub start: Expression, - pub stop: Expression, - pub statements: Vec, - pub span: Span, -} - -// impl Statement { -// /// Resolve an iteration statement -// pub(crate) fn iteration( -// table: &mut SymbolTable, -// return_type: FunctionOutputType, -// index: Identifier, -// start: UnresolvedExpression, -// stop: UnresolvedExpression, -// statements: Vec, -// span: Span, -// ) -> Result { -// // TODO: Create child symbol table and add variables from parent -// -// // Resolve index numbers to a u32 type -// let type_number = Type::IntegerType(IntegerType::U32); -// -// let start_resolved = Expression::resolve(table, (Some(type_number.clone()), start))?; -// let stop_resolved = Expression::resolve(table, (Some(type_number.clone()), stop))?; -// -// // Add index to symbol table -// let key = index.name.clone(); -// let value = ParameterType { -// identifier: index.clone(), -// type_: type_number, -// attributes: vec![], -// }; -// -// table.insert_name(key, value); -// -// // Resolve statements -// let statements_resolved = statements -// .into_iter() -// .map(|statement| Statement::resolve(table, (return_type.clone(), statement))) -// .collect::, _>>()?; -// -// Ok(Statement::Iteration(Iteration { -// index, -// start: start_resolved, -// stop: stop_resolved, -// statements: statements_resolved, -// span, -// })) -// } -// } diff --git a/dynamic-check/src/ast/statements/iteration/mod.rs b/dynamic-check/src/ast/statements/iteration/mod.rs deleted file mode 100644 index d37c83519b..0000000000 --- a/dynamic-check/src/ast/statements/iteration/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod iteration; -pub use self::iteration::*; diff --git a/dynamic-check/src/ast/statements/mod.rs b/dynamic-check/src/ast/statements/mod.rs deleted file mode 100644 index ff0e53541a..0000000000 --- a/dynamic-check/src/ast/statements/mod.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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 . - -pub mod assign; -pub use self::assign::*; - -pub mod conditional; -pub use self::conditional::*; - -pub mod definition; -pub use self::definition::*; - -pub mod iteration; -pub use self::iteration::*; - -pub mod return_; -pub use self::return_::*; - -pub mod statement; -pub use self::statement::*; diff --git a/dynamic-check/src/ast/statements/return_/mod.rs b/dynamic-check/src/ast/statements/return_/mod.rs deleted file mode 100644 index a58752e3b2..0000000000 --- a/dynamic-check/src/ast/statements/return_/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod return_; -pub use self::return_::*; diff --git a/dynamic-check/src/ast/statements/return_/return_.rs b/dynamic-check/src/ast/statements/return_/return_.rs deleted file mode 100644 index ef08de01c3..0000000000 --- a/dynamic-check/src/ast/statements/return_/return_.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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 . - -use crate::{Expression, Frame, ResolvedNode, Statement, StatementError, VariableTable}; -use leo_static_check::{SymbolTable, Type}; -use leo_typed::{Expression as UnresolvedExpression, Span}; - -impl Statement { - /// - /// Returns a new return statement from a given `UnresolvedExpression`. - /// - /// Performs a lookup in the given variable table if the statement contains user-defined types. - /// - pub(crate) fn resolve_return( - function_body: &Frame, - unresolved_expression: UnresolvedExpression, - span: Span, - ) -> Result { - // Get function return type from frame. - let return_type = &function_body.function_type.output.type_; - - // Create a new `Expression` from the unresolved return expression - let expression = Expression::new(function_body, return_type, unresolved_expression)?; - - Ok(Statement::Return(expression, span)) - } -} diff --git a/dynamic-check/src/ast/statements/statement.rs b/dynamic-check/src/ast/statements/statement.rs deleted file mode 100644 index f012b5bc20..0000000000 --- a/dynamic-check/src/ast/statements/statement.rs +++ /dev/null @@ -1,96 +0,0 @@ -// 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 . -use crate::{ - Assign, Conditional, Definition, Expression, Frame, Iteration, ResolvedNode, StatementError, VariableTable, -}; -use leo_static_check::{FunctionOutputType, FunctionType, SymbolTable}; -use leo_typed::{ConsoleFunctionCall, Span, Statement as UnresolvedStatement}; - -use serde::{Deserialize, Serialize}; - -/// Stores a type-checked statement in a Leo program -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub enum Statement { - Return(Expression, Span), - Definition(Definition), - Assign(Assign), - Conditional(Conditional), - Iteration(Iteration), - Console(ConsoleFunctionCall), - Expression(Expression, Span), -} - -impl Statement { - /// - /// Returns a new `Statement` from a given `UnresolvedStatement`. - /// - /// Performs a lookup in the given function body's variable table if the statement contains - /// user-defined types. - /// - pub fn new(frame: &Frame, unresolved_statement: UnresolvedStatement) -> Result { - match unresolved_statement { - UnresolvedStatement::Return(expression, span) => Self::resolve_return(frame, expression, span), - UnresolvedStatement::Definition(declare, variables, expressions, span) => { - Self::definition(frame, declare, variables, expressions, span) - } - // UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(frame, assignee, expression, span), - // UnresolvedStatement::Conditional(conditional, span) => { - // Self::conditional(frame, return_type, conditional, span) - // } - // UnresolvedStatement::Iteration(index, start, stop, statements, span) => { - // Self::iteration(frame, return_type, index, start, stop, statements, span) - // } - // UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)), - // UnresolvedStatement::Expression(expression, span) => { - // Ok(Statement::Expression(Expression::new(frame, expression)?, span)) - // } - _ => unimplemented!("statement not implemented"), - } - } -} - -impl ResolvedNode for Statement { - type Error = StatementError; - type UnresolvedNode = (FunctionOutputType, UnresolvedStatement); - - /// Type check a statement inside a program AST - fn resolve(_table: &mut SymbolTable, _unresolved: Self::UnresolvedNode) -> Result { - // let return_type = unresolved.0; - // let statement = unresolved.1; - // - // match statement { - // // UnresolvedStatement::Return(expression, span) => { - // // Self::resolve_return(table, return_type.type_, expression, span) - // // } - // // UnresolvedStatement::Definition(declare, variables, expressions, span) => { - // // Self::definition(table, declare, variables, expressions, span) - // // } - // // UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(table, assignee, expression, span), - // // UnresolvedStatement::Conditional(conditional, span) => { - // // Self::conditional(table, return_type, conditional, span) - // // } - // // UnresolvedStatement::Iteration(index, start, stop, statements, span) => { - // // Self::iteration(table, return_type, index, start, stop, statements, span) - // // } - // // UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)), - // // UnresolvedStatement::Expression(expression, span) => Ok(Statement::Expression( - // // Expression::resolve(table, (None, expression))?, - // // span, - // // )), - // } - unimplemented!("statement resolve deprecated"); - } -} diff --git a/dynamic-check/src/lib.rs b/dynamic-check/src/lib.rs index 930adca205..1590b58772 100644 --- a/dynamic-check/src/lib.rs +++ b/dynamic-check/src/lib.rs @@ -17,9 +17,6 @@ #[macro_use] extern crate thiserror; -// pub mod ast; -// pub use self::ast::*; - pub mod dynamic_check; pub use self::dynamic_check::*; From 84861dde32213919db3306c77283eacde70de389 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 17:57:37 -0700 Subject: [PATCH 072/139] remove more unused code --- dynamic-check/src/dynamic_check.rs | 51 +----------------------------- 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 8790d86534..3a6cdaee77 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -34,7 +34,6 @@ use leo_typed::{ CircuitVariableDefinition, ConditionalNestedOrEndStatement, ConditionalStatement, - ConsoleFunctionCall, Declare, Expression, Function, @@ -404,7 +403,7 @@ impl Frame { self.parse_iteration(identifier, from, to, statements, span) } Statement::Expression(expression, span) => self.parse_statement_expression(expression, span), - Statement::Console(console_call) => self.parse_console_function_call(console_call), + Statement::Console(_console_call) => Ok(()), // Console function calls do not generate type assertions. } } @@ -635,14 +634,6 @@ impl Frame { Ok(()) } - /// - /// Collects `TypeAssertion` predicates from a console statement. - /// - fn parse_console_function_call(&mut self, _console_function_call: &ConsoleFunctionCall) -> Result<(), FrameError> { - // TODO (collinc97) find a way to fetch console function call types here - Ok(()) - } - /// /// Returns the type of an expression. /// @@ -1313,22 +1304,6 @@ impl Frame { } } } - - // Solve the `TypeAssertion`. - // - // If the `TypeAssertion` has a solution, then continue the loop. - // If the `TypeAssertion` returns a `TypeVariablePair`, then substitute the `TypeVariable` - // for it's paired `Type` in all `TypeAssertion`s. - // if let Some(pair) = type_assertion.solve()? { - // // Substitute the `TypeVariable` for it's paired `Type` in all `TypeAssertion`s. - // for original in &mut unsolved { - // original.substitute(&pair.0, &pair.1) - // } - // - // for original in &mut unsolved_membership { - // original.substitute(&pair.0, &pair.1) - // } - // }; } // Solve all type membership assertions. @@ -1340,18 +1315,6 @@ impl Frame { type_assertion.evaluate()?; } - // for type_assertion in unsolved.pop() { - // if let Some((type_variable, type_)) = type_assertion.get_substitute() { - // // Substitute type variable in unsolved type assertions - // for mut original in unsolved { - // original.substitute(type_variable, type_) - // } - // } - // } - - // Return a new resolved function struct. - // Function::new(self) - Ok(()) } } @@ -1575,18 +1538,6 @@ impl TypeMembership { )) } } - - /// - /// Returns the (type variable, type) pair from this assertion. - /// - pub fn get_pair(&self) -> Option<(TypeVariable, Type)> { - // match (&self.left, &self.right) { - // (Type::TypeVariable(variable), type_) => Some((variable.clone(), type_.clone())), - // (type_, Type::TypeVariable(variable)) => Some((variable.clone(), type_.clone())), - // (_type1, _type2) => None, // No (type variable, type) pair can be returned from two types - // } - unimplemented!() - } } /// A predicate that evaluates equality between two `Type`s. From d3125a0f9fcfbc903e6eb72eea740574510c936d Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 18:41:51 -0700 Subject: [PATCH 073/139] add new dynamic check errors and tests for variables --- compiler/tests/statements/ternary_basic.leo | 2 +- dynamic-check/src/dynamic_check.rs | 25 ++++++---- dynamic-check/src/errors/dynamic_check.rs | 16 ------ dynamic-check/src/errors/frame.rs | 48 ++++++++++++++---- dynamic-check/tests/mod.rs | 28 ++++++++--- .../tests/variables/duplicate_variable.leo | 4 ++ .../variables/duplicate_variable_multi.leo | 3 ++ dynamic-check/tests/variables/mod.rs | 49 +++++++++++++++++++ .../tests/variables/not_enough_values.leo | 3 ++ .../tests/variables/too_many_values.leo | 3 ++ 10 files changed, 137 insertions(+), 44 deletions(-) create mode 100644 dynamic-check/tests/variables/duplicate_variable.leo create mode 100644 dynamic-check/tests/variables/duplicate_variable_multi.leo create mode 100644 dynamic-check/tests/variables/mod.rs create mode 100644 dynamic-check/tests/variables/not_enough_values.leo create mode 100644 dynamic-check/tests/variables/too_many_values.leo diff --git a/compiler/tests/statements/ternary_basic.leo b/compiler/tests/statements/ternary_basic.leo index 89158a3e78..5106363ce2 100644 --- a/compiler/tests/statements/ternary_basic.leo +++ b/compiler/tests/statements/ternary_basic.leo @@ -1,5 +1,5 @@ function main(a: bool, b: bool) { let c = if a ? true : false; - const a = c == b; + const d = c == b; } \ No newline at end of file diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 3a6cdaee77..c6645e24c4 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -299,12 +299,15 @@ impl Frame { /// /// Insert a variable into the symbol table in the current scope. /// - fn insert_variable(&mut self, name: String, type_: Type) -> Option { + fn insert_variable(&mut self, name: String, type_: Type, span: &Span) -> Result<(), FrameError> { // Modify the current scope. let scope = self.scopes.last_mut().unwrap(); // Insert the variable name -> type. - scope.variables.insert(name, type_) + match scope.variables.insert(name.clone(), type_) { + Some(_type) => Err(FrameError::duplicate_variable(&name, span)), + None => Ok(()), + } } /// @@ -459,24 +462,26 @@ impl Frame { // Insert variable into symbol table let variable = variables.names[0].clone(); - // TODO (collinc97) throw error for duplicate variable definitions. - let _expect_none = self.insert_variable(variable.identifier.name, actual_type); + self.insert_variable(variable.identifier.name, actual_type, span)?; } else { // Expect a tuple type. let types = match actual_type { Type::Tuple(types) => types, - _ => unimplemented!("expected a tuple type for multiple defined variables"), + _ => return Err(FrameError::not_enough_values(span)), }; // Check number of variables == number of types. if types.len() != variables.names.len() { - unimplemented!("Incorrect number of defined variables") + return Err(FrameError::invalid_number_of_values( + types.len(), + variables.names.len(), + span, + )); } // Insert variables into symbol table for (variable, type_) in variables.names.iter().zip(types) { - // TODO (collinc97) throw error for duplicate variable definitions. - let _expect_none = self.insert_variable(variable.identifier.name.clone(), type_); + self.insert_variable(variable.identifier.name.clone(), type_, span)?; } } @@ -605,7 +610,7 @@ impl Frame { ) -> Result<(), FrameError> { // Insert variable into symbol table with u32 type. let u32_type = Type::IntegerType(IntegerType::U32); - let _expect_none = self.insert_variable(identifier.name.to_owned(), u32_type.clone()); + let _expect_none = self.insert_variable(identifier.name.to_owned(), u32_type.clone(), span); // Parse `from` and `to` expressions. let from_type = self.parse_expression(from)?; @@ -1043,7 +1048,7 @@ impl Frame { // Check the length of the circuit members. if circuit_type.variables.len() != members.len() { - return Err(FrameError::num_variables( + return Err(FrameError::num_circuit_variables( circuit_type.variables.len(), members.len(), span, diff --git a/dynamic-check/src/errors/dynamic_check.rs b/dynamic-check/src/errors/dynamic_check.rs index bbcfffe457..33cdc2715b 100644 --- a/dynamic-check/src/errors/dynamic_check.rs +++ b/dynamic-check/src/errors/dynamic_check.rs @@ -27,18 +27,6 @@ pub enum DynamicCheckError { #[error("{}", _0)] FrameError(#[from] FrameError), - // - // #[error("{}", _0)] - // ExpressionError(#[from] ExpressionError), - // - // #[error("{}", _0)] - // FunctionError(#[from] FunctionError), - // - // #[error("{}", _0)] - // StatementError(#[from] StatementError), - // - // #[error("{}", _0)] - // ProgramError(#[from] ProgramError), } impl DynamicCheckError { @@ -49,10 +37,6 @@ impl DynamicCheckError { match self { DynamicCheckError::Error(error) => error.set_path(path), DynamicCheckError::FrameError(error) => error.set_path(path), - // DynamicCheckError::ExpressionError(error) => error.set_path(path), - // DynamicCheckError::FunctionError(error) => error.set_path(path), - // DynamicCheckError::StatementError(error) => error.set_path(path), - // DynamicCheckError::ProgramError(error) => error.set_path(path), } } } diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index 0b9c6a7fee..3a199558ac 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -65,6 +65,15 @@ impl FrameError { Self::new_from_span(message, span.to_owned()) } + /// + /// Two variables have been defined with the same name. + /// + pub fn duplicate_variable(name: &str, span: &Span) -> Self { + let message = format!("Duplicate variable definition found for `{}`", name); + + Self::new_from_span(message, span.to_owned()) + } + /// /// Attempted to call non-static member using `::`. /// @@ -83,6 +92,15 @@ impl FrameError { Self::new_from_span(message, identifier.span.to_owned()) } + /// + /// Attempted to create a circuit with the incorrect number of member variables. + /// + pub fn num_circuit_variables(expected: usize, actual: usize, span: &Span) -> Self { + let message = format!("Circuit expected {} variables, found {} variables.", expected, actual); + + Self::new_from_span(message, span.clone()) + } + /// /// Attempted to call a function with the incorrect number of inputs. /// @@ -95,15 +113,6 @@ impl FrameError { Self::new_from_span(message, span.clone()) } - /// - /// Attempted to create a circuit with the incorrect number of member variables. - /// - pub fn num_variables(expected: usize, actual: usize, span: &Span) -> Self { - let message = format!("Circuit expected {} variables, found {} variables.", expected, actual); - - Self::new_from_span(message, span.clone()) - } - /// /// Attempted to call a circuit type that is not defined in the current context. /// @@ -139,4 +148,25 @@ impl FrameError { Self::new_from_span(message, identifier.span.to_owned()) } + + /// + /// Attempted to assign a tuple of variables to a single value. + /// + pub fn not_enough_values(span: &Span) -> Self { + let message = "Expected a tuple type for multiple defined variables".to_string(); + + Self::new_from_span(message, span.to_owned()) + } + + /// + /// Attempted to assign a tuple with a different number of variables than values. + /// + pub fn invalid_number_of_values(expected: usize, actual: usize, span: &Span) -> Self { + let message = format!( + "Incorrect number of defined variables. Expected `{}`, found `{}`.", + expected, actual + ); + + Self::new_from_span(message, span.to_owned()) + } } diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 96eac2b74e..71be9af341 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -13,13 +13,14 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +pub mod variables; use leo_ast::LeoAst; use leo_dynamic_check::DynamicCheck; use leo_imports::ImportParser; -use leo_static_check::StaticCheck; -use leo_typed::{Input, LeoTypedAst}; +use leo_static_check::{StaticCheck, SymbolTable}; +use leo_typed::{Input, LeoTypedAst, Program}; use std::path::PathBuf; const TEST_PROGRAM_PATH: &str = ""; @@ -27,7 +28,8 @@ const TEST_PROGRAM_NAME: &str = "test"; /// A helper struct to test a `DynamicCheck`. pub struct TestDynamicCheck { - dynamic_check: DynamicCheck, + program: Program, + symbol_table: SymbolTable, } impl TestDynamicCheck { @@ -54,14 +56,24 @@ impl TestDynamicCheck { // Create static check. let symbol_table = StaticCheck::run_with_input(&program, &import_parser, &input).unwrap(); - // Create dynamic check - let dynamic_check = DynamicCheck::new(&program, symbol_table).unwrap(); - - Self { dynamic_check } + // Store fields for new dynamic check. + Self { program, symbol_table } } pub fn solve(self) { - self.dynamic_check.solve().unwrap(); + let dynamic_check = DynamicCheck::new(&self.program, self.symbol_table).unwrap(); + + dynamic_check.solve().unwrap(); + } + + pub fn expect_create_error(self) { + assert!(DynamicCheck::new(&self.program, self.symbol_table).is_err()); + } + + pub fn expect_solve_error(self) { + let dynamic_check = DynamicCheck::new(&self.program, self.symbol_table).unwrap(); + + assert!(dynamic_check.solve().is_err()); } } diff --git a/dynamic-check/tests/variables/duplicate_variable.leo b/dynamic-check/tests/variables/duplicate_variable.leo new file mode 100644 index 0000000000..a748ef4efe --- /dev/null +++ b/dynamic-check/tests/variables/duplicate_variable.leo @@ -0,0 +1,4 @@ +function main() { + let a = 1u8; + let a = 2u8; // Redefining variables with the same name is unsafe in Leo. +} \ No newline at end of file diff --git a/dynamic-check/tests/variables/duplicate_variable_multi.leo b/dynamic-check/tests/variables/duplicate_variable_multi.leo new file mode 100644 index 0000000000..d0fabdea07 --- /dev/null +++ b/dynamic-check/tests/variables/duplicate_variable_multi.leo @@ -0,0 +1,3 @@ +function main() { + let (a, a) = (2u8, 2u8); // Defining multiple variables with the same name is unsafe in Leo. +} \ No newline at end of file diff --git a/dynamic-check/tests/variables/mod.rs b/dynamic-check/tests/variables/mod.rs new file mode 100644 index 0000000000..b60a7217f0 --- /dev/null +++ b/dynamic-check/tests/variables/mod.rs @@ -0,0 +1,49 @@ +// 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 . + +use crate::TestDynamicCheck; + +#[test] +fn test_duplicate_variable() { + let bytes = include_bytes!("duplicate_variable.leo"); + let check = TestDynamicCheck::new(bytes); + + check.expect_create_error(); +} + +#[test] +fn test_duplicate_variable_multi() { + let bytes = include_bytes!("duplicate_variable_multi.leo"); + let check = TestDynamicCheck::new(bytes); + + check.expect_create_error(); +} + +#[test] +fn test_not_enough_values() { + let bytes = include_bytes!("not_enough_values.leo"); + let check = TestDynamicCheck::new(bytes); + + check.expect_create_error(); +} + +#[test] +fn test_too_many_values() { + let bytes = include_bytes!("too_many_values.leo"); + let check = TestDynamicCheck::new(bytes); + + check.expect_create_error(); +} diff --git a/dynamic-check/tests/variables/not_enough_values.leo b/dynamic-check/tests/variables/not_enough_values.leo new file mode 100644 index 0000000000..58b1ad7244 --- /dev/null +++ b/dynamic-check/tests/variables/not_enough_values.leo @@ -0,0 +1,3 @@ +function main() { + let (a, b): (u8, u8) = 1; // A tuple of values must be used when defining two variables. +} \ No newline at end of file diff --git a/dynamic-check/tests/variables/too_many_values.leo b/dynamic-check/tests/variables/too_many_values.leo new file mode 100644 index 0000000000..bd3f551231 --- /dev/null +++ b/dynamic-check/tests/variables/too_many_values.leo @@ -0,0 +1,3 @@ +function main() { + let (a, b): (u8, u8) = (1, 2, 3); // Cannot assign 2 variables to 3 values. +} \ No newline at end of file From c4a7e36623f147bec954ae4e8ea76a3d02e22a5d Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 19:13:37 -0700 Subject: [PATCH 074/139] add new dynamic check errors and tests for tuples and arrays --- dynamic-check/src/dynamic_check.rs | 18 +++-- dynamic-check/src/errors/frame.rs | 71 +++++++++++++++---- dynamic-check/tests/arrays/empty_array.leo | 3 + .../tests/arrays/invalid_array_access.leo | 5 ++ dynamic-check/tests/arrays/invalid_spread.leo | 5 ++ dynamic-check/tests/arrays/mod.rs | 44 ++++++++++++ dynamic-check/tests/mod.rs | 3 + .../tests/tuples/invalid_tuple_access.leo | 5 ++ dynamic-check/tests/tuples/mod.rs | 25 +++++++ 9 files changed, 157 insertions(+), 22 deletions(-) create mode 100644 dynamic-check/tests/arrays/empty_array.leo create mode 100644 dynamic-check/tests/arrays/invalid_array_access.leo create mode 100644 dynamic-check/tests/arrays/invalid_spread.leo create mode 100644 dynamic-check/tests/arrays/mod.rs create mode 100644 dynamic-check/tests/tuples/invalid_tuple_access.leo create mode 100644 dynamic-check/tests/tuples/mod.rs diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index c6645e24c4..2cde75e18e 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -879,11 +879,11 @@ impl Frame { /// /// Returns the type of the accessed tuple element. /// - fn parse_tuple_access(&mut self, type_: Type, index: usize, _span: &Span) -> Result { + fn parse_tuple_access(&mut self, type_: Type, index: usize, span: &Span) -> Result { // Check the type is a tuple. let elements = match type_ { Type::Tuple(elements) => elements, - _ => unimplemented!("expected a tuple type"), + type_ => return Err(FrameError::tuple_access(&type_, span)), }; let element_type = elements[index].clone(); @@ -902,7 +902,7 @@ impl Frame { // Parse all array elements. for expression in expressions { // Get the type and count of elements in each spread or expression. - let (type_, element_count) = self.parse_spread_or_expression(expression)?; + let (type_, element_count) = self.parse_spread_or_expression(expression, span)?; // Assert that array element types are the same. if let Some(prev_type) = element_type { @@ -919,7 +919,7 @@ impl Frame { // Return an error for empty arrays. let type_ = match element_type { Some(type_) => type_, - None => unimplemented!("return empty array error"), + None => return Err(FrameError::empty_array(span)), }; Ok(Type::Array(Box::new(type_), vec![count])) @@ -928,7 +928,11 @@ impl Frame { /// /// Returns the type and count of elements in a spread or expression. /// - fn parse_spread_or_expression(&mut self, s_or_e: &SpreadOrExpression) -> Result<(Type, usize), FrameError> { + fn parse_spread_or_expression( + &mut self, + s_or_e: &SpreadOrExpression, + span: &Span, + ) -> Result<(Type, usize), FrameError> { Ok(match s_or_e { SpreadOrExpression::Spread(expression) => { // Parse the type of the spread array expression. @@ -937,7 +941,7 @@ impl Frame { // Check that the type is an array. let (element_type, mut dimensions) = match array_type { Type::Array(element_type, dimensions) => (element_type, dimensions), - _ => unimplemented!("Spread type must be an array"), + type_ => return Err(FrameError::invalid_spread(type_, span)), }; // A spread copies the elements of an array. @@ -980,7 +984,7 @@ impl Frame { // Check the type is an array. let (element_type, _dimensions) = match type_ { Type::Array(type_, dimensions) => (type_, dimensions), - _ => unimplemented!("expected an array type"), + type_ => return Err(FrameError::array_access(&type_, span)), }; // Get the length of the array. diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index 3a199558ac..50bd1829ac 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ScopeError, TypeAssertionError}; -use leo_static_check::TypeError; +use leo_static_check::{Type, TypeError}; use leo_typed::{Error as FormattedError, Identifier, Span}; use std::path::PathBuf; @@ -52,8 +52,17 @@ impl FrameError { /// /// Return a new formatted error with a given message and span information /// - fn new_from_span(message: String, span: Span) -> Self { - FrameError::Error(FormattedError::new_from_span(message, span)) + fn new_from_span(message: String, span: &Span) -> Self { + FrameError::Error(FormattedError::new_from_span(message, span.to_owned())) + } + + /// + /// Attempted to access the index of a non-array type. + /// + pub fn array_access(actual: &Type, span: &Span) -> Self { + let message = format!("Cannot access the index of non-array type `{}`.", actual); + + Self::new_from_span(message, span) } /// @@ -62,7 +71,7 @@ impl FrameError { pub fn circuit_self(span: &Span) -> Self { let message = "The `Self` keyword is only valid inside a circuit context.".to_string(); - Self::new_from_span(message, span.to_owned()) + Self::new_from_span(message, span) } /// @@ -71,7 +80,18 @@ impl FrameError { pub fn duplicate_variable(name: &str, span: &Span) -> Self { let message = format!("Duplicate variable definition found for `{}`", name); - Self::new_from_span(message, span.to_owned()) + Self::new_from_span(message, span) + } + + /// + /// Attempted to create an empty array in a Leo program. + /// + /// Arrays in Leo are not resizeable so defining empty arrays are effectively dead code. + /// + pub fn empty_array(span: &Span) -> Self { + let message = "Cannot create an empty array in a Leo program.".to_string(); + + Self::new_from_span(message, span) } /// @@ -80,7 +100,19 @@ impl FrameError { pub fn invalid_member_access(identifier: &Identifier) -> Self { let message = format!("non-static member `{}` must be accessed using `.` syntax.", identifier); - Self::new_from_span(message, identifier.span.to_owned()) + Self::new_from_span(message, &identifier.span) + } + + /// + /// Attempted to use the spread operator on a non-array type. + /// + pub fn invalid_spread(actual: Type, span: &Span) -> Self { + let message = format!( + "The spread operator `...` can only be applied to array types. Found type `{}`.", + actual + ); + + Self::new_from_span(message, span) } /// @@ -89,7 +121,7 @@ impl FrameError { pub fn invalid_static_access(identifier: &Identifier) -> Self { let message = format!("static member `{}` must be accessed using `::` syntax.", identifier); - Self::new_from_span(message, identifier.span.to_owned()) + Self::new_from_span(message, &identifier.span) } /// @@ -98,7 +130,7 @@ impl FrameError { pub fn num_circuit_variables(expected: usize, actual: usize, span: &Span) -> Self { let message = format!("Circuit expected {} variables, found {} variables.", expected, actual); - Self::new_from_span(message, span.clone()) + Self::new_from_span(message, span) } /// @@ -110,7 +142,16 @@ impl FrameError { expected, actual ); - Self::new_from_span(message, span.clone()) + Self::new_from_span(message, span) + } + + /// + /// Attempted to access the index of a non-tuple type. + /// + pub fn tuple_access(actual: &Type, span: &Span) -> Self { + let message = format!("Cannot access the index of non-tuple type `{}`.", actual); + + Self::new_from_span(message, span) } /// @@ -119,7 +160,7 @@ impl FrameError { pub fn undefined_circuit(identifier: &Identifier) -> Self { let message = format!("The circuit `{}` is not defined.", identifier); - Self::new_from_span(message, identifier.span.to_owned()) + Self::new_from_span(message, &identifier.span) } /// @@ -128,7 +169,7 @@ impl FrameError { pub fn undefined_circuit_function(identifier: &Identifier) -> Self { let message = format!("The circuit function `{}` is not defined.", identifier); - Self::new_from_span(message, identifier.span.to_owned()) + Self::new_from_span(message, &identifier.span) } /// @@ -137,7 +178,7 @@ impl FrameError { pub fn undefined_function(identifier: &Identifier) -> Self { let message = format!("The function `{}` is not defined.", identifier); - Self::new_from_span(message, identifier.span.to_owned()) + Self::new_from_span(message, &identifier.span) } /// @@ -146,7 +187,7 @@ impl FrameError { pub fn undefined_variable(identifier: &Identifier) -> Self { let message = format!("The variable `{}` is not defined.", identifier); - Self::new_from_span(message, identifier.span.to_owned()) + Self::new_from_span(message, &identifier.span) } /// @@ -155,7 +196,7 @@ impl FrameError { pub fn not_enough_values(span: &Span) -> Self { let message = "Expected a tuple type for multiple defined variables".to_string(); - Self::new_from_span(message, span.to_owned()) + Self::new_from_span(message, span) } /// @@ -167,6 +208,6 @@ impl FrameError { expected, actual ); - Self::new_from_span(message, span.to_owned()) + Self::new_from_span(message, span) } } diff --git a/dynamic-check/tests/arrays/empty_array.leo b/dynamic-check/tests/arrays/empty_array.leo new file mode 100644 index 0000000000..7cf517014e --- /dev/null +++ b/dynamic-check/tests/arrays/empty_array.leo @@ -0,0 +1,3 @@ +function main() { + let a = [1u8; 0]; // Empty arrays are illegal in Leo programs since arrays cannot be resized. +} \ No newline at end of file diff --git a/dynamic-check/tests/arrays/invalid_array_access.leo b/dynamic-check/tests/arrays/invalid_array_access.leo new file mode 100644 index 0000000000..0064d41ae6 --- /dev/null +++ b/dynamic-check/tests/arrays/invalid_array_access.leo @@ -0,0 +1,5 @@ +function main() { + let a = (1u8, 2u8); + + let b = a[0]; // It is illegal to index into a tuple using bracket syntax. +} \ No newline at end of file diff --git a/dynamic-check/tests/arrays/invalid_spread.leo b/dynamic-check/tests/arrays/invalid_spread.leo new file mode 100644 index 0000000000..0153b3d04b --- /dev/null +++ b/dynamic-check/tests/arrays/invalid_spread.leo @@ -0,0 +1,5 @@ +function main() { + let a: u8 = 1; + + let b = [...a]; +} \ No newline at end of file diff --git a/dynamic-check/tests/arrays/mod.rs b/dynamic-check/tests/arrays/mod.rs new file mode 100644 index 0000000000..cf0dd3cb37 --- /dev/null +++ b/dynamic-check/tests/arrays/mod.rs @@ -0,0 +1,44 @@ +// 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 . + +use crate::TestDynamicCheck; + +#[test] +fn test_empty_array() { + let bytes = include_bytes!("empty_array.leo"); + + let check = TestDynamicCheck::new(bytes); + + check.expect_create_error(); +} + +#[test] +fn test_invalid_array_access() { + let bytes = include_bytes!("invalid_array_access.leo"); + + let check = TestDynamicCheck::new(bytes); + + check.expect_create_error(); +} + +#[test] +fn test_invalid_spread() { + let bytes = include_bytes!("invalid_spread.leo"); + + let check = TestDynamicCheck::new(bytes); + + check.expect_create_error(); +} diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 71be9af341..512dc579f2 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -13,6 +13,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . + +pub mod arrays; +pub mod tuples; pub mod variables; use leo_ast::LeoAst; diff --git a/dynamic-check/tests/tuples/invalid_tuple_access.leo b/dynamic-check/tests/tuples/invalid_tuple_access.leo new file mode 100644 index 0000000000..1fc14e3a6b --- /dev/null +++ b/dynamic-check/tests/tuples/invalid_tuple_access.leo @@ -0,0 +1,5 @@ +function main() { + let a = [1u8; 3]; + + let b = a.0; // It is illegal to index into an array using dot syntax. +} \ No newline at end of file diff --git a/dynamic-check/tests/tuples/mod.rs b/dynamic-check/tests/tuples/mod.rs new file mode 100644 index 0000000000..1d4fe1292e --- /dev/null +++ b/dynamic-check/tests/tuples/mod.rs @@ -0,0 +1,25 @@ +// 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 . + +use crate::TestDynamicCheck; + +#[test] +fn test_invalid_tuple_access() { + let bytes = include_bytes!("invalid_tuple_access.leo"); + let check = TestDynamicCheck::new(bytes); + + check.expect_create_error(); +} From b28cbc7680fcda4c23c38bdd42f50b4416f7e580 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 20:02:44 -0700 Subject: [PATCH 075/139] remove unused errors, add tests for new errors --- dynamic-check/src/dynamic_check.rs | 15 +- dynamic-check/src/errors/circuit.rs | 45 ---- dynamic-check/src/errors/expression.rs | 192 ------------------ dynamic-check/src/errors/frame.rs | 22 +- dynamic-check/src/errors/function.rs | 60 ------ dynamic-check/src/errors/mod.rs | 15 -- dynamic-check/src/errors/program.rs | 49 ----- dynamic-check/src/errors/statement.rs | 141 ------------- dynamic-check/src/errors/symbol_table.rs | 59 ------ dynamic-check/src/errors/type_.rs | 117 ----------- dynamic-check/src/errors/type_assertion.rs | 20 +- .../tests/circuits/invalid_circuit.leo | 4 + .../resolver.rs => tests/circuits/mod.rs} | 21 +- .../tests/functions/invalid_function.leo | 4 + dynamic-check/tests/functions/mod.rs | 25 +++ dynamic-check/tests/mod.rs | 7 + 16 files changed, 92 insertions(+), 704 deletions(-) delete mode 100644 dynamic-check/src/errors/circuit.rs delete mode 100644 dynamic-check/src/errors/expression.rs delete mode 100644 dynamic-check/src/errors/function.rs delete mode 100644 dynamic-check/src/errors/program.rs delete mode 100644 dynamic-check/src/errors/statement.rs delete mode 100644 dynamic-check/src/errors/symbol_table.rs delete mode 100644 dynamic-check/src/errors/type_.rs create mode 100644 dynamic-check/tests/circuits/invalid_circuit.leo rename dynamic-check/{src/errors/resolver.rs => tests/circuits/mod.rs} (61%) create mode 100644 dynamic-check/tests/functions/invalid_function.leo create mode 100644 dynamic-check/tests/functions/mod.rs diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 2cde75e18e..4877f96fc6 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -1121,7 +1121,7 @@ impl Frame { /// /// Returns a `CircuitType` given a circuit expression. /// - fn parse_circuit_name(&mut self, type_: Type, _span: &Span) -> Result<&CircuitType, FrameError> { + fn parse_circuit_name(&mut self, type_: Type, span: &Span) -> Result<&CircuitType, FrameError> { // Check that type is a circuit type. match type_ { Type::Circuit(identifier) => { @@ -1130,7 +1130,7 @@ impl Frame { .get_circuit(&identifier.name) .ok_or_else(|| FrameError::undefined_circuit(&identifier)) } - type_ => unimplemented!("expected circuit type {:?}", type_), + type_ => Err(FrameError::invalid_circuit(type_, span)), } } @@ -1150,7 +1150,7 @@ impl Frame { Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { self.parse_static_circuit_function(expression, identifier, span) } - _ => unimplemented!("Invalid function name"), + expression => Err(FrameError::invalid_function(expression, span)), } } @@ -1481,7 +1481,7 @@ impl TypeAssertion { pub fn pairs(&self) -> Result { match self { TypeAssertion::Equality(equality) => equality.pairs(), - TypeAssertion::Membership(_) => unimplemented!("Cannot generate pairs from type membership"), + TypeAssertion::Membership(membership) => Err(TypeAssertionError::membership_pairs(membership)), } } @@ -1547,6 +1547,13 @@ impl TypeMembership { )) } } + + /// + /// Returns the self.span. + /// + pub fn span(&self) -> &Span { + &self.span + } } /// A predicate that evaluates equality between two `Type`s. diff --git a/dynamic-check/src/errors/circuit.rs b/dynamic-check/src/errors/circuit.rs deleted file mode 100644 index 2c78160e95..0000000000 --- a/dynamic-check/src/errors/circuit.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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 . - -use crate::FunctionError; -use leo_typed::Error as FormattedError; - -use std::path::PathBuf; - -/// Errors encountered when resolving a program -#[derive(Debug, Error)] -pub enum CircuitError { - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - FunctionError(#[from] FunctionError), -} - -impl CircuitError { - /// Set the filepath for the error stacktrace - pub fn set_path(&mut self, path: PathBuf) { - match self { - CircuitError::Error(error) => error.set_path(path), - CircuitError::FunctionError(error) => error.set_path(path), - } - } - - // /// Return a new formatted error with a given message and span information - // fn new_from_span(message: String, span: Span) -> Self { - // CircuitError::Error(FormattedError::new_from_span(message, span)) - // } -} diff --git a/dynamic-check/src/errors/expression.rs b/dynamic-check/src/errors/expression.rs deleted file mode 100644 index 3c8f896ac0..0000000000 --- a/dynamic-check/src/errors/expression.rs +++ /dev/null @@ -1,192 +0,0 @@ -// 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 . - -use crate::VariableTableError; -use leo_static_check::{Type, TypeError}; -use leo_typed::{Error as FormattedError, Identifier, Span}; - -use std::path::PathBuf; - -/// Errors encountered when resolving an expression. -#[derive(Debug, Error)] -pub enum ExpressionError { - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - TypeError(#[from] TypeError), - - #[error("{}", _0)] - VariableTableError(#[from] VariableTableError), -} - -impl ExpressionError { - /// - /// Set the filepath for the error stacktrace. - /// - pub fn set_path(&mut self, path: PathBuf) { - match self { - ExpressionError::Error(error) => error.set_path(path), - ExpressionError::TypeError(error) => error.set_path(path), - ExpressionError::VariableTableError(error) => error.set_path(path), - } - } - - /// - /// Return a new formatted error with a given message and span information. - /// - fn new_from_span(message: String, span: Span) -> Self { - ExpressionError::Error(FormattedError::new_from_span(message, span)) - } - - /// - /// Attempted to access a circuit member that is static using double colon syntax. - /// - pub fn invalid_member_access(member: String, span: Span) -> Self { - let message = format!("Circuit member `{}` must be accessed using `::` syntax.", member); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to access a circuit member that is static using dot syntax. - /// - pub fn invalid_static_member_access(member: String, span: Span) -> Self { - let message = format!("Static member `{}` must be accessed using `.` syntax.", member); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to access a tuple index that does not exist. - /// - pub fn invalid_index_tuple(index: usize, max: usize, span: Span) -> Self { - let message = format!("Attempted to access index {} of tuple with length {}.", index, max); - - Self::new_from_span(message, span) - } - - /// - /// Found an array with an unexpected length. - /// - pub fn invalid_length_array(expected: usize, actual: usize, span: Span) -> Self { - let message = format!( - "Expected array with length {}, found array with length {}.", - expected, actual - ); - - Self::new_from_span(message, span) - } - - /// - /// Found a circuit with an incorrect number of members - /// - pub fn invalid_length_circuit_members(expected: usize, actual: usize, span: Span) -> Self { - let message = format!( - "Expected circuit with {} members, found circuit with {} members.", - expected, actual - ); - - Self::new_from_span(message, span) - } - - /// - /// Found a circuit with an incorrect number of members. - /// - pub fn invalid_length_function_inputs(expected: usize, actual: usize, span: Span) -> Self { - let message = format!( - "Function expected {} inputs, found function with {} members.", - expected, actual - ); - - Self::new_from_span(message, span) - } - - /// - /// Found a tuple with an unexpected length. - /// - pub fn invalid_length_tuple(expected: usize, actual: usize, span: Span) -> Self { - let message = format!( - "Expected tuple with length {}, found tuple with length {}.", - expected, actual - ); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to assign a tuple expression to a variable with a different explicit type. - /// - pub fn invalid_type_tuple(actual: &Type, span: &Span) -> Self { - let message = format!("Expected tuple type, found type {}", actual); - - Self::new_from_span(message, span.clone()) - } - - /// - /// Attempted to lookup an unknown variable name. - /// - pub fn undefined_identifier(identifier: Identifier) -> Self { - let message = format!("Cannot find variable `{}` in this scope.", identifier.name); - - Self::new_from_span(message, identifier.span) - } - - /// - /// Attempted to lookup an unknown circuit name. - /// - pub fn undefined_circuit(identifier: Identifier) -> Self { - let message = format!("Cannot find circuit `{}` in this scope.", identifier.name); - - Self::new_from_span(message, identifier.span) - } - - /// - /// Attempted to lookup an unknown circuit variable name. - /// - pub fn undefined_circuit_variable(identifier: Identifier) -> Self { - let message = format!("Circuit has no member variable named `{}`.", identifier.name); - - Self::new_from_span(message, identifier.span) - } - - /// - /// Attempted to lookup an unknown circuit function name. - /// - pub fn undefined_circuit_function(identifier: Identifier, span: Span) -> Self { - let message = format!("Circuit has no member function named `{}`.", identifier.name); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to lookup an unknown circuit function static name. - /// - pub fn undefined_circuit_function_static(identifier: Identifier, span: Span) -> Self { - let message = format!("Circuit has no static member function named `{}`.", identifier.name); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to lookup an unknown circuit name. - /// - pub fn undefined_function(identifier: Identifier) -> Self { - let message = format!("Cannot find function `{}` in this scope.", identifier.name); - - Self::new_from_span(message, identifier.span) - } -} diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index 50bd1829ac..0d8b2542fa 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -16,7 +16,7 @@ use crate::{ScopeError, TypeAssertionError}; use leo_static_check::{Type, TypeError}; -use leo_typed::{Error as FormattedError, Identifier, Span}; +use leo_typed::{Error as FormattedError, Expression, Identifier, Span}; use std::path::PathBuf; @@ -94,6 +94,24 @@ impl FrameError { Self::new_from_span(message, span) } + /// + /// Expected a circuit name but found a different type. + /// + pub fn invalid_circuit(type_: Type, span: &Span) -> Self { + let message = format!("Expected a circuit type. Found type `{}`.", type_); + + Self::new_from_span(message, span) + } + + /// + /// Expected a function name but found a different expression. + /// + pub fn invalid_function(expression: &Expression, span: &Span) -> Self { + let message = format!("Expected a function name. Found expression `{}`.", expression); + + Self::new_from_span(message, span) + } + /// /// Attempted to call non-static member using `::`. /// @@ -119,7 +137,7 @@ impl FrameError { /// Attempted to call static member using `.`. /// pub fn invalid_static_access(identifier: &Identifier) -> Self { - let message = format!("static member `{}` must be accessed using `::` syntax.", identifier); + let message = format!("Static member `{}` must be accessed using `::` syntax.", identifier); Self::new_from_span(message, &identifier.span) } diff --git a/dynamic-check/src/errors/function.rs b/dynamic-check/src/errors/function.rs deleted file mode 100644 index 87b29f1850..0000000000 --- a/dynamic-check/src/errors/function.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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 . - -use crate::StatementError; -use leo_static_check::TypeError; -use leo_typed::{Error as FormattedError, Identifier, Span}; - -use std::path::PathBuf; - -/// Errors encountered when resolving a function -#[derive(Debug, Error)] -pub enum FunctionError { - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - StatementError(#[from] StatementError), - - #[error("{}", _0)] - TypeError(#[from] TypeError), -} - -impl FunctionError { - /// Set the filepath for the error stacktrace - pub fn set_path(&mut self, path: PathBuf) { - match self { - FunctionError::Error(error) => error.set_path(path), - FunctionError::StatementError(error) => error.set_path(path), - FunctionError::TypeError(error) => error.set_path(path), - } - } - - /// Return a new formatted error with a given message and span information - fn new_from_span(message: String, span: Span) -> Self { - FunctionError::Error(FormattedError::new_from_span(message, span)) - } - - /// Found two function inputs with the same name - pub fn duplicate_input(identifier: Identifier) -> Self { - let message = format!( - "Function input `{}` is bound more than once in this parameter list", - identifier - ); - - Self::new_from_span(message, identifier.span) - } -} diff --git a/dynamic-check/src/errors/mod.rs b/dynamic-check/src/errors/mod.rs index 5cf3d1a478..20b47dc46e 100644 --- a/dynamic-check/src/errors/mod.rs +++ b/dynamic-check/src/errors/mod.rs @@ -23,21 +23,6 @@ pub use self::dynamic_check::*; pub mod frame; pub use self::frame::*; -// pub mod expression; -// pub use self::expression::*; -// -// pub mod function; -// pub use self::function::*; -// -// pub mod program; -// pub use self::program::*; -// -// pub mod resolver; -// pub use self::resolver::*; -// -// pub mod statement; -// pub use self::statement::*; - pub mod scope; pub use self::scope::*; diff --git a/dynamic-check/src/errors/program.rs b/dynamic-check/src/errors/program.rs deleted file mode 100644 index 9fb6c79401..0000000000 --- a/dynamic-check/src/errors/program.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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 . - -use crate::{CircuitError, FunctionError}; -use leo_typed::Error as FormattedError; - -use std::path::PathBuf; - -/// Errors encountered when resolving a program -#[derive(Debug, Error)] -pub enum ProgramError { - #[error("{}", _0)] - CircuitError(#[from] CircuitError), - - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - FunctionError(#[from] FunctionError), -} - -impl ProgramError { - /// Set the filepath for the error stacktrace - pub fn set_path(&mut self, path: PathBuf) { - match self { - ProgramError::CircuitError(error) => error.set_path(path), - ProgramError::Error(error) => error.set_path(path), - ProgramError::FunctionError(error) => error.set_path(path), - } - } - - // /// Return a new formatted error with a given message and span information - // fn new_from_span(message: String, span: Span) -> Self { - // ProgramError::Error(FormattedError::new_from_span(message, span)) - // } -} diff --git a/dynamic-check/src/errors/statement.rs b/dynamic-check/src/errors/statement.rs deleted file mode 100644 index 52ac639368..0000000000 --- a/dynamic-check/src/errors/statement.rs +++ /dev/null @@ -1,141 +0,0 @@ -// 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 . - -use crate::{ExpressionError, VariableTableError}; -use leo_static_check::{Type, TypeError}; -use leo_typed::{Error as FormattedError, Expression as UnresolvedExpression, Identifier, Span}; - -use std::path::PathBuf; - -/// -/// Errors encountered when resolving a statement -/// -#[derive(Debug, Error)] -pub enum StatementError { - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - ExpressionError(#[from] ExpressionError), - - #[error("{}", _0)] - TypeError(#[from] TypeError), - - #[error("{}", _0)] - VariableTableError(#[from] VariableTableError), -} - -impl StatementError { - /// - /// Set the filepath for the error stacktrace. - /// - pub fn set_path(&mut self, path: PathBuf) { - match self { - StatementError::Error(error) => error.set_path(path), - StatementError::ExpressionError(error) => error.set_path(path), - StatementError::TypeError(error) => error.set_path(path), - StatementError::VariableTableError(error) => error.set_path(path), - } - } - - /// - /// Return a new formatted error with a given message and span information. - /// - fn new_from_span(message: String, span: Span) -> Self { - StatementError::Error(FormattedError::new_from_span(message, span)) - } - - /// - /// Attempted to define a variable name twice. - /// - pub fn duplicate_variable(name: String, span: Span) -> Self { - let message = format!("Duplicate variable definition found for `{}`", name); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to assign to an immutable variable. - /// - pub fn immutable_assign(name: String, span: Span) -> Self { - let message = format!("Cannot assign to immutable variable `{}`.", name); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to assign to a non-variable type. - /// - pub fn invalid_assign(type_: &Type, span: Span) -> Self { - let message = format!("Cannot assign to type `{}` in a statement.", type_); - - Self::new_from_span(message, span) - } - - /// - /// Provided a different number of explicit types than variables being defined in a tuple - /// - pub fn multiple_variable_types(expected: usize, actual: usize, span: Span) -> Self { - let message = format!( - "Expected {} explicit types when defining variables, found {}", - expected, actual - ); - - Self::new_from_span(message, span) - } - - /// - /// Provided a different number of expression values than variables being defined in a tuple - /// - pub fn multiple_variable_expressions(expected: usize, actual: usize, span: &Span) -> Self { - let message = format!( - "Expected {} values when defining variables, found {} values", - expected, actual - ); - - Self::new_from_span(message, span.clone()) - } - - /// - /// Attempted to assign multiple variables to a single expression value. - /// - pub fn invalid_tuple(expected: usize, expression: UnresolvedExpression, span: Span) -> Self { - let message = format!( - "Expected {} values when defining variables, found single value `{}`", - expected, expression - ); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to assign to an unknown variable. - /// - pub fn undefined_variable(name: String, span: Span) -> Self { - let message = format!("Attempted to assign to unknown variable `{}`.", name); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to assign to an undefined circuit. - /// - pub fn undefined_circuit(identifier: Identifier) -> Self { - let message = format!("Attempted to assign to unknown circuit `{}`.", identifier.name); - - Self::new_from_span(message, identifier.span) - } -} diff --git a/dynamic-check/src/errors/symbol_table.rs b/dynamic-check/src/errors/symbol_table.rs deleted file mode 100644 index b05a884bc1..0000000000 --- a/dynamic-check/src/errors/symbol_table.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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 . - -use crate::TypeError; -use leo_typed::{Error as FormattedError, Identifier, Span}; - -use std::path::PathBuf; - -/// Errors encountered when tracking variable, function, and circuit names in a program -#[derive(Debug, Error)] -pub enum SymbolTableError { - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - TypeError(#[from] TypeError), -} - -impl SymbolTableError { - /// Set the filepath for the error stacktrace - pub fn set_path(&mut self, path: PathBuf) { - match self { - SymbolTableError::Error(error) => error.set_path(path), - SymbolTableError::TypeError(error) => error.set_path(path), - } - } - - /// Return a new formatted error with a given message and span information - fn new_from_span(message: String, span: Span) -> Self { - SymbolTableError::Error(FormattedError::new_from_span(message, span)) - } - - /// 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); - - Self::new_from_span(message, 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); - - Self::new_from_span(message, span) - } -} diff --git a/dynamic-check/src/errors/type_.rs b/dynamic-check/src/errors/type_.rs deleted file mode 100644 index f7e6ad79ae..0000000000 --- a/dynamic-check/src/errors/type_.rs +++ /dev/null @@ -1,117 +0,0 @@ -// 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 . - -use crate::Type; -use leo_typed::{Error as FormattedError, Identifier, Span}; - -use std::path::PathBuf; - -/// Errors encountered when resolving types -#[derive(Debug, Error)] -pub enum TypeError { - #[error("{}", _0)] - Error(#[from] FormattedError), -} - -impl TypeError { - /// Set the filepath for the error stacktrace - pub fn set_path(&mut self, path: PathBuf) { - match self { - TypeError::Error(error) => error.set_path(path), - } - } - - /// Return a new formatted error with a given message and span information - fn new_from_span(message: String, span: Span) -> Self { - TypeError::Error(FormattedError::new_from_span(message, span)) - } - - /// Expected an array type from the given expression - pub fn invalid_array(actual: &Type, span: Span) -> Self { - let message = format!("Expected array type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// Expected a circuit type from the given expression - pub fn invalid_circuit(actual: &Type, span: Span) -> Self { - let message = format!("Expected circuit type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// Expected a function type from the given expression - pub fn invalid_function(actual: &Type, span: Span) -> Self { - let message = format!("Expected function type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// Expected an integer type from the given expression - pub fn invalid_integer(actual: &Type, span: Span) -> Self { - let message = format!("Expected integer type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// Expected a tuple type from the given expression - pub fn invalid_tuple(actual: &Type, span: Span) -> Self { - let message = format!("Expected tuple type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// The value of the expression does not match the given explicit type - pub fn mismatched_types(expected: &Type, actual: &Type, span: Span) -> Self { - let message = format!("Expected type `{}`, found type `{}`.", expected, actual); - - Self::new_from_span(message, span) - } - - /// The `Self` keyword was used outside of a circuit - pub fn self_not_available(span: Span) -> Self { - let message = format!("Type `Self` is only available in circuit definitions and circuit functions."); - - Self::new_from_span(message, span) - } - - /// Found an unknown circuit name - pub fn undefined_circuit(identifier: Identifier) -> Self { - let message = format!( - "Type circuit `{}` must be defined before it is used in an expression.", - identifier.name - ); - - Self::new_from_span(message, identifier.span) - } - - /// Found an unknown circuit member name - pub fn undefined_circuit_member(identifier: Identifier) -> Self { - let message = format!("Circuit has no member `{}`.", identifier.name); - - Self::new_from_span(message, identifier.span) - } - - /// Found an unknown function name - pub fn undefined_function(identifier: Identifier) -> Self { - let message = format!( - "Type function `{}` must be defined before it is used in an expression.", - identifier.name - ); - - Self::new_from_span(message, identifier.span) - } -} diff --git a/dynamic-check/src/errors/type_assertion.rs b/dynamic-check/src/errors/type_assertion.rs index da61010947..c13eb06dcc 100644 --- a/dynamic-check/src/errors/type_assertion.rs +++ b/dynamic-check/src/errors/type_assertion.rs @@ -17,6 +17,7 @@ use leo_static_check::Type; use leo_typed::{Error as FormattedError, Span}; +use crate::TypeMembership; use std::path::PathBuf; /// Errors encountered when attempting to solve a type assertion. @@ -39,8 +40,8 @@ impl TypeAssertionError { /// /// Returns a new formatted error with a given message and span information. /// - fn new_from_span(message: String, span: Span) -> Self { - TypeAssertionError::Error(FormattedError::new_from_span(message, span)) + fn new_from_span(message: String, span: &Span) -> Self { + TypeAssertionError::Error(FormattedError::new_from_span(message, span.to_owned())) } /// @@ -49,7 +50,7 @@ impl TypeAssertionError { pub fn equality_failed(left: &Type, right: &Type, span: &Span) -> Self { let message = format!("Mismatched types. Expected type `{}`, found type `{}`.", left, right); - Self::new_from_span(message, span.to_owned()) + Self::new_from_span(message, span) } /// @@ -61,7 +62,16 @@ impl TypeAssertionError { given, set ); - Self::new_from_span(message, span.to_owned()) + Self::new_from_span(message, span) + } + + /// + /// Attempted to generate pairs from a membership assertion. + /// + pub fn membership_pairs(membership: &TypeMembership) -> Self { + let message = "Cannot generate a type variable -> type pair for the given type membership".to_string(); + + Self::new_from_span(message, membership.span()) } /// @@ -73,6 +83,6 @@ impl TypeAssertionError { dimensions1, dimensions2 ); - Self::new_from_span(message, span.to_owned()) + Self::new_from_span(message, span) } } diff --git a/dynamic-check/tests/circuits/invalid_circuit.leo b/dynamic-check/tests/circuits/invalid_circuit.leo new file mode 100644 index 0000000000..aff73cc8d4 --- /dev/null +++ b/dynamic-check/tests/circuits/invalid_circuit.leo @@ -0,0 +1,4 @@ +function main() { + let a = 1u8; + let b = a::foo(); // Variable `a` is not a circuit type. +} \ No newline at end of file diff --git a/dynamic-check/src/errors/resolver.rs b/dynamic-check/tests/circuits/mod.rs similarity index 61% rename from dynamic-check/src/errors/resolver.rs rename to dynamic-check/tests/circuits/mod.rs index 3fa847e8f3..069000a2b0 100644 --- a/dynamic-check/src/errors/resolver.rs +++ b/dynamic-check/tests/circuits/mod.rs @@ -13,22 +13,13 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::ProgramError; -use leo_imports::ImportParserError; -use leo_static_check::SymbolTableError; -use leo_typed::Error as FormattedError; -#[derive(Debug, Error)] -pub enum ResolverError { - #[error("{}", _0)] - Error(#[from] FormattedError), +use crate::TestDynamicCheck; - #[error("{}", _0)] - ImportParserError(#[from] ImportParserError), +#[test] +fn test_invalid_circuit() { + let bytes = include_bytes!("invalid_circuit.leo"); + let check = TestDynamicCheck::new(bytes); - #[error("{}", _0)] - ProgramError(#[from] ProgramError), - - #[error("{}", _0)] - SymbolTableError(#[from] SymbolTableError), + check.expect_create_error(); } diff --git a/dynamic-check/tests/functions/invalid_function.leo b/dynamic-check/tests/functions/invalid_function.leo new file mode 100644 index 0000000000..1e72c4e8d6 --- /dev/null +++ b/dynamic-check/tests/functions/invalid_function.leo @@ -0,0 +1,4 @@ +function main() { + let a = 1u8; + let b = a(); // Variable `a` is not a function. +} \ No newline at end of file diff --git a/dynamic-check/tests/functions/mod.rs b/dynamic-check/tests/functions/mod.rs new file mode 100644 index 0000000000..6348658eec --- /dev/null +++ b/dynamic-check/tests/functions/mod.rs @@ -0,0 +1,25 @@ +// 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 . + +use crate::TestDynamicCheck; + +#[test] +fn test_invalid_function() { + let bytes = include_bytes!("invalid_function.leo"); + let check = TestDynamicCheck::new(bytes); + + check.expect_create_error(); +} diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 512dc579f2..884db0422b 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -15,6 +15,8 @@ // along with the Leo library. If not, see . pub mod arrays; +pub mod circuits; +pub mod functions; pub mod tuples; pub mod variables; @@ -70,6 +72,11 @@ impl TestDynamicCheck { } pub fn expect_create_error(self) { + // println!( + // "{:?}", + // DynamicCheck::new(&self.program, self.symbol_table.clone()).err() + // ); + assert!(DynamicCheck::new(&self.program, self.symbol_table).is_err()); } From 52810588ffc383368966db8d8a23964407846313 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 26 Oct 2020 23:42:01 -0700 Subject: [PATCH 076/139] refactor modules and make function names more clear --- compiler/src/compiler.rs | 4 +- compiler/src/import/store/import.rs | 2 +- dynamic-check/src/assertions/mod.rs | 27 + .../src/assertions/type_assertion.rs | 74 + dynamic-check/src/assertions/type_equality.rs | 68 + .../src/assertions/type_membership.rs | 71 + .../src/assertions/type_variable_pair.rs | 147 ++ dynamic-check/src/dynamic_check.rs | 1700 +---------------- dynamic-check/src/errors/mod.rs | 3 - dynamic-check/src/lib.rs | 6 + dynamic-check/src/objects/frame.rs | 1198 ++++++++++++ dynamic-check/src/objects/mod.rs | 24 + dynamic-check/src/objects/scope.rs | 90 + dynamic-check/src/objects/variable_table.rs | 70 + dynamic-check/tests/arrays/mod.rs | 6 +- dynamic-check/tests/circuits/mod.rs | 2 +- dynamic-check/tests/functions/mod.rs | 2 +- dynamic-check/tests/mod.rs | 23 +- dynamic-check/tests/tuples/mod.rs | 2 +- dynamic-check/tests/variables/mod.rs | 8 +- static-check/src/imports/imported_symbols.rs | 32 +- static-check/src/lib.rs | 6 +- static-check/src/objects/mod.rs | 18 + .../src/{ => objects}/symbol_table.rs | 469 +++-- static-check/src/static_check.rs | 69 +- static-check/src/types/functions/function.rs | 2 +- static-check/src/types/type_.rs | 2 +- static-check/tests/mod.rs | 6 +- 28 files changed, 2140 insertions(+), 1991 deletions(-) create mode 100644 dynamic-check/src/assertions/mod.rs create mode 100644 dynamic-check/src/assertions/type_assertion.rs create mode 100644 dynamic-check/src/assertions/type_equality.rs create mode 100644 dynamic-check/src/assertions/type_membership.rs create mode 100644 dynamic-check/src/assertions/type_variable_pair.rs create mode 100644 dynamic-check/src/objects/frame.rs create mode 100644 dynamic-check/src/objects/mod.rs create mode 100644 dynamic-check/src/objects/scope.rs create mode 100644 dynamic-check/src/objects/variable_table.rs create mode 100644 static-check/src/objects/mod.rs rename static-check/src/{ => objects}/symbol_table.rs (82%) diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 77fa923493..a87443fdb1 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -170,10 +170,10 @@ impl> Compiler { self.imported_programs = ImportParser::parse(&self.program)?; // Run static check on program. - let symbol_table = StaticCheck::run_with_input(&self.program, &self.imported_programs, &self.program_input)?; + let symbol_table = StaticCheck::new(&self.program, &self.imported_programs, &self.program_input)?; // Run dynamic check on program. - DynamicCheck::run(&self.program, symbol_table)?; + DynamicCheck::new(&self.program, symbol_table)?; tracing::debug!("Program parsing complete\n{:#?}", self.program); diff --git a/compiler/src/import/store/import.rs b/compiler/src/import/store/import.rs index 8be8ef77d0..2f0c96fbf9 100644 --- a/compiler/src/import/store/import.rs +++ b/compiler/src/import/store/import.rs @@ -38,7 +38,7 @@ impl> ConstrainedProgram { } // Fetch dependencies for the current import - let imported_symbols = ImportedSymbols::from(import); + let imported_symbols = ImportedSymbols::new(import); for (name, symbol) in imported_symbols.symbols { // Find imported program diff --git a/dynamic-check/src/assertions/mod.rs b/dynamic-check/src/assertions/mod.rs new file mode 100644 index 0000000000..d98b3aad82 --- /dev/null +++ b/dynamic-check/src/assertions/mod.rs @@ -0,0 +1,27 @@ +// 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 . + +pub mod type_assertion; +pub use self::type_assertion::*; + +pub mod type_equality; +pub use self::type_equality::*; + +pub mod type_membership; +pub use self::type_membership::*; + +pub mod type_variable_pair; +pub use self::type_variable_pair::*; diff --git a/dynamic-check/src/assertions/type_assertion.rs b/dynamic-check/src/assertions/type_assertion.rs new file mode 100644 index 0000000000..2655e85298 --- /dev/null +++ b/dynamic-check/src/assertions/type_assertion.rs @@ -0,0 +1,74 @@ +// 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 . + +use crate::{TypeAssertionError, TypeEquality, TypeMembership, TypeVariablePairs}; +use leo_static_check::{Type, TypeVariable}; +use leo_typed::Span; + +use serde::{Deserialize, Serialize}; + +/// A predicate that evaluates equality between two `Types`s. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum TypeAssertion { + Equality(TypeEquality), + Membership(TypeMembership), +} + +impl TypeAssertion { + /// + /// Returns a `TypeAssertion::Equality` predicate from given left and right `Types`s. + /// + pub fn new_equality(left: Type, right: Type, span: &Span) -> Self { + Self::Equality(TypeEquality::new(left, right, span)) + } + + /// + /// Returns a `TypeAssertion::Membership` predicate from given and set `Type`s. + /// + pub fn new_membership(given: Type, set: Vec, span: &Span) -> Self { + Self::Membership(TypeMembership::new(given, set, span)) + } + + /// + /// Returns one or more `TypeVariablePairs` generated by the given `TypeAssertion`. + /// + pub fn pairs(&self) -> Result { + match self { + TypeAssertion::Equality(equality) => equality.pairs(), + TypeAssertion::Membership(membership) => Err(TypeAssertionError::membership_pairs(membership)), + } + } + + /// + /// Substitutes the given type for self if self is equal to the type variable. + /// + pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { + match self { + TypeAssertion::Equality(equality) => equality.substitute(variable, type_), + TypeAssertion::Membership(membership) => membership.substitute(variable, type_), + } + } + + /// + /// Checks if the `TypeAssertion` is satisfied. + /// + pub fn evaluate(&self) -> Result<(), TypeAssertionError> { + match self { + TypeAssertion::Equality(equality) => equality.evaluate(), + TypeAssertion::Membership(membership) => membership.evaluate(), + } + } +} diff --git a/dynamic-check/src/assertions/type_equality.rs b/dynamic-check/src/assertions/type_equality.rs new file mode 100644 index 0000000000..50a13eb448 --- /dev/null +++ b/dynamic-check/src/assertions/type_equality.rs @@ -0,0 +1,68 @@ +// 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 . + +use crate::{TypeAssertionError, TypeVariablePairs}; +use leo_static_check::{Type, TypeVariable}; +use leo_typed::Span; + +use serde::{Deserialize, Serialize}; + +/// A predicate that evaluates equality between two `Type`s. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct TypeEquality { + left: Type, + right: Type, + span: Span, +} + +impl TypeEquality { + /// + /// Returns a `TypeEquality` predicate from given left and right `Types`s + /// + pub fn new(left: Type, right: Type, span: &Span) -> Self { + Self { + left, + right, + span: span.to_owned(), + } + } + + /// + /// Substitutes the given `TypeVariable` for each `Types` in the `TypeEquality`. + /// + pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { + self.left.substitute(variable, type_); + self.right.substitute(variable, type_); + } + + /// + /// Checks if the `self.left` == `self.right`. + /// + pub fn evaluate(&self) -> Result<(), TypeAssertionError> { + if self.left.eq(&self.right) { + Ok(()) + } else { + Err(TypeAssertionError::equality_failed(&self.left, &self.right, &self.span)) + } + } + + /// + /// Returns the (type variable, type) pair from this assertion. + /// + pub fn pairs(&self) -> Result { + TypeVariablePairs::new(&self.left, &self.right, &self.span) + } +} diff --git a/dynamic-check/src/assertions/type_membership.rs b/dynamic-check/src/assertions/type_membership.rs new file mode 100644 index 0000000000..312f810056 --- /dev/null +++ b/dynamic-check/src/assertions/type_membership.rs @@ -0,0 +1,71 @@ +// 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 . + +use crate::TypeAssertionError; +use leo_static_check::{Type, TypeVariable}; +use leo_typed::Span; + +use serde::{Deserialize, Serialize}; + +/// A predicate that evaluates to true if the given type is equal to a member in the set vector of types. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct TypeMembership { + given: Type, + set: Vec, + span: Span, +} + +impl TypeMembership { + /// + /// Returns a `TypeMembership` predicate from given and set `Type`s. + /// + pub fn new(given: Type, set: Vec, span: &Span) -> Self { + Self { + given, + set, + span: span.to_owned(), + } + } + + /// + /// Substitutes the given `TypeVariable` for each `Type` in the `TypeMembership`. + /// + pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { + self.given.substitute(variable, type_) + } + + /// + /// Returns true if the given type is equal to a member of the set. + /// + pub fn evaluate(&self) -> Result<(), TypeAssertionError> { + if self.set.contains(&self.given) { + Ok(()) + } else { + Err(TypeAssertionError::membership_failed( + &self.given, + &self.set, + &self.span, + )) + } + } + + /// + /// Returns the self.span. + /// + pub fn span(&self) -> &Span { + &self.span + } +} diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs new file mode 100644 index 0000000000..71daf593e3 --- /dev/null +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -0,0 +1,147 @@ +// 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 . + +use crate::TypeAssertionError; +use leo_static_check::{flatten_array_type, Type, TypeVariable}; +use leo_typed::Span; + +/// A type variable -> type pair. +pub struct TypeVariablePair(TypeVariable, Type); + +impl TypeVariablePair { + pub fn first(&self) -> &TypeVariable { + &self.0 + } + + pub fn second(&self) -> &Type { + &self.1 + } +} + +/// A vector of `TypeVariablePair`s. +pub struct TypeVariablePairs(Vec); + +impl Default for TypeVariablePairs { + fn default() -> Self { + Self(Vec::new()) + } +} + +impl TypeVariablePairs { + /// + /// Returns a new `TypeVariablePairs` struct from the given left and right types. + /// + pub fn new(left: &Type, right: &Type, span: &Span) -> Result { + let mut pairs = Self::default(); + + // Push all `TypeVariablePair`s. + pairs.push_pairs(left, right, span)?; + + Ok(pairs) + } + + /// + /// Returns true if the self vector has no pairs. + /// + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// + /// Returns the self vector of pairs. + /// + pub fn get_pairs(&self) -> &Vec { + &self.0 + } + + /// + /// Pushes a new `TypeVariablePair` struct to self. + /// + pub fn push(&mut self, variable: &TypeVariable, type_: &Type) { + // Create a new type variable -> type pair. + let pair = TypeVariablePair(variable.clone(), type_.clone()); + + // Push the pair to the self vector. + self.0.push(pair); + } + + /// + /// Checks if the given left or right type contains a `TypeVariable`. + /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left + /// and right type. + /// + pub fn push_pairs(&mut self, left: &Type, right: &Type, span: &Span) -> Result<(), TypeAssertionError> { + match (left, right) { + (Type::TypeVariable(variable), type_) => Ok(self.push(variable, type_)), + (type_, Type::TypeVariable(variable)) => Ok(self.push(variable, type_)), + (Type::Array(left_type, left_dimensions), Type::Array(right_type, right_dimensions)) => { + self.push_pairs_array(left_type, left_dimensions, right_type, right_dimensions, span) + } + (Type::Tuple(left_types), Type::Tuple(right_types)) => self.push_pairs_tuple(left_types, right_types, span), + (_, _) => Ok(()), // No `TypeVariable` found so we do not push any pairs. + } + } + + /// + /// Checks if the given left or right array type contains a `TypeVariable`. + /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left + /// and right type. + /// + fn push_pairs_array( + &mut self, + left_type: &Type, + left_dimensions: &Vec, + right_type: &Type, + right_dimensions: &Vec, + span: &Span, + ) -> Result<(), TypeAssertionError> { + // Flatten the array types to get the element types. + let (left_type_flat, left_dimensions_flat) = flatten_array_type(left_type, left_dimensions.to_owned()); + let (right_type_flat, right_dimensions_flat) = flatten_array_type(right_type, right_dimensions.to_owned()); + + // If the dimensions do not match, then throw an error. + if left_dimensions_flat.ne(&right_dimensions_flat) { + return Err(TypeAssertionError::array_dimensions( + left_dimensions_flat, + right_dimensions_flat, + span, + )); + } + + // Compare the array element types. + self.push_pairs(left_type_flat, right_type_flat, span) + } + + /// + /// Checks if any given left or right tuple type contains a `TypeVariable`. + /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left + /// and right type. + /// + fn push_pairs_tuple( + &mut self, + left_types: &Vec, + right_types: &Vec, + span: &Span, + ) -> Result<(), TypeAssertionError> { + // Iterate over each left == right pair of types. + for (left, right) in left_types.iter().zip(right_types) { + // Check for `TypeVariablePair`s. + self.push_pairs(left, right, span)?; + } + + Ok(()) + } +} diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 759b1757bc..d1c94c0e47 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -14,41 +14,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{DynamicCheckError, FrameError, ScopeError, TypeAssertionError, VariableTableError}; -use leo_static_check::{ - flatten_array_type, - Attribute, - CircuitFunctionType, - CircuitType, - FunctionInputType, - FunctionType, - SymbolTable, - Type, - TypeVariable, -}; -use leo_typed::{ - Assignee, - AssigneeAccess, - Circuit, - CircuitMember, - CircuitVariableDefinition, - ConditionalNestedOrEndStatement, - ConditionalStatement, - Declare, - Expression, - Function, - Identifier, - Program, - RangeOrExpression, - Span, - SpreadOrExpression, - Statement, - Variables, -}; - -use leo_typed::integer_type::IntegerType; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use crate::{DynamicCheckError, Frame, Scope}; +use leo_static_check::SymbolTable; +use leo_typed::{Circuit, CircuitMember, Function, Program}; /// Performs a dynamic type inference check over a program. pub struct DynamicCheck { @@ -58,20 +26,11 @@ pub struct DynamicCheck { impl DynamicCheck { /// - /// Creates a new `DynamicCheck` from a given program and symbol table. + /// Creates a new `DynamicCheck` on a given program and symbol table. /// /// Evaluates all `TypeAssertion` predicates. /// - pub fn run(program: &Program, symbol_table: SymbolTable) -> Result<(), DynamicCheckError> { - let dynamic_check = Self::new(program, symbol_table)?; - - dynamic_check.solve() - } - - /// - /// Returns a new `DynamicCheck` from a given program and symbol table. - /// - pub fn new(program: &Program, symbol_table: SymbolTable) -> Result { + pub fn new(program: &Program, symbol_table: SymbolTable) -> Result<(), DynamicCheckError> { let mut dynamic_check = Self { table: symbol_table, frames: Vec::new(), @@ -79,16 +38,13 @@ impl DynamicCheck { dynamic_check.parse_program(program)?; - Ok(dynamic_check) + dynamic_check.check() } /// /// Collects a vector of `TypeAssertion` predicates from a program. /// fn parse_program(&mut self, program: &Program) -> Result<(), DynamicCheckError> { - // Parse program input keyword as a circuit type. - // let input_type = CircuitType::from_input() - // Iterate over circuit types. let circuits = program .circuits @@ -110,6 +66,48 @@ impl DynamicCheck { self.parse_functions(functions) } + /// + /// Collects a vector of `Frames`s from a vector of circuit functions. + /// + fn parse_circuits(&mut self, circuits: Vec<&Circuit>) -> Result<(), DynamicCheckError> { + for circuit in circuits { + self.parse_circuit(circuit)?; + } + + Ok(()) + } + + /// + /// Collects a vector of `Frames`s from a circuit function. + /// + /// Each frame collects a vector of `TypeAssertion` predicates from each function. + /// + fn parse_circuit(&mut self, circuit: &Circuit) -> Result<(), DynamicCheckError> { + let name = &circuit.circuit_name.name; + + // Get circuit type from circuit symbol table. + let circuit_type = self.table.get_circuit_type(name).unwrap().clone(); + + // Create a new function for each circuit member function. + for circuit_member in &circuit.members { + // ignore circuit member variables + if let CircuitMember::CircuitFunction(_, function) = circuit_member { + // Collect `TypeAssertion` predicates from the function. + // Pass down circuit self type and circuit variable types to each function. + let frame = Frame::new_circuit_function( + function.to_owned(), + circuit_type.clone(), + Scope::default(), + self.table.clone(), + )?; + + self.frames.push(frame) + } + } + + Ok(()) + } + /// /// Collects a vector of `TypeAssertion` predicates from a vector of functions. /// @@ -132,48 +130,6 @@ impl DynamicCheck { Ok(()) } - /// - /// Collects a vector of `Frames`s from a vector of circuit functions. - /// - fn parse_circuits(&mut self, circuits: Vec<&Circuit>) -> Result<(), DynamicCheckError> { - for circuit in circuits { - self.parse_circuit(circuit)?; - } - - Ok(()) - } - - /// - /// Collects a vector of `Frames`s from a circuit function. - /// - /// Each frame collects a vector of `TypeAssertion` predicates from each function. - /// - fn parse_circuit(&mut self, circuit: &Circuit) -> Result<(), DynamicCheckError> { - let name = &circuit.circuit_name.name; - - // Get circuit type from circuit symbol table. - let circuit_type = self.table.get_circuit(name).unwrap().clone(); - - // Create a new function for each circuit member function. - for circuit_member in &circuit.members { - // ignore circuit member variables - if let CircuitMember::CircuitFunction(_, function) = circuit_member { - // Collect `TypeAssertion` predicates from the function. - // Pass down circuit self type and circuit variable types to each function. - let frame = Frame::new_circuit_function( - function.to_owned(), - circuit_type.clone(), - Scope::empty(), - self.table.clone(), - )?; - - self.frames.push(frame) - } - } - - Ok(()) - } - /// /// Returns the result of evaluating all `TypeAssertion` predicates. /// @@ -181,1565 +137,9 @@ impl DynamicCheck { /// Returns a `LeoResolvedAst` if all `TypeAssertion` predicates are true. /// Returns ERROR if a `TypeAssertion` predicate is false or a solution does not exist. /// - pub fn solve(self) -> Result<(), DynamicCheckError> { + pub fn check(self) -> Result<(), DynamicCheckError> { for frame in self.frames { - frame.solve()?; - } - - Ok(()) - } -} - -/// A vector of `TypeAssertion` predicates created from a function body. -#[derive(Clone)] -pub struct Frame { - pub function_type: FunctionType, - pub self_type: Option, - pub scopes: Vec, - pub statements: Vec, - pub type_assertions: Vec, - pub user_defined_types: SymbolTable, -} - -impl Frame { - /// - /// Collects a vector of `TypeAssertion` predicates from a function. - /// - pub fn new_function( - function: Function, - self_type: Option, - parent_scope: Option, - user_defined_types: SymbolTable, - ) -> Result { - let name = &function.identifier.name; - - // Get function type from symbol table. - let function_type = user_defined_types.get_function(name).unwrap().clone(); - - // Create a new scope for the function variables. - let mut scope = Scope::new(parent_scope); - - // Initialize function inputs as variables. - scope.parse_function_inputs(&function_type.inputs)?; - - // Create new list of scopes for frame. - let scopes = vec![scope]; - - // Create new frame struct. - // Update variables when encountering let/const variable definitions. - let mut frame = Self { - function_type, - self_type, - scopes, - statements: function.statements, - type_assertions: vec![], - user_defined_types, - }; - - // Create type assertions for function statements - frame.parse_statements()?; - - Ok(frame) - } - - /// - /// Collects vector of `TypeAssertion` predicates from a circuit function. - /// - pub fn new_circuit_function( - function: Function, - self_type: CircuitType, - parent_scope: Scope, - user_defined_types: SymbolTable, - ) -> Result { - let identifier = &function.identifier; - - // Find function name in circuit members. - let circuit_function_type = self_type.member_function_type(identifier).unwrap().to_owned(); - - // Create a new scope for the function variables. - let mut scope = Scope::new(Some(parent_scope)); - - // Initialize function inputs as variables. - scope.parse_function_inputs(&circuit_function_type.function.inputs)?; - - // Create new list of scopes for frame. - let scopes = vec![scope]; - - // Create new frame struct. - // Update variables when encountering let/const variable definitions. - let mut frame = Self { - function_type: circuit_function_type.function, - self_type: Some(self_type), - scopes, - statements: function.statements, - type_assertions: Vec::new(), - user_defined_types, - }; - - // Create type assertions for function statements - frame.parse_statements()?; - - Ok(frame) - } - - /// - /// Pushes a new variable `Scope` to the list of scopes in the current `Frame`. - /// - fn push_scope(&mut self, scope: Scope) { - self.scopes.push(scope) - } - - /// - /// Removes and returns the most recent `Scope` from the list of scopes in the current `Frame`. - /// - fn pop_scope(&mut self) -> Option { - self.scopes.pop() - } - - /// - /// Insert a variable into the symbol table in the current scope. - /// - fn insert_variable(&mut self, name: String, type_: Type, span: &Span) -> Result<(), FrameError> { - // Modify the current scope. - let scope = self.scopes.last_mut().unwrap(); - - // Insert the variable name -> type. - match scope.variables.insert(name.clone(), type_) { - Some(_type) => Err(FrameError::duplicate_variable(&name, span)), - None => Ok(()), - } - } - - /// - /// Get a variable's type from the symbol table in the current scope. - /// - fn get_variable(&self, name: &String) -> Option<&Type> { - // Lookup in the current scope. - let scope = self.scopes.last().unwrap(); - - // Get the variable by name. - scope.get_variable(name) - } - - /// - /// Get a function's type from the user defined types in the current scope. - /// - fn get_function(&self, name: &String) -> Option<&FunctionType> { - self.user_defined_types.get_function(name) - } - - /// - /// Get a circuit's type from the user defined types in the current scope. - /// - fn get_circuit(&self, name: &String) -> Option<&CircuitType> { - self.user_defined_types.get_circuit(name) - } - - /// - /// Creates a new equality type assertion between the given types. - /// - fn assert_equal(&mut self, left: Type, right: Type, span: &Span) { - let type_assertion = TypeAssertion::new_equality(left, right, span); - - self.type_assertions.push(type_assertion); - } - - /// - /// Creates a new membership type assertion between a given and set of types. - /// - fn assert_membership(&mut self, given: Type, set: Vec, span: &Span) { - let type_assertion = TypeAssertion::new_membership(given, set, span); - - self.type_assertions.push(type_assertion); - } - - /// - /// Creates a new membership type assertion between a given and the set of negative integer types. - /// - fn assert_negative_integer(&mut self, given: &Type, span: &Span) { - let negative_integer_types = Type::negative_integer_types(); - - self.assert_membership(given.clone(), negative_integer_types, span) - } - - /// - /// Creates a new membership type assertion between a given and the set of all integer types. - /// - fn assert_integer(&mut self, given: &Type, span: &Span) { - let integer_types = Type::integer_types(); - - self.assert_membership(given.clone(), integer_types, span) - } - - /// - /// Creates a new membership type assertion between a given and the set of index types. - /// - fn assert_index(&mut self, given: &Type, span: &Span) { - let index_types = Type::index_types(); - - self.assert_membership(given.clone(), index_types, span) - } - - /// - /// Collects a vector of `TypeAssertion` predicates from a vector of statements. - /// - fn parse_statements(&mut self) -> Result<(), FrameError> { - for statement in self.statements.clone() { - self.parse_statement(&statement)?; - } - - Ok(()) - } - - /// - /// Collects a vector of `TypeAssertion` predicates from a statement. - /// - fn parse_statement(&mut self, statement: &Statement) -> Result<(), FrameError> { - match statement { - Statement::Return(expression, span) => self.parse_return(expression, span), - Statement::Definition(declare, variables, expression, span) => { - self.parse_definition(declare, variables, expression, span) - } - Statement::Assign(assignee, expression, span) => self.parse_assign(assignee, expression, span), - Statement::Conditional(conditional, span) => self.parse_statement_conditional(conditional, span), - Statement::Iteration(identifier, from_to, statements, span) => { - self.parse_iteration(identifier, from_to, statements, span) - } - Statement::Expression(expression, span) => self.parse_statement_expression(expression, span), - Statement::Console(_console_call) => Ok(()), // Console function calls do not generate type assertions. - } - } - - /// - /// Collects `TypeAssertion` predicates from a return statement. - /// - fn parse_return(&mut self, expression: &Expression, span: &Span) -> Result<(), FrameError> { - // Get the function output type. - let output_type = &self.function_type.output.type_; - - // Create the left hand side of a type assertion. - let left = output_type.clone(); - - // Create the right hand side from the statement return expression. - let right = self.parse_expression(expression)?; - - // Create a new type assertion for the statement return. - self.assert_equal(left, right, span); - - Ok(()) - } - - /// - /// Collects `Type Assertion` predicates from a definition statement. - /// - fn parse_definition( - &mut self, - _declare: &Declare, - variables: &Variables, - expression: &Expression, - span: &Span, - ) -> Result<(), FrameError> { - // Parse the definition expression. - let actual_type = self.parse_expression(expression)?; - - // Check if an explicit type is given. - if let Some(type_) = variables.type_.clone() { - // Convert the expected type into a dynamic check type. - let expected_type = match self.self_type.clone() { - Some(circuit_type) => { - Type::new_from_circuit(&self.user_defined_types, type_, circuit_type.identifier, span.clone()) - .unwrap() - } - None => Type::new(&self.user_defined_types, type_, span.clone()).unwrap(), - }; - - // Assert that the expected type is equal to the actual type. - self.assert_equal(expected_type.clone(), actual_type.clone(), span) - } - - // Check for multiple defined variables. - if variables.names.len() == 1 { - // Insert variable into symbol table - let variable = variables.names[0].clone(); - - self.insert_variable(variable.identifier.name, actual_type, span)?; - } else { - // Expect a tuple type. - let types = match actual_type { - Type::Tuple(types) => types, - _ => return Err(FrameError::not_enough_values(span)), - }; - - // Check number of variables == number of types. - if types.len() != variables.names.len() { - return Err(FrameError::invalid_number_of_values( - types.len(), - variables.names.len(), - span, - )); - } - - // Insert variables into symbol table - for (variable, type_) in variables.names.iter().zip(types) { - self.insert_variable(variable.identifier.name.clone(), type_, span)?; - } - } - - Ok(()) - } - - /// - /// Asserts that the assignee's type is equal to the `Expression` type. - /// - fn parse_assign(&mut self, assignee: &Assignee, expression: &Expression, span: &Span) -> Result<(), FrameError> { - // Parse assignee type. - let assignee_type = self.parse_assignee(assignee, span)?; - - // Parse expression type. - let expression_type = self.parse_expression(expression)?; - - // Assert that the assignee_type == expression_type. - self.assert_equal(assignee_type, expression_type, span); - - Ok(()) - } - - /// - /// Returns the type of the assignee. - /// - fn parse_assignee(&mut self, assignee: &Assignee, span: &Span) -> Result { - // Get the type of the assignee variable. - let mut type_ = if assignee.identifier.is_self() { - // If the variable is the self keyword, then return the self.circuit_type - let self_type = self.self_type_or_error(span)?; - - Type::Circuit(self_type.identifier) - } else { - // Otherwise, lookup the variable by name in the symbol table. - self.get_variable(&assignee.identifier.name) - .map(|type_| type_.to_owned()) - .ok_or_else(|| FrameError::undefined_variable(&assignee.identifier))? - }; - - // Iteratively evaluate assignee access types. - for access in &assignee.accesses { - let access_type = match access { - AssigneeAccess::Array(r_or_e) => self.parse_array_access(type_, r_or_e, span), - AssigneeAccess::Tuple(index) => self.parse_tuple_access(type_, *index, span), - AssigneeAccess::Member(identifier) => self.parse_circuit_member_access(type_, identifier, span), - }?; - - type_ = access_type; - } - - Ok(type_) - } - - /// - /// Collects `TypeAssertion` predicates from a block of statements. - /// - fn parse_block(&mut self, statements: &Vec, _span: &Span) -> Result<(), FrameError> { - // Push new scope. - let scope = Scope::new(self.scopes.last().map(|scope| scope.clone())); - self.push_scope(scope); - - // Parse all statements. - for statement in statements.iter() { - self.parse_statement(statement)?; - } - - // Pop out of scope. - let _scope = self.pop_scope(); - - Ok(()) - } - - /// - /// Collects `TypeAssertion` predicates from a conditional statement. - /// - /// Creates a new scope for each code block in the conditional. - /// - fn parse_statement_conditional( - &mut self, - conditional: &ConditionalStatement, - span: &Span, - ) -> Result<(), FrameError> { - // Parse the condition expression. - let condition = self.parse_expression(&conditional.condition)?; - - // Assert that the condition is a boolean type. - let boolean_type = Type::Boolean; - self.assert_equal(boolean_type, condition, span); - - // Parse conditional statements. - self.parse_block(&conditional.statements, span)?; - - // Parse conditional or end. - match &conditional.next { - Some(cond_or_end) => self.parse_conditional_nested_or_end(cond_or_end, span)?, - None => {} - } - - Ok(()) - } - - /// - /// Collects `TypeAssertion` predicates from a conditional statement. - /// - fn parse_conditional_nested_or_end( - &mut self, - cond_or_end: &ConditionalNestedOrEndStatement, - span: &Span, - ) -> Result<(), FrameError> { - match cond_or_end { - ConditionalNestedOrEndStatement::Nested(nested) => self.parse_statement_conditional(nested, span), - ConditionalNestedOrEndStatement::End(statements) => self.parse_block(statements, span), - } - } - - /// - /// Collects `TypeAssertion` predicates from an iteration statement. - /// - fn parse_iteration( - &mut self, - identifier: &Identifier, - from_to: &(Expression, Expression), - statements: &Vec, - span: &Span, - ) -> Result<(), FrameError> { - // Insert variable into symbol table with u32 type. - let u32_type = Type::IntegerType(IntegerType::U32); - let _expect_none = self.insert_variable(identifier.name.to_owned(), u32_type.clone(), span); - - // Parse `from` and `to` expressions. - let from_type = self.parse_expression(&from_to.0)?; - let to_type = self.parse_expression(&from_to.1)?; - - // Assert `from` and `to` types are a u32 or implicit. - self.assert_equal(u32_type.clone(), from_type, span); - self.assert_equal(u32_type, to_type, span); - - // Parse block of statements. - self.parse_block(statements, span) - } - - /// - /// Asserts that the statement `UnresolvedExpression` returns an empty tuple. - /// - fn parse_statement_expression(&mut self, expression: &Expression, span: &Span) -> Result<(), FrameError> { - // Create empty tuple type. - let expected_type = Type::Tuple(Vec::with_capacity(0)); - - // Parse the actual type of the expression. - let actual_type = self.parse_expression(expression)?; - - self.assert_equal(expected_type, actual_type, span); - - Ok(()) - } - - /// - /// Returns the type of an expression. - /// - fn parse_expression(&mut self, expression: &Expression) -> Result { - match expression { - // Type variables - Expression::Identifier(identifier) => self.parse_identifier(identifier), - - // Explicit types - Expression::Boolean(_, _) => Ok(Type::Boolean), - Expression::Address(_, _) => Ok(Type::Address), - Expression::Field(_, _) => Ok(Type::Field), - Expression::Group(_) => Ok(Type::Group), - Expression::Implicit(name, span) => Ok(Self::parse_implicit(Identifier::new_with_span(name, span))), - Expression::Integer(integer_type, _, _) => Ok(Type::IntegerType(integer_type.clone())), - - // Number operations - Expression::Add(left_right, span) => { - self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Sub(left_right, span) => { - self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Mul(left_right, span) => { - self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Div(left_right, span) => { - self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Pow(left_right, span) => { - self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Negate(expression, span) => self.parse_negate_expression(expression, span), - - // Boolean operations - Expression::Not(expression, span) => self.parse_boolean_expression(expression, span), - Expression::Or(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::And(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Eq(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Ge(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Gt(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Le(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Lt(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - - // Conditionals - Expression::IfElse(triplet, span) => { - self.parse_conditional_expression(&triplet.0, &triplet.1, &triplet.2, span) - } - - // Arrays - Expression::Array(expressions, span) => self.parse_array(expressions, span), - Expression::ArrayAccess(array_w_index, span) => { - self.parse_expression_array_access(&array_w_index.0, &array_w_index.1, span) - } - - // Tuples - Expression::Tuple(expressions, span) => self.parse_tuple(expressions, span), - Expression::TupleAccess(tuple, index, span) => self.parse_expression_tuple_access(tuple, *index, span), - - // Circuits - Expression::Circuit(identifier, members, span) => self.parse_circuit(identifier, members, span), - Expression::CircuitMemberAccess(expression, identifier, span) => { - self.parse_expression_circuit_member_access(expression, identifier, span) - } - Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { - self.parse_static_circuit_function_access(expression, identifier, span) - } - - // Functions - Expression::FunctionCall(name, arguments, span) => self.parse_function_call(name, arguments, span), - Expression::CoreFunctionCall(name, arguments, span) => self.parse_core_function_call(name, arguments, span), - } - } - - /// - /// Returns the type of the identifier in the symbol table. - /// - fn parse_identifier(&self, identifier: &Identifier) -> Result { - // Check Self type. - if identifier.is_self() { - // Check for frame circuit self type. - let circuit_type = self.self_type_or_error(&identifier.span)?; - - // Return new type with circuit identifier. - return Ok(Type::Circuit(circuit_type.identifier)); - } - - // Check variable symbol table. - if let Some(type_) = self.get_variable(&identifier.name) { - return Ok(type_.to_owned()); - }; - - // Check function symbol table. - if let Some(function_type) = self.get_function(&identifier.name) { - return Ok(Type::Function(function_type.identifier.to_owned())); - }; - - // Check circuit symbol table. - if let Some(circuit_type) = self.get_circuit(&identifier.name) { - return Ok(Type::Circuit(circuit_type.identifier.to_owned())); - } - - Ok(Self::parse_implicit(identifier.to_owned())) - } - - /// - /// Returns a new type variable from a given identifier - /// - fn parse_implicit(identifier: Identifier) -> Type { - Type::TypeVariable(TypeVariable::from(identifier)) - } - - /// - /// Returns the type of a binary expression. - /// - fn parse_binary_expression( - &mut self, - left: &Expression, - right: &Expression, - span: &Span, - ) -> Result { - // Get the left expression type. - let left_type = self.parse_expression(left)?; - - // Get the right expression type. - let right_type = self.parse_expression(right)?; - - // Create a type assertion left_type == right_type. - self.assert_equal(left_type.clone(), right_type, span); - - Ok(left_type) - } - - /// - /// Returns the `Type` of the expression after the binary operation. - /// - /// Asserts that the `Type` is an integer. - /// - fn parse_integer_binary_expression( - &mut self, - left: &Expression, - right: &Expression, - span: &Span, - ) -> Result { - let type_ = self.parse_binary_expression(left, right, span)?; - - // Assert that the type is an integer. - self.assert_integer(&type_, span); - - Ok(type_) - } - - /// - /// Returns the `Boolean` type if the expression is a `Boolean` type. - /// - fn parse_boolean_expression(&mut self, expression: &Expression, span: &Span) -> Result { - // Return the `Boolean` type - let boolean_type = Type::Boolean; - - // Get the type of the expression - let expression_type = self.parse_expression(expression)?; - - // Assert that the type is a boolean. - self.assert_equal(boolean_type.clone(), expression_type, span); - - Ok(boolean_type) - } - - /// - /// Returns the `Type` of the expression being negated. Must be a negative integer type. - /// - fn parse_negate_expression(&mut self, expression: &Expression, span: &Span) -> Result { - // Parse the expression type. - let type_ = self.parse_expression(expression)?; - - // Assert that this integer can be negated. - self.assert_negative_integer(&type_, span); - - Ok(type_) - } - - /// - /// Returns the `Boolean` type if the binary expression is a `Boolean` type. - /// - fn parse_boolean_binary_expression( - &mut self, - left: &Expression, - right: &Expression, - span: &Span, - ) -> Result { - // Create the `Boolean` type. - let boolean_type = Type::Boolean; - - // Create a new type assertion for the binary expression - let _binary_expression_type = self.parse_binary_expression(left, right, span)?; - - // Return the `Boolean` type. - Ok(boolean_type) - } - - /// - /// Returns the type of the conditional expression. - /// - fn parse_conditional_expression( - &mut self, - condition: &Expression, - first: &Expression, - second: &Expression, - span: &Span, - ) -> Result { - // Check that the type of the condition expression is a boolean. - let _condition_type = self.parse_boolean_expression(condition, span)?; - - // Check that the types of the first and second expression are equal. - self.parse_binary_expression(first, second, span) - } - - /// - /// Returns the type of the tuple expression. - /// - fn parse_tuple(&mut self, expressions: &Vec, _span: &Span) -> Result { - let mut types = vec![]; - - // Parse all tuple expressions. - for expression in expressions { - let type_ = self.parse_expression(expression)?; - - types.push(type_) - } - - Ok(Type::Tuple(types)) - } - - /// - /// Returns the type of the accessed tuple element when called as an expression. - /// - fn parse_expression_tuple_access( - &mut self, - expression: &Expression, - index: usize, - span: &Span, - ) -> Result { - // Parse the tuple expression which could be a variable with type tuple. - let type_ = self.parse_expression(expression)?; - - // Parse the tuple access. - self.parse_tuple_access(type_, index, span) - } - - /// - /// Returns the type of the accessed tuple element. - /// - fn parse_tuple_access(&mut self, type_: Type, index: usize, span: &Span) -> Result { - // Check the type is a tuple. - let elements = match type_ { - Type::Tuple(elements) => elements, - type_ => return Err(FrameError::tuple_access(&type_, span)), - }; - - let element_type = elements[index].clone(); - - Ok(element_type) - } - - /// - /// Returns the type of the array expression. - /// - fn parse_array(&mut self, expressions: &Vec, span: &Span) -> Result { - // Store array element type. - let mut element_type = None; - let mut count = 0usize; - - // Parse all array elements. - for expression in expressions { - // Get the type and count of elements in each spread or expression. - let (type_, element_count) = self.parse_spread_or_expression(expression, span)?; - - // Assert that array element types are the same. - if let Some(prev_type) = element_type { - self.assert_equal(prev_type, type_.clone(), span); - } - - // Update array element type. - element_type = Some(type_); - - // Update number of array elements. - count += element_count; - } - - // Return an error for empty arrays. - let type_ = match element_type { - Some(type_) => type_, - None => return Err(FrameError::empty_array(span)), - }; - - Ok(Type::Array(Box::new(type_), vec![count])) - } - - /// - /// Returns the type and count of elements in a spread or expression. - /// - fn parse_spread_or_expression( - &mut self, - s_or_e: &SpreadOrExpression, - span: &Span, - ) -> Result<(Type, usize), FrameError> { - Ok(match s_or_e { - SpreadOrExpression::Spread(expression) => { - // Parse the type of the spread array expression. - let array_type = self.parse_expression(expression)?; - - // Check that the type is an array. - let (element_type, mut dimensions) = match array_type { - Type::Array(element_type, dimensions) => (element_type, dimensions), - type_ => return Err(FrameError::invalid_spread(type_, span)), - }; - - // A spread copies the elements of an array. - // If the array has elements of type array, we must return a new array type with proper dimensions. - // If the array has elements of any other type, we can return the type and count directly. - let count = dimensions.pop().unwrap(); - - let type_ = if dimensions.is_empty() { - *element_type - } else { - Type::Array(element_type, dimensions) - }; - - (type_, count) - } - SpreadOrExpression::Expression(expression) => (self.parse_expression(expression)?, 1), - }) - } - - /// - /// Returns the type of the accessed array element when called as an expression. - /// - fn parse_expression_array_access( - &mut self, - expression: &Expression, - r_or_e: &RangeOrExpression, - span: &Span, - ) -> Result { - // Parse the array expression which could be a variable with type array. - let type_ = self.parse_expression(expression)?; - - // Parse the array access. - self.parse_array_access(type_, r_or_e, span) - } - - /// - /// Returns the type of the accessed array element. - /// - fn parse_array_access(&mut self, type_: Type, r_or_e: &RangeOrExpression, span: &Span) -> Result { - // Check the type is an array. - let (element_type, _dimensions) = match type_ { - Type::Array(type_, dimensions) => (type_, dimensions), - type_ => return Err(FrameError::array_access(&type_, span)), - }; - - // Get the length of the array. - // let length = *dimensions.last().unwrap(); - - // Evaluate the range as an array type or the expression as the element type. - match r_or_e { - RangeOrExpression::Range(from, to) => { - if let Some(expression) = from { - // Parse the expression type. - let type_ = self.parse_expression(expression)?; - - self.assert_index(&type_, span); - } - - if let Some(expression) = to { - // Parse the expression type. - let type_ = self.parse_expression(expression)?; - - self.assert_index(&type_, span); - } - } - RangeOrExpression::Expression(expression) => { - // Parse the expression type. - let type_ = self.parse_expression(expression)?; - - // Assert the type is an index. - self.assert_index(&type_, span); - } - } - - Ok(*element_type) - } - - /// - /// Returns the Self type of the frame or an error if it does not exist. - /// - fn self_type_or_error(&self, span: &Span) -> Result { - self.self_type - .as_ref() - .map(|circuit_type| circuit_type.clone()) - .ok_or_else(|| FrameError::circuit_self(span)) - } - - /// - /// Returns the type of inline circuit expression. - /// - fn parse_circuit( - &mut self, - identifier: &Identifier, - members: &Vec, - span: &Span, - ) -> Result { - // Check if identifier is Self circuit type. - let circuit_type = if identifier.is_self() { - // Get the Self type of the frame. - self.self_type_or_error(span)? - } else { - // Get circuit type. - self.user_defined_types - .get_circuit(&identifier.name) - .map(|circuit_type| circuit_type.clone()) - .ok_or_else(|| FrameError::undefined_circuit(identifier))? - }; - - // Check the length of the circuit members. - if circuit_type.variables.len() != members.len() { - return Err(FrameError::num_circuit_variables( - circuit_type.variables.len(), - members.len(), - span, - )); - } - - // Assert members are circuit type member types. - for (expected_variable, actual_variable) in circuit_type.variables.iter().zip(members) { - // Parse actual variable expression. - let actual_type = self.parse_expression(&actual_variable.expression)?; - - // Assert expected variable type == actual variable type. - self.assert_equal(expected_variable.type_.clone(), actual_type, span) - } - - Ok(Type::Circuit(circuit_type.identifier)) - } - - /// - /// Returns the type of the accessed circuit member when called as an expression. - /// - fn parse_expression_circuit_member_access( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Parse circuit name. - let type_ = self.parse_expression(expression)?; - - // Parse the circuit member access. - self.parse_circuit_member_access(type_, identifier, span) - } - - /// - /// Returns the type of the accessed circuit member. - /// - fn parse_circuit_member_access( - &mut self, - type_: Type, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Check that type is a circuit type. - let circuit_type = self.parse_circuit_name(type_, span)?; - - // Look for member with matching name. - Ok(circuit_type.member_type(&identifier)?) - } - - /// - /// Returns the type returned by calling the static circuit function. - /// - fn parse_static_circuit_function_access( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Parse the circuit name. - let type_ = self.parse_expression(expression)?; - - self.parse_circuit_member_access(type_, identifier, span) - } - - /// - /// Returns a `CircuitType` given a circuit expression. - /// - fn parse_circuit_name(&mut self, type_: Type, span: &Span) -> Result<&CircuitType, FrameError> { - // Check that type is a circuit type. - match type_ { - Type::Circuit(identifier) => { - // Lookup circuit identifier. - self.user_defined_types - .get_circuit(&identifier.name) - .ok_or_else(|| FrameError::undefined_circuit(&identifier)) - } - type_ => Err(FrameError::invalid_circuit(type_, span)), - } - } - - /// - /// Returns a `FunctionType` given a function expression. - /// - fn parse_function_name(&mut self, expression: &Expression, span: &Span) -> Result { - // Case 1: Call a function defined in the program file. - // Case 2: Call a circuit function. - // Case 3: Call a static circuit function. - // Return an Error in any other case. - match expression { - Expression::Identifier(identifier) => self.parse_program_function(identifier, span), - Expression::CircuitMemberAccess(expression, identifier, span) => { - self.parse_circuit_function(expression, identifier, span) - } - Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { - self.parse_static_circuit_function(expression, identifier, span) - } - expression => Err(FrameError::invalid_function(expression, span)), - } - } - - /// - /// Returns a `FunctionType` given a function identifier. - /// - fn parse_program_function(&mut self, identifier: &Identifier, _span: &Span) -> Result { - self.user_defined_types - .get_function(&identifier.name) - .map(|function_type| function_type.to_owned()) - .ok_or_else(|| FrameError::undefined_function(identifier)) - } - - /// - /// Returns a `CircuitFunctionType` given a circuit expression and function identifier. - /// - fn parse_circuit_function_type( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result<&CircuitFunctionType, FrameError> { - // Parse circuit name. - let type_ = self.parse_expression(expression)?; - - // Get circuit type. - let circuit_type = self.parse_circuit_name(type_, span)?; - - // Find circuit function by identifier. - circuit_type - .member_function_type(identifier) - .ok_or_else(|| FrameError::undefined_circuit_function(identifier)) - } - - /// - /// Returns a `FunctionType` given a circuit expression and non-static function identifier. - /// - fn parse_circuit_function( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Find circuit function type. - let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; - - // Check that the function is non-static. - if circuit_function_type.attributes.contains(&Attribute::Static) { - return Err(FrameError::invalid_static_access(identifier)); - } - - // Return the function type. - Ok(circuit_function_type.function.to_owned()) - } - - /// - /// Returns a `FunctionType` given a circuit expression and static function identifier. - /// - fn parse_static_circuit_function( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Find circuit function type. - let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; - - // Check that the function is static. - if !circuit_function_type.attributes.contains(&Attribute::Static) { - return Err(FrameError::invalid_member_access(identifier)); - } - - Ok(circuit_function_type.function.to_owned()) - } - - /// - /// Returns the type returned by calling the function. - /// - /// Does not attempt to evaluate the function call. We are just checking types at this step. - /// - fn parse_function_call( - &mut self, - expression: &Expression, - inputs: &Vec, - span: &Span, - ) -> Result { - // Parse the function name. - let function_type = self.parse_function_name(expression, span)?; - - // Check the length of arguments - if function_type.inputs.len() != inputs.len() { - return Err(FrameError::num_inputs(function_type.inputs.len(), inputs.len(), span)); - } - - // Assert function inputs are correct types. - for (expected_input, actual_input) in function_type.inputs.iter().zip(inputs) { - // Parse expected input type. - let expected_type = expected_input.type_(); - - // Parse actual input type. - let actual_type = self.parse_expression(actual_input)?; - - // Assert expected input type == actual input type. - self.assert_equal(expected_type, actual_type, span); - } - - // Return the function output type. - Ok(function_type.output.type_.clone()) - } - - /// - /// Returns the type returned by calling the core function. - /// - fn parse_core_function_call( - &mut self, - _name: &String, - _arguments: &Vec, - _span: &Span, - ) -> Result { - unimplemented!("type checks for core function calls not implemented") - } - - /// - /// Returns a new `Function` if all `TypeAssertions` can be solved successfully. - /// - fn solve(self) -> Result<(), FrameError> { - let mut unsolved = self.type_assertions.clone(); - - // Solve all type equality assertions first. - let mut unsolved_membership = Vec::new(); - - while !unsolved.is_empty() { - // Pop type assertion from list - let type_assertion = unsolved.pop().unwrap(); - - // If it is a membership assertion, then skip it for now. - if let TypeAssertion::Membership(membership) = type_assertion { - unsolved_membership.push(membership); - - continue; - } - - // Collect `TypeVariablePairs` from the `TypeAssertion`. - let pairs = type_assertion.pairs()?; - - // If no pairs are found, attempt to evaluate the `TypeAssertion`. - if pairs.is_empty() { - // Evaluate the `TypeAssertion`. - type_assertion.evaluate()? - } else { - // Iterate over each `TypeVariable` -> `Type` pair. - for pair in pairs.get_pairs() { - // Substitute the `TypeVariable` for it's paired `Type` in all `TypeAssertion`s. - for original in &mut unsolved { - original.substitute(&pair.0, &pair.1) - } - - for original in &mut unsolved_membership { - original.substitute(&pair.0, &pair.1) - } - } - } - } - - // Solve all type membership assertions. - while !unsolved_membership.is_empty() { - // Pop type assertion from list - let type_assertion = unsolved_membership.pop().unwrap(); - - // Solve the membership assertion. - type_assertion.evaluate()?; - } - - Ok(()) - } -} - -/// A structure for tracking the types of defined variables in a block of code. -#[derive(Clone)] -pub struct Scope { - pub loop_variables: VariableTable, - pub variables: VariableTable, -} - -impl Scope { - /// - /// Returns a new `Scope` from an optional given `Scope`. - /// - /// The new scope will contain the variables of the optional given `Scope`. - /// - pub fn new(parent: Option) -> Self { - match parent { - Some(scope) => scope.clone(), - None => Self::empty(), - } - } - - /// - /// Returns a new `Scope` with no variables. - /// - fn empty() -> Self { - Self { - loop_variables: VariableTable::new(), - variables: VariableTable::new(), - } - } - - /// - /// Inserts a variable name -> type mapping into the loop variable table. - /// - pub fn insert_loop_variable(&mut self, name: String, type_: Type) -> Option { - self.loop_variables.insert(name, type_) - } - - /// - /// Inserts a variable name -> type mapping into the variable table. - /// - pub fn insert_variable(&mut self, name: String, type_: Type) -> Option { - self.variables.insert(name, type_) - } - - /// - /// Returns a reference to the type corresponding to the loop variable name. - /// - pub fn get_loop_variable(&self, name: &String) -> Option<&Type> { - self.loop_variables.get(name) - } - - /// - /// Returns a reference to the type corresponding to the variable name. - /// - /// Checks loop variables first, then non-loop variables. - /// - pub fn get_variable(&self, name: &String) -> Option<&Type> { - match self.get_loop_variable(name) { - Some(loop_variable_type) => Some(loop_variable_type), - None => self.variables.get(name), - } - } - - /// - /// Inserts a vector of function input types into the `Scope` variable table. - /// - pub fn parse_function_inputs(&mut self, function_inputs: &Vec) -> Result<(), ScopeError> { - self.variables - .parse_function_inputs(function_inputs) - .map_err(|err| ScopeError::VariableTableError(err)) - } -} - -/// Mapping of variable names to types -#[derive(Clone)] -pub struct VariableTable(pub HashMap); - -impl VariableTable { - /// - /// Returns a new variable table - /// - pub fn new() -> Self { - Self(HashMap::new()) - } - - /// - /// Insert a name -> type pair into the variable table. - /// - /// If the variable table did not have this key present, [`None`] is returned. - /// - /// If the variable table did have this key present, the type is updated, and the old - /// type is returned. - /// - pub fn insert(&mut self, name: String, type_: Type) -> Option { - self.0.insert(name, type_) - } - - /// - /// Returns a reference to the type corresponding to the name. - /// - /// If the variable table did not have this key present, throw an undefined variable error - /// using the given span. - /// - pub fn get(&self, name: &String) -> Option<&Type> { - self.0.get(name) - } - - /// - /// Inserts a vector of function input types into the variable table. - /// - pub fn parse_function_inputs( - &mut self, - function_inputs: &Vec, - ) -> Result<(), VariableTableError> { - for input in function_inputs { - let input_name = input.identifier().name.clone(); - let input_type = input.type_(); - - // TODO (collinc97) throw an error for duplicate function input names. - self.insert(input_name, input_type); - } - Ok(()) - } -} - -/// A predicate that evaluates equality between two `Types`s. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub enum TypeAssertion { - Equality(TypeEquality), - Membership(TypeMembership), -} - -impl TypeAssertion { - /// - /// Returns a `TypeAssertion::Equality` predicate from given left and right `Types`s. - /// - pub fn new_equality(left: Type, right: Type, span: &Span) -> Self { - Self::Equality(TypeEquality::new(left, right, span)) - } - - /// - /// Returns a `TypeAssertion::Membership` predicate from given and set `Type`s. - /// - pub fn new_membership(given: Type, set: Vec, span: &Span) -> Self { - Self::Membership(TypeMembership::new(given, set, span)) - } - - /// - /// Returns one or more `TypeVariablePairs` generated by the given `TypeAssertion`. - /// - pub fn pairs(&self) -> Result { - match self { - TypeAssertion::Equality(equality) => equality.pairs(), - TypeAssertion::Membership(membership) => Err(TypeAssertionError::membership_pairs(membership)), - } - } - - /// - /// Substitutes the given type for self if self is equal to the type variable. - /// - pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { - match self { - TypeAssertion::Equality(equality) => equality.substitute(variable, type_), - TypeAssertion::Membership(membership) => membership.substitute(variable, type_), - } - } - - /// - /// Checks if the `TypeAssertion` is satisfied. - /// - pub fn evaluate(&self) -> Result<(), TypeAssertionError> { - match self { - TypeAssertion::Equality(equality) => equality.evaluate(), - TypeAssertion::Membership(membership) => membership.evaluate(), - } - } -} - -/// A predicate that evaluates to true if the given type is equal to a member in the set vector of types. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct TypeMembership { - given: Type, - set: Vec, - span: Span, -} - -impl TypeMembership { - /// - /// Returns a `TypeMembership` predicate from given and set `Type`s. - /// - pub fn new(given: Type, set: Vec, span: &Span) -> Self { - Self { - given, - set, - span: span.to_owned(), - } - } - - /// - /// Substitutes the given `TypeVariable` for each `Type` in the `TypeMembership`. - /// - pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { - self.given.substitute(variable, type_) - } - - /// - /// Returns true if the given type is equal to a member of the set. - /// - pub fn evaluate(&self) -> Result<(), TypeAssertionError> { - if self.set.contains(&self.given) { - Ok(()) - } else { - Err(TypeAssertionError::membership_failed( - &self.given, - &self.set, - &self.span, - )) - } - } - - /// - /// Returns the self.span. - /// - pub fn span(&self) -> &Span { - &self.span - } -} - -/// A predicate that evaluates equality between two `Type`s. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct TypeEquality { - left: Type, - right: Type, - span: Span, -} - -impl TypeEquality { - /// - /// Returns a `TypeEquality` predicate from given left and right `Types`s - /// - pub fn new(left: Type, right: Type, span: &Span) -> Self { - Self { - left, - right, - span: span.to_owned(), - } - } - - /// - /// Substitutes the given `TypeVariable` for each `Types` in the `TypeEquality`. - /// - pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { - self.left.substitute(variable, type_); - self.right.substitute(variable, type_); - } - - /// - /// Checks if the `self.left` == `self.right`. - /// - pub fn evaluate(&self) -> Result<(), TypeAssertionError> { - if self.left.eq(&self.right) { - Ok(()) - } else { - Err(TypeAssertionError::equality_failed(&self.left, &self.right, &self.span)) - } - } - - /// - /// Returns the (type variable, type) pair from this assertion. - /// - pub fn pairs(&self) -> Result { - TypeVariablePairs::new(&self.left, &self.right, &self.span) - } -} - -/// A type variable -> type pair. -pub struct TypeVariablePair(TypeVariable, Type); - -/// A vector of `TypeVariablePair`s. -pub struct TypeVariablePairs(Vec); - -impl Default for TypeVariablePairs { - fn default() -> Self { - Self(Vec::new()) - } -} - -impl TypeVariablePairs { - /// - /// Returns a new `TypeVariablePairs` struct from the given left and right types. - /// - pub fn new(left: &Type, right: &Type, span: &Span) -> Result { - let mut pairs = Self::default(); - - // Push all `TypeVariablePair`s. - pairs.push_pairs(left, right, span)?; - - Ok(pairs) - } - - /// - /// Returns true if the self vector has no pairs. - /// - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - /// - /// Returns the self vector of pairs. - /// - pub fn get_pairs(&self) -> &Vec { - &self.0 - } - - /// - /// Pushes a new `TypeVariablePair` struct to self. - /// - pub fn push(&mut self, variable: &TypeVariable, type_: &Type) { - // Create a new type variable -> type pair. - let pair = TypeVariablePair(variable.clone(), type_.clone()); - - // Push the pair to the self vector. - self.0.push(pair); - } - - /// - /// Checks if the given left or right type contains a `TypeVariable`. - /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left - /// and right type. - /// - pub fn push_pairs(&mut self, left: &Type, right: &Type, span: &Span) -> Result<(), TypeAssertionError> { - match (left, right) { - (Type::TypeVariable(variable), type_) => Ok(self.push(variable, type_)), - (type_, Type::TypeVariable(variable)) => Ok(self.push(variable, type_)), - (Type::Array(left_type, left_dimensions), Type::Array(right_type, right_dimensions)) => { - self.push_pairs_array(left_type, left_dimensions, right_type, right_dimensions, span) - } - (Type::Tuple(left_types), Type::Tuple(right_types)) => self.push_pairs_tuple(left_types, right_types, span), - (_, _) => Ok(()), // No `TypeVariable` found so we do not push any pairs. - } - } - - /// - /// Checks if the given left or right array type contains a `TypeVariable`. - /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left - /// and right type. - /// - fn push_pairs_array( - &mut self, - left_type: &Type, - left_dimensions: &Vec, - right_type: &Type, - right_dimensions: &Vec, - span: &Span, - ) -> Result<(), TypeAssertionError> { - // Flatten the array types to get the element types. - let (left_type_flat, left_dimensions_flat) = flatten_array_type(left_type, left_dimensions.to_owned()); - let (right_type_flat, right_dimensions_flat) = flatten_array_type(right_type, right_dimensions.to_owned()); - - // If the dimensions do not match, then throw an error. - if left_dimensions_flat.ne(&right_dimensions_flat) { - return Err(TypeAssertionError::array_dimensions( - left_dimensions_flat, - right_dimensions_flat, - span, - )); - } - - // Compare the array element types. - self.push_pairs(left_type_flat, right_type_flat, span) - } - - /// - /// Checks if any given left or right tuple type contains a `TypeVariable`. - /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left - /// and right type. - /// - fn push_pairs_tuple( - &mut self, - left_types: &Vec, - right_types: &Vec, - span: &Span, - ) -> Result<(), TypeAssertionError> { - // Iterate over each left == right pair of types. - for (left, right) in left_types.iter().zip(right_types) { - // Check for `TypeVariablePair`s. - self.push_pairs(left, right, span)?; + frame.check()?; } Ok(()) diff --git a/dynamic-check/src/errors/mod.rs b/dynamic-check/src/errors/mod.rs index 20b47dc46e..12128a8127 100644 --- a/dynamic-check/src/errors/mod.rs +++ b/dynamic-check/src/errors/mod.rs @@ -14,9 +14,6 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -// pub mod circuit; -// pub use self::circuit::*; - pub mod dynamic_check; pub use self::dynamic_check::*; diff --git a/dynamic-check/src/lib.rs b/dynamic-check/src/lib.rs index 1590b58772..3c1f97a363 100644 --- a/dynamic-check/src/lib.rs +++ b/dynamic-check/src/lib.rs @@ -17,8 +17,14 @@ #[macro_use] extern crate thiserror; +pub mod assertions; +pub use self::assertions::*; + pub mod dynamic_check; pub use self::dynamic_check::*; pub mod errors; pub use self::errors::*; + +pub mod objects; +pub use self::objects::*; diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs new file mode 100644 index 0000000000..fbdf1af3b9 --- /dev/null +++ b/dynamic-check/src/objects/frame.rs @@ -0,0 +1,1198 @@ +// 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 . + +use crate::{FrameError, Scope, TypeAssertion}; +use leo_static_check::{Attribute, CircuitFunctionType, CircuitType, FunctionType, SymbolTable, Type, TypeVariable}; +use leo_typed::{ + Assignee, + AssigneeAccess, + CircuitVariableDefinition, + ConditionalNestedOrEndStatement, + ConditionalStatement, + Declare, + Expression, + Function, + Identifier, + IntegerType, + RangeOrExpression, + Span, + SpreadOrExpression, + Statement, + Variables, +}; + +/// A vector of `TypeAssertion` predicates created from a function body. +#[derive(Clone)] +pub struct Frame { + pub function_type: FunctionType, + pub self_type: Option, + pub scopes: Vec, + pub statements: Vec, + pub type_assertions: Vec, + pub user_defined_types: SymbolTable, +} + +impl Frame { + /// + /// Collects a vector of `TypeAssertion` predicates from a function. + /// + pub fn new_function( + function: Function, + self_type: Option, + parent_scope: Option, + user_defined_types: SymbolTable, + ) -> Result { + let name = &function.identifier.name; + + // Get function type from symbol table. + let function_type = user_defined_types.get_function_type(name).unwrap().clone(); + + // Create a new scope for the function variables. + let mut scope = Scope::new(parent_scope); + + // Initialize function inputs as variables. + scope.insert_function_inputs(&function_type.inputs)?; + + // Create new list of scopes for frame. + let scopes = vec![scope]; + + // Create new frame struct. + // Update variables when encountering let/const variable definitions. + let mut frame = Self { + function_type, + self_type, + scopes, + statements: function.statements, + type_assertions: vec![], + user_defined_types, + }; + + // Create type assertions for function statements + frame.parse_statements()?; + + Ok(frame) + } + + /// + /// Collects vector of `TypeAssertion` predicates from a circuit function. + /// + pub fn new_circuit_function( + function: Function, + self_type: CircuitType, + parent_scope: Scope, + user_defined_types: SymbolTable, + ) -> Result { + let identifier = &function.identifier; + + // Find function name in circuit members. + let circuit_function_type = self_type.member_function_type(identifier).unwrap().to_owned(); + + // Create a new scope for the function variables. + let mut scope = Scope::new(Some(parent_scope)); + + // Initialize function inputs as variables. + scope.insert_function_inputs(&circuit_function_type.function.inputs)?; + + // Create new list of scopes for frame. + let scopes = vec![scope]; + + // Create new frame struct. + // Update variables when encountering let/const variable definitions. + let mut frame = Self { + function_type: circuit_function_type.function, + self_type: Some(self_type), + scopes, + statements: function.statements, + type_assertions: Vec::new(), + user_defined_types, + }; + + // Create type assertions for function statements + frame.parse_statements()?; + + Ok(frame) + } + + /// + /// Pushes a new variable `Scope` to the list of scopes in the current `Frame`. + /// + fn push_scope(&mut self, scope: Scope) { + self.scopes.push(scope) + } + + /// + /// Removes and returns the most recent `Scope` from the list of scopes in the current `Frame`. + /// + fn pop_scope(&mut self) -> Option { + self.scopes.pop() + } + + /// + /// Insert a variable into the symbol table in the current scope. + /// + fn insert_variable(&mut self, name: String, type_: Type, span: &Span) -> Result<(), FrameError> { + // Modify the current scope. + let scope = self.scopes.last_mut().unwrap(); + + // Insert the variable name -> type. + match scope.variables.insert(name.clone(), type_) { + Some(_type) => Err(FrameError::duplicate_variable(&name, span)), + None => Ok(()), + } + } + + /// + /// Get a variable's type from the symbol table in the current scope. + /// + fn get_variable(&self, name: &String) -> Option<&Type> { + // Lookup in the current scope. + let scope = self.scopes.last().unwrap(); + + // Get the variable by name. + scope.get_variable(name) + } + + /// + /// Get a function's type from the user defined types in the current scope. + /// + fn get_function(&self, name: &String) -> Option<&FunctionType> { + self.user_defined_types.get_function_type(name) + } + + /// + /// Get a circuit's type from the user defined types in the current scope. + /// + fn get_circuit(&self, name: &String) -> Option<&CircuitType> { + self.user_defined_types.get_circuit_type(name) + } + + /// + /// Creates a new equality type assertion between the given types. + /// + fn assert_equal(&mut self, left: Type, right: Type, span: &Span) { + let type_assertion = TypeAssertion::new_equality(left, right, span); + + self.type_assertions.push(type_assertion); + } + + /// + /// Creates a new membership type assertion between a given and set of types. + /// + fn assert_membership(&mut self, given: Type, set: Vec, span: &Span) { + let type_assertion = TypeAssertion::new_membership(given, set, span); + + self.type_assertions.push(type_assertion); + } + + /// + /// Creates a new membership type assertion between a given and the set of negative integer types. + /// + fn assert_negative_integer(&mut self, given: &Type, span: &Span) { + let negative_integer_types = Type::negative_integer_types(); + + self.assert_membership(given.clone(), negative_integer_types, span) + } + + /// + /// Creates a new membership type assertion between a given and the set of all integer types. + /// + fn assert_integer(&mut self, given: &Type, span: &Span) { + let integer_types = Type::integer_types(); + + self.assert_membership(given.clone(), integer_types, span) + } + + /// + /// Creates a new membership type assertion between a given and the set of index types. + /// + fn assert_index(&mut self, given: &Type, span: &Span) { + let index_types = Type::index_types(); + + self.assert_membership(given.clone(), index_types, span) + } + + /// + /// Collects a vector of `TypeAssertion` predicates from a vector of statements. + /// + fn parse_statements(&mut self) -> Result<(), FrameError> { + for statement in self.statements.clone() { + self.parse_statement(&statement)?; + } + + Ok(()) + } + + /// + /// Collects a vector of `TypeAssertion` predicates from a statement. + /// + fn parse_statement(&mut self, statement: &Statement) -> Result<(), FrameError> { + match statement { + Statement::Return(expression, span) => self.parse_return(expression, span), + Statement::Definition(declare, variables, expression, span) => { + self.parse_definition(declare, variables, expression, span) + } + Statement::Assign(assignee, expression, span) => self.parse_assign(assignee, expression, span), + Statement::Conditional(conditional, span) => self.parse_statement_conditional(conditional, span), + Statement::Iteration(identifier, from_to, statements, span) => { + self.parse_iteration(identifier, from_to, statements, span) + } + Statement::Expression(expression, span) => self.parse_statement_expression(expression, span), + Statement::Console(_console_call) => Ok(()), // Console function calls do not generate type assertions. + } + } + + /// + /// Collects `TypeAssertion` predicates from a return statement. + /// + fn parse_return(&mut self, expression: &Expression, span: &Span) -> Result<(), FrameError> { + // Get the function output type. + let output_type = &self.function_type.output.type_; + + // Create the left hand side of a type assertion. + let left = output_type.clone(); + + // Create the right hand side from the statement return expression. + let right = self.parse_expression(expression)?; + + // Create a new type assertion for the statement return. + self.assert_equal(left, right, span); + + Ok(()) + } + + /// + /// Collects `Type Assertion` predicates from a definition statement. + /// + fn parse_definition( + &mut self, + _declare: &Declare, + variables: &Variables, + expression: &Expression, + span: &Span, + ) -> Result<(), FrameError> { + // Parse the definition expression. + let actual_type = self.parse_expression(expression)?; + + // Check if an explicit type is given. + if let Some(type_) = variables.type_.clone() { + // Convert the expected type into a dynamic check type. + let expected_type = match self.self_type.clone() { + Some(circuit_type) => { + Type::new_from_circuit(&self.user_defined_types, type_, circuit_type.identifier, span.clone()) + .unwrap() + } + None => Type::new(&self.user_defined_types, type_, span.clone()).unwrap(), + }; + + // Assert that the expected type is equal to the actual type. + self.assert_equal(expected_type.clone(), actual_type.clone(), span) + } + + // Check for multiple defined variables. + if variables.names.len() == 1 { + // Insert variable into symbol table + let variable = variables.names[0].clone(); + + self.insert_variable(variable.identifier.name, actual_type, span)?; + } else { + // Expect a tuple type. + let types = match actual_type { + Type::Tuple(types) => types, + _ => return Err(FrameError::not_enough_values(span)), + }; + + // Check number of variables == number of types. + if types.len() != variables.names.len() { + return Err(FrameError::invalid_number_of_values( + types.len(), + variables.names.len(), + span, + )); + } + + // Insert variables into symbol table + for (variable, type_) in variables.names.iter().zip(types) { + self.insert_variable(variable.identifier.name.clone(), type_, span)?; + } + } + + Ok(()) + } + + /// + /// Asserts that the assignee's type is equal to the `Expression` type. + /// + fn parse_assign(&mut self, assignee: &Assignee, expression: &Expression, span: &Span) -> Result<(), FrameError> { + // Parse assignee type. + let assignee_type = self.parse_assignee(assignee, span)?; + + // Parse expression type. + let expression_type = self.parse_expression(expression)?; + + // Assert that the assignee_type == expression_type. + self.assert_equal(assignee_type, expression_type, span); + + Ok(()) + } + + /// + /// Returns the type of the assignee. + /// + fn parse_assignee(&mut self, assignee: &Assignee, span: &Span) -> Result { + // Get the type of the assignee variable. + let mut type_ = if assignee.identifier.is_self() { + // If the variable is the self keyword, then return the self.circuit_type + let self_type = self.self_type_or_error(span)?; + + Type::Circuit(self_type.identifier) + } else { + // Otherwise, lookup the variable by name in the symbol table. + self.get_variable(&assignee.identifier.name) + .map(|type_| type_.to_owned()) + .ok_or_else(|| FrameError::undefined_variable(&assignee.identifier))? + }; + + // Iteratively evaluate assignee access types. + for access in &assignee.accesses { + let access_type = match access { + AssigneeAccess::Array(r_or_e) => self.parse_array_access(type_, r_or_e, span), + AssigneeAccess::Tuple(index) => self.parse_tuple_access(type_, *index, span), + AssigneeAccess::Member(identifier) => self.parse_circuit_member_access(type_, identifier, span), + }?; + + type_ = access_type; + } + + Ok(type_) + } + + /// + /// Collects `TypeAssertion` predicates from a block of statements. + /// + fn parse_block(&mut self, statements: &Vec, _span: &Span) -> Result<(), FrameError> { + // Push new scope. + let scope = Scope::new(self.scopes.last().map(|scope| scope.clone())); + self.push_scope(scope); + + // Parse all statements. + for statement in statements.iter() { + self.parse_statement(statement)?; + } + + // Pop out of scope. + let _scope = self.pop_scope(); + + Ok(()) + } + + /// + /// Collects `TypeAssertion` predicates from a conditional statement. + /// + /// Creates a new scope for each code block in the conditional. + /// + fn parse_statement_conditional( + &mut self, + conditional: &ConditionalStatement, + span: &Span, + ) -> Result<(), FrameError> { + // Parse the condition expression. + let condition = self.parse_expression(&conditional.condition)?; + + // Assert that the condition is a boolean type. + let boolean_type = Type::Boolean; + self.assert_equal(boolean_type, condition, span); + + // Parse conditional statements. + self.parse_block(&conditional.statements, span)?; + + // Parse conditional or end. + match &conditional.next { + Some(cond_or_end) => self.parse_conditional_nested_or_end(cond_or_end, span)?, + None => {} + } + + Ok(()) + } + + /// + /// Collects `TypeAssertion` predicates from a conditional statement. + /// + fn parse_conditional_nested_or_end( + &mut self, + cond_or_end: &ConditionalNestedOrEndStatement, + span: &Span, + ) -> Result<(), FrameError> { + match cond_or_end { + ConditionalNestedOrEndStatement::Nested(nested) => self.parse_statement_conditional(nested, span), + ConditionalNestedOrEndStatement::End(statements) => self.parse_block(statements, span), + } + } + + /// + /// Collects `TypeAssertion` predicates from an iteration statement. + /// + fn parse_iteration( + &mut self, + identifier: &Identifier, + from_to: &(Expression, Expression), + statements: &Vec, + span: &Span, + ) -> Result<(), FrameError> { + // Insert variable into symbol table with u32 type. + let u32_type = Type::IntegerType(IntegerType::U32); + let _expect_none = self.insert_variable(identifier.name.to_owned(), u32_type.clone(), span); + + // Parse `from` and `to` expressions. + let from_type = self.parse_expression(&from_to.0)?; + let to_type = self.parse_expression(&from_to.1)?; + + // Assert `from` and `to` types are a u32 or implicit. + self.assert_equal(u32_type.clone(), from_type, span); + self.assert_equal(u32_type, to_type, span); + + // Parse block of statements. + self.parse_block(statements, span) + } + + /// + /// Asserts that the statement `UnresolvedExpression` returns an empty tuple. + /// + fn parse_statement_expression(&mut self, expression: &Expression, span: &Span) -> Result<(), FrameError> { + // Create empty tuple type. + let expected_type = Type::Tuple(Vec::with_capacity(0)); + + // Parse the actual type of the expression. + let actual_type = self.parse_expression(expression)?; + + self.assert_equal(expected_type, actual_type, span); + + Ok(()) + } + + /// + /// Returns the type of an expression. + /// + fn parse_expression(&mut self, expression: &Expression) -> Result { + match expression { + // Type variables + Expression::Identifier(identifier) => self.parse_identifier(identifier), + + // Explicit types + Expression::Boolean(_, _) => Ok(Type::Boolean), + Expression::Address(_, _) => Ok(Type::Address), + Expression::Field(_, _) => Ok(Type::Field), + Expression::Group(_) => Ok(Type::Group), + Expression::Implicit(name, span) => Ok(Self::parse_implicit(Identifier::new_with_span(name, span))), + Expression::Integer(integer_type, _, _) => Ok(Type::IntegerType(integer_type.clone())), + + // Number operations + Expression::Add(left_right, span) => { + self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::Sub(left_right, span) => { + self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::Mul(left_right, span) => { + self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::Div(left_right, span) => { + self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::Pow(left_right, span) => { + self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::Negate(expression, span) => self.parse_negate_expression(expression, span), + + // Boolean operations + Expression::Not(expression, span) => self.parse_boolean_expression(expression, span), + Expression::Or(left_right, span) => { + self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::And(left_right, span) => { + self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::Eq(left_right, span) => { + self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::Ge(left_right, span) => { + self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::Gt(left_right, span) => { + self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::Le(left_right, span) => { + self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) + } + Expression::Lt(left_right, span) => { + self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) + } + + // Conditionals + Expression::IfElse(triplet, span) => { + self.parse_conditional_expression(&triplet.0, &triplet.1, &triplet.2, span) + } + + // Arrays + Expression::Array(expressions, span) => self.parse_array(expressions, span), + Expression::ArrayAccess(array_w_index, span) => { + self.parse_expression_array_access(&array_w_index.0, &array_w_index.1, span) + } + + // Tuples + Expression::Tuple(expressions, span) => self.parse_tuple(expressions, span), + Expression::TupleAccess(tuple, index, span) => self.parse_expression_tuple_access(tuple, *index, span), + + // Circuits + Expression::Circuit(identifier, members, span) => self.parse_circuit(identifier, members, span), + Expression::CircuitMemberAccess(expression, identifier, span) => { + self.parse_expression_circuit_member_access(expression, identifier, span) + } + Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { + self.parse_static_circuit_function_access(expression, identifier, span) + } + + // Functions + Expression::FunctionCall(name, arguments, span) => self.parse_function_call(name, arguments, span), + Expression::CoreFunctionCall(name, arguments, span) => self.parse_core_function_call(name, arguments, span), + } + } + + /// + /// Returns the type of the identifier in the symbol table. + /// + fn parse_identifier(&self, identifier: &Identifier) -> Result { + // Check Self type. + if identifier.is_self() { + // Check for frame circuit self type. + let circuit_type = self.self_type_or_error(&identifier.span)?; + + // Return new type with circuit identifier. + return Ok(Type::Circuit(circuit_type.identifier)); + } + + // Check variable symbol table. + if let Some(type_) = self.get_variable(&identifier.name) { + return Ok(type_.to_owned()); + }; + + // Check function symbol table. + if let Some(function_type) = self.get_function(&identifier.name) { + return Ok(Type::Function(function_type.identifier.to_owned())); + }; + + // Check circuit symbol table. + if let Some(circuit_type) = self.get_circuit(&identifier.name) { + return Ok(Type::Circuit(circuit_type.identifier.to_owned())); + } + + Ok(Self::parse_implicit(identifier.to_owned())) + } + + /// + /// Returns a new type variable from a given identifier + /// + fn parse_implicit(identifier: Identifier) -> Type { + Type::TypeVariable(TypeVariable::from(identifier)) + } + + /// + /// Returns the type of a binary expression. + /// + fn parse_binary_expression( + &mut self, + left: &Expression, + right: &Expression, + span: &Span, + ) -> Result { + // Get the left expression type. + let left_type = self.parse_expression(left)?; + + // Get the right expression type. + let right_type = self.parse_expression(right)?; + + // Create a type assertion left_type == right_type. + self.assert_equal(left_type.clone(), right_type, span); + + Ok(left_type) + } + + /// + /// Returns the `Type` of the expression after the binary operation. + /// + /// Asserts that the `Type` is an integer. + /// + fn parse_integer_binary_expression( + &mut self, + left: &Expression, + right: &Expression, + span: &Span, + ) -> Result { + let type_ = self.parse_binary_expression(left, right, span)?; + + // Assert that the type is an integer. + self.assert_integer(&type_, span); + + Ok(type_) + } + + /// + /// Returns the `Boolean` type if the expression is a `Boolean` type. + /// + fn parse_boolean_expression(&mut self, expression: &Expression, span: &Span) -> Result { + // Return the `Boolean` type + let boolean_type = Type::Boolean; + + // Get the type of the expression + let expression_type = self.parse_expression(expression)?; + + // Assert that the type is a boolean. + self.assert_equal(boolean_type.clone(), expression_type, span); + + Ok(boolean_type) + } + + /// + /// Returns the `Type` of the expression being negated. Must be a negative integer type. + /// + fn parse_negate_expression(&mut self, expression: &Expression, span: &Span) -> Result { + // Parse the expression type. + let type_ = self.parse_expression(expression)?; + + // Assert that this integer can be negated. + self.assert_negative_integer(&type_, span); + + Ok(type_) + } + + /// + /// Returns the `Boolean` type if the binary expression is a `Boolean` type. + /// + fn parse_boolean_binary_expression( + &mut self, + left: &Expression, + right: &Expression, + span: &Span, + ) -> Result { + // Create the `Boolean` type. + let boolean_type = Type::Boolean; + + // Create a new type assertion for the binary expression + let _binary_expression_type = self.parse_binary_expression(left, right, span)?; + + // Return the `Boolean` type. + Ok(boolean_type) + } + + /// + /// Returns the type of the conditional expression. + /// + fn parse_conditional_expression( + &mut self, + condition: &Expression, + first: &Expression, + second: &Expression, + span: &Span, + ) -> Result { + // Check that the type of the condition expression is a boolean. + let _condition_type = self.parse_boolean_expression(condition, span)?; + + // Check that the types of the first and second expression are equal. + self.parse_binary_expression(first, second, span) + } + + /// + /// Returns the type of the tuple expression. + /// + fn parse_tuple(&mut self, expressions: &Vec, _span: &Span) -> Result { + let mut types = vec![]; + + // Parse all tuple expressions. + for expression in expressions { + let type_ = self.parse_expression(expression)?; + + types.push(type_) + } + + Ok(Type::Tuple(types)) + } + + /// + /// Returns the type of the accessed tuple element when called as an expression. + /// + fn parse_expression_tuple_access( + &mut self, + expression: &Expression, + index: usize, + span: &Span, + ) -> Result { + // Parse the tuple expression which could be a variable with type tuple. + let type_ = self.parse_expression(expression)?; + + // Parse the tuple access. + self.parse_tuple_access(type_, index, span) + } + + /// + /// Returns the type of the accessed tuple element. + /// + fn parse_tuple_access(&mut self, type_: Type, index: usize, span: &Span) -> Result { + // Check the type is a tuple. + let elements = match type_ { + Type::Tuple(elements) => elements, + type_ => return Err(FrameError::tuple_access(&type_, span)), + }; + + let element_type = elements[index].clone(); + + Ok(element_type) + } + + /// + /// Returns the type of the array expression. + /// + fn parse_array(&mut self, expressions: &Vec, span: &Span) -> Result { + // Store array element type. + let mut element_type = None; + let mut count = 0usize; + + // Parse all array elements. + for expression in expressions { + // Get the type and count of elements in each spread or expression. + let (type_, element_count) = self.parse_spread_or_expression(expression, span)?; + + // Assert that array element types are the same. + if let Some(prev_type) = element_type { + self.assert_equal(prev_type, type_.clone(), span); + } + + // Update array element type. + element_type = Some(type_); + + // Update number of array elements. + count += element_count; + } + + // Return an error for empty arrays. + let type_ = match element_type { + Some(type_) => type_, + None => return Err(FrameError::empty_array(span)), + }; + + Ok(Type::Array(Box::new(type_), vec![count])) + } + + /// + /// Returns the type and count of elements in a spread or expression. + /// + fn parse_spread_or_expression( + &mut self, + s_or_e: &SpreadOrExpression, + span: &Span, + ) -> Result<(Type, usize), FrameError> { + Ok(match s_or_e { + SpreadOrExpression::Spread(expression) => { + // Parse the type of the spread array expression. + let array_type = self.parse_expression(expression)?; + + // Check that the type is an array. + let (element_type, mut dimensions) = match array_type { + Type::Array(element_type, dimensions) => (element_type, dimensions), + type_ => return Err(FrameError::invalid_spread(type_, span)), + }; + + // A spread copies the elements of an array. + // If the array has elements of type array, we must return a new array type with proper dimensions. + // If the array has elements of any other type, we can return the type and count directly. + let count = dimensions.pop().unwrap(); + + let type_ = if dimensions.is_empty() { + *element_type + } else { + Type::Array(element_type, dimensions) + }; + + (type_, count) + } + SpreadOrExpression::Expression(expression) => (self.parse_expression(expression)?, 1), + }) + } + + /// + /// Returns the type of the accessed array element when called as an expression. + /// + fn parse_expression_array_access( + &mut self, + expression: &Expression, + r_or_e: &RangeOrExpression, + span: &Span, + ) -> Result { + // Parse the array expression which could be a variable with type array. + let type_ = self.parse_expression(expression)?; + + // Parse the array access. + self.parse_array_access(type_, r_or_e, span) + } + + /// + /// Returns the type of the accessed array element. + /// + fn parse_array_access(&mut self, type_: Type, r_or_e: &RangeOrExpression, span: &Span) -> Result { + // Check the type is an array. + let (element_type, _dimensions) = match type_ { + Type::Array(type_, dimensions) => (type_, dimensions), + type_ => return Err(FrameError::array_access(&type_, span)), + }; + + // Get the length of the array. + // let length = *dimensions.last().unwrap(); + + // Evaluate the range as an array type or the expression as the element type. + match r_or_e { + RangeOrExpression::Range(from, to) => { + if let Some(expression) = from { + // Parse the expression type. + let type_ = self.parse_expression(expression)?; + + self.assert_index(&type_, span); + } + + if let Some(expression) = to { + // Parse the expression type. + let type_ = self.parse_expression(expression)?; + + self.assert_index(&type_, span); + } + } + RangeOrExpression::Expression(expression) => { + // Parse the expression type. + let type_ = self.parse_expression(expression)?; + + // Assert the type is an index. + self.assert_index(&type_, span); + } + } + + Ok(*element_type) + } + + /// + /// Returns the Self type of the frame or an error if it does not exist. + /// + fn self_type_or_error(&self, span: &Span) -> Result { + self.self_type + .as_ref() + .map(|circuit_type| circuit_type.clone()) + .ok_or_else(|| FrameError::circuit_self(span)) + } + + /// + /// Returns the type of inline circuit expression. + /// + fn parse_circuit( + &mut self, + identifier: &Identifier, + members: &Vec, + span: &Span, + ) -> Result { + // Check if identifier is Self circuit type. + let circuit_type = if identifier.is_self() { + // Get the Self type of the frame. + self.self_type_or_error(span)? + } else { + // Get circuit type. + self.user_defined_types + .get_circuit_type(&identifier.name) + .map(|circuit_type| circuit_type.clone()) + .ok_or_else(|| FrameError::undefined_circuit(identifier))? + }; + + // Check the length of the circuit members. + if circuit_type.variables.len() != members.len() { + return Err(FrameError::num_circuit_variables( + circuit_type.variables.len(), + members.len(), + span, + )); + } + + // Assert members are circuit type member types. + for (expected_variable, actual_variable) in circuit_type.variables.iter().zip(members) { + // Parse actual variable expression. + let actual_type = self.parse_expression(&actual_variable.expression)?; + + // Assert expected variable type == actual variable type. + self.assert_equal(expected_variable.type_.clone(), actual_type, span) + } + + Ok(Type::Circuit(circuit_type.identifier)) + } + + /// + /// Returns the type of the accessed circuit member when called as an expression. + /// + fn parse_expression_circuit_member_access( + &mut self, + expression: &Expression, + identifier: &Identifier, + span: &Span, + ) -> Result { + // Parse circuit name. + let type_ = self.parse_expression(expression)?; + + // Parse the circuit member access. + self.parse_circuit_member_access(type_, identifier, span) + } + + /// + /// Returns the type of the accessed circuit member. + /// + fn parse_circuit_member_access( + &mut self, + type_: Type, + identifier: &Identifier, + span: &Span, + ) -> Result { + // Check that type is a circuit type. + let circuit_type = self.parse_circuit_name(type_, span)?; + + // Look for member with matching name. + Ok(circuit_type.member_type(&identifier)?) + } + + /// + /// Returns the type returned by calling the static circuit function. + /// + fn parse_static_circuit_function_access( + &mut self, + expression: &Expression, + identifier: &Identifier, + span: &Span, + ) -> Result { + // Parse the circuit name. + let type_ = self.parse_expression(expression)?; + + self.parse_circuit_member_access(type_, identifier, span) + } + + /// + /// Returns a `CircuitType` given a circuit expression. + /// + fn parse_circuit_name(&mut self, type_: Type, span: &Span) -> Result<&CircuitType, FrameError> { + // Check that type is a circuit type. + match type_ { + Type::Circuit(identifier) => { + // Lookup circuit identifier. + self.user_defined_types + .get_circuit_type(&identifier.name) + .ok_or_else(|| FrameError::undefined_circuit(&identifier)) + } + type_ => Err(FrameError::invalid_circuit(type_, span)), + } + } + + /// + /// Returns a `FunctionType` given a function expression. + /// + fn parse_function_name(&mut self, expression: &Expression, span: &Span) -> Result { + // Case 1: Call a function defined in the program file. + // Case 2: Call a circuit function. + // Case 3: Call a static circuit function. + // Return an Error in any other case. + match expression { + Expression::Identifier(identifier) => self.parse_program_function(identifier, span), + Expression::CircuitMemberAccess(expression, identifier, span) => { + self.parse_circuit_function(expression, identifier, span) + } + Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { + self.parse_static_circuit_function(expression, identifier, span) + } + expression => Err(FrameError::invalid_function(expression, span)), + } + } + + /// + /// Returns a `FunctionType` given a function identifier. + /// + fn parse_program_function(&mut self, identifier: &Identifier, _span: &Span) -> Result { + self.user_defined_types + .get_function_type(&identifier.name) + .map(|function_type| function_type.to_owned()) + .ok_or_else(|| FrameError::undefined_function(identifier)) + } + + /// + /// Returns a `CircuitFunctionType` given a circuit expression and function identifier. + /// + fn parse_circuit_function_type( + &mut self, + expression: &Expression, + identifier: &Identifier, + span: &Span, + ) -> Result<&CircuitFunctionType, FrameError> { + // Parse circuit name. + let type_ = self.parse_expression(expression)?; + + // Get circuit type. + let circuit_type = self.parse_circuit_name(type_, span)?; + + // Find circuit function by identifier. + circuit_type + .member_function_type(identifier) + .ok_or_else(|| FrameError::undefined_circuit_function(identifier)) + } + + /// + /// Returns a `FunctionType` given a circuit expression and non-static function identifier. + /// + fn parse_circuit_function( + &mut self, + expression: &Expression, + identifier: &Identifier, + span: &Span, + ) -> Result { + // Find circuit function type. + let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; + + // Check that the function is non-static. + if circuit_function_type.attributes.contains(&Attribute::Static) { + return Err(FrameError::invalid_static_access(identifier)); + } + + // Return the function type. + Ok(circuit_function_type.function.to_owned()) + } + + /// + /// Returns a `FunctionType` given a circuit expression and static function identifier. + /// + fn parse_static_circuit_function( + &mut self, + expression: &Expression, + identifier: &Identifier, + span: &Span, + ) -> Result { + // Find circuit function type. + let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; + + // Check that the function is static. + if !circuit_function_type.attributes.contains(&Attribute::Static) { + return Err(FrameError::invalid_member_access(identifier)); + } + + Ok(circuit_function_type.function.to_owned()) + } + + /// + /// Returns the type returned by calling the function. + /// + /// Does not attempt to evaluate the function call. We are just checking types at this step. + /// + fn parse_function_call( + &mut self, + expression: &Expression, + inputs: &Vec, + span: &Span, + ) -> Result { + // Parse the function name. + let function_type = self.parse_function_name(expression, span)?; + + // Check the length of arguments + if function_type.inputs.len() != inputs.len() { + return Err(FrameError::num_inputs(function_type.inputs.len(), inputs.len(), span)); + } + + // Assert function inputs are correct types. + for (expected_input, actual_input) in function_type.inputs.iter().zip(inputs) { + // Parse expected input type. + let expected_type = expected_input.type_(); + + // Parse actual input type. + let actual_type = self.parse_expression(actual_input)?; + + // Assert expected input type == actual input type. + self.assert_equal(expected_type, actual_type, span); + } + + // Return the function output type. + Ok(function_type.output.type_.clone()) + } + + /// + /// Returns the type returned by calling the core function. + /// + fn parse_core_function_call( + &mut self, + _name: &String, + _arguments: &Vec, + _span: &Span, + ) -> Result { + unimplemented!("type checks for core function calls not implemented") + } + + /// + /// Returns `Ok` if all `TypeAssertions` can be solved successfully. + /// + pub(crate) fn check(self) -> Result<(), FrameError> { + let mut unsolved = self.type_assertions.clone(); + + // Solve all type equality assertions first. + let mut unsolved_membership = Vec::new(); + + while !unsolved.is_empty() { + // Pop type assertion from list + let type_assertion = unsolved.pop().unwrap(); + + // If it is a membership assertion, then skip it for now. + if let TypeAssertion::Membership(membership) = type_assertion { + unsolved_membership.push(membership); + + continue; + } + + // Collect `TypeVariablePairs` from the `TypeAssertion`. + let pairs = type_assertion.pairs()?; + + // If no pairs are found, attempt to evaluate the `TypeAssertion`. + if pairs.is_empty() { + // Evaluate the `TypeAssertion`. + type_assertion.evaluate()? + } else { + // Iterate over each `TypeVariable` -> `Type` pair. + for pair in pairs.get_pairs() { + // Substitute the `TypeVariable` for it's paired `Type` in all `TypeAssertion`s. + for original in &mut unsolved { + original.substitute(pair.first(), pair.second()) + } + + for original in &mut unsolved_membership { + original.substitute(pair.first(), pair.second()) + } + } + } + } + + // Solve all type membership assertions. + while !unsolved_membership.is_empty() { + // Pop type assertion from list + let type_assertion = unsolved_membership.pop().unwrap(); + + // Solve the membership assertion. + type_assertion.evaluate()?; + } + + Ok(()) + } +} diff --git a/dynamic-check/src/objects/mod.rs b/dynamic-check/src/objects/mod.rs new file mode 100644 index 0000000000..745c8eca50 --- /dev/null +++ b/dynamic-check/src/objects/mod.rs @@ -0,0 +1,24 @@ +// 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 . + +pub mod frame; +pub use self::frame::*; + +pub mod scope; +pub use self::scope::*; + +pub mod variable_table; +pub use self::variable_table::*; diff --git a/dynamic-check/src/objects/scope.rs b/dynamic-check/src/objects/scope.rs new file mode 100644 index 0000000000..19c8f95961 --- /dev/null +++ b/dynamic-check/src/objects/scope.rs @@ -0,0 +1,90 @@ +// 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 . + +use crate::{ScopeError, VariableTable}; +use leo_static_check::{FunctionInputType, Type}; + +/// A structure for tracking the types of defined variables in a block of code. +#[derive(Clone)] +pub struct Scope { + pub loop_variables: VariableTable, + pub variables: VariableTable, +} + +impl Scope { + /// + /// Returns a new `Scope` from an optional given `Scope`. + /// + /// The new scope will contain the variables of the optional given `Scope`. + /// + pub fn new(parent: Option) -> Self { + match parent { + Some(scope) => scope.clone(), + None => Self::default(), + } + } + + /// + /// Inserts a variable name -> type mapping into the loop variable table. + /// + pub fn insert_loop_variable(&mut self, name: String, type_: Type) -> Option { + self.loop_variables.insert(name, type_) + } + + /// + /// Inserts a variable name -> type mapping into the variable table. + /// + pub fn insert_variable(&mut self, name: String, type_: Type) -> Option { + self.variables.insert(name, type_) + } + + /// + /// Returns a reference to the type corresponding to the loop variable name. + /// + pub fn get_loop_variable(&self, name: &String) -> Option<&Type> { + self.loop_variables.get(name) + } + + /// + /// Returns a reference to the type corresponding to the variable name. + /// + /// Checks loop variables first, then non-loop variables. + /// + pub fn get_variable(&self, name: &String) -> Option<&Type> { + match self.get_loop_variable(name) { + Some(loop_variable_type) => Some(loop_variable_type), + None => self.variables.get(name), + } + } + + /// + /// Inserts a vector of function input types into the `Scope` variable table. + /// + pub fn insert_function_inputs(&mut self, function_inputs: &Vec) -> Result<(), ScopeError> { + self.variables + .insert_function_inputs(function_inputs) + .map_err(|err| ScopeError::VariableTableError(err)) + } +} + +impl Default for Scope { + fn default() -> Self { + Self { + loop_variables: VariableTable::default(), + variables: VariableTable::default(), + } + } +} diff --git a/dynamic-check/src/objects/variable_table.rs b/dynamic-check/src/objects/variable_table.rs new file mode 100644 index 0000000000..078cea1c82 --- /dev/null +++ b/dynamic-check/src/objects/variable_table.rs @@ -0,0 +1,70 @@ +// 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 . + +use crate::VariableTableError; +use leo_static_check::{FunctionInputType, Type}; +use std::collections::HashMap; + +/// Mapping of variable names to types +#[derive(Clone)] +pub struct VariableTable(pub HashMap); + +impl VariableTable { + /// + /// Insert a name -> type pair into the variable table. + /// + /// If the variable table did not have this key present, [`None`] is returned. + /// + /// If the variable table did have this key present, the type is updated, and the old + /// type is returned. + /// + pub fn insert(&mut self, name: String, type_: Type) -> Option { + self.0.insert(name, type_) + } + + /// + /// Returns a reference to the type corresponding to the name. + /// + /// If the variable table did not have this key present, throw an undefined variable error + /// using the given span. + /// + pub fn get(&self, name: &String) -> Option<&Type> { + self.0.get(name) + } + + /// + /// Inserts a vector of function input types into the variable table. + /// + pub fn insert_function_inputs( + &mut self, + function_inputs: &Vec, + ) -> Result<(), VariableTableError> { + for input in function_inputs { + let input_name = input.identifier().name.clone(); + let input_type = input.type_(); + + // TODO (collinc97) throw an error for duplicate function input names. + self.insert(input_name, input_type); + } + Ok(()) + } +} + +impl Default for VariableTable { + fn default() -> Self { + Self(HashMap::new()) + } +} diff --git a/dynamic-check/tests/arrays/mod.rs b/dynamic-check/tests/arrays/mod.rs index cf0dd3cb37..72a2845b3f 100644 --- a/dynamic-check/tests/arrays/mod.rs +++ b/dynamic-check/tests/arrays/mod.rs @@ -22,7 +22,7 @@ fn test_empty_array() { let check = TestDynamicCheck::new(bytes); - check.expect_create_error(); + check.expect_error(); } #[test] @@ -31,7 +31,7 @@ fn test_invalid_array_access() { let check = TestDynamicCheck::new(bytes); - check.expect_create_error(); + check.expect_error(); } #[test] @@ -40,5 +40,5 @@ fn test_invalid_spread() { let check = TestDynamicCheck::new(bytes); - check.expect_create_error(); + check.expect_error(); } diff --git a/dynamic-check/tests/circuits/mod.rs b/dynamic-check/tests/circuits/mod.rs index 069000a2b0..d82726197b 100644 --- a/dynamic-check/tests/circuits/mod.rs +++ b/dynamic-check/tests/circuits/mod.rs @@ -21,5 +21,5 @@ fn test_invalid_circuit() { let bytes = include_bytes!("invalid_circuit.leo"); let check = TestDynamicCheck::new(bytes); - check.expect_create_error(); + check.expect_error(); } diff --git a/dynamic-check/tests/functions/mod.rs b/dynamic-check/tests/functions/mod.rs index 6348658eec..5599451646 100644 --- a/dynamic-check/tests/functions/mod.rs +++ b/dynamic-check/tests/functions/mod.rs @@ -21,5 +21,5 @@ fn test_invalid_function() { let bytes = include_bytes!("invalid_function.leo"); let check = TestDynamicCheck::new(bytes); - check.expect_create_error(); + check.expect_error(); } diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 884db0422b..f19d302866 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -59,32 +59,19 @@ impl TestDynamicCheck { let input = Input::new(); // Create static check. - let symbol_table = StaticCheck::run_with_input(&program, &import_parser, &input).unwrap(); + let symbol_table = StaticCheck::new(&program, &import_parser, &input).unwrap(); // Store fields for new dynamic check. Self { program, symbol_table } } - pub fn solve(self) { - let dynamic_check = DynamicCheck::new(&self.program, self.symbol_table).unwrap(); - - dynamic_check.solve().unwrap(); + pub fn run(self) { + DynamicCheck::new(&self.program, self.symbol_table).unwrap(); } - pub fn expect_create_error(self) { - // println!( - // "{:?}", - // DynamicCheck::new(&self.program, self.symbol_table.clone()).err() - // ); - + pub fn expect_error(self) { assert!(DynamicCheck::new(&self.program, self.symbol_table).is_err()); } - - pub fn expect_solve_error(self) { - let dynamic_check = DynamicCheck::new(&self.program, self.symbol_table).unwrap(); - - assert!(dynamic_check.solve().is_err()); - } } #[test] @@ -93,5 +80,5 @@ fn test_new() { let dynamic_check = TestDynamicCheck::new(bytes); - dynamic_check.solve() + dynamic_check.run() } diff --git a/dynamic-check/tests/tuples/mod.rs b/dynamic-check/tests/tuples/mod.rs index 1d4fe1292e..31b18ffa45 100644 --- a/dynamic-check/tests/tuples/mod.rs +++ b/dynamic-check/tests/tuples/mod.rs @@ -21,5 +21,5 @@ fn test_invalid_tuple_access() { let bytes = include_bytes!("invalid_tuple_access.leo"); let check = TestDynamicCheck::new(bytes); - check.expect_create_error(); + check.expect_error(); } diff --git a/dynamic-check/tests/variables/mod.rs b/dynamic-check/tests/variables/mod.rs index b60a7217f0..2712890704 100644 --- a/dynamic-check/tests/variables/mod.rs +++ b/dynamic-check/tests/variables/mod.rs @@ -21,7 +21,7 @@ fn test_duplicate_variable() { let bytes = include_bytes!("duplicate_variable.leo"); let check = TestDynamicCheck::new(bytes); - check.expect_create_error(); + check.expect_error(); } #[test] @@ -29,7 +29,7 @@ fn test_duplicate_variable_multi() { let bytes = include_bytes!("duplicate_variable_multi.leo"); let check = TestDynamicCheck::new(bytes); - check.expect_create_error(); + check.expect_error(); } #[test] @@ -37,7 +37,7 @@ fn test_not_enough_values() { let bytes = include_bytes!("not_enough_values.leo"); let check = TestDynamicCheck::new(bytes); - check.expect_create_error(); + check.expect_error(); } #[test] @@ -45,5 +45,5 @@ fn test_too_many_values() { let bytes = include_bytes!("too_many_values.leo"); let check = TestDynamicCheck::new(bytes); - check.expect_create_error(); + check.expect_error(); } diff --git a/static-check/src/imports/imported_symbols.rs b/static-check/src/imports/imported_symbols.rs index 8ee3c747c3..f42542471a 100644 --- a/static-check/src/imports/imported_symbols.rs +++ b/static-check/src/imports/imported_symbols.rs @@ -23,25 +23,21 @@ pub struct ImportedSymbols { } impl ImportedSymbols { - fn new() -> Self { - Self { symbols: vec![] } + pub fn new(import: &ImportStatement) -> Self { + let mut imported_symbols = Self::default(); + + imported_symbols.push_package(&import.package); + + imported_symbols } - pub fn from(import: &ImportStatement) -> Self { - let mut symbols = Self::new(); - - symbols.from_package(&import.package); - - symbols + fn push_package(&mut self, package: &Package) { + self.push_package_access(package.name.name.clone(), &package.access); } - 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) { + fn push_package_access(&mut self, package: String, access: &PackageAccess) { match access { - PackageAccess::SubPackage(package) => self.from_package(package), + PackageAccess::SubPackage(package) => self.push_package(package), PackageAccess::Star(span) => { let star = ImportSymbol::star(span); self.symbols.push((package, star)); @@ -49,7 +45,13 @@ impl ImportedSymbols { PackageAccess::Symbol(symbol) => self.symbols.push((package, symbol.clone())), PackageAccess::Multiple(packages) => packages .iter() - .for_each(|access| self.from_package_access(package.clone(), access)), + .for_each(|access| self.push_package_access(package.clone(), access)), } } } + +impl Default for ImportedSymbols { + fn default() -> Self { + Self { symbols: Vec::new() } + } +} diff --git a/static-check/src/lib.rs b/static-check/src/lib.rs index 22815db239..0522d5ef9e 100644 --- a/static-check/src/lib.rs +++ b/static-check/src/lib.rs @@ -26,11 +26,11 @@ pub use self::errors::*; pub mod imports; pub use self::imports::*; +pub mod objects; +pub use self::objects::*; + pub mod static_check; pub use self::static_check::*; -pub mod symbol_table; -pub use self::symbol_table::*; - pub mod types; pub use self::types::*; diff --git a/static-check/src/objects/mod.rs b/static-check/src/objects/mod.rs new file mode 100644 index 0000000000..bdfe157c95 --- /dev/null +++ b/static-check/src/objects/mod.rs @@ -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 . + +pub mod symbol_table; +pub use self::symbol_table::*; diff --git a/static-check/src/symbol_table.rs b/static-check/src/objects/symbol_table.rs similarity index 82% rename from static-check/src/symbol_table.rs rename to static-check/src/objects/symbol_table.rs index 06987a423a..709e14e86a 100644 --- a/static-check/src/symbol_table.rs +++ b/static-check/src/objects/symbol_table.rs @@ -27,7 +27,7 @@ pub const REGISTERS_VARIABLE_NAME: &str = "registers"; pub const STATE_VARIABLE_NAME: &str = "state"; pub const STATE_LEAF_VARIABLE_NAME: &str = "state_leaf"; -/// A abstract data type that builds symbol tables for functions and circuits +/// A abstract data type that tracks the current bindings for functions and circuits. /// /// A symbol table has access to all function and circuit names in its /// parent's symbol table. @@ -106,7 +106,7 @@ impl SymbolTable { /// If the symbol table did have this name present, the circuit type is updated, and the old /// circuit type is returned. /// - pub fn insert_circuit(&mut self, identifier: Identifier, circuit_type: CircuitType) -> Option { + pub fn insert_circuit_type(&mut self, identifier: Identifier, circuit_type: CircuitType) -> Option { self.circuits.insert(identifier.name, circuit_type) } @@ -118,37 +118,28 @@ impl SymbolTable { /// If the symbol table did have this name present, the function type is updated, and the old /// function type is returned. /// - pub fn insert_function(&mut self, identifier: Identifier, function_type: FunctionType) -> Option { + pub fn insert_function_type( + &mut self, + identifier: Identifier, + function_type: FunctionType, + ) -> Option { self.functions.insert(identifier.name, function_type) } - /// - /// Returns a reference to the variable type corresponding to the name. - /// - /// If the symbol table did not have this name present, then `None` is returned. - /// - pub fn get_variable(&self, name: &String) -> Option<&ParameterType> { - // Lookup variable name in symbol table. - match self.names.get(name) { - Some(variable) => Some(variable), - None => None, - } - } - /// /// Returns a reference to the circuit type corresponding to the name. /// /// If the symbol table did not have this name present, then the parent symbol table is checked. /// If there is no parent symbol table, then `None` is returned. /// - pub fn get_circuit(&self, name: &String) -> Option<&CircuitType> { + pub fn get_circuit_type(&self, name: &String) -> Option<&CircuitType> { // Lookup name in symbol table. match self.circuits.get(name) { Some(circuit) => Some(circuit), None => { // Lookup name in parent symbol table. match &self.parent { - Some(parent) => parent.get_circuit(name), + Some(parent) => parent.get_circuit_type(name), None => None, } } @@ -161,14 +152,14 @@ impl SymbolTable { /// If the symbol table did not have this name present, then the parent symbol table is checked. /// If there is no parent symbol table, then `None` is returned. /// - pub fn get_function(&self, key: &String) -> Option<&FunctionType> { + pub fn get_function_type(&self, key: &String) -> Option<&FunctionType> { // Lookup name in symbol table. match self.functions.get(key) { Some(circuit) => Some(circuit), None => { // Lookup name in parent symbol table match &self.parent { - Some(parent) => parent.get_function(key), + Some(parent) => parent.get_function_type(key), None => None, } } @@ -176,46 +167,172 @@ impl SymbolTable { } /// - /// Inserts function input types into symbol table. + /// Checks for duplicate import, circuit, and function names given a program. /// - /// Creates a new `CircuitType` to represent the input values. - /// 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`. + /// 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 insert_input(&mut self, input: &Input) -> Result<(), SymbolTableError> { - // Get values for each input section. - let registers_values = input.get_registers().values(); - let record_values = input.get_record().values(); - let state_values = input.get_state().values(); - let state_leaf_values = input.get_state_leaf().values(); + pub fn check_program_names( + &mut self, + program: &Program, + import_parser: &ImportParser, + ) -> Result<(), SymbolTableError> { + // Check unresolved program import names. + self.check_import_names(&program.imports, import_parser)?; - // Create a new `CircuitType` for each input section. - let registers_type = - CircuitType::from_input_section(&self, REGISTERS_VARIABLE_NAME.to_string(), registers_values)?; - let record_type = CircuitType::from_input_section(&self, RECORD_VARIABLE_NAME.to_string(), record_values)?; - let state_type = CircuitType::from_input_section(&self, STATE_VARIABLE_NAME.to_string(), state_values)?; - let state_leaf_type = - CircuitType::from_input_section(&self, STATE_LEAF_VARIABLE_NAME.to_string(), state_leaf_values)?; + // Check unresolved program circuit names. + self.check_circuit_names(&program.circuits)?; - // Create a new `CircuitVariableType` for each type. - let registers_variable = CircuitVariableType::from(®isters_type); - let record_variable = CircuitVariableType::from(&record_type); - let state_variable = CircuitVariableType::from(&state_type); - let state_leaf_variable = CircuitVariableType::from(&state_leaf_type); + // Check unresolved program function names. + self.check_function_names(&program.functions)?; - // Create new `CircuitType` for input keyword. - let input_type = CircuitType { - identifier: Identifier::new(INPUT_VARIABLE_NAME.to_string()), - variables: vec![registers_variable, record_variable, state_variable, state_leaf_variable], - functions: Vec::new(), - }; + Ok(()) + } - // Insert each circuit type into the symbol table. - self.insert_circuit(registers_type.identifier.clone(), registers_type); - self.insert_circuit(record_type.identifier.clone(), record_type); - self.insert_circuit(state_type.identifier.clone(), state_type); - self.insert_circuit(state_leaf_type.identifier.clone(), state_leaf_type); - self.insert_circuit(input_type.identifier.clone(), input_type); + /// + /// Checks for duplicate circuit names given a hashmap of circuits. + /// + /// If a circuit name has no duplicates, then it is inserted into the symbol table. + /// Types defined later in the program cannot have the same name. + /// + pub fn check_circuit_names(&mut self, circuits: &HashMap) -> Result<(), SymbolTableError> { + // Iterate over circuit names and definitions. + for (identifier, circuit) in circuits.iter() { + // Attempt to insert the circuit name into the symbol table. + self.insert_circuit_name(identifier.to_string(), ParameterType::from(circuit.clone()))?; + } + + Ok(()) + } + + /// + /// Checks for duplicate function names given a hashmap of functions. + /// + /// If a function name has no duplicates, then it is inserted into the symbol table. + /// Types defined later in the program cannot have the same name. + /// + pub fn check_function_names(&mut self, functions: &HashMap) -> Result<(), SymbolTableError> { + // Iterate over function names and definitions. + for (identifier, function) in functions.iter() { + // Attempt to insert the function name into the symbol table. + self.insert_function_name(identifier.to_string(), ParameterType::from(function.clone()))?; + } + + Ok(()) + } + + /// + /// Checks that all given imported names 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_names( + &mut self, + imports: &Vec, + import_parser: &ImportParser, + ) -> Result<(), SymbolTableError> { + // Iterate over imported names. + for import in imports.iter() { + self.check_import_statement(import, import_parser)?; + } + + Ok(()) + } + + /// + /// Checks that a given import statement imports an existing package. + /// + /// 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_statement( + &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.check_core_package(package); + } + + // Attempt to insert the imported names into the symbol table. + self.check_package(import, import_parser) + } + + /// + /// Inserts imported core package circuit names and types into the symbol table. + /// + /// Checks that the core package and all circuit names exist. Checks that imported circuit types + /// only contain known types. + /// + pub fn check_core_package(&mut self, package: &Package) -> Result<(), SymbolTableError> { + // Create list of imported core packages. + let list = CorePackageList::from_package_access(package.access.to_owned())?; + + // Fetch core package symbols from `leo-core`. + let symbol_list = list.to_symbols()?; + + // Insert name and type information for each core package symbol. + for (name, circuit) in symbol_list.symbols() { + // Store name of symbol. + self.insert_circuit_name(name.to_string(), ParameterType::from(circuit.clone()))?; + + // Create new circuit type for symbol. + let circuit_type = CircuitType::new(&self, circuit.to_owned())?; + + // Insert circuit type of symbol. + self.insert_circuit_type(circuit_type.identifier.clone(), circuit_type); + } + + Ok(()) + } + + /// + /// Inserts one or more imported symbols for a given imported package. + /// + /// Checks that the package and all circuit and function names exist. Checks that imported circuit + /// and function types only contain known types. + /// + pub fn check_package( + &mut self, + import: &ImportStatement, + import_parser: &ImportParser, + ) -> Result<(), SymbolTableError> { + // Get imported symbols from statement. + let imported_symbols = ImportedSymbols::new(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 for duplicate types. + self.check_program_names(program, import_parser)?; + + // Check the imported program for undefined types. + self.check_types_program(program)?; + + // 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(()) } @@ -227,10 +344,10 @@ impl SymbolTable { // Check for import *. if symbol.is_star() { // Insert all program circuits. - self.check_duplicate_circuits(&program.circuits)?; + self.check_circuit_names(&program.circuits)?; // Insert all program functions. - self.check_duplicate_functions(&program.functions) + self.check_function_names(&program.functions) } else { // Check for a symbol alias. let identifier = symbol.alias.to_owned().unwrap_or(symbol.symbol.to_owned()); @@ -265,181 +382,6 @@ impl SymbolTable { } } - /// - /// Inserts one or more imported symbols for a given import statement. - /// - /// No type resolution performed at this step. - /// - 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 for duplicate types. - self.check_duplicate_program(program, import_parser)?; - - // Check the imported program for undefined types. - self.check_unknown_types_program(program)?; - - // 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. - /// - pub fn insert_core_package(&mut self, package: &Package) -> Result<(), SymbolTableError> { - // Create list of imported core packages. - let list = CorePackageList::from_package_access(package.access.to_owned())?; - - // Fetch core package symbols from `leo-core`. - let symbol_list = list.to_symbols()?; - - // Insert name and type information for each core package symbol. - for (name, circuit) in symbol_list.symbols() { - // Store name of symbol. - self.insert_circuit_name(name.to_string(), ParameterType::from(circuit.clone()))?; - - // Create new circuit type for symbol. - let circuit_type = CircuitType::new(&self, circuit.to_owned())?; - - // Insert circuit type of symbol. - self.insert_circuit(circuit_type.identifier.clone(), circuit_type); - } - - 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); - } - - // 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. - /// - /// 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_imports( - &mut self, - imports: &Vec, - import_parser: &ImportParser, - ) -> Result<(), SymbolTableError> { - // Iterate over imported names. - for import in imports.iter() { - 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. - /// - /// If a circuit name has no duplicates, then it is inserted into the symbol table. - /// Types defined later in the program cannot have the same name. - /// - pub fn check_duplicate_circuits( - &mut self, - circuits: &HashMap, - ) -> Result<(), SymbolTableError> { - // Iterate over circuit names and definitions. - for (identifier, circuit) in circuits.iter() { - // Attempt to insert the circuit name into the symbol table. - self.insert_circuit_name(identifier.to_string(), ParameterType::from(circuit.clone()))?; - } - - Ok(()) - } - - /// - /// Checks for duplicate function names given a hashmap of functions. - /// - /// If a function name has no duplicates, then it is inserted into the symbol table. - /// Types defined later in the program cannot have the same name. - /// - pub fn check_duplicate_functions( - &mut self, - functions: &HashMap, - ) -> Result<(), SymbolTableError> { - // Iterate over function names and definitions. - for (identifier, function) in functions.iter() { - // Attempt to insert the function name into the symbol table. - self.insert_function_name(identifier.to_string(), ParameterType::from(function.clone()))?; - } - - Ok(()) - } - /// /// Checks for unknown types in circuit and function definitions given an unresolved program. /// @@ -447,12 +389,12 @@ impl SymbolTable { /// symbol table. Variables defined later in the unresolved program can lookup the definition and /// refer to its expected types. /// - pub fn check_unknown_types_program(&mut self, program: &Program) -> Result<(), SymbolTableError> { + pub fn check_types_program(&mut self, program: &Program) -> Result<(), SymbolTableError> { // Check unresolved program circuit definitions. - self.check_unknown_types_circuits(&program.circuits)?; + self.check_types_circuits(&program.circuits)?; // Check unresolved program function definitions. - self.check_unknown_types_functions(&program.functions)?; + self.check_types_functions(&program.functions)?; Ok(()) } @@ -464,10 +406,7 @@ impl SymbolTable { /// symbol table. Variables defined later in the program can lookup the definition /// and refer to its expected types /// - pub fn check_unknown_types_circuits( - &mut self, - circuits: &HashMap, - ) -> Result<(), SymbolTableError> { + pub fn check_types_circuits(&mut self, circuits: &HashMap) -> Result<(), SymbolTableError> { // Iterate over circuit names and definitions. for (_, circuit) in circuits.iter() { // Get the identifier of the circuit. @@ -477,7 +416,7 @@ impl SymbolTable { let circuit_type = CircuitType::new(self, circuit.clone())?; // Attempt to insert the circuit definition into the symbol table. - self.insert_circuit(identifier, circuit_type); + self.insert_circuit_type(identifier, circuit_type); } Ok(()) @@ -490,10 +429,7 @@ impl SymbolTable { /// symbol table. Variables defined later in the program can lookup the definition /// and refer to its expected types /// - pub fn check_unknown_types_functions( - &mut self, - functions: &HashMap, - ) -> Result<(), SymbolTableError> { + pub fn check_types_functions(&mut self, functions: &HashMap) -> Result<(), SymbolTableError> { // Iterate over function names and definitions. for (_, function) in functions.iter() { // Get the identifier of the function. @@ -503,9 +439,54 @@ impl SymbolTable { let function_type = FunctionType::new(&self, function.clone())?; // Attempt to insert the function definition into the symbol table. - self.insert_function(identifier, function_type); + self.insert_function_type(identifier, function_type); } Ok(()) } + + /// + /// Inserts function input types into the symbol table. + /// + /// Creates a new `CircuitType` to represent the input values. + /// 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> { + // Get values for each input section. + let registers_values = input.get_registers().values(); + let record_values = input.get_record().values(); + let state_values = input.get_state().values(); + let state_leaf_values = input.get_state_leaf().values(); + + // Create a new `CircuitType` for each input section. + let registers_type = + CircuitType::from_input_section(&self, REGISTERS_VARIABLE_NAME.to_string(), registers_values)?; + let record_type = CircuitType::from_input_section(&self, RECORD_VARIABLE_NAME.to_string(), record_values)?; + let state_type = CircuitType::from_input_section(&self, STATE_VARIABLE_NAME.to_string(), state_values)?; + let state_leaf_type = + CircuitType::from_input_section(&self, STATE_LEAF_VARIABLE_NAME.to_string(), state_leaf_values)?; + + // Create a new `CircuitVariableType` for each type. + let registers_variable = CircuitVariableType::from(®isters_type); + let record_variable = CircuitVariableType::from(&record_type); + let state_variable = CircuitVariableType::from(&state_type); + let state_leaf_variable = CircuitVariableType::from(&state_leaf_type); + + // Create new `CircuitType` for input keyword. + let input_type = CircuitType { + identifier: Identifier::new(INPUT_VARIABLE_NAME.to_string()), + variables: vec![registers_variable, record_variable, state_variable, state_leaf_variable], + functions: Vec::new(), + }; + + // Insert each circuit type into the symbol table. + self.insert_circuit_type(registers_type.identifier.clone(), registers_type); + self.insert_circuit_type(record_type.identifier.clone(), record_type); + self.insert_circuit_type(state_type.identifier.clone(), state_type); + self.insert_circuit_type(state_leaf_type.identifier.clone(), state_leaf_type); + self.insert_circuit_type(input_type.identifier.clone(), input_type); + + Ok(()) + } } diff --git a/static-check/src/static_check.rs b/static-check/src/static_check.rs index ca7162a5a8..27751ad812 100644 --- a/static-check/src/static_check.rs +++ b/static-check/src/static_check.rs @@ -24,50 +24,40 @@ pub struct StaticCheck { } impl StaticCheck { - /// - /// Returns a new `StaticCheck` with an empty symbol table. - /// - pub fn new() -> Self { - Self { - table: SymbolTable::new(None), - } - } - - /// - /// Returns a new `SymbolTable` from a given program and import parser. - /// - pub fn run(program: &Program, import_parser: &ImportParser) -> Result { - 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( + /// Runs pass one name checks and pass two type checks. + /// Builds a symbol table of circuit and function types to be used in the dynamic check. + /// + pub fn new( program: &Program, import_parser: &ImportParser, input: &Input, ) -> Result { - let mut check = Self::new(); + let mut check = Self::default(); - // Load program input types. - check.insert_input(input)?; - - // Run checks on program and imports. - check.check(program, import_parser)?; + // Run checks on program, imports, and input. + check.check(program, import_parser, input)?; + // Return the symbol table of types. Ok(check.table) } /// /// Computes pass one and pass two checks on self. /// - pub fn check(&mut self, program: &Program, import_parser: &ImportParser) -> Result<(), StaticCheckError> { + pub fn check( + &mut self, + program: &Program, + import_parser: &ImportParser, + input: &Input, + ) -> Result<(), StaticCheckError> { + // Insert input types. + self.table + .insert_input(input) + .map_err(|err| StaticCheckError::SymbolTableError(err))?; + // Run pass one checks. self.pass_one(program, import_parser)?; @@ -75,15 +65,6 @@ impl StaticCheck { self.pass_two(program) } - /// - /// Inserts the program input types into the symbol table. - /// - pub fn insert_input(&mut self, input: &Input) -> Result<(), StaticCheckError> { - self.table - .insert_input(input) - .map_err(|err| StaticCheckError::SymbolTableError(err)) - } - /// /// Checks for duplicate circuit and function names given an unresolved program. /// @@ -92,7 +73,7 @@ impl StaticCheck { /// pub fn pass_one(&mut self, program: &Program, import_parser: &ImportParser) -> Result<(), StaticCheckError> { self.table - .check_duplicate_program(program, import_parser) + .check_program_names(program, import_parser) .map_err(|err| StaticCheckError::SymbolTableError(err)) } @@ -105,7 +86,15 @@ impl StaticCheck { /// pub fn pass_two(&mut self, program: &Program) -> Result<(), StaticCheckError> { self.table - .check_unknown_types_program(program) + .check_types_program(program) .map_err(|err| StaticCheckError::SymbolTableError(err)) } } + +impl Default for StaticCheck { + fn default() -> Self { + Self { + table: SymbolTable::new(None), + } + } +} diff --git a/static-check/src/types/functions/function.rs b/static-check/src/types/functions/function.rs index 31465bfdd0..fef225b411 100644 --- a/static-check/src/types/functions/function.rs +++ b/static-check/src/types/functions/function.rs @@ -114,7 +114,7 @@ impl FunctionType { let function = Self::new(table, unresolved_function)?; // Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table. - table.insert_function(function_identifier, function); + table.insert_function_type(function_identifier, function); Ok(()) } diff --git a/static-check/src/types/type_.rs b/static-check/src/types/type_.rs index 11fb31e280..378a3f7c5a 100644 --- a/static-check/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -75,7 +75,7 @@ impl Type { UnresolvedType::Circuit(identifier) => { // Lookup the circuit type in the symbol table let circuit_type = table - .get_circuit(&identifier.name) + .get_circuit_type(&identifier.name) .ok_or(TypeError::undefined_circuit(identifier))?; Type::Circuit(circuit_type.identifier.clone()) diff --git a/static-check/tests/mod.rs b/static-check/tests/mod.rs index 631b9ca6a0..8e0d41bbd0 100644 --- a/static-check/tests/mod.rs +++ b/static-check/tests/mod.rs @@ -66,7 +66,7 @@ impl TestStaticCheck { let input = Input::new(); // Create new symbol table. - let _symbol_table = StaticCheck::run_with_input(&program, &import_parser, &input).unwrap(); + let _symbol_table = StaticCheck::new(&program, &import_parser, &input).unwrap(); } /// @@ -79,7 +79,7 @@ impl TestStaticCheck { let program = self.typed.into_repr(); // Create new symbol table. - let static_check = &mut StaticCheck::new(); + let static_check = &mut StaticCheck::default(); // Create empty import parser. let import_parser = ImportParser::new(); @@ -103,7 +103,7 @@ impl TestStaticCheck { let program = self.typed.into_repr(); // Create a new symbol table. - let static_check = &mut StaticCheck::new(); + let static_check = &mut StaticCheck::default(); // Create empty import parser. let import_parser = ImportParser::new(); From 46f585e2ffc0bf21bcd02b54698dea543d67c363 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 00:31:36 -0700 Subject: [PATCH 077/139] refactor compiler methods --- compiler/src/compiler.rs | 151 +++++++++++++++++++++++++-------------- compiler/tests/mod.rs | 7 -- dynamic-check/Cargo.toml | 2 +- imports/Cargo.toml | 2 +- static-check/Cargo.toml | 2 +- 5 files changed, 100 insertions(+), 64 deletions(-) diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index a87443fdb1..7515d6c359 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -59,6 +59,9 @@ pub struct Compiler> { } impl> Compiler { + /// + /// Returns a new Leo program compiler. + /// pub fn new(package_name: String, main_file_path: PathBuf, output_directory: PathBuf) -> Self { Self { package_name: package_name.clone(), @@ -72,8 +75,51 @@ impl> Compiler { } } + /// + /// Parses program files. + /// + /// Returns a compiler struct that stores the typed program abstract syntax trees (ast). + /// + pub fn parse_program_without_input( + package_name: String, + main_file_path: PathBuf, + output_directory: PathBuf, + ) -> Result { + let mut compiler = Self::new(package_name, main_file_path, output_directory); + + compiler.parse_and_check_program()?; + + Ok(compiler) + } + + /// + /// Parses input, state, and program files. + /// + /// Returns a compiler struct that stores the typed input and typed program abstract syntax trees (ast). + /// + pub fn parse_program_with_input( + package_name: String, + main_file_path: PathBuf, + output_directory: PathBuf, + input_string: &str, + input_path: &Path, + state_string: &str, + state_path: &Path, + ) -> Result { + let mut compiler = Self::new(package_name, main_file_path, output_directory); + + compiler.parse_input(input_string, input_path, state_string, state_path)?; + + compiler.parse_and_check_program()?; + + Ok(compiler) + } + + /// /// Parse the input and state files. + /// /// Stores a typed ast of all input variables to the program. + /// pub fn parse_input( &mut self, input_string: &str, @@ -106,51 +152,59 @@ impl> Compiler { Ok(()) } - /// Parses program files. - /// Returns a compiler struct that stores the typed program abstract syntax trees (ast). - pub fn parse_program_without_input( - package_name: String, - main_file_path: PathBuf, - output_directory: PathBuf, - ) -> Result { - let mut compiler = Self::new(package_name, main_file_path, output_directory); + /// + /// Runs program parser and program checker consecutively. + /// + pub(crate) fn parse_and_check_program(&mut self) -> Result<(), CompilerError> { + self.parse_program()?; - compiler.parse_program()?; - - Ok(compiler) - } - - /// Parses input, state, and program files. - /// Returns a compiler struct that stores the typed input and typed program abstract syntax trees (ast). - pub fn parse_program_with_input( - package_name: String, - main_file_path: PathBuf, - output_directory: PathBuf, - input_string: &str, - input_path: &Path, - state_string: &str, - state_path: &Path, - ) -> Result { - let mut compiler = Self::new(package_name, main_file_path, output_directory); - - compiler.parse_input(input_string, input_path, state_string, state_path)?; - - compiler.parse_program()?; - - Ok(compiler) + self.check_program() } + /// /// Parses the Leo program file, constructs a syntax tree, and generates a program. - #[allow(deprecated)] + /// pub(crate) fn parse_program(&mut self) -> Result<(), CompilerError> { - // Use the parser to construct the abstract syntax tree. + // Load the program file. let program_string = LeoAst::load_file(&self.main_file_path)?; - self.parse_program_from_string(&program_string) + // Use the parser to construct the abstract syntax tree. + let ast = LeoAst::new(&self.main_file_path, &program_string).map_err(|mut e| { + e.set_path(&self.main_file_path); + + e + })?; + + // Use the typed parser to construct the typed syntax tree. + let typed_tree = LeoTypedAst::new(&self.package_name, &ast); + + self.program = typed_tree.into_repr(); + self.imported_programs = ImportParser::parse(&self.program)?; + + tracing::debug!("Program parsing complete\n{:#?}", self.program); + + Ok(()) } + /// + /// Runs static and dynamic type checks on the program, imports, and input. + /// + pub(crate) fn check_program(&self) -> Result<(), CompilerError> { + // Run static check on program. + let symbol_table = StaticCheck::new(&self.program, &self.imported_programs, &self.program_input)?; + + // Run dynamic check on program. + DynamicCheck::new(&self.program, symbol_table)?; + + tracing::debug!("Program checks complete"); + + Ok(()) + } + + /// /// Parses the Leo program string, constructs a syntax tree, and generates a program. /// Used for testing only. + /// #[deprecated(note = "Please use the 'parse_program' method instead.")] pub fn parse_program_from_string(&mut self, program_string: &str) -> Result<(), CompilerError> { // Use the given bytes to construct the abstract syntax tree. @@ -180,12 +234,16 @@ impl> Compiler { Ok(()) } + /// /// Manually sets main function input + /// pub fn set_main_input(&mut self, input: MainInput) { self.program_input.set_main_input(input); } + /// /// Verifies the input to the program + /// pub fn verify_local_data_commitment( &self, system_parameters: &SystemParameters, @@ -195,6 +253,9 @@ impl> Compiler { Ok(result) } + /// + /// Returns a Sha256 checksum of the program file. + /// pub fn checksum(&self) -> Result { // Read in the main file as string let unparsed_file = fs::read_to_string(&self.main_file_path) @@ -208,7 +269,9 @@ impl> Compiler { Ok(hex::encode(hash)) } + /// /// Synthesizes the circuit without program input to verify correctness. + /// pub fn compile_constraints>(self, cs: &mut CS) -> Result { let path = self.main_file_path; @@ -245,26 +308,6 @@ impl> Compiler { }, ) } - - pub fn to_bytes(&self) -> Result, CompilerError> { - Ok(bincode::serialize(&self.program)?) - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - let program: Program = bincode::deserialize(bytes)?; - let program_input = Input::new(); - - Ok(Self { - package_name: program.name.clone(), - main_file_path: PathBuf::new(), - output_directory: PathBuf::new(), - program, - program_input, - imported_programs: ImportParser::new(), - _engine: PhantomData, - _group: PhantomData, - }) - } } impl> ConstraintSynthesizer for Compiler { diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index e4fce62e92..bd3e196c32 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -199,13 +199,6 @@ pub(crate) fn expect_static_check_error(error: CompilerError) { assert!(is_static_check) } -// pub(crate) fn expect_synthesis_error(program: EdwardsTestCompiler) { -// let mut cs = TestConstraintSystem::::new(); -// let _output = program.generate_constraints_helper(&mut cs).unwrap(); -// -// assert!(!cs.is_satisfied()); -// } - pub(crate) fn generate_main_input(input: Vec<(&str, Option)>) -> MainInput { let mut main_input = MainInput::new(); diff --git a/dynamic-check/Cargo.toml b/dynamic-check/Cargo.toml index c10ea4bc98..76855ac894 100644 --- a/dynamic-check/Cargo.toml +++ b/dynamic-check/Cargo.toml @@ -4,7 +4,7 @@ version = "1.0.3" authors = [ "The Aleo Team " ] description = "Checks that a program is correct using type inference" homepage = "https://aleo.org" -respository = "https://github.com/AleoHQ/leo" +repository = "https://github.com/AleoHQ/leo" keywords = [ "aleo", "cryptography", diff --git a/imports/Cargo.toml b/imports/Cargo.toml index 51bca2a856..6ef01f1426 100644 --- a/imports/Cargo.toml +++ b/imports/Cargo.toml @@ -4,7 +4,7 @@ version = "1.0.3" authors = [ "The Aleo Team "] description = "Import parser for Leo program package dependencies" homepage = "https://aleo.org" -respository = "https://github.com/AleoHQ/leo" +repository = "https://github.com/AleoHQ/leo" keywords = [ "aleo", "cryptography", diff --git a/static-check/Cargo.toml b/static-check/Cargo.toml index c79a458702..0e605147d9 100644 --- a/static-check/Cargo.toml +++ b/static-check/Cargo.toml @@ -4,7 +4,7 @@ version = "1.0.3" authors = [ "The Aleo Team " ] description = "Stores user-defined variables during type resolution" homepage = "https://aleo.org" -respository = "https://github.com/AleoHQ/leo" +repository = "https://github.com/AleoHQ/leo" keywords = [ "aleo", "cryptography", From 1a39ae93ca186949bd3bbc9db34796632c3de97c Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 10:06:50 -0700 Subject: [PATCH 078/139] Use matches macro --- compiler/tests/mod.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index bd3e196c32..afd4063378 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -182,21 +182,11 @@ pub(crate) fn expect_compiler_error(program: EdwardsTestCompiler) -> CompilerErr } pub(crate) fn expect_dynamic_check_error(error: CompilerError) { - let is_dynamic_check = match error { - CompilerError::DynamicCheckError(_) => true, - _ => false, - }; - - assert!(is_dynamic_check) + assert!(matches!(error, CompilerError::DynamicCheckError(_))) } pub(crate) fn expect_static_check_error(error: CompilerError) { - let is_static_check = match error { - CompilerError::StaticCheckError(_) => true, - _ => false, - }; - - assert!(is_static_check) + assert!(matches!(error, CompilerError::StaticCheckError(_))) } pub(crate) fn generate_main_input(input: Vec<(&str, Option)>) -> MainInput { From e68c7ad563b53dcb5119b4f544edb7c31743efb6 Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 10:09:55 -0700 Subject: [PATCH 079/139] Update dynamic-check/src/assertions/type_variable_pair.rs Co-authored-by: ljedrz --- dynamic-check/src/assertions/type_variable_pair.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs index 71daf593e3..76762482ba 100644 --- a/dynamic-check/src/assertions/type_variable_pair.rs +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -63,7 +63,7 @@ impl TypeVariablePairs { /// /// Returns the self vector of pairs. /// - pub fn get_pairs(&self) -> &Vec { + pub fn get_pairs(&self) -> &[TypeVariablePair] { &self.0 } From 861e092485d46b22af29a02ea03e8fbbc6183e1a Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 10:39:45 -0700 Subject: [PATCH 080/139] push arguments by value --- dynamic-check/src/assertions/type_equality.rs | 2 +- .../src/assertions/type_variable_pair.rs | 30 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/dynamic-check/src/assertions/type_equality.rs b/dynamic-check/src/assertions/type_equality.rs index 50a13eb448..ed7e70f6ab 100644 --- a/dynamic-check/src/assertions/type_equality.rs +++ b/dynamic-check/src/assertions/type_equality.rs @@ -63,6 +63,6 @@ impl TypeEquality { /// Returns the (type variable, type) pair from this assertion. /// pub fn pairs(&self) -> Result { - TypeVariablePairs::new(&self.left, &self.right, &self.span) + TypeVariablePairs::new(self.left.to_owned(), self.right.to_owned(), &self.span) } } diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs index 76762482ba..da3dd52dc3 100644 --- a/dynamic-check/src/assertions/type_variable_pair.rs +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -44,7 +44,7 @@ impl TypeVariablePairs { /// /// Returns a new `TypeVariablePairs` struct from the given left and right types. /// - pub fn new(left: &Type, right: &Type, span: &Span) -> Result { + pub fn new(left: Type, right: Type, span: &Span) -> Result { let mut pairs = Self::default(); // Push all `TypeVariablePair`s. @@ -70,9 +70,9 @@ impl TypeVariablePairs { /// /// Pushes a new `TypeVariablePair` struct to self. /// - pub fn push(&mut self, variable: &TypeVariable, type_: &Type) { + pub fn push(&mut self, variable: TypeVariable, type_: Type) { // Create a new type variable -> type pair. - let pair = TypeVariablePair(variable.clone(), type_.clone()); + let pair = TypeVariablePair(variable, type_); // Push the pair to the self vector. self.0.push(pair); @@ -83,12 +83,12 @@ impl TypeVariablePairs { /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left /// and right type. /// - pub fn push_pairs(&mut self, left: &Type, right: &Type, span: &Span) -> Result<(), TypeAssertionError> { + pub fn push_pairs(&mut self, left: Type, right: Type, span: &Span) -> Result<(), TypeAssertionError> { match (left, right) { (Type::TypeVariable(variable), type_) => Ok(self.push(variable, type_)), (type_, Type::TypeVariable(variable)) => Ok(self.push(variable, type_)), (Type::Array(left_type, left_dimensions), Type::Array(right_type, right_dimensions)) => { - self.push_pairs_array(left_type, left_dimensions, right_type, right_dimensions, span) + self.push_pairs_array(*left_type, left_dimensions, *right_type, right_dimensions, span) } (Type::Tuple(left_types), Type::Tuple(right_types)) => self.push_pairs_tuple(left_types, right_types, span), (_, _) => Ok(()), // No `TypeVariable` found so we do not push any pairs. @@ -102,15 +102,15 @@ impl TypeVariablePairs { /// fn push_pairs_array( &mut self, - left_type: &Type, - left_dimensions: &Vec, - right_type: &Type, - right_dimensions: &Vec, + left_type: Type, + left_dimensions: Vec, + right_type: Type, + right_dimensions: Vec, span: &Span, ) -> Result<(), TypeAssertionError> { // Flatten the array types to get the element types. - let (left_type_flat, left_dimensions_flat) = flatten_array_type(left_type, left_dimensions.to_owned()); - let (right_type_flat, right_dimensions_flat) = flatten_array_type(right_type, right_dimensions.to_owned()); + let (left_type_flat, left_dimensions_flat) = flatten_array_type(&left_type, left_dimensions.to_owned()); + let (right_type_flat, right_dimensions_flat) = flatten_array_type(&right_type, right_dimensions.to_owned()); // If the dimensions do not match, then throw an error. if left_dimensions_flat.ne(&right_dimensions_flat) { @@ -122,7 +122,7 @@ impl TypeVariablePairs { } // Compare the array element types. - self.push_pairs(left_type_flat, right_type_flat, span) + self.push_pairs(left_type_flat.to_owned(), right_type_flat.to_owned(), span) } /// @@ -132,12 +132,12 @@ impl TypeVariablePairs { /// fn push_pairs_tuple( &mut self, - left_types: &Vec, - right_types: &Vec, + left_types: Vec, + right_types: Vec, span: &Span, ) -> Result<(), TypeAssertionError> { // Iterate over each left == right pair of types. - for (left, right) in left_types.iter().zip(right_types) { + for (left, right) in left_types.into_iter().zip(right_types) { // Check for `TypeVariablePair`s. self.push_pairs(left, right, span)?; } From ff03e643147e59358cf1b00a25140a5d0219575a Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 10:58:09 -0700 Subject: [PATCH 081/139] Prefer to_vec over to_owned --- dynamic-check/src/assertions/type_variable_pair.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs index da3dd52dc3..34a91dff3e 100644 --- a/dynamic-check/src/assertions/type_variable_pair.rs +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -109,8 +109,8 @@ impl TypeVariablePairs { span: &Span, ) -> Result<(), TypeAssertionError> { // Flatten the array types to get the element types. - let (left_type_flat, left_dimensions_flat) = flatten_array_type(&left_type, left_dimensions.to_owned()); - let (right_type_flat, right_dimensions_flat) = flatten_array_type(&right_type, right_dimensions.to_owned()); + let (left_type_flat, left_dimensions_flat) = flatten_array_type(&left_type, left_dimensions.to_vec()); + let (right_type_flat, right_dimensions_flat) = flatten_array_type(&right_type, right_dimensions.to_vec()); // If the dimensions do not match, then throw an error. if left_dimensions_flat.ne(&right_dimensions_flat) { From 6931cadd71a97c549e0d2dc8f6ada20a32baafde Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:04:48 -0700 Subject: [PATCH 082/139] Prefer iterator over vector in parse_circuits Co-authored-by: ljedrz --- dynamic-check/src/dynamic_check.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index d1c94c0e47..f930dd9cca 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -69,7 +69,7 @@ impl DynamicCheck { /// /// Collects a vector of `Frames`s from a vector of circuit functions. /// - fn parse_circuits(&mut self, circuits: Vec<&Circuit>) -> Result<(), DynamicCheckError> { + fn parse_circuits<'a>(&mut self, circuits: impl Iterator) -> Result<(), DynamicCheckError> { for circuit in circuits { self.parse_circuit(circuit)?; } From 21c569d9503809ef266bd8e00a136b491995e0ef Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:05:42 -0700 Subject: [PATCH 083/139] Prefer iterator over vector in parse_functions Co-authored-by: ljedrz --- dynamic-check/src/dynamic_check.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index f930dd9cca..e86f34f896 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -111,7 +111,7 @@ impl DynamicCheck { /// /// Collects a vector of `TypeAssertion` predicates from a vector of functions. /// - fn parse_functions(&mut self, functions: Vec<&Function>) -> Result<(), DynamicCheckError> { + fn parse_functions<'a>(&mut self, functions: impl Iterator) -> Result<(), DynamicCheckError> { for function in functions { self.parse_function(function)?; } From 2133756d506c3aec77bc89816c7e5d0e229df912 Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:07:35 -0700 Subject: [PATCH 084/139] Prefer slice over vector reference in membership_failed Co-authored-by: ljedrz --- dynamic-check/src/errors/type_assertion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/errors/type_assertion.rs b/dynamic-check/src/errors/type_assertion.rs index 04ce0c7c3f..f776ea4b02 100644 --- a/dynamic-check/src/errors/type_assertion.rs +++ b/dynamic-check/src/errors/type_assertion.rs @@ -57,7 +57,7 @@ impl TypeAssertionError { /// /// Given type is not a member of the set of expected types. /// - pub fn membership_failed(given: &Type, set: &Vec, span: &Span) -> Self { + pub fn membership_failed(given: &Type, set: &[Type], span: &Span) -> Self { let message = format!( "Mismatched types. Given type `{}` is not in the expected type set `{:?}`.", given, set From c4f5d61a173a7650ddbe129680a9591e971246d6 Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:08:17 -0700 Subject: [PATCH 085/139] Prefer slice over vector reference in undefined_variable_name Co-authored-by: ljedrz --- dynamic-check/src/errors/variable_table.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/errors/variable_table.rs b/dynamic-check/src/errors/variable_table.rs index 306d2a9e22..d89432f0a0 100644 --- a/dynamic-check/src/errors/variable_table.rs +++ b/dynamic-check/src/errors/variable_table.rs @@ -45,7 +45,7 @@ impl VariableTableError { /// /// Attempted to lookup a variable name that does not exist in the table. /// - pub fn undefined_variable_name(name: &String, span: &Span) -> Self { + pub fn undefined_variable_name(name: &str, span: &Span) -> Self { let message = format!("Cannot find variable `{}` in this scope.", name); Self::new_from_span(message, span.clone()) From 3c30ca342bbc342d6e11bac7c075466568a6575b Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:09:12 -0700 Subject: [PATCH 086/139] Prefer string slice over string reference get_variable Co-authored-by: ljedrz --- dynamic-check/src/objects/frame.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index fbdf1af3b9..50a09bce48 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -157,7 +157,7 @@ impl Frame { /// /// Get a variable's type from the symbol table in the current scope. /// - fn get_variable(&self, name: &String) -> Option<&Type> { + fn get_variable(&self, name: &str) -> Option<&Type> { // Lookup in the current scope. let scope = self.scopes.last().unwrap(); From c05fe32d77ba1d472ed076d74dbea0281822a6e3 Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:11:28 -0700 Subject: [PATCH 087/139] Prefer str over String get_function Co-authored-by: ljedrz --- dynamic-check/src/objects/frame.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index 50a09bce48..793dfef914 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -168,7 +168,7 @@ impl Frame { /// /// Get a function's type from the user defined types in the current scope. /// - fn get_function(&self, name: &String) -> Option<&FunctionType> { + fn get_function(&self, name: &str) -> Option<&FunctionType> { self.user_defined_types.get_function_type(name) } From 2288510fec105f2c18480f3145bcc42bc5412d3f Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:12:23 -0700 Subject: [PATCH 088/139] Prefer str over String in get_circuit Co-authored-by: ljedrz --- dynamic-check/src/objects/frame.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index 793dfef914..6c839088fe 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -175,7 +175,7 @@ impl Frame { /// /// Get a circuit's type from the user defined types in the current scope. /// - fn get_circuit(&self, name: &String) -> Option<&CircuitType> { + fn get_circuit(&self, name: &str) -> Option<&CircuitType> { self.user_defined_types.get_circuit_type(name) } From b987a6df7c11257335f44da215ac5af6d1f3974e Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:14:02 -0700 Subject: [PATCH 089/139] Iterate over references instead of cloning in parse_statements Co-authored-by: ljedrz --- dynamic-check/src/objects/frame.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index 6c839088fe..d5b694a830 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -228,7 +228,7 @@ impl Frame { /// Collects a vector of `TypeAssertion` predicates from a vector of statements. /// fn parse_statements(&mut self) -> Result<(), FrameError> { - for statement in self.statements.clone() { + for statement in &self.statements { self.parse_statement(&statement)?; } From d5d34d3bdfe2ae86e1f3d671a8302b587b18fdc9 Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:18:32 -0700 Subject: [PATCH 090/139] Prefer iterator over vector in parse_block Co-authored-by: ljedrz --- dynamic-check/src/objects/frame.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index d5b694a830..2a695ad921 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -382,7 +382,7 @@ impl Frame { /// /// Collects `TypeAssertion` predicates from a block of statements. /// - fn parse_block(&mut self, statements: &Vec, _span: &Span) -> Result<(), FrameError> { + fn parse_block(&mut self, statements: impl Iterator, _span: &Span) -> Result<(), FrameError> { // Push new scope. let scope = Scope::new(self.scopes.last().map(|scope| scope.clone())); self.push_scope(scope); From 6cb0d5c3c185d115c244cbef1c44316264a7d335 Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:20:01 -0700 Subject: [PATCH 091/139] Prefer cloned over map + clone in parse_block Co-authored-by: ljedrz --- dynamic-check/src/objects/frame.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index 2a695ad921..ca1430c8d2 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -384,7 +384,7 @@ impl Frame { /// fn parse_block(&mut self, statements: impl Iterator, _span: &Span) -> Result<(), FrameError> { // Push new scope. - let scope = Scope::new(self.scopes.last().map(|scope| scope.clone())); + let scope = Scope::new(self.scopes.last().cloned()); self.push_scope(scope); // Parse all statements. From 74bfe113d09b134b4a81062d18e80cf06f48f243 Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:21:51 -0700 Subject: [PATCH 092/139] Prefer iterator over vector in parse_iteration Co-authored-by: ljedrz --- dynamic-check/src/objects/frame.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index ca1430c8d2..c4de0861b7 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -448,7 +448,7 @@ impl Frame { &mut self, identifier: &Identifier, from_to: &(Expression, Expression), - statements: &Vec, + statements: impl Iterator, span: &Span, ) -> Result<(), FrameError> { // Insert variable into symbol table with u32 type. From 0636997ddbba5a871d0829e35a512ce83e622cc9 Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:23:19 -0700 Subject: [PATCH 093/139] Prefer Vec new over with capacity in parse_statement_expression Co-authored-by: ljedrz --- dynamic-check/src/objects/frame.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index c4de0861b7..399ecc8ed9 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -472,7 +472,7 @@ impl Frame { /// fn parse_statement_expression(&mut self, expression: &Expression, span: &Span) -> Result<(), FrameError> { // Create empty tuple type. - let expected_type = Type::Tuple(Vec::with_capacity(0)); + let expected_type = Type::Tuple(Vec::new()); // Parse the actual type of the expression. let actual_type = self.parse_expression(expression)?; From e58f00d8b5cf377c5411ff0b42b481d866d61da8 Mon Sep 17 00:00:00 2001 From: Collin Chin Date: Tue, 27 Oct 2020 11:25:43 -0700 Subject: [PATCH 094/139] Prefer iterator over vector in parse_array Co-authored-by: ljedrz --- dynamic-check/src/objects/frame.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index 399ecc8ed9..eea43c32f8 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -763,7 +763,7 @@ impl Frame { /// /// Returns the type of the array expression. /// - fn parse_array(&mut self, expressions: &Vec, span: &Span) -> Result { + fn parse_array(&mut self, expressions: impl Iterator, span: &Span) -> Result { // Store array element type. let mut element_type = None; let mut count = 0usize; From f0a2e8298a977584a53a4dd6f8a12abfc17da03a Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 12:22:07 -0700 Subject: [PATCH 095/139] fix compilation errors --- .../src/assertions/type_variable_pair.rs | 8 +++++--- dynamic-check/src/dynamic_check.rs | 18 ++---------------- dynamic-check/src/objects/frame.rs | 12 ++++++------ dynamic-check/src/objects/scope.rs | 4 ++-- dynamic-check/src/objects/variable_table.rs | 2 +- static-check/src/objects/symbol_table.rs | 8 ++++---- 6 files changed, 20 insertions(+), 32 deletions(-) diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs index 34a91dff3e..c856be7ab7 100644 --- a/dynamic-check/src/assertions/type_variable_pair.rs +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -90,7 +90,9 @@ impl TypeVariablePairs { (Type::Array(left_type, left_dimensions), Type::Array(right_type, right_dimensions)) => { self.push_pairs_array(*left_type, left_dimensions, *right_type, right_dimensions, span) } - (Type::Tuple(left_types), Type::Tuple(right_types)) => self.push_pairs_tuple(left_types, right_types, span), + (Type::Tuple(left_types), Type::Tuple(right_types)) => { + self.push_pairs_tuple(left_types.into_iter(), right_types.into_iter(), span) + } (_, _) => Ok(()), // No `TypeVariable` found so we do not push any pairs. } } @@ -132,8 +134,8 @@ impl TypeVariablePairs { /// fn push_pairs_tuple( &mut self, - left_types: Vec, - right_types: Vec, + left_types: impl Iterator, + right_types: impl Iterator, span: &Span, ) -> Result<(), TypeAssertionError> { // Iterate over each left == right pair of types. diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index e86f34f896..f5aa5f2845 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -45,25 +45,11 @@ impl DynamicCheck { /// Collects a vector of `TypeAssertion` predicates from a program. /// fn parse_program(&mut self, program: &Program) -> Result<(), DynamicCheckError> { - // Iterate over circuit types. - let circuits = program - .circuits - .iter() - .map(|(_identifier, circuit)| circuit) - .collect::>(); - // Parse circuit types in program context. - self.parse_circuits(circuits)?; - - // Iterate over functions. - let functions = program - .functions - .iter() - .map(|(_identifier, function)| function) - .collect::>(); + self.parse_circuits(program.circuits.iter().map(|(_identifier, circuit)| circuit))?; // Parse functions in program context. - self.parse_functions(functions) + self.parse_functions(program.functions.iter().map(|(_identifier, function)| function)) } /// diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index eea43c32f8..b12111f75b 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -228,7 +228,7 @@ impl Frame { /// Collects a vector of `TypeAssertion` predicates from a vector of statements. /// fn parse_statements(&mut self) -> Result<(), FrameError> { - for statement in &self.statements { + for statement in self.statements.clone() { self.parse_statement(&statement)?; } @@ -382,14 +382,14 @@ impl Frame { /// /// Collects `TypeAssertion` predicates from a block of statements. /// - fn parse_block(&mut self, statements: impl Iterator, _span: &Span) -> Result<(), FrameError> { + fn parse_block(&mut self, statements: &[Statement], _span: &Span) -> Result<(), FrameError> { // Push new scope. let scope = Scope::new(self.scopes.last().cloned()); self.push_scope(scope); // Parse all statements. - for statement in statements.iter() { - self.parse_statement(statement)?; + for statement in statements { + self.parse_statement(&statement)?; } // Pop out of scope. @@ -448,7 +448,7 @@ impl Frame { &mut self, identifier: &Identifier, from_to: &(Expression, Expression), - statements: impl Iterator, + statements: &[Statement], span: &Span, ) -> Result<(), FrameError> { // Insert variable into symbol table with u32 type. @@ -763,7 +763,7 @@ impl Frame { /// /// Returns the type of the array expression. /// - fn parse_array(&mut self, expressions: impl Iterator, span: &Span) -> Result { + fn parse_array(&mut self, expressions: &[SpreadOrExpression], span: &Span) -> Result { // Store array element type. let mut element_type = None; let mut count = 0usize; diff --git a/dynamic-check/src/objects/scope.rs b/dynamic-check/src/objects/scope.rs index 19c8f95961..6ff5589404 100644 --- a/dynamic-check/src/objects/scope.rs +++ b/dynamic-check/src/objects/scope.rs @@ -54,7 +54,7 @@ impl Scope { /// /// Returns a reference to the type corresponding to the loop variable name. /// - pub fn get_loop_variable(&self, name: &String) -> Option<&Type> { + pub fn get_loop_variable(&self, name: &str) -> Option<&Type> { self.loop_variables.get(name) } @@ -63,7 +63,7 @@ impl Scope { /// /// Checks loop variables first, then non-loop variables. /// - pub fn get_variable(&self, name: &String) -> Option<&Type> { + pub fn get_variable(&self, name: &str) -> Option<&Type> { match self.get_loop_variable(name) { Some(loop_variable_type) => Some(loop_variable_type), None => self.variables.get(name), diff --git a/dynamic-check/src/objects/variable_table.rs b/dynamic-check/src/objects/variable_table.rs index 078cea1c82..cd8346fcc8 100644 --- a/dynamic-check/src/objects/variable_table.rs +++ b/dynamic-check/src/objects/variable_table.rs @@ -41,7 +41,7 @@ impl VariableTable { /// If the variable table did not have this key present, throw an undefined variable error /// using the given span. /// - pub fn get(&self, name: &String) -> Option<&Type> { + pub fn get(&self, name: &str) -> Option<&Type> { self.0.get(name) } diff --git a/static-check/src/objects/symbol_table.rs b/static-check/src/objects/symbol_table.rs index 709e14e86a..a5f73e2fc1 100644 --- a/static-check/src/objects/symbol_table.rs +++ b/static-check/src/objects/symbol_table.rs @@ -132,7 +132,7 @@ impl SymbolTable { /// If the symbol table did not have this name present, then the parent symbol table is checked. /// If there is no parent symbol table, then `None` is returned. /// - pub fn get_circuit_type(&self, name: &String) -> Option<&CircuitType> { + pub fn get_circuit_type(&self, name: &str) -> Option<&CircuitType> { // Lookup name in symbol table. match self.circuits.get(name) { Some(circuit) => Some(circuit), @@ -152,14 +152,14 @@ impl SymbolTable { /// If the symbol table did not have this name present, then the parent symbol table is checked. /// If there is no parent symbol table, then `None` is returned. /// - pub fn get_function_type(&self, key: &String) -> Option<&FunctionType> { + pub fn get_function_type(&self, name: &str) -> Option<&FunctionType> { // Lookup name in symbol table. - match self.functions.get(key) { + match self.functions.get(name) { Some(circuit) => Some(circuit), None => { // Lookup name in parent symbol table match &self.parent { - Some(parent) => parent.get_function_type(key), + Some(parent) => parent.get_function_type(name), None => None, } } From 0fbb797f206fda6900c95b6a9ab6d3821c7b8e85 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 12:48:44 -0700 Subject: [PATCH 096/139] Batch changes for frame.rs --- dynamic-check/src/objects/frame.rs | 45 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index b12111f75b..e7d2bb15fe 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -289,11 +289,14 @@ impl Frame { // Check if an explicit type is given. if let Some(type_) = variables.type_.clone() { // Convert the expected type into a dynamic check type. - let expected_type = match self.self_type.clone() { - Some(circuit_type) => { - Type::new_from_circuit(&self.user_defined_types, type_, circuit_type.identifier, span.clone()) - .unwrap() - } + let expected_type = match self.self_type { + Some(ref circuit_type) => Type::new_from_circuit( + &self.user_defined_types, + type_, + circuit_type.identifier.clone(), + span.clone(), + ) + .unwrap(), None => Type::new(&self.user_defined_types, type_, span.clone()).unwrap(), }; @@ -419,9 +422,8 @@ impl Frame { self.parse_block(&conditional.statements, span)?; // Parse conditional or end. - match &conditional.next { - Some(cond_or_end) => self.parse_conditional_nested_or_end(cond_or_end, span)?, - None => {} + if let Some(cond_or_end) = &conditional.next { + self.parse_conditional_nested_or_end(cond_or_end, span)?; } Ok(()) @@ -716,8 +718,8 @@ impl Frame { /// /// Returns the type of the tuple expression. /// - fn parse_tuple(&mut self, expressions: &Vec, _span: &Span) -> Result { - let mut types = vec![]; + fn parse_tuple(&mut self, expressions: &[Expression], _span: &Span) -> Result { + let mut types = Vec::with_capacity(expressions.len()); // Parse all tuple expressions. for expression in expressions { @@ -750,12 +752,12 @@ impl Frame { /// fn parse_tuple_access(&mut self, type_: Type, index: usize, span: &Span) -> Result { // Check the type is a tuple. - let elements = match type_ { + let mut elements = match type_ { Type::Tuple(elements) => elements, type_ => return Err(FrameError::tuple_access(&type_, span)), }; - let element_type = elements[index].clone(); + let element_type = elements.swap_remove(index); Ok(element_type) } @@ -892,10 +894,7 @@ impl Frame { /// Returns the Self type of the frame or an error if it does not exist. /// fn self_type_or_error(&self, span: &Span) -> Result { - self.self_type - .as_ref() - .map(|circuit_type| circuit_type.clone()) - .ok_or_else(|| FrameError::circuit_self(span)) + self.self_type.clone().ok_or_else(|| FrameError::circuit_self(span)) } /// @@ -904,7 +903,7 @@ impl Frame { fn parse_circuit( &mut self, identifier: &Identifier, - members: &Vec, + members: &[CircuitVariableDefinition], span: &Span, ) -> Result { // Check if identifier is Self circuit type. @@ -915,7 +914,7 @@ impl Frame { // Get circuit type. self.user_defined_types .get_circuit_type(&identifier.name) - .map(|circuit_type| circuit_type.clone()) + .cloned() .ok_or_else(|| FrameError::undefined_circuit(identifier))? }; @@ -1029,7 +1028,7 @@ impl Frame { fn parse_program_function(&mut self, identifier: &Identifier, _span: &Span) -> Result { self.user_defined_types .get_function_type(&identifier.name) - .map(|function_type| function_type.to_owned()) + .cloned() .ok_or_else(|| FrameError::undefined_function(identifier)) } @@ -1103,7 +1102,7 @@ impl Frame { fn parse_function_call( &mut self, expression: &Expression, - inputs: &Vec, + inputs: &[Expression], span: &Span, ) -> Result { // Parse the function name. @@ -1135,8 +1134,8 @@ impl Frame { /// fn parse_core_function_call( &mut self, - _name: &String, - _arguments: &Vec, + _name: &str, + _arguments: &[Expression], _span: &Span, ) -> Result { unimplemented!("type checks for core function calls not implemented") @@ -1146,7 +1145,7 @@ impl Frame { /// Returns `Ok` if all `TypeAssertions` can be solved successfully. /// pub(crate) fn check(self) -> Result<(), FrameError> { - let mut unsolved = self.type_assertions.clone(); + let mut unsolved = self.type_assertions; // Solve all type equality assertions first. let mut unsolved_membership = Vec::new(); From 817a3bd450e08f60cc64d0dd106402f359ec751d Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 12:54:02 -0700 Subject: [PATCH 097/139] Batch changes for scope.rs --- dynamic-check/src/objects/scope.rs | 17 ++++------------- dynamic-check/src/objects/variable_table.rs | 5 +---- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/dynamic-check/src/objects/scope.rs b/dynamic-check/src/objects/scope.rs index 6ff5589404..aed1547380 100644 --- a/dynamic-check/src/objects/scope.rs +++ b/dynamic-check/src/objects/scope.rs @@ -18,7 +18,7 @@ use crate::{ScopeError, VariableTable}; use leo_static_check::{FunctionInputType, Type}; /// A structure for tracking the types of defined variables in a block of code. -#[derive(Clone)] +#[derive(Clone, Default)] pub struct Scope { pub loop_variables: VariableTable, pub variables: VariableTable, @@ -32,7 +32,7 @@ impl Scope { /// pub fn new(parent: Option) -> Self { match parent { - Some(scope) => scope.clone(), + Some(scope) => scope, None => Self::default(), } } @@ -73,18 +73,9 @@ impl Scope { /// /// Inserts a vector of function input types into the `Scope` variable table. /// - pub fn insert_function_inputs(&mut self, function_inputs: &Vec) -> Result<(), ScopeError> { + pub fn insert_function_inputs(&mut self, function_inputs: &[FunctionInputType]) -> Result<(), ScopeError> { self.variables .insert_function_inputs(function_inputs) - .map_err(|err| ScopeError::VariableTableError(err)) - } -} - -impl Default for Scope { - fn default() -> Self { - Self { - loop_variables: VariableTable::default(), - variables: VariableTable::default(), - } + .map_err(ScopeError::VariableTableError) } } diff --git a/dynamic-check/src/objects/variable_table.rs b/dynamic-check/src/objects/variable_table.rs index cd8346fcc8..85f84bae0e 100644 --- a/dynamic-check/src/objects/variable_table.rs +++ b/dynamic-check/src/objects/variable_table.rs @@ -48,10 +48,7 @@ impl VariableTable { /// /// Inserts a vector of function input types into the variable table. /// - pub fn insert_function_inputs( - &mut self, - function_inputs: &Vec, - ) -> Result<(), VariableTableError> { + pub fn insert_function_inputs(&mut self, function_inputs: &[FunctionInputType]) -> Result<(), VariableTableError> { for input in function_inputs { let input_name = input.identifier().name.clone(); let input_type = input.type_(); From f275a7cddfa9c75f43849ef4d9ae61546779b03a Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 13:13:16 -0700 Subject: [PATCH 098/139] Batch changes for imports module --- imports/src/errors/import_parser.rs | 9 ------- imports/src/parser/import_parser.rs | 32 +++++++++------------- imports/src/parser/parse_symbol.rs | 42 +++++++++-------------------- typed/src/imports/import_symbol.rs | 2 +- typed/src/imports/package.rs | 2 +- typed/src/imports/package_access.rs | 2 +- 6 files changed, 28 insertions(+), 61 deletions(-) diff --git a/imports/src/errors/import_parser.rs b/imports/src/errors/import_parser.rs index 7717286c37..cb3ea1f4b1 100644 --- a/imports/src/errors/import_parser.rs +++ b/imports/src/errors/import_parser.rs @@ -45,15 +45,6 @@ impl ImportParserError { Self::new_from_span(message, identifier.span) } - /// - /// A package name has been imported twice. - /// - pub fn duplicate_import(name: String, span: Span) -> Self { - let message = format!("Duplicate imports found for `{}`.", name); - - Self::new_from_span(message, span) - } - /// /// A core package name has been imported twice. /// diff --git a/imports/src/parser/import_parser.rs b/imports/src/parser/import_parser.rs index 66322776dc..35540c4d73 100644 --- a/imports/src/parser/import_parser.rs +++ b/imports/src/parser/import_parser.rs @@ -17,7 +17,10 @@ use crate::errors::ImportParserError; use leo_typed::{Package, Program}; -use std::{collections::HashMap, env::current_dir}; +use std::{ + collections::{HashMap, HashSet}, + env::current_dir, +}; /// Stores imported packages. /// @@ -26,7 +29,7 @@ use std::{collections::HashMap, env::current_dir}; #[derive(Clone)] pub struct ImportParser { imports: HashMap, - core_packages: Vec, + core_packages: HashSet, } impl ImportParser { @@ -36,7 +39,7 @@ impl ImportParser { pub fn new() -> Self { Self { imports: HashMap::new(), - core_packages: vec![], + core_packages: HashSet::new(), } } @@ -48,7 +51,7 @@ impl ImportParser { /// pub(crate) fn insert_import(&mut self, file_name: String, program: Program) { // Insert the imported program. - let _program = self.imports.insert(file_name.clone(), program); + let _program = self.imports.insert(file_name, program); } /// @@ -65,7 +68,7 @@ impl ImportParser { } // Append the core package. - self.core_packages.push(package.clone()); + self.core_packages.insert(package.clone()); Ok(()) } @@ -81,16 +84,7 @@ impl ImportParser { /// Returns a reference to the core package corresponding to the given package. /// pub fn get_core_package(&self, package: &Package) -> Option<&Package> { - self.core_packages() - .iter() - .find(|core_package| core_package.eq(&package)) - } - - /// - /// Returns a reference to the vector of core packages. - /// - pub fn core_packages(&self) -> &Vec { - &self.core_packages + self.core_packages.iter().find(|core_package| core_package.eq(&package)) } /// @@ -108,11 +102,9 @@ impl ImportParser { let path = current_dir().map_err(|error| ImportParserError::current_directory_error(error))?; // Parse each import statement. - program - .imports - .iter() - .map(|import| imports.parse_package(path.clone(), &import.package)) - .collect::, ImportParserError>>()?; + for import in &program.imports { + imports.parse_package(path.clone(), &import.package)?; + } Ok(imports) } diff --git a/imports/src/parser/parse_symbol.rs b/imports/src/parser/parse_symbol.rs index c62ce8c84b..1b98912b27 100644 --- a/imports/src/parser/parse_symbol.rs +++ b/imports/src/parser/parse_symbol.rs @@ -82,29 +82,7 @@ impl ImportParser { // import * can only be invoked on a package with a library file or a leo file if is_package || is_leo_file { - // Get the package typed syntax tree. - let program = parse_import_file(package, span)?; - - // Insert the package's imports into the import parser. - program - .imports - .iter() - .map(|import| self.parse_package(package.path(), &import.package)) - .collect::, ImportParserError>>()?; - - // Get the package file name from the path. - let file_name_path = PathBuf::from(package.file_name()); - let file_name = file_name_path - .file_stem() - .unwrap() - .to_os_string() - .into_string() - .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); - - Ok(()) + self.parse_import_package(package, span) } else { // importing * from a directory or non-leo file in `package/src/` is illegal Err(ImportParserError::star(&package.path(), span.clone())) @@ -116,14 +94,20 @@ impl ImportParser { /// pub fn parse_import_symbol(&mut self, package: &DirEntry, symbol: &ImportSymbol) -> Result<(), ImportParserError> { // Get the package typed syntax tree. - let program = parse_import_file(package, &symbol.span)?; + self.parse_import_package(package, &symbol.span) + } + + /// + /// Import a symbol from a given package. + /// + pub fn parse_import_package(&mut self, package: &DirEntry, span: &Span) -> Result<(), ImportParserError> { + // Get the package typed syntax tree. + let program = parse_import_file(package, span)?; // Insert the package's imports into the import parser. - program - .imports - .iter() - .map(|import| self.parse_package(package.path(), &import.package)) - .collect::, ImportParserError>>()?; + for import in &program.imports { + self.parse_package(package.path(), &import.package)?; + } // Get the package file name from the path. let file_name_path = PathBuf::from(package.file_name()); diff --git a/typed/src/imports/import_symbol.rs b/typed/src/imports/import_symbol.rs index 7c1e129927..d27904f0fb 100644 --- a/typed/src/imports/import_symbol.rs +++ b/typed/src/imports/import_symbol.rs @@ -20,7 +20,7 @@ use leo_ast::imports::ImportSymbol as AstImportSymbol; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)] pub struct ImportSymbol { pub symbol: Identifier, pub alias: Option, diff --git a/typed/src/imports/package.rs b/typed/src/imports/package.rs index d67cde967f..79ddfb6cb9 100644 --- a/typed/src/imports/package.rs +++ b/typed/src/imports/package.rs @@ -20,7 +20,7 @@ use leo_ast::imports::Package as AstPackage; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)] pub struct Package { pub name: Identifier, pub access: PackageAccess, diff --git a/typed/src/imports/package_access.rs b/typed/src/imports/package_access.rs index 27608905ad..0af5b54820 100644 --- a/typed/src/imports/package_access.rs +++ b/typed/src/imports/package_access.rs @@ -20,7 +20,7 @@ use leo_ast::imports::PackageAccess as AstPackageAccess; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)] pub enum PackageAccess { Star(Span), SubPackage(Box), From 085d59e67a1d096b93aca0421ee56735d8422adc Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 14:27:18 -0700 Subject: [PATCH 099/139] Batch changes for static check module 1 --- .../src/assertions/type_variable_pair.rs | 4 +- dynamic-check/src/objects/frame.rs | 10 ++--- static-check/src/attributes/attribute.rs | 2 +- static-check/src/objects/symbol_table.rs | 44 +++++++------------ static-check/src/types/circuits/circuit.rs | 31 +++++++++---- .../src/types/circuits/circuit_function.rs | 2 +- .../src/types/circuits/circuit_variable.rs | 6 +-- static-check/src/types/functions/function.rs | 6 +-- .../functions/function_input_variable.rs | 34 +++++++++----- .../src/types/parameters/parameter.rs | 41 +++++++++-------- static-check/src/types/type_.rs | 38 +++++++++------- static-check/src/types/type_variable.rs | 4 +- typed/src/common/assignee.rs | 2 +- typed/src/common/identifier.rs | 17 +++++-- typed/src/common/span.rs | 4 +- typed/src/common/variable_name.rs | 9 ---- 16 files changed, 139 insertions(+), 115 deletions(-) diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs index c856be7ab7..030aef6390 100644 --- a/dynamic-check/src/assertions/type_variable_pair.rs +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -90,9 +90,7 @@ impl TypeVariablePairs { (Type::Array(left_type, left_dimensions), Type::Array(right_type, right_dimensions)) => { self.push_pairs_array(*left_type, left_dimensions, *right_type, right_dimensions, span) } - (Type::Tuple(left_types), Type::Tuple(right_types)) => { - self.push_pairs_tuple(left_types.into_iter(), right_types.into_iter(), span) - } + (Type::Tuple(left_types), Type::Tuple(right_types)) => self.push_pairs_tuple(left_types, right_types, span), (_, _) => Ok(()), // No `TypeVariable` found so we do not push any pairs. } } diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index e7d2bb15fe..63ab137d83 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -1066,7 +1066,7 @@ impl Frame { let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; // Check that the function is non-static. - if circuit_function_type.attributes.contains(&Attribute::Static) { + if let Some(Attribute::Static) = circuit_function_type.attribute { return Err(FrameError::invalid_static_access(identifier)); } @@ -1087,11 +1087,11 @@ impl Frame { let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; // Check that the function is static. - if !circuit_function_type.attributes.contains(&Attribute::Static) { - return Err(FrameError::invalid_member_access(identifier)); + if let Some(Attribute::Static) = circuit_function_type.attribute { + Ok(circuit_function_type.function.to_owned()) + } else { + Err(FrameError::invalid_member_access(identifier)) } - - Ok(circuit_function_type.function.to_owned()) } /// diff --git a/static-check/src/attributes/attribute.rs b/static-check/src/attributes/attribute.rs index 0fa7153b69..81d1dca02e 100644 --- a/static-check/src/attributes/attribute.rs +++ b/static-check/src/attributes/attribute.rs @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; /// Indicates that a program variable has additional functionality. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Attribute { Mutable, Static, diff --git a/static-check/src/objects/symbol_table.rs b/static-check/src/objects/symbol_table.rs index a5f73e2fc1..1ae5c10a82 100644 --- a/static-check/src/objects/symbol_table.rs +++ b/static-check/src/objects/symbol_table.rs @@ -19,7 +19,7 @@ use leo_core::CorePackageList; use leo_imports::ImportParser; use leo_typed::{Circuit, Function, Identifier, ImportStatement, ImportSymbol, Input, Package, Program}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; pub const INPUT_VARIABLE_NAME: &str = "input"; pub const RECORD_VARIABLE_NAME: &str = "record"; @@ -229,11 +229,11 @@ impl SymbolTable { /// pub fn check_import_names( &mut self, - imports: &Vec, + imports: &[ImportStatement], import_parser: &ImportParser, ) -> Result<(), SymbolTableError> { // Iterate over imported names. - for import in imports.iter() { + for import in imports { self.check_import_statement(import, import_parser)?; } @@ -307,29 +307,27 @@ impl SymbolTable { // Import all symbols from an imported file for now. // Keep track of which import files have already been checked. - let mut checked = Vec::new(); + let mut checked = HashSet::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))?; + // Push the imported file's name to checked import files. + if !checked.insert(name) { + // Skip the imported symbol if we have already checked the file. + continue; + }; + // Check the imported program for duplicate types. self.check_program_names(program, import_parser)?; // Check the imported program for undefined types. self.check_types_program(program)?; - // 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. } @@ -353,25 +351,15 @@ impl SymbolTable { 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)) => { + match program.circuits.get(&symbol.symbol) { + Some(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)) => { + match program.functions.get(&symbol.symbol) { + Some(function) => { // Insert the imported function. self.insert_function_name(identifier.to_string(), ParameterType::from(function.to_owned())) } @@ -408,7 +396,7 @@ impl SymbolTable { /// pub fn check_types_circuits(&mut self, circuits: &HashMap) -> Result<(), SymbolTableError> { // Iterate over circuit names and definitions. - for (_, circuit) in circuits.iter() { + for circuit in circuits.values() { // Get the identifier of the circuit. let identifier = circuit.circuit_name.clone(); @@ -431,7 +419,7 @@ impl SymbolTable { /// pub fn check_types_functions(&mut self, functions: &HashMap) -> Result<(), SymbolTableError> { // Iterate over function names and definitions. - for (_, function) in functions.iter() { + for function in functions.values() { // Get the identifier of the function. let identifier = function.identifier.clone(); diff --git a/static-check/src/types/circuits/circuit.rs b/static-check/src/types/circuits/circuit.rs index 16ba130f6d..a9a453cce2 100644 --- a/static-check/src/types/circuits/circuit.rs +++ b/static-check/src/types/circuits/circuit.rs @@ -25,13 +25,16 @@ use crate::{ use leo_typed::{Circuit, CircuitMember, Identifier, InputValue, Parameter, Span}; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use std::{ + collections::HashMap, + hash::{Hash, Hasher}, +}; /// Stores circuit definition details. /// /// This type should be added to the circuit symbol table for a resolved syntax tree. /// This is a user-defined type. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, Serialize, Deserialize)] pub struct CircuitType { /// The name of the circuit definition. pub identifier: Identifier, @@ -68,13 +71,13 @@ impl CircuitType { )?; // Check if the circuit member variable is mutable. - let attributes = if is_mutable { vec![Attribute::Mutable] } else { vec![] }; + let attribute = if is_mutable { Some(Attribute::Mutable) } else { None }; // Create a new circuit variable type. let variable = CircuitVariableType { identifier: variable_identifier, type_, - attributes, + attribute, }; // Store the circuit variable type. @@ -85,12 +88,12 @@ impl CircuitType { let function_type = FunctionType::from_circuit(table, circuit_identifier.clone(), function)?; // Check if the circuit member function is static. - let attributes = if is_static { vec![Attribute::Static] } else { vec![] }; + let attribute = if is_static { Some(Attribute::Static) } else { None }; // Create a new circuit function type. let function = CircuitFunctionType { function: function_type, - attributes, + attribute, }; // Store the circuit function type. @@ -101,7 +104,7 @@ impl CircuitType { // Return a new circuit type. Ok(CircuitType { - identifier: circuit_identifier.clone(), + identifier: circuit_identifier, variables, functions, }) @@ -158,7 +161,7 @@ impl CircuitType { let variable = CircuitVariableType { identifier: parameter.variable, type_: Type::new(table, parameter.type_, Span::default())?, - attributes: Vec::new(), + attribute: None, }; variables.push(variable); @@ -175,3 +178,15 @@ impl CircuitType { }) } } + +impl PartialEq for CircuitType { + fn eq(&self, other: &Self) -> bool { + self.identifier.eq(&other.identifier) + } +} + +impl Hash for CircuitType { + fn hash(&self, state: &mut H) { + self.identifier.hash(state); + } +} diff --git a/static-check/src/types/circuits/circuit_function.rs b/static-check/src/types/circuits/circuit_function.rs index 0eff740236..4c6d8686a9 100644 --- a/static-check/src/types/circuits/circuit_function.rs +++ b/static-check/src/types/circuits/circuit_function.rs @@ -23,5 +23,5 @@ pub struct CircuitFunctionType { /// The function signature of the circuit function pub function: FunctionType, /// The attributes of the circuit function - pub attributes: Vec, + pub attribute: Option, } diff --git a/static-check/src/types/circuits/circuit_variable.rs b/static-check/src/types/circuits/circuit_variable.rs index e471f3a752..a23d864782 100644 --- a/static-check/src/types/circuits/circuit_variable.rs +++ b/static-check/src/types/circuits/circuit_variable.rs @@ -25,8 +25,8 @@ pub struct CircuitVariableType { pub identifier: Identifier, /// The type of the circuit variable pub type_: Type, - /// The attributes of the circuit variable - pub attributes: Vec, + /// The attribute of the circuit variable + pub attribute: Option, } impl From<&CircuitType> for CircuitVariableType { @@ -34,7 +34,7 @@ impl From<&CircuitType> for CircuitVariableType { Self { identifier: type_.identifier.clone(), type_: Type::Circuit(type_.identifier.clone()), - attributes: Vec::new(), + attribute: None, } } } diff --git a/static-check/src/types/functions/function.rs b/static-check/src/types/functions/function.rs index fef225b411..5480794c2a 100644 --- a/static-check/src/types/functions/function.rs +++ b/static-check/src/types/functions/function.rs @@ -47,7 +47,7 @@ impl FunctionType { /// user-defined types. /// pub fn new(table: &SymbolTable, unresolved: Function) -> Result { - let mut inputs_resolved = vec![]; + let mut inputs_resolved = Vec::with_capacity(unresolved.input.len()); // Type check function inputs for input in unresolved.input { @@ -80,7 +80,7 @@ impl FunctionType { unresolved_function: Function, ) -> Result { let function_identifier = unresolved_function.identifier; - let mut inputs = vec![]; + let mut inputs = Vec::with_capacity(unresolved_function.input.len()); // Type check function inputs. for unresolved_input in unresolved_function.input { @@ -97,7 +97,7 @@ impl FunctionType { )?; Ok(FunctionType { - identifier: function_identifier.clone(), + identifier: function_identifier, inputs, output, }) diff --git a/static-check/src/types/functions/function_input_variable.rs b/static-check/src/types/functions/function_input_variable.rs index 80b6614525..1e6d1c7bd8 100644 --- a/static-check/src/types/functions/function_input_variable.rs +++ b/static-check/src/types/functions/function_input_variable.rs @@ -18,8 +18,9 @@ use crate::{Attribute, ParameterType, SymbolTable, Type, TypeError}; use leo_typed::{FunctionInputVariable, Identifier, Span}; use serde::{Deserialize, Serialize}; +use std::hash::{Hash, Hasher}; -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, Serialize, Deserialize)] pub struct FunctionInputVariableType { /// Name of function input. pub identifier: Identifier, @@ -28,7 +29,7 @@ pub struct FunctionInputVariableType { pub type_: Type, /// The attributes of the function input. - pub attributes: Vec, + pub attribute: Option, /// The span of the function input. pub span: Span, @@ -42,16 +43,16 @@ impl FunctionInputVariableType { /// pub fn new(table: &SymbolTable, unresolved: FunctionInputVariable) -> Result { let type_ = Type::new(table, unresolved.type_, unresolved.span.clone())?; - let attributes = if unresolved.mutable { - vec![Attribute::Mutable] + let attribute = if unresolved.mutable { + Some(Attribute::Mutable) } else { - vec![] + None }; Ok(FunctionInputVariableType { identifier: unresolved.identifier, type_, - attributes, + attribute, span: unresolved.span, }) } @@ -75,16 +76,17 @@ impl FunctionInputVariableType { circuit_name, unresolved_function_input.span.clone(), )?; - let attributes = if unresolved_function_input.mutable { - vec![Attribute::Mutable] + + let attribute = if unresolved_function_input.mutable { + Some(Attribute::Mutable) } else { - vec![] + None }; Ok(FunctionInputVariableType { identifier: unresolved_function_input.identifier, type_, - attributes, + attribute, span: unresolved_function_input.span, }) } @@ -101,3 +103,15 @@ impl FunctionInputVariableType { table.insert_name(key, value) } } + +impl PartialEq for FunctionInputVariableType { + fn eq(&self, other: &Self) -> bool { + self.identifier.eq(&other.identifier) + } +} + +impl Hash for FunctionInputVariableType { + fn hash(&self, state: &mut H) { + self.identifier.hash(state) + } +} diff --git a/static-check/src/types/parameters/parameter.rs b/static-check/src/types/parameters/parameter.rs index 9c269c926b..ce1ca9088b 100644 --- a/static-check/src/types/parameters/parameter.rs +++ b/static-check/src/types/parameters/parameter.rs @@ -13,29 +13,22 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Attribute, Type}; +use crate::{Attribute, FunctionInputVariableType, Type}; use leo_typed::{Circuit, Function, Identifier}; -use crate::FunctionInputVariableType; -use std::fmt; +use std::{ + fmt, + hash::{Hash, Hasher}, +}; /// Stores variable definition details. /// /// This type should be added to the variable symbol table for a resolved syntax tree. -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Eq)] pub struct ParameterType { pub identifier: Identifier, pub type_: Type, - pub attributes: Vec, -} - -impl ParameterType { - /// - /// Returns `true` if this variable's value can be modified. - /// - pub fn is_mutable(&self) -> bool { - self.attributes.contains(&Attribute::Mutable) - } + pub attribute: Option, } impl From for ParameterType { @@ -45,7 +38,7 @@ impl From for ParameterType { ParameterType { identifier: identifier.clone(), type_: Type::Circuit(identifier), - attributes: vec![], + attribute: None, } } } @@ -56,8 +49,8 @@ impl From for ParameterType { ParameterType { identifier: identifier.clone(), - type_: Type::Function(identifier.clone()), - attributes: vec![], + type_: Type::Function(identifier), + attribute: None, } } } @@ -67,7 +60,7 @@ impl From for ParameterType { ParameterType { identifier: value.identifier, type_: value.type_, - attributes: value.attributes, + attribute: value.attribute, } } } @@ -77,3 +70,15 @@ impl fmt::Display for ParameterType { write!(f, "{}", self.identifier) } } + +impl PartialEq for ParameterType { + fn eq(&self, other: &Self) -> bool { + self.identifier.eq(&other.identifier) + } +} + +impl Hash for ParameterType { + fn hash(&self, state: &mut H) { + self.identifier.hash(state); + } +} diff --git a/static-check/src/types/type_.rs b/static-check/src/types/type_.rs index 378a3f7c5a..94e6d300b4 100644 --- a/static-check/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -23,7 +23,7 @@ use std::{ }; /// A type in a Leo program. -#[derive(Clone, Debug, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize)] pub enum Type { // Data types Address, @@ -186,8 +186,8 @@ impl Type { } /// Returns a list of signed integer types. - pub fn signed_integer_types() -> Vec { - vec![ + pub const fn signed_integer_types() -> [Type; 5] { + [ Type::IntegerType(IntegerType::I8), Type::IntegerType(IntegerType::I16), Type::IntegerType(IntegerType::I32), @@ -197,8 +197,8 @@ impl Type { } /// Returns a list of unsigned integer types. - pub fn unsigned_integer_types() -> Vec { - vec![ + pub const fn unsigned_integer_types() -> [Type; 5] { + [ Type::IntegerType(IntegerType::U8), Type::IntegerType(IntegerType::U16), Type::IntegerType(IntegerType::U32), @@ -209,29 +209,39 @@ impl Type { /// Returns a list of positive integer types. pub fn negative_integer_types() -> Vec { - let mut types = vec![Type::Field, Type::Group]; + let field_group = [Type::Field, Type::Group]; - types.append(&mut Self::signed_integer_types()); + let mut types = Vec::new(); + + types.extend_from_slice(&field_group); + types.extend_from_slice(&Self::signed_integer_types()); types } /// Returns a list of integer types. pub fn integer_types() -> Vec { - let mut types = Self::negative_integer_types(); + let mut types = Vec::new(); - types.append(&mut Self::unsigned_integer_types()); + types.extend_from_slice(&Self::unsigned_integer_types()); + types.extend_from_slice(&Self::negative_integer_types()); types } /// Returns a list of possible index types (u8, u16, u32). pub fn index_types() -> Vec { - vec![ + let index_types = [ Type::IntegerType(IntegerType::U8), Type::IntegerType(IntegerType::U16), Type::IntegerType(IntegerType::U32), - ] + ]; + + let mut types = Vec::new(); + + types.extend_from_slice(&index_types); + + types } /// @@ -267,14 +277,14 @@ impl fmt::Display for Type { Type::Array(type_, dimensions) => { let dimensions_string = dimensions .iter() - .map(|dimension| format!("{}", dimension)) + .map(|dimension| dimension.to_string()) .collect::>() .join(", "); write!(f, "[{}; ({})]", *type_, dimensions_string) } Type::Tuple(tuple) => { - let tuple_string = tuple.iter().map(|x| format!("{}", x)).collect::>().join(", "); + let tuple_string = tuple.iter().map(|x| x.to_string()).collect::>().join(", "); write!(f, "({})", tuple_string) } @@ -313,8 +323,6 @@ impl PartialEq for Type { } } -impl Eq for Type {} - /// /// Returns the data type of the array element and vector of dimensions. /// diff --git a/static-check/src/types/type_variable.rs b/static-check/src/types/type_variable.rs index 5a07795030..fc08c78e78 100644 --- a/static-check/src/types/type_variable.rs +++ b/static-check/src/types/type_variable.rs @@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; /// An unknown type in a Leo program. -#[derive(Clone, Debug, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize)] pub struct TypeVariable { identifier: Identifier, } @@ -42,5 +42,3 @@ impl PartialEq for TypeVariable { self.identifier.name.eq(&other.identifier.name) || self.identifier.span.eq(&other.identifier.span) } } - -impl Eq for TypeVariable {} diff --git a/typed/src/common/assignee.rs b/typed/src/common/assignee.rs index b548450166..9007420a6f 100644 --- a/typed/src/common/assignee.rs +++ b/typed/src/common/assignee.rs @@ -59,7 +59,7 @@ impl<'ast> From> for Assignee { accesses: assignee .accesses .into_iter() - .map(|access| AssigneeAccess::from(access)) + .map(AssigneeAccess::from) .collect::>(), span: Span::from(assignee.span), } diff --git a/typed/src/common/identifier.rs b/typed/src/common/identifier.rs index 20195b37c7..8b24fcd91f 100644 --- a/typed/src/common/identifier.rs +++ b/typed/src/common/identifier.rs @@ -32,14 +32,18 @@ use serde::{ Serialize, Serializer, }; -use std::{collections::BTreeMap, fmt, hash::Hash}; +use std::{ + collections::BTreeMap, + fmt, + hash::{Hash, Hasher}, +}; /// An identifier in the constrained program. /// /// Attention - When adding or removing fields from this struct, /// please remember to update it's Serialize and Deserialize implementation /// to reflect the new struct instantiation. -#[derive(Clone, Hash)] +#[derive(Clone, Eq)] pub struct Identifier { pub name: String, pub span: Span, @@ -53,7 +57,7 @@ impl Identifier { } } - pub fn new_with_span(name: &String, span: &Span) -> Self { + pub fn new_with_span(name: &str, span: &Span) -> Self { Self { name: name.to_owned(), span: span.to_owned(), @@ -177,7 +181,12 @@ impl PartialEq for Identifier { } } -impl Eq for Identifier {} +impl Hash for Identifier { + fn hash(&self, state: &mut H) { + self.name.hash(state); + self.span.hash(state); + } +} impl Serialize for Identifier { fn serialize(&self, serializer: S) -> Result { diff --git a/typed/src/common/span.rs b/typed/src/common/span.rs index d2cd7a244f..4d933e0ff4 100644 --- a/typed/src/common/span.rs +++ b/typed/src/common/span.rs @@ -18,7 +18,7 @@ use pest::Span as AstSpan; use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, Serialize, Deserialize)] pub struct Span { /// text of input string pub text: String, @@ -36,8 +36,6 @@ impl PartialEq for Span { } } -impl Eq for Span {} - impl Hash for Span { fn hash(&self, state: &mut H) { self.line.hash(state); diff --git a/typed/src/common/variable_name.rs b/typed/src/common/variable_name.rs index 6cf69fec81..bb0a92300f 100644 --- a/typed/src/common/variable_name.rs +++ b/typed/src/common/variable_name.rs @@ -27,15 +27,6 @@ pub struct VariableName { pub span: Span, } -impl VariableName { - /// - /// Returns the name of the `VariableName` as a string. - /// - pub fn name_string(&self) -> &String { - &self.identifier.name - } -} - impl<'ast> From> for VariableName { fn from(name: AstVariableName<'ast>) -> Self { Self { From 078827310c845d5066770dbdcd62d3f99851d0b9 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 15:08:22 -0700 Subject: [PATCH 100/139] fix type variable tuple parsing --- dynamic-check/src/assertions/type_variable_pair.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs index 030aef6390..c856be7ab7 100644 --- a/dynamic-check/src/assertions/type_variable_pair.rs +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -90,7 +90,9 @@ impl TypeVariablePairs { (Type::Array(left_type, left_dimensions), Type::Array(right_type, right_dimensions)) => { self.push_pairs_array(*left_type, left_dimensions, *right_type, right_dimensions, span) } - (Type::Tuple(left_types), Type::Tuple(right_types)) => self.push_pairs_tuple(left_types, right_types, span), + (Type::Tuple(left_types), Type::Tuple(right_types)) => { + self.push_pairs_tuple(left_types.into_iter(), right_types.into_iter(), span) + } (_, _) => Ok(()), // No `TypeVariable` found so we do not push any pairs. } } From 1ef9b33dec37f8993461075d8b0593f739d322b2 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 16:47:28 -0700 Subject: [PATCH 101/139] Prefer manual PartialEq and Hash impls to save space --- .../src/types/circuits/circuit_variable.rs | 2 +- static-check/src/types/functions/function.rs | 17 ++++++++++++++++- .../src/types/functions/function_input.rs | 2 +- .../src/types/functions/function_output.rs | 2 +- static-check/src/types/type_.rs | 4 +++- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/static-check/src/types/circuits/circuit_variable.rs b/static-check/src/types/circuits/circuit_variable.rs index a23d864782..275687203d 100644 --- a/static-check/src/types/circuits/circuit_variable.rs +++ b/static-check/src/types/circuits/circuit_variable.rs @@ -19,7 +19,7 @@ use leo_typed::Identifier; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct CircuitVariableType { /// The name of the circuit variable pub identifier: Identifier, diff --git a/static-check/src/types/functions/function.rs b/static-check/src/types/functions/function.rs index 5480794c2a..9531b45a90 100644 --- a/static-check/src/types/functions/function.rs +++ b/static-check/src/types/functions/function.rs @@ -22,12 +22,13 @@ use crate::{ use leo_typed::{Function, Identifier}; use serde::{Deserialize, Serialize}; +use std::hash::{Hash, Hasher}; /// Stores function definition details. /// /// This type should be added to the function symbol table for a resolved syntax tree. /// This is a user-defined type. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct FunctionType { /// The name of the function definition. pub identifier: Identifier, @@ -119,3 +120,17 @@ impl FunctionType { Ok(()) } } + +impl PartialEq for FunctionType { + fn eq(&self, other: &Self) -> bool { + self.identifier.eq(&other.identifier) + } +} + +impl Eq for FunctionType {} + +impl Hash for FunctionType { + fn hash(&self, state: &mut H) { + self.identifier.hash(state); + } +} diff --git a/static-check/src/types/functions/function_input.rs b/static-check/src/types/functions/function_input.rs index 4062abe8ef..40a45024fd 100644 --- a/static-check/src/types/functions/function_input.rs +++ b/static-check/src/types/functions/function_input.rs @@ -19,7 +19,7 @@ use leo_typed::{FunctionInput, Identifier}; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum FunctionInputType { InputKeyword(Identifier), Variable(FunctionInputVariableType), diff --git a/static-check/src/types/functions/function_output.rs b/static-check/src/types/functions/function_output.rs index a877c4ab94..c0bae87201 100644 --- a/static-check/src/types/functions/function_output.rs +++ b/static-check/src/types/functions/function_output.rs @@ -20,7 +20,7 @@ use leo_typed::{Identifier, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct FunctionOutputType { /// Type of function output. pub type_: Type, diff --git a/static-check/src/types/type_.rs b/static-check/src/types/type_.rs index 94e6d300b4..4ac1788da9 100644 --- a/static-check/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -23,7 +23,7 @@ use std::{ }; /// A type in a Leo program. -#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub enum Type { // Data types Address, @@ -323,6 +323,8 @@ impl PartialEq for Type { } } +impl Eq for Type {} + /// /// Returns the data type of the array element and vector of dimensions. /// From 1779bb04e0ad822dd66373bc5c71ab337d970c59 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 16:56:47 -0700 Subject: [PATCH 102/139] Prefer manual Eq impl --- static-check/src/types/circuits/circuit.rs | 4 +++- static-check/src/types/functions/function_input_variable.rs | 4 +++- static-check/src/types/parameters/parameter.rs | 4 +++- static-check/src/types/type_variable.rs | 4 +++- typed/src/common/identifier.rs | 4 +++- typed/src/common/span.rs | 4 +++- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/static-check/src/types/circuits/circuit.rs b/static-check/src/types/circuits/circuit.rs index a9a453cce2..270d0a9805 100644 --- a/static-check/src/types/circuits/circuit.rs +++ b/static-check/src/types/circuits/circuit.rs @@ -34,7 +34,7 @@ use std::{ /// /// This type should be added to the circuit symbol table for a resolved syntax tree. /// This is a user-defined type. -#[derive(Clone, Debug, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct CircuitType { /// The name of the circuit definition. pub identifier: Identifier, @@ -185,6 +185,8 @@ impl PartialEq for CircuitType { } } +impl Eq for CircuitType {} + impl Hash for CircuitType { fn hash(&self, state: &mut H) { self.identifier.hash(state); diff --git a/static-check/src/types/functions/function_input_variable.rs b/static-check/src/types/functions/function_input_variable.rs index 1e6d1c7bd8..b4e54d6257 100644 --- a/static-check/src/types/functions/function_input_variable.rs +++ b/static-check/src/types/functions/function_input_variable.rs @@ -20,7 +20,7 @@ use leo_typed::{FunctionInputVariable, Identifier, Span}; use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; -#[derive(Clone, Debug, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct FunctionInputVariableType { /// Name of function input. pub identifier: Identifier, @@ -110,6 +110,8 @@ impl PartialEq for FunctionInputVariableType { } } +impl Eq for FunctionInputVariableType {} + impl Hash for FunctionInputVariableType { fn hash(&self, state: &mut H) { self.identifier.hash(state) diff --git a/static-check/src/types/parameters/parameter.rs b/static-check/src/types/parameters/parameter.rs index ce1ca9088b..dedd4439e5 100644 --- a/static-check/src/types/parameters/parameter.rs +++ b/static-check/src/types/parameters/parameter.rs @@ -24,7 +24,7 @@ use std::{ /// Stores variable definition details. /// /// This type should be added to the variable symbol table for a resolved syntax tree. -#[derive(Clone, Debug, Eq)] +#[derive(Clone, Debug)] pub struct ParameterType { pub identifier: Identifier, pub type_: Type, @@ -77,6 +77,8 @@ impl PartialEq for ParameterType { } } +impl Eq for ParameterType {} + impl Hash for ParameterType { fn hash(&self, state: &mut H) { self.identifier.hash(state); diff --git a/static-check/src/types/type_variable.rs b/static-check/src/types/type_variable.rs index fc08c78e78..7e19139324 100644 --- a/static-check/src/types/type_variable.rs +++ b/static-check/src/types/type_variable.rs @@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; /// An unknown type in a Leo program. -#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct TypeVariable { identifier: Identifier, } @@ -42,3 +42,5 @@ impl PartialEq for TypeVariable { self.identifier.name.eq(&other.identifier.name) || self.identifier.span.eq(&other.identifier.span) } } + +impl Eq for TypeVariable {} diff --git a/typed/src/common/identifier.rs b/typed/src/common/identifier.rs index 8b24fcd91f..b83fa5b557 100644 --- a/typed/src/common/identifier.rs +++ b/typed/src/common/identifier.rs @@ -43,7 +43,7 @@ use std::{ /// Attention - When adding or removing fields from this struct, /// please remember to update it's Serialize and Deserialize implementation /// to reflect the new struct instantiation. -#[derive(Clone, Eq)] +#[derive(Clone)] pub struct Identifier { pub name: String, pub span: Span, @@ -181,6 +181,8 @@ impl PartialEq for Identifier { } } +impl Eq for Identifier {} + impl Hash for Identifier { fn hash(&self, state: &mut H) { self.name.hash(state); diff --git a/typed/src/common/span.rs b/typed/src/common/span.rs index 4d933e0ff4..d2cd7a244f 100644 --- a/typed/src/common/span.rs +++ b/typed/src/common/span.rs @@ -18,7 +18,7 @@ use pest::Span as AstSpan; use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; -#[derive(Clone, Debug, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Span { /// text of input string pub text: String, @@ -36,6 +36,8 @@ impl PartialEq for Span { } } +impl Eq for Span {} + impl Hash for Span { fn hash(&self, state: &mut H) { self.line.hash(state); From 665cb3f4664437833b670580db07546de5406b37 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 17:32:00 -0700 Subject: [PATCH 103/139] use copy on write data structure for array type flatten method --- dynamic-check/src/assertions/type_variable_pair.rs | 5 +++-- dynamic-check/src/errors/type_assertion.rs | 4 ++-- static-check/src/types/type_.rs | 9 +++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs index c856be7ab7..b4b5c91aa0 100644 --- a/dynamic-check/src/assertions/type_variable_pair.rs +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -17,6 +17,7 @@ use crate::TypeAssertionError; use leo_static_check::{flatten_array_type, Type, TypeVariable}; use leo_typed::Span; +use std::borrow::Cow; /// A type variable -> type pair. pub struct TypeVariablePair(TypeVariable, Type); @@ -111,8 +112,8 @@ impl TypeVariablePairs { span: &Span, ) -> Result<(), TypeAssertionError> { // Flatten the array types to get the element types. - let (left_type_flat, left_dimensions_flat) = flatten_array_type(&left_type, left_dimensions.to_vec()); - let (right_type_flat, right_dimensions_flat) = flatten_array_type(&right_type, right_dimensions.to_vec()); + let (left_type_flat, left_dimensions_flat) = flatten_array_type(&left_type, Cow::from(&left_dimensions)); + let (right_type_flat, right_dimensions_flat) = flatten_array_type(&right_type, Cow::from(&right_dimensions)); // If the dimensions do not match, then throw an error. if left_dimensions_flat.ne(&right_dimensions_flat) { diff --git a/dynamic-check/src/errors/type_assertion.rs b/dynamic-check/src/errors/type_assertion.rs index f776ea4b02..3dd0fe5cf1 100644 --- a/dynamic-check/src/errors/type_assertion.rs +++ b/dynamic-check/src/errors/type_assertion.rs @@ -19,7 +19,7 @@ use crate::TypeMembership; use leo_static_check::Type; use leo_typed::{Error as FormattedError, Span}; -use std::path::Path; +use std::{borrow::Cow, path::Path}; /// Errors encountered when attempting to solve a type assertion. #[derive(Debug, Error)] @@ -78,7 +78,7 @@ impl TypeAssertionError { /// /// Mismatched array type dimensions. /// - pub fn array_dimensions(dimensions1: Vec, dimensions2: Vec, span: &Span) -> Self { + pub fn array_dimensions(dimensions1: Cow<[usize]>, dimensions2: Cow<[usize]>, span: &Span) -> Self { let message = format!( "Expected array with dimensions `{:?}`, found array with dimensions `{:?}`.", dimensions1, dimensions2 diff --git a/static-check/src/types/type_.rs b/static-check/src/types/type_.rs index 4ac1788da9..c3f55b55a4 100644 --- a/static-check/src/types/type_.rs +++ b/static-check/src/types/type_.rs @@ -18,6 +18,7 @@ use leo_typed::{Identifier, IntegerType, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; use std::{ + borrow::Cow, cmp::{Eq, PartialEq}, fmt, }; @@ -307,8 +308,8 @@ impl PartialEq for Type { (Type::Array(type1, dimensions1), Type::Array(type2, dimensions2)) => { // Flatten both array types before comparison. - let (type1_flat, dimensions1_flat) = flatten_array_type(type1, dimensions1.to_owned()); - let (type2_flat, dimensions2_flat) = flatten_array_type(type2, dimensions2.to_owned()); + let (type1_flat, dimensions1_flat) = flatten_array_type(type1, Cow::from(dimensions1)); + let (type2_flat, dimensions2_flat) = flatten_array_type(type2, Cow::from(dimensions2)); // Element types and dimensions must match type1_flat.eq(type2_flat) && dimensions1_flat.eq(&dimensions2_flat) @@ -330,9 +331,9 @@ impl Eq for Type {} /// /// Will flatten an array type `[[[u8; 1]; 2]; 3]` into `[u8; (3, 2, 1)]`. /// -pub fn flatten_array_type(type_: &Type, mut dimensions: Vec) -> (&Type, Vec) { +pub fn flatten_array_type<'a>(type_: &'a Type, mut dimensions: Cow<'a, [usize]>) -> (&'a Type, Cow<'a, [usize]>) { if let Type::Array(element_type, element_dimensions) = type_ { - dimensions.append(&mut element_dimensions.to_owned()); + dimensions.to_mut().extend(element_dimensions); flatten_array_type(element_type, dimensions) } else { (type_, dimensions) From cb3ad47f4fc3ab90d2799a1146dedc24c7d94193 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 27 Oct 2020 21:53:40 -0700 Subject: [PATCH 104/139] use derive Default for Spans --- typed/src/common/span.rs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/typed/src/common/span.rs b/typed/src/common/span.rs index d2cd7a244f..4b68a98ce1 100644 --- a/typed/src/common/span.rs +++ b/typed/src/common/span.rs @@ -18,7 +18,7 @@ use pest::Span as AstSpan; use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct Span { /// text of input string pub text: String, @@ -62,14 +62,3 @@ impl<'ast> From> for Span { } } } - -impl Default for Span { - fn default() -> Self { - Self { - text: String::new(), - line: 0, - start: 0, - end: 0, - } - } -} From 833eb51c680c103342f8ab4d9eda9ff0284c2f67 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 28 Oct 2020 09:53:27 -0700 Subject: [PATCH 105/139] fix type assertion error --- dynamic-check/src/assertions/type_variable_pair.rs | 4 ++-- dynamic-check/src/errors/type_assertion.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs index b4b5c91aa0..0cf33318ee 100644 --- a/dynamic-check/src/assertions/type_variable_pair.rs +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -118,8 +118,8 @@ impl TypeVariablePairs { // If the dimensions do not match, then throw an error. if left_dimensions_flat.ne(&right_dimensions_flat) { return Err(TypeAssertionError::array_dimensions( - left_dimensions_flat, - right_dimensions_flat, + &left_dimensions_flat, + &right_dimensions_flat, span, )); } diff --git a/dynamic-check/src/errors/type_assertion.rs b/dynamic-check/src/errors/type_assertion.rs index 3dd0fe5cf1..4fad9ffeeb 100644 --- a/dynamic-check/src/errors/type_assertion.rs +++ b/dynamic-check/src/errors/type_assertion.rs @@ -19,7 +19,7 @@ use crate::TypeMembership; use leo_static_check::Type; use leo_typed::{Error as FormattedError, Span}; -use std::{borrow::Cow, path::Path}; +use std::path::Path; /// Errors encountered when attempting to solve a type assertion. #[derive(Debug, Error)] @@ -78,7 +78,7 @@ impl TypeAssertionError { /// /// Mismatched array type dimensions. /// - pub fn array_dimensions(dimensions1: Cow<[usize]>, dimensions2: Cow<[usize]>, span: &Span) -> Self { + pub fn array_dimensions(dimensions1: &[usize], dimensions2: &[usize], span: &Span) -> Self { let message = format!( "Expected array with dimensions `{:?}`, found array with dimensions `{:?}`.", dimensions1, dimensions2 From 20ac83265d551fed74684e926a59c9b41f2d54e6 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 10:25:44 -0700 Subject: [PATCH 106/139] rename static-check -> symbol-table 1 --- compiler/src/compiler.rs | 17 ++++- compiler/src/errors/compiler.rs | 7 +- static-check/src/errors/symbol_table.rs | 6 +- static-check/src/objects/symbol_table.rs | 74 ++++++++++++++----- static-check/src/static_check.rs | 4 +- .../functions/function_input_variable.rs | 6 +- static-check/src/types/mod.rs | 4 +- .../types/{parameters => user_defined}/mod.rs | 4 +- .../user_defined_type.rs} | 26 +++---- 9 files changed, 99 insertions(+), 49 deletions(-) rename static-check/src/types/{parameters => user_defined}/mod.rs (92%) rename static-check/src/types/{parameters/parameter.rs => user_defined/user_defined_type.rs} (79%) diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 7515d6c359..4d42d1e6c9 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -29,7 +29,7 @@ use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; use leo_state::verify_local_data_commitment; -use leo_static_check::StaticCheck; +use leo_static_check::{StaticCheck, SymbolTable}; use leo_typed::{Input, LeoTypedAst, MainInput, Program}; use snarkos_dpc::{base_dpc::instantiated::Components, SystemParameters}; @@ -190,11 +190,20 @@ impl> Compiler { /// Runs static and dynamic type checks on the program, imports, and input. /// pub(crate) fn check_program(&self) -> Result<(), CompilerError> { - // Run static check on program. - let symbol_table = StaticCheck::new(&self.program, &self.imported_programs, &self.program_input)?; + // Create a new symbol table from the program, imported_programs, and program_input. + let symbol_table = + SymbolTable::run(&self.program, &self.imported_programs, &self.program_input).map_err(|mut e| { + e.set_path(&self.main_file_path); + + e + })?; // Run dynamic check on program. - DynamicCheck::new(&self.program, symbol_table)?; + DynamicCheck::new(&self.program, symbol_table).map_err(|mut e| { + e.set_path(&self.main_file_path); + + e + })?; tracing::debug!("Program checks complete"); diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index 1071f4aa87..1854ac6100 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -22,7 +22,7 @@ use leo_state::LocalDataVerificationError; use bincode::Error as SerdeError; use leo_dynamic_check::DynamicCheckError; -use leo_static_check::StaticCheckError; +use leo_static_check::{StaticCheckError, SymbolTableError}; use std::path::{Path, PathBuf}; #[derive(Debug, Error)] @@ -74,14 +74,19 @@ pub enum CompilerError { #[error("{}", _0)] StaticCheckError(#[from] StaticCheckError), + + #[error("{}", _0)] + SymbolTableError(#[from] SymbolTableError), } impl CompilerError { pub fn set_path(&mut self, path: &Path) { match self { + CompilerError::DynamicCheckError(error) => error.set_path(path), CompilerError::InputParserError(error) => error.set_path(path), CompilerError::FunctionError(error) => error.set_path(path), CompilerError::OutputStringError(error) => error.set_path(path), + CompilerError::SymbolTableError(error) => error.set_path(path), _ => {} } } diff --git a/static-check/src/errors/symbol_table.rs b/static-check/src/errors/symbol_table.rs index 1c0f63c806..57efaec0b8 100644 --- a/static-check/src/errors/symbol_table.rs +++ b/static-check/src/errors/symbol_table.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ParameterType, TypeError}; +use crate::{TypeError, UserDefinedType}; use leo_core::{CorePackageListError, LeoCoreError}; use leo_typed::{Error as FormattedError, ImportSymbol, Program, Span}; @@ -59,7 +59,7 @@ impl SymbolTableError { /// /// Two circuits have been defined with the same name. /// - pub fn duplicate_circuit(variable: ParameterType) -> Self { + pub fn duplicate_circuit(variable: UserDefinedType) -> Self { let message = format!("Duplicate circuit definition found for `{}`", variable.identifier); Self::new_from_span(message, variable.identifier.span) @@ -68,7 +68,7 @@ impl SymbolTableError { /// /// Two functions have been defined with the same name. /// - pub fn duplicate_function(variable: ParameterType) -> Self { + pub fn duplicate_function(variable: UserDefinedType) -> Self { let message = format!("Duplicate function definition found for `{}`", variable.identifier); Self::new_from_span(message, variable.identifier.span) diff --git a/static-check/src/objects/symbol_table.rs b/static-check/src/objects/symbol_table.rs index 1ae5c10a82..dad2f78a41 100644 --- a/static-check/src/objects/symbol_table.rs +++ b/static-check/src/objects/symbol_table.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{CircuitType, CircuitVariableType, FunctionType, ImportedSymbols, ParameterType, SymbolTableError}; +use crate::{CircuitType, CircuitVariableType, FunctionType, ImportedSymbols, SymbolTableError, UserDefinedType}; use leo_core::CorePackageList; use leo_imports::ImportParser; use leo_typed::{Circuit, Function, Identifier, ImportStatement, ImportSymbol, Input, Package, Program}; @@ -33,10 +33,10 @@ pub const STATE_LEAF_VARIABLE_NAME: &str = "state_leaf"; /// parent's symbol table. /// A symbol table cannot access names in its child's symbol table. /// Children cannot access names in another sibling's symbol table. -#[derive(Clone)] +#[derive(Clone, Default)] pub struct SymbolTable { /// Maps name -> parameter type. - names: HashMap, + names: HashMap, /// Maps circuit name -> circuit type. circuits: HashMap, @@ -61,6 +61,35 @@ impl SymbolTable { } } + /// + /// Returns a new `SymbolTable` from a given, program, imported programs, and program input. + /// + /// Checks that each circuit or function name is unique. + /// Unique names are added to a table of name -> user defined type. + /// + /// Checks that each circuit or function definition contains valid types. + /// + /// + pub fn run( + program: &Program, + import_parser: &ImportParser, + input: &Input, + ) -> Result { + // Create a new symbol table. + let mut table = Self::default(); + + // Insert input types into symbol table. + table.insert_input(input)?; + + // Check for duplicate program and import names. + table.check_names(program, import_parser)?; + + // Check for unknown or invalid types. + table.check_types(program)?; + + Ok(table) + } + /// /// Insert a function or circuit name into the symbol table from a given name and variable type. /// @@ -68,7 +97,7 @@ impl SymbolTable { /// If the symbol table did have this name present, the variable type is updated, and the old /// variable type is returned. /// - pub fn insert_name(&mut self, name: String, variable_type: ParameterType) -> Option { + pub fn insert_name(&mut self, name: String, variable_type: UserDefinedType) -> Option { self.names.insert(name, variable_type) } @@ -77,7 +106,11 @@ impl SymbolTable { /// /// Returns an error if the circuit name is a duplicate. /// - pub fn insert_circuit_name(&mut self, name: String, variable_type: ParameterType) -> Result<(), SymbolTableError> { + pub fn insert_circuit_name( + &mut self, + name: String, + variable_type: UserDefinedType, + ) -> Result<(), SymbolTableError> { // Check that the circuit name is unique. match self.insert_name(name, variable_type) { Some(duplicate) => Err(SymbolTableError::duplicate_circuit(duplicate)), @@ -90,7 +123,11 @@ impl SymbolTable { /// /// Returns an error if the function name is a duplicate. /// - pub fn insert_function_name(&mut self, name: String, variable_type: ParameterType) -> Result<(), SymbolTableError> { + pub fn insert_function_name( + &mut self, + name: String, + variable_type: UserDefinedType, + ) -> Result<(), SymbolTableError> { // Check that the circuit name is unique. match self.insert_name(name, variable_type) { Some(duplicate) => Err(SymbolTableError::duplicate_function(duplicate)), @@ -172,11 +209,7 @@ impl SymbolTable { /// 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_program_names( - &mut self, - program: &Program, - import_parser: &ImportParser, - ) -> Result<(), SymbolTableError> { + pub fn check_names(&mut self, program: &Program, import_parser: &ImportParser) -> Result<(), SymbolTableError> { // Check unresolved program import names. self.check_import_names(&program.imports, import_parser)?; @@ -199,7 +232,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. - self.insert_circuit_name(identifier.to_string(), ParameterType::from(circuit.clone()))?; + self.insert_circuit_name(identifier.to_string(), UserDefinedType::from(circuit.clone()))?; } Ok(()) @@ -215,7 +248,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. - self.insert_function_name(identifier.to_string(), ParameterType::from(function.clone()))?; + self.insert_function_name(identifier.to_string(), UserDefinedType::from(function.clone()))?; } Ok(()) @@ -279,7 +312,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_circuit_name(name.to_string(), ParameterType::from(circuit.clone()))?; + self.insert_circuit_name(name.to_string(), UserDefinedType::from(circuit.clone()))?; // Create new circuit type for symbol. let circuit_type = CircuitType::new(&self, circuit.to_owned())?; @@ -323,10 +356,10 @@ impl SymbolTable { }; // Check the imported program for duplicate types. - self.check_program_names(program, import_parser)?; + self.check_names(program, import_parser)?; // Check the imported program for undefined types. - self.check_types_program(program)?; + self.check_types(program)?; // Store the imported symbol. // self.insert_import_symbol(symbol, program)?; // TODO (collinc97) uncomment this line when public/private import scopes are implemented. @@ -354,14 +387,17 @@ impl SymbolTable { match program.circuits.get(&symbol.symbol) { Some(circuit) => { // Insert imported circuit. - self.insert_circuit_name(identifier.to_string(), ParameterType::from(circuit.to_owned())) + self.insert_circuit_name(identifier.to_string(), UserDefinedType::from(circuit.to_owned())) } None => { // Check if the imported symbol is a function. match program.functions.get(&symbol.symbol) { Some(function) => { // Insert the imported function. - self.insert_function_name(identifier.to_string(), ParameterType::from(function.to_owned())) + self.insert_function_name( + identifier.to_string(), + UserDefinedType::from(function.to_owned()), + ) } None => Err(SymbolTableError::unknown_symbol(&symbol, program)), } @@ -377,7 +413,7 @@ impl SymbolTable { /// symbol table. Variables defined later in the unresolved program can lookup the definition and /// refer to its expected types. /// - pub fn check_types_program(&mut self, program: &Program) -> Result<(), SymbolTableError> { + pub fn check_types(&mut self, program: &Program) -> Result<(), SymbolTableError> { // Check unresolved program circuit definitions. self.check_types_circuits(&program.circuits)?; diff --git a/static-check/src/static_check.rs b/static-check/src/static_check.rs index 27751ad812..d8300e4f43 100644 --- a/static-check/src/static_check.rs +++ b/static-check/src/static_check.rs @@ -73,7 +73,7 @@ impl StaticCheck { /// pub fn pass_one(&mut self, program: &Program, import_parser: &ImportParser) -> Result<(), StaticCheckError> { self.table - .check_program_names(program, import_parser) + .check_names(program, import_parser) .map_err(|err| StaticCheckError::SymbolTableError(err)) } @@ -86,7 +86,7 @@ impl StaticCheck { /// pub fn pass_two(&mut self, program: &Program) -> Result<(), StaticCheckError> { self.table - .check_types_program(program) + .check_types(program) .map_err(|err| StaticCheckError::SymbolTableError(err)) } } diff --git a/static-check/src/types/functions/function_input_variable.rs b/static-check/src/types/functions/function_input_variable.rs index b4e54d6257..1dde943094 100644 --- a/static-check/src/types/functions/function_input_variable.rs +++ b/static-check/src/types/functions/function_input_variable.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Attribute, ParameterType, SymbolTable, Type, TypeError}; +use crate::{Attribute, SymbolTable, Type, TypeError, UserDefinedType}; use leo_typed::{FunctionInputVariable, Identifier, Span}; use serde::{Deserialize, Serialize}; @@ -96,9 +96,9 @@ impl FunctionInputVariableType { /// /// If the symbol table did not have this name present, `None` is returned. /// - pub fn insert(&self, table: &mut SymbolTable) -> Option { + pub fn insert(&self, table: &mut SymbolTable) -> Option { let key = self.identifier.name.clone(); - let value = ParameterType::from(self.clone()); + let value = UserDefinedType::from(self.clone()); table.insert_name(key, value) } diff --git a/static-check/src/types/mod.rs b/static-check/src/types/mod.rs index 90ec0339ce..8c8adaad13 100644 --- a/static-check/src/types/mod.rs +++ b/static-check/src/types/mod.rs @@ -26,5 +26,5 @@ pub use self::type_::*; pub mod type_variable; pub use self::type_variable::*; -pub mod parameters; -pub use self::parameters::*; +pub mod user_defined; +pub use self::user_defined::*; diff --git a/static-check/src/types/parameters/mod.rs b/static-check/src/types/user_defined/mod.rs similarity index 92% rename from static-check/src/types/parameters/mod.rs rename to static-check/src/types/user_defined/mod.rs index 2930d7be45..c919d6a014 100644 --- a/static-check/src/types/parameters/mod.rs +++ b/static-check/src/types/user_defined/mod.rs @@ -14,5 +14,5 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -pub mod parameter; -pub use self::parameter::*; +pub mod user_defined_type; +pub use self::user_defined_type::*; diff --git a/static-check/src/types/parameters/parameter.rs b/static-check/src/types/user_defined/user_defined_type.rs similarity index 79% rename from static-check/src/types/parameters/parameter.rs rename to static-check/src/types/user_defined/user_defined_type.rs index dedd4439e5..7aae9530fb 100644 --- a/static-check/src/types/parameters/parameter.rs +++ b/static-check/src/types/user_defined/user_defined_type.rs @@ -21,21 +21,21 @@ use std::{ hash::{Hash, Hasher}, }; -/// Stores variable definition details. +/// Stores information for a user defined type. /// -/// This type should be added to the variable symbol table for a resolved syntax tree. +/// User defined types include circuits and functions in a Leo program. #[derive(Clone, Debug)] -pub struct ParameterType { +pub struct UserDefinedType { pub identifier: Identifier, pub type_: Type, pub attribute: Option, } -impl From for ParameterType { +impl From for UserDefinedType { fn from(value: Circuit) -> Self { let identifier = value.circuit_name; - ParameterType { + UserDefinedType { identifier: identifier.clone(), type_: Type::Circuit(identifier), attribute: None, @@ -43,11 +43,11 @@ impl From for ParameterType { } } -impl From for ParameterType { +impl From for UserDefinedType { fn from(value: Function) -> Self { let identifier = value.identifier; - ParameterType { + UserDefinedType { identifier: identifier.clone(), type_: Type::Function(identifier), attribute: None, @@ -55,9 +55,9 @@ impl From for ParameterType { } } -impl From for ParameterType { +impl From for UserDefinedType { fn from(value: FunctionInputVariableType) -> Self { - ParameterType { + UserDefinedType { identifier: value.identifier, type_: value.type_, attribute: value.attribute, @@ -65,21 +65,21 @@ impl From for ParameterType { } } -impl fmt::Display for ParameterType { +impl fmt::Display for UserDefinedType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.identifier) } } -impl PartialEq for ParameterType { +impl PartialEq for UserDefinedType { fn eq(&self, other: &Self) -> bool { self.identifier.eq(&other.identifier) } } -impl Eq for ParameterType {} +impl Eq for UserDefinedType {} -impl Hash for ParameterType { +impl Hash for UserDefinedType { fn hash(&self, state: &mut H) { self.identifier.hash(state); } From b5a05be09deea4b21d9891656e4dc0c120e074b2 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 10:44:44 -0700 Subject: [PATCH 107/139] rename static-check -> symbol-table 2 --- compiler/src/compiler.rs | 6 +- compiler/src/errors/compiler.rs | 7 +- compiler/tests/core/mod.rs | 10 +- compiler/tests/mod.rs | 4 +- dynamic-check/tests/mod.rs | 6 +- static-check/src/errors/mod.rs | 3 - static-check/src/errors/static_check.rs | 42 -------- static-check/src/lib.rs | 7 +- static-check/src/objects/mod.rs | 18 ---- static-check/src/static_check.rs | 100 ------------------ .../src/{objects => }/symbol_table.rs | 15 +-- static-check/tests/mod.rs | 22 ++-- static-check/tests/symbol_table/mod.rs | 10 +- 13 files changed, 34 insertions(+), 216 deletions(-) delete mode 100644 static-check/src/errors/static_check.rs delete mode 100644 static-check/src/objects/mod.rs delete mode 100644 static-check/src/static_check.rs rename static-check/src/{objects => }/symbol_table.rs (98%) diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 4d42d1e6c9..3c653f4a7a 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -29,7 +29,7 @@ use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; use leo_state::verify_local_data_commitment; -use leo_static_check::{StaticCheck, SymbolTable}; +use leo_static_check::SymbolTable; use leo_typed::{Input, LeoTypedAst, MainInput, Program}; use snarkos_dpc::{base_dpc::instantiated::Components, SystemParameters}; @@ -192,7 +192,7 @@ impl> Compiler { pub(crate) fn check_program(&self) -> Result<(), CompilerError> { // Create a new symbol table from the program, imported_programs, and program_input. let symbol_table = - SymbolTable::run(&self.program, &self.imported_programs, &self.program_input).map_err(|mut e| { + SymbolTable::new(&self.program, &self.imported_programs, &self.program_input).map_err(|mut e| { e.set_path(&self.main_file_path); e @@ -233,7 +233,7 @@ impl> Compiler { self.imported_programs = ImportParser::parse(&self.program)?; // Run static check on program. - let symbol_table = StaticCheck::new(&self.program, &self.imported_programs, &self.program_input)?; + let symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; // Run dynamic check on program. DynamicCheck::new(&self.program, symbol_table)?; diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index 1854ac6100..2ebe45a579 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -16,13 +16,13 @@ use crate::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError}; use leo_ast::ParserError; +use leo_dynamic_check::DynamicCheckError; use leo_imports::ImportParserError; use leo_input::InputParserError; use leo_state::LocalDataVerificationError; +use leo_static_check::SymbolTableError; use bincode::Error as SerdeError; -use leo_dynamic_check::DynamicCheckError; -use leo_static_check::{StaticCheckError, SymbolTableError}; use std::path::{Path, PathBuf}; #[derive(Debug, Error)] @@ -72,9 +72,6 @@ pub enum CompilerError { #[error("{}", _0)] SerdeError(#[from] SerdeError), - #[error("{}", _0)] - StaticCheckError(#[from] StaticCheckError), - #[error("{}", _0)] SymbolTableError(#[from] SymbolTableError), } diff --git a/compiler/tests/core/mod.rs b/compiler/tests/core/mod.rs index 6a7728361e..20943b7c36 100644 --- a/compiler/tests/core/mod.rs +++ b/compiler/tests/core/mod.rs @@ -16,14 +16,14 @@ pub mod packages; -use crate::{assert_satisfied, expect_static_check_error, parse_program}; +use crate::{assert_satisfied, expect_symbol_table_error, parse_program}; #[test] fn test_core_circuit_invalid() { let program_bytes = include_bytes!("core_package_invalid.leo"); let program = parse_program(program_bytes).err().unwrap(); - expect_static_check_error(program); + expect_symbol_table_error(program); } #[test] @@ -31,7 +31,7 @@ fn test_core_circuit_star_fail() { let program_bytes = include_bytes!("core_circuit_star_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_static_check_error(error); + expect_symbol_table_error(error); } #[test] @@ -39,7 +39,7 @@ fn test_core_package_invalid() { let program_bytes = include_bytes!("core_package_invalid.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_static_check_error(error); + expect_symbol_table_error(error); } #[test] @@ -47,7 +47,7 @@ fn test_core_unstable_package_invalid() { let program_bytes = include_bytes!("core_unstable_package_invalid.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_static_check_error(error); + expect_symbol_table_error(error); } #[test] diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index afd4063378..e34d048dbb 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -185,8 +185,8 @@ pub(crate) fn expect_dynamic_check_error(error: CompilerError) { assert!(matches!(error, CompilerError::DynamicCheckError(_))) } -pub(crate) fn expect_static_check_error(error: CompilerError) { - assert!(matches!(error, CompilerError::StaticCheckError(_))) +pub(crate) fn expect_symbol_table_error(error: CompilerError) { + assert!(matches!(error, CompilerError::SymbolTableError(_))) } pub(crate) fn generate_main_input(input: Vec<(&str, Option)>) -> MainInput { diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index f19d302866..d51648c106 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -24,7 +24,7 @@ use leo_ast::LeoAst; use leo_dynamic_check::DynamicCheck; use leo_imports::ImportParser; -use leo_static_check::{StaticCheck, SymbolTable}; +use leo_static_check::SymbolTable; use leo_typed::{Input, LeoTypedAst, Program}; use std::path::PathBuf; @@ -58,8 +58,8 @@ impl TestDynamicCheck { // Create empty input. let input = Input::new(); - // Create static check. - let symbol_table = StaticCheck::new(&program, &import_parser, &input).unwrap(); + // Create symbol table. + let symbol_table = SymbolTable::new(&program, &import_parser, &input).unwrap(); // Store fields for new dynamic check. Self { program, symbol_table } diff --git a/static-check/src/errors/mod.rs b/static-check/src/errors/mod.rs index 56968c74ff..107ac193f8 100644 --- a/static-check/src/errors/mod.rs +++ b/static-check/src/errors/mod.rs @@ -14,9 +14,6 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -pub mod static_check; -pub use self::static_check::*; - pub mod symbol_table; pub use self::symbol_table::*; diff --git a/static-check/src/errors/static_check.rs b/static-check/src/errors/static_check.rs deleted file mode 100644 index 5d3aa2f460..0000000000 --- a/static-check/src/errors/static_check.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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 . - -use crate::SymbolTableError; -use leo_typed::Error as FormattedError; - -use std::path::Path; - -/// Errors encountered when tracking variable, function and circuit names in a program. -#[derive(Debug, Error)] -pub enum StaticCheckError { - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - SymbolTableError(#[from] SymbolTableError), -} - -impl StaticCheckError { - /// - /// Sets the filepath for the error stacktrace. - /// - pub fn set_path(&mut self, path: &Path) { - match self { - StaticCheckError::Error(error) => error.set_path(path), - StaticCheckError::SymbolTableError(error) => error.set_path(path), - } - } -} diff --git a/static-check/src/lib.rs b/static-check/src/lib.rs index 0522d5ef9e..2497e304eb 100644 --- a/static-check/src/lib.rs +++ b/static-check/src/lib.rs @@ -26,11 +26,8 @@ pub use self::errors::*; pub mod imports; pub use self::imports::*; -pub mod objects; -pub use self::objects::*; - -pub mod static_check; -pub use self::static_check::*; +pub mod symbol_table; +pub use self::symbol_table::*; pub mod types; pub use self::types::*; diff --git a/static-check/src/objects/mod.rs b/static-check/src/objects/mod.rs deleted file mode 100644 index bdfe157c95..0000000000 --- a/static-check/src/objects/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod symbol_table; -pub use self::symbol_table::*; diff --git a/static-check/src/static_check.rs b/static-check/src/static_check.rs deleted file mode 100644 index d8300e4f43..0000000000 --- a/static-check/src/static_check.rs +++ /dev/null @@ -1,100 +0,0 @@ -// 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 . - -use crate::{StaticCheckError, SymbolTable}; -use leo_imports::ImportParser; -use leo_typed::{Input, Program}; - -/// Performs a static type check over a program. -pub struct StaticCheck { - table: SymbolTable, -} - -impl StaticCheck { - /// - /// Returns a new `SymbolTable` from a given program, input, and import parser. - /// - /// Runs pass one name checks and pass two type checks. - /// Builds a symbol table of circuit and function types to be used in the dynamic check. - /// - pub fn new( - program: &Program, - import_parser: &ImportParser, - input: &Input, - ) -> Result { - let mut check = Self::default(); - - // Run checks on program, imports, and input. - check.check(program, import_parser, input)?; - - // Return the symbol table of types. - Ok(check.table) - } - - /// - /// Computes pass one and pass two checks on self. - /// - pub fn check( - &mut self, - program: &Program, - import_parser: &ImportParser, - input: &Input, - ) -> Result<(), StaticCheckError> { - // Insert input types. - self.table - .insert_input(input) - .map_err(|err| StaticCheckError::SymbolTableError(err))?; - - // Run pass one checks. - self.pass_one(program, import_parser)?; - - // Run pass two checks. - self.pass_two(program) - } - - /// - /// Checks for duplicate circuit and function names given an unresolved 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 pass_one(&mut self, program: &Program, import_parser: &ImportParser) -> Result<(), StaticCheckError> { - self.table - .check_names(program, import_parser) - .map_err(|err| StaticCheckError::SymbolTableError(err)) - } - - /// - /// Checks for unknown types in circuit and function definitions given an unresolved program. - /// - /// If a circuit or function definition only contains known types, then it is inserted into the - /// symbol table. Variables defined later in the unresolved program can lookup the definition and - /// refer to its expected types. - /// - pub fn pass_two(&mut self, program: &Program) -> Result<(), StaticCheckError> { - self.table - .check_types(program) - .map_err(|err| StaticCheckError::SymbolTableError(err)) - } -} - -impl Default for StaticCheck { - fn default() -> Self { - Self { - table: SymbolTable::new(None), - } - } -} diff --git a/static-check/src/objects/symbol_table.rs b/static-check/src/symbol_table.rs similarity index 98% rename from static-check/src/objects/symbol_table.rs rename to static-check/src/symbol_table.rs index dad2f78a41..eb6bf1a8da 100644 --- a/static-check/src/objects/symbol_table.rs +++ b/static-check/src/symbol_table.rs @@ -49,18 +49,6 @@ pub struct SymbolTable { } impl SymbolTable { - /// - /// Creates a new symbol table with a given parent symbol table. - /// - pub fn new(parent: Option>) -> Self { - SymbolTable { - names: HashMap::new(), - circuits: HashMap::new(), - functions: HashMap::new(), - parent, - } - } - /// /// Returns a new `SymbolTable` from a given, program, imported programs, and program input. /// @@ -69,8 +57,7 @@ impl SymbolTable { /// /// Checks that each circuit or function definition contains valid types. /// - /// - pub fn run( + pub fn new( program: &Program, import_parser: &ImportParser, input: &Input, diff --git a/static-check/tests/mod.rs b/static-check/tests/mod.rs index 8e0d41bbd0..6da6a83779 100644 --- a/static-check/tests/mod.rs +++ b/static-check/tests/mod.rs @@ -17,7 +17,7 @@ pub mod symbol_table; use leo_ast::LeoAst; -use leo_static_check::{StaticCheck, StaticCheckError, SymbolTableError}; +use leo_static_check::{SymbolTable, SymbolTableError}; use leo_typed::{Input, LeoTypedAst}; use leo_imports::ImportParser; @@ -26,11 +26,11 @@ use std::path::PathBuf; const TEST_PROGRAM_PATH: &str = ""; /// A helper struct to test a `SymbolTable`. -pub struct TestStaticCheck { +pub struct TestSymbolTable { typed: LeoTypedAst, } -impl TestStaticCheck { +impl TestSymbolTable { /// /// Returns a typed syntax tree given a Leo program. /// @@ -66,7 +66,7 @@ impl TestStaticCheck { let input = Input::new(); // Create new symbol table. - let _symbol_table = StaticCheck::new(&program, &import_parser, &input).unwrap(); + let _symbol_table = SymbolTable::new(&program, &import_parser, &input).unwrap(); } /// @@ -79,16 +79,16 @@ impl TestStaticCheck { let program = self.typed.into_repr(); // Create new symbol table. - let static_check = &mut StaticCheck::default(); + let static_check = &mut SymbolTable::default(); // Create empty import parser. let import_parser = ImportParser::new(); // Run pass one and expect an error. - let error = static_check.pass_one(&program, &import_parser).unwrap_err(); + let error = static_check.check_names(&program, &import_parser).unwrap_err(); match error { - StaticCheckError::SymbolTableError(SymbolTableError::Error(_)) => {} // Ok + SymbolTableError::Error(_) => {} // Ok error => panic!("Expected a symbol table error found `{}`", error), } } @@ -103,19 +103,19 @@ impl TestStaticCheck { let program = self.typed.into_repr(); // Create a new symbol table. - let static_check = &mut StaticCheck::default(); + let static_check = &mut SymbolTable::default(); // Create empty import parser. let import_parser = ImportParser::new(); // Run the pass one and expect no errors. - static_check.pass_one(&program, &import_parser).unwrap(); + static_check.check_names(&program, &import_parser).unwrap(); // Run the pass two and expect and error. - let error = static_check.pass_two(&program).unwrap_err(); + let error = static_check.check_types(&program).unwrap_err(); match error { - StaticCheckError::SymbolTableError(SymbolTableError::TypeError(_)) => {} //Ok + SymbolTableError::TypeError(_) => {} //Ok error => panic!("Expected a type error found `{}`", error), } } diff --git a/static-check/tests/symbol_table/mod.rs b/static-check/tests/symbol_table/mod.rs index c703db4d17..b6d511c89c 100644 --- a/static-check/tests/symbol_table/mod.rs +++ b/static-check/tests/symbol_table/mod.rs @@ -11,7 +11,7 @@ // 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 . -use crate::TestStaticCheck; +use crate::TestSymbolTable; /// /// Defines a circuit `Foo {}`. @@ -23,7 +23,7 @@ use crate::TestStaticCheck; #[test] fn test_duplicate_circuit() { let program_bytes = include_bytes!("duplicate_circuit.leo"); - let resolver = TestStaticCheck::new(program_bytes); + let resolver = TestSymbolTable::new(program_bytes); resolver.expect_pass_one_error(); } @@ -38,7 +38,7 @@ fn test_duplicate_circuit() { #[test] fn test_duplicate_function() { let program_bytes = include_bytes!("duplicate_function.leo"); - let resolver = TestStaticCheck::new(program_bytes); + let resolver = TestSymbolTable::new(program_bytes); resolver.expect_pass_one_error(); } @@ -52,7 +52,7 @@ fn test_duplicate_function() { #[test] fn test_self_not_available() { let program_bytes = include_bytes!("self_not_available.leo"); - let resolver = TestStaticCheck::new(program_bytes); + let resolver = TestSymbolTable::new(program_bytes); resolver.expect_pass_two_error(); } @@ -66,7 +66,7 @@ fn test_self_not_available() { #[test] fn test_undefined_circuit() { let program_bytes = include_bytes!("undefined_circuit.leo"); - let resolver = TestStaticCheck::new(program_bytes); + let resolver = TestSymbolTable::new(program_bytes); resolver.expect_pass_two_error(); } From 7cf41558bcf956e0403288f14dcf12c0370e68a1 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 10:51:45 -0700 Subject: [PATCH 108/139] rename static-check -> symbol-table 3 --- Cargo.lock | 8 ++++---- Cargo.toml | 6 +++--- compiler/Cargo.toml | 4 ++-- compiler/src/compiler.rs | 4 ++-- compiler/src/errors/compiler.rs | 2 +- compiler/src/import/store/import.rs | 2 +- dynamic-check/Cargo.toml | 4 ++-- dynamic-check/src/assertions/type_assertion.rs | 2 +- dynamic-check/src/assertions/type_equality.rs | 2 +- dynamic-check/src/assertions/type_membership.rs | 2 +- dynamic-check/src/assertions/type_variable_pair.rs | 2 +- dynamic-check/src/dynamic_check.rs | 2 +- dynamic-check/src/errors/frame.rs | 2 +- dynamic-check/src/errors/type_assertion.rs | 2 +- dynamic-check/src/objects/frame.rs | 2 +- dynamic-check/src/objects/scope.rs | 2 +- dynamic-check/src/objects/variable_table.rs | 2 +- dynamic-check/tests/mod.rs | 2 +- {static-check => symbol-table}/Cargo.toml | 2 +- .../src/attributes/attribute.rs | 0 {static-check => symbol-table}/src/attributes/mod.rs | 0 {static-check => symbol-table}/src/errors/mod.rs | 0 {static-check => symbol-table}/src/errors/symbol_table.rs | 0 {static-check => symbol-table}/src/errors/type_.rs | 0 .../src/imports/imported_symbols.rs | 0 {static-check => symbol-table}/src/imports/mod.rs | 0 {static-check => symbol-table}/src/lib.rs | 0 {static-check => symbol-table}/src/symbol_table.rs | 0 .../src/types/circuits/circuit.rs | 0 .../src/types/circuits/circuit_function.rs | 0 .../src/types/circuits/circuit_variable.rs | 0 {static-check => symbol-table}/src/types/circuits/mod.rs | 0 .../src/types/functions/function.rs | 0 .../src/types/functions/function_input.rs | 0 .../src/types/functions/function_input_variable.rs | 0 .../src/types/functions/function_output.rs | 0 {static-check => symbol-table}/src/types/functions/mod.rs | 0 {static-check => symbol-table}/src/types/mod.rs | 0 {static-check => symbol-table}/src/types/type_.rs | 0 {static-check => symbol-table}/src/types/type_variable.rs | 0 .../src/types/user_defined/mod.rs | 0 .../src/types/user_defined/user_defined_type.rs | 0 {static-check => symbol-table}/tests/mod.rs | 0 .../tests/symbol_table/duplicate_circuit.leo | 0 .../tests/symbol_table/duplicate_function.leo | 0 {static-check => symbol-table}/tests/symbol_table/mod.rs | 0 .../tests/symbol_table/self_not_available.leo | 0 .../tests/symbol_table/undefined_circuit.leo | 0 48 files changed, 27 insertions(+), 27 deletions(-) rename {static-check => symbol-table}/Cargo.toml (96%) rename {static-check => symbol-table}/src/attributes/attribute.rs (100%) rename {static-check => symbol-table}/src/attributes/mod.rs (100%) rename {static-check => symbol-table}/src/errors/mod.rs (100%) rename {static-check => symbol-table}/src/errors/symbol_table.rs (100%) rename {static-check => symbol-table}/src/errors/type_.rs (100%) rename {static-check => symbol-table}/src/imports/imported_symbols.rs (100%) rename {static-check => symbol-table}/src/imports/mod.rs (100%) rename {static-check => symbol-table}/src/lib.rs (100%) rename {static-check => symbol-table}/src/symbol_table.rs (100%) rename {static-check => symbol-table}/src/types/circuits/circuit.rs (100%) rename {static-check => symbol-table}/src/types/circuits/circuit_function.rs (100%) rename {static-check => symbol-table}/src/types/circuits/circuit_variable.rs (100%) rename {static-check => symbol-table}/src/types/circuits/mod.rs (100%) rename {static-check => symbol-table}/src/types/functions/function.rs (100%) rename {static-check => symbol-table}/src/types/functions/function_input.rs (100%) rename {static-check => symbol-table}/src/types/functions/function_input_variable.rs (100%) rename {static-check => symbol-table}/src/types/functions/function_output.rs (100%) rename {static-check => symbol-table}/src/types/functions/mod.rs (100%) rename {static-check => symbol-table}/src/types/mod.rs (100%) rename {static-check => symbol-table}/src/types/type_.rs (100%) rename {static-check => symbol-table}/src/types/type_variable.rs (100%) rename {static-check => symbol-table}/src/types/user_defined/mod.rs (100%) rename {static-check => symbol-table}/src/types/user_defined/user_defined_type.rs (100%) rename {static-check => symbol-table}/tests/mod.rs (100%) rename {static-check => symbol-table}/tests/symbol_table/duplicate_circuit.leo (100%) rename {static-check => symbol-table}/tests/symbol_table/duplicate_function.leo (100%) rename {static-check => symbol-table}/tests/symbol_table/mod.rs (100%) rename {static-check => symbol-table}/tests/symbol_table/self_not_available.leo (100%) rename {static-check => symbol-table}/tests/symbol_table/undefined_circuit.leo (100%) diff --git a/Cargo.lock b/Cargo.lock index 7e9d4d1a47..cdf38c7bed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1259,7 +1259,7 @@ dependencies = [ "leo-input", "leo-package", "leo-state", - "leo-static-check", + "leo-symbol-table", "leo-typed", "num-bigint", "pest", @@ -1302,7 +1302,7 @@ version = "1.0.3" dependencies = [ "leo-ast", "leo-imports", - "leo-static-check", + "leo-symbol-table", "leo-typed", "serde", "serde_json", @@ -1369,7 +1369,7 @@ dependencies = [ "leo-input", "leo-package", "leo-state", - "leo-static-check", + "leo-symbol-table", "notify", "num-bigint", "rand", @@ -1430,7 +1430,7 @@ dependencies = [ ] [[package]] -name = "leo-static-check" +name = "leo-symbol-table" version = "1.0.3" dependencies = [ "leo-ast", diff --git a/Cargo.toml b/Cargo.toml index 6ea0e8e171..6becd8320c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ members = [ "package", "typed", "state", - "static-check", + "symbol-table", ] [dependencies.leo-compiler] @@ -72,8 +72,8 @@ version = "1.0.3" path = "./state" version = "1.0.3" -[dependencies.leo-static-check] -path = "./static-check" +[dependencies.leo-symbol-table] +path = "./symbol-table" version = "1.0.3" [dependencies.snarkos-algorithms] diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 25e05398bb..9944c1551a 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -53,8 +53,8 @@ version = "1.0.3" path = "../state" version = "1.0.3" -[dependencies.leo-static-check] -path = "../static-check" +[dependencies.leo-symbol-table] +path = "../symbol-table" version = "1.0.3" [dependencies.snarkos-curves] diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 3c653f4a7a..28eaf8a715 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -29,7 +29,7 @@ use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; use leo_state::verify_local_data_commitment; -use leo_static_check::SymbolTable; +use leo_symbol_table::SymbolTable; use leo_typed::{Input, LeoTypedAst, MainInput, Program}; use snarkos_dpc::{base_dpc::instantiated::Components, SystemParameters}; @@ -232,7 +232,7 @@ impl> Compiler { self.program = typed_tree.into_repr(); self.imported_programs = ImportParser::parse(&self.program)?; - // Run static check on program. + // Create a new symbol table from the program, imported programs, and program input. let symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; // Run dynamic check on program. diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index 2ebe45a579..c82569dccb 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -20,7 +20,7 @@ use leo_dynamic_check::DynamicCheckError; use leo_imports::ImportParserError; use leo_input::InputParserError; use leo_state::LocalDataVerificationError; -use leo_static_check::SymbolTableError; +use leo_symbol_table::SymbolTableError; use bincode::Error as SerdeError; use std::path::{Path, PathBuf}; diff --git a/compiler/src/import/store/import.rs b/compiler/src/import/store/import.rs index 2f0c96fbf9..094d7c0ca0 100644 --- a/compiler/src/import/store/import.rs +++ b/compiler/src/import/store/import.rs @@ -16,7 +16,7 @@ use crate::{errors::ImportError, ConstrainedProgram, GroupType}; use leo_imports::ImportParser; -use leo_static_check::imported_symbols::ImportedSymbols; +use leo_symbol_table::imported_symbols::ImportedSymbols; use leo_typed::ImportStatement; use snarkos_models::curves::{Field, PrimeField}; diff --git a/dynamic-check/Cargo.toml b/dynamic-check/Cargo.toml index 76855ac894..cd4bf2b8f4 100644 --- a/dynamic-check/Cargo.toml +++ b/dynamic-check/Cargo.toml @@ -28,8 +28,8 @@ version = "1.0.3" [dependencies.serde_json] version = "1.0" -[dependencies.leo-static-check] -path = "../static-check" +[dependencies.leo-symbol-table] +path = "../symbol-table" version = "1.0.3" [dependencies.leo-typed] diff --git a/dynamic-check/src/assertions/type_assertion.rs b/dynamic-check/src/assertions/type_assertion.rs index 2655e85298..030603cb22 100644 --- a/dynamic-check/src/assertions/type_assertion.rs +++ b/dynamic-check/src/assertions/type_assertion.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{TypeAssertionError, TypeEquality, TypeMembership, TypeVariablePairs}; -use leo_static_check::{Type, TypeVariable}; +use leo_symbol_table::{Type, TypeVariable}; use leo_typed::Span; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/assertions/type_equality.rs b/dynamic-check/src/assertions/type_equality.rs index ed7e70f6ab..d8380ee085 100644 --- a/dynamic-check/src/assertions/type_equality.rs +++ b/dynamic-check/src/assertions/type_equality.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{TypeAssertionError, TypeVariablePairs}; -use leo_static_check::{Type, TypeVariable}; +use leo_symbol_table::{Type, TypeVariable}; use leo_typed::Span; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/assertions/type_membership.rs b/dynamic-check/src/assertions/type_membership.rs index 312f810056..b1590a21f2 100644 --- a/dynamic-check/src/assertions/type_membership.rs +++ b/dynamic-check/src/assertions/type_membership.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::TypeAssertionError; -use leo_static_check::{Type, TypeVariable}; +use leo_symbol_table::{Type, TypeVariable}; use leo_typed::Span; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs index 0cf33318ee..446413f435 100644 --- a/dynamic-check/src/assertions/type_variable_pair.rs +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::TypeAssertionError; -use leo_static_check::{flatten_array_type, Type, TypeVariable}; +use leo_symbol_table::{flatten_array_type, Type, TypeVariable}; use leo_typed::Span; use std::borrow::Cow; diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index f5aa5f2845..797084ce49 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{DynamicCheckError, Frame, Scope}; -use leo_static_check::SymbolTable; +use leo_symbol_table::SymbolTable; use leo_typed::{Circuit, CircuitMember, Function, Program}; /// Performs a dynamic type inference check over a program. diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index 74484ad9f6..14e2914457 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ScopeError, TypeAssertionError}; -use leo_static_check::{Type, TypeError}; +use leo_symbol_table::{Type, TypeError}; use leo_typed::{Error as FormattedError, Expression, Identifier, Span}; use std::path::Path; diff --git a/dynamic-check/src/errors/type_assertion.rs b/dynamic-check/src/errors/type_assertion.rs index 4fad9ffeeb..eca87557ab 100644 --- a/dynamic-check/src/errors/type_assertion.rs +++ b/dynamic-check/src/errors/type_assertion.rs @@ -16,7 +16,7 @@ use crate::TypeMembership; -use leo_static_check::Type; +use leo_symbol_table::Type; use leo_typed::{Error as FormattedError, Span}; use std::path::Path; diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index 63ab137d83..5ae47b1b44 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{FrameError, Scope, TypeAssertion}; -use leo_static_check::{Attribute, CircuitFunctionType, CircuitType, FunctionType, SymbolTable, Type, TypeVariable}; +use leo_symbol_table::{Attribute, CircuitFunctionType, CircuitType, FunctionType, SymbolTable, Type, TypeVariable}; use leo_typed::{ Assignee, AssigneeAccess, diff --git a/dynamic-check/src/objects/scope.rs b/dynamic-check/src/objects/scope.rs index aed1547380..34a0e20c58 100644 --- a/dynamic-check/src/objects/scope.rs +++ b/dynamic-check/src/objects/scope.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ScopeError, VariableTable}; -use leo_static_check::{FunctionInputType, Type}; +use leo_symbol_table::{FunctionInputType, Type}; /// A structure for tracking the types of defined variables in a block of code. #[derive(Clone, Default)] diff --git a/dynamic-check/src/objects/variable_table.rs b/dynamic-check/src/objects/variable_table.rs index 85f84bae0e..f6060b33a7 100644 --- a/dynamic-check/src/objects/variable_table.rs +++ b/dynamic-check/src/objects/variable_table.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::VariableTableError; -use leo_static_check::{FunctionInputType, Type}; +use leo_symbol_table::{FunctionInputType, Type}; use std::collections::HashMap; /// Mapping of variable names to types diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index d51648c106..9998780b58 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -24,7 +24,7 @@ use leo_ast::LeoAst; use leo_dynamic_check::DynamicCheck; use leo_imports::ImportParser; -use leo_static_check::SymbolTable; +use leo_symbol_table::SymbolTable; use leo_typed::{Input, LeoTypedAst, Program}; use std::path::PathBuf; diff --git a/static-check/Cargo.toml b/symbol-table/Cargo.toml similarity index 96% rename from static-check/Cargo.toml rename to symbol-table/Cargo.toml index 0e605147d9..8527bf14e8 100644 --- a/static-check/Cargo.toml +++ b/symbol-table/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "leo-static-check" +name = "leo-symbol-table" version = "1.0.3" authors = [ "The Aleo Team " ] description = "Stores user-defined variables during type resolution" diff --git a/static-check/src/attributes/attribute.rs b/symbol-table/src/attributes/attribute.rs similarity index 100% rename from static-check/src/attributes/attribute.rs rename to symbol-table/src/attributes/attribute.rs diff --git a/static-check/src/attributes/mod.rs b/symbol-table/src/attributes/mod.rs similarity index 100% rename from static-check/src/attributes/mod.rs rename to symbol-table/src/attributes/mod.rs diff --git a/static-check/src/errors/mod.rs b/symbol-table/src/errors/mod.rs similarity index 100% rename from static-check/src/errors/mod.rs rename to symbol-table/src/errors/mod.rs diff --git a/static-check/src/errors/symbol_table.rs b/symbol-table/src/errors/symbol_table.rs similarity index 100% rename from static-check/src/errors/symbol_table.rs rename to symbol-table/src/errors/symbol_table.rs diff --git a/static-check/src/errors/type_.rs b/symbol-table/src/errors/type_.rs similarity index 100% rename from static-check/src/errors/type_.rs rename to symbol-table/src/errors/type_.rs diff --git a/static-check/src/imports/imported_symbols.rs b/symbol-table/src/imports/imported_symbols.rs similarity index 100% rename from static-check/src/imports/imported_symbols.rs rename to symbol-table/src/imports/imported_symbols.rs diff --git a/static-check/src/imports/mod.rs b/symbol-table/src/imports/mod.rs similarity index 100% rename from static-check/src/imports/mod.rs rename to symbol-table/src/imports/mod.rs diff --git a/static-check/src/lib.rs b/symbol-table/src/lib.rs similarity index 100% rename from static-check/src/lib.rs rename to symbol-table/src/lib.rs diff --git a/static-check/src/symbol_table.rs b/symbol-table/src/symbol_table.rs similarity index 100% rename from static-check/src/symbol_table.rs rename to symbol-table/src/symbol_table.rs diff --git a/static-check/src/types/circuits/circuit.rs b/symbol-table/src/types/circuits/circuit.rs similarity index 100% rename from static-check/src/types/circuits/circuit.rs rename to symbol-table/src/types/circuits/circuit.rs diff --git a/static-check/src/types/circuits/circuit_function.rs b/symbol-table/src/types/circuits/circuit_function.rs similarity index 100% rename from static-check/src/types/circuits/circuit_function.rs rename to symbol-table/src/types/circuits/circuit_function.rs diff --git a/static-check/src/types/circuits/circuit_variable.rs b/symbol-table/src/types/circuits/circuit_variable.rs similarity index 100% rename from static-check/src/types/circuits/circuit_variable.rs rename to symbol-table/src/types/circuits/circuit_variable.rs diff --git a/static-check/src/types/circuits/mod.rs b/symbol-table/src/types/circuits/mod.rs similarity index 100% rename from static-check/src/types/circuits/mod.rs rename to symbol-table/src/types/circuits/mod.rs diff --git a/static-check/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs similarity index 100% rename from static-check/src/types/functions/function.rs rename to symbol-table/src/types/functions/function.rs diff --git a/static-check/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs similarity index 100% rename from static-check/src/types/functions/function_input.rs rename to symbol-table/src/types/functions/function_input.rs diff --git a/static-check/src/types/functions/function_input_variable.rs b/symbol-table/src/types/functions/function_input_variable.rs similarity index 100% rename from static-check/src/types/functions/function_input_variable.rs rename to symbol-table/src/types/functions/function_input_variable.rs diff --git a/static-check/src/types/functions/function_output.rs b/symbol-table/src/types/functions/function_output.rs similarity index 100% rename from static-check/src/types/functions/function_output.rs rename to symbol-table/src/types/functions/function_output.rs diff --git a/static-check/src/types/functions/mod.rs b/symbol-table/src/types/functions/mod.rs similarity index 100% rename from static-check/src/types/functions/mod.rs rename to symbol-table/src/types/functions/mod.rs diff --git a/static-check/src/types/mod.rs b/symbol-table/src/types/mod.rs similarity index 100% rename from static-check/src/types/mod.rs rename to symbol-table/src/types/mod.rs diff --git a/static-check/src/types/type_.rs b/symbol-table/src/types/type_.rs similarity index 100% rename from static-check/src/types/type_.rs rename to symbol-table/src/types/type_.rs diff --git a/static-check/src/types/type_variable.rs b/symbol-table/src/types/type_variable.rs similarity index 100% rename from static-check/src/types/type_variable.rs rename to symbol-table/src/types/type_variable.rs diff --git a/static-check/src/types/user_defined/mod.rs b/symbol-table/src/types/user_defined/mod.rs similarity index 100% rename from static-check/src/types/user_defined/mod.rs rename to symbol-table/src/types/user_defined/mod.rs diff --git a/static-check/src/types/user_defined/user_defined_type.rs b/symbol-table/src/types/user_defined/user_defined_type.rs similarity index 100% rename from static-check/src/types/user_defined/user_defined_type.rs rename to symbol-table/src/types/user_defined/user_defined_type.rs diff --git a/static-check/tests/mod.rs b/symbol-table/tests/mod.rs similarity index 100% rename from static-check/tests/mod.rs rename to symbol-table/tests/mod.rs diff --git a/static-check/tests/symbol_table/duplicate_circuit.leo b/symbol-table/tests/symbol_table/duplicate_circuit.leo similarity index 100% rename from static-check/tests/symbol_table/duplicate_circuit.leo rename to symbol-table/tests/symbol_table/duplicate_circuit.leo diff --git a/static-check/tests/symbol_table/duplicate_function.leo b/symbol-table/tests/symbol_table/duplicate_function.leo similarity index 100% rename from static-check/tests/symbol_table/duplicate_function.leo rename to symbol-table/tests/symbol_table/duplicate_function.leo diff --git a/static-check/tests/symbol_table/mod.rs b/symbol-table/tests/symbol_table/mod.rs similarity index 100% rename from static-check/tests/symbol_table/mod.rs rename to symbol-table/tests/symbol_table/mod.rs diff --git a/static-check/tests/symbol_table/self_not_available.leo b/symbol-table/tests/symbol_table/self_not_available.leo similarity index 100% rename from static-check/tests/symbol_table/self_not_available.leo rename to symbol-table/tests/symbol_table/self_not_available.leo diff --git a/static-check/tests/symbol_table/undefined_circuit.leo b/symbol-table/tests/symbol_table/undefined_circuit.leo similarity index 100% rename from static-check/tests/symbol_table/undefined_circuit.leo rename to symbol-table/tests/symbol_table/undefined_circuit.leo From 87d440dfa1e2bf9bbd5123a1d4d0352f1fd70e5c Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 11:10:29 -0700 Subject: [PATCH 109/139] fix symbol table test --- symbol-table/tests/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symbol-table/tests/mod.rs b/symbol-table/tests/mod.rs index 6da6a83779..7444d06267 100644 --- a/symbol-table/tests/mod.rs +++ b/symbol-table/tests/mod.rs @@ -17,7 +17,7 @@ pub mod symbol_table; use leo_ast::LeoAst; -use leo_static_check::{SymbolTable, SymbolTableError}; +use leo_symbol_table::{SymbolTable, SymbolTableError}; use leo_typed::{Input, LeoTypedAst}; use leo_imports::ImportParser; From 4e8bc7f1a8a68f8650d8c6ad79894e8e31cb11bd Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 11:15:06 -0700 Subject: [PATCH 110/139] fix license header --- symbol-table/tests/symbol_table/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/symbol-table/tests/symbol_table/mod.rs b/symbol-table/tests/symbol_table/mod.rs index b6d511c89c..4d40891377 100644 --- a/symbol-table/tests/symbol_table/mod.rs +++ b/symbol-table/tests/symbol_table/mod.rs @@ -5,12 +5,15 @@ // 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 . + use crate::TestSymbolTable; /// From be2a805d4986d63740f090aebba0a1c41324c02d Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 11:30:52 -0700 Subject: [PATCH 111/139] rename typed -> core-ast 1 --- compiler/src/compiler.rs | 6 +++--- dynamic-check/tests/mod.rs | 4 ++-- symbol-table/tests/mod.rs | 6 +++--- typed/benches/typed_ast.rs | 20 ++++++++++---------- typed/src/lib.rs | 12 ++++++------ typed/src/main.rs | 22 +++++++++++----------- typed/src/program.rs | 2 +- typed/tests/serialization/json.rs | 10 +++++----- 8 files changed, 41 insertions(+), 41 deletions(-) diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 28eaf8a715..c83e7a5b03 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -30,7 +30,7 @@ use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; use leo_state::verify_local_data_commitment; use leo_symbol_table::SymbolTable; -use leo_typed::{Input, LeoTypedAst, MainInput, Program}; +use leo_typed::{Input, LeoCoreAst, MainInput, Program}; use snarkos_dpc::{base_dpc::instantiated::Components, SystemParameters}; use snarkos_errors::gadgets::SynthesisError; @@ -176,7 +176,7 @@ impl> Compiler { })?; // Use the typed parser to construct the typed syntax tree. - let typed_tree = LeoTypedAst::new(&self.package_name, &ast); + let typed_tree = LeoCoreAst::new(&self.package_name, &ast); self.program = typed_tree.into_repr(); self.imported_programs = ImportParser::parse(&self.program)?; @@ -227,7 +227,7 @@ impl> Compiler { let package_name = &self.package_name; // Use the typed parser to construct the typed syntax tree. - let typed_tree = LeoTypedAst::new(package_name, &ast); + let typed_tree = LeoCoreAst::new(package_name, &ast); self.program = typed_tree.into_repr(); self.imported_programs = ImportParser::parse(&self.program)?; diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 9998780b58..dcb4638f0d 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -25,7 +25,7 @@ use leo_dynamic_check::DynamicCheck; use leo_imports::ImportParser; use leo_symbol_table::SymbolTable; -use leo_typed::{Input, LeoTypedAst, Program}; +use leo_typed::{Input, LeoCoreAst, Program}; use std::path::PathBuf; const TEST_PROGRAM_PATH: &str = ""; @@ -49,7 +49,7 @@ impl TestDynamicCheck { let ast = LeoAst::new(&file_path, &*file_string).unwrap(); // Get typed syntax tree. - let typed = LeoTypedAst::new(TEST_PROGRAM_NAME, &ast); + let typed = LeoCoreAst::new(TEST_PROGRAM_NAME, &ast); let program = typed.into_repr(); // Create empty import parser. diff --git a/symbol-table/tests/mod.rs b/symbol-table/tests/mod.rs index 7444d06267..a9aea958a7 100644 --- a/symbol-table/tests/mod.rs +++ b/symbol-table/tests/mod.rs @@ -18,7 +18,7 @@ pub mod symbol_table; use leo_ast::LeoAst; use leo_symbol_table::{SymbolTable, SymbolTableError}; -use leo_typed::{Input, LeoTypedAst}; +use leo_typed::{Input, LeoCoreAst}; use leo_imports::ImportParser; use std::path::PathBuf; @@ -27,7 +27,7 @@ const TEST_PROGRAM_PATH: &str = ""; /// A helper struct to test a `SymbolTable`. pub struct TestSymbolTable { - typed: LeoTypedAst, + typed: LeoCoreAst, } impl TestSymbolTable { @@ -45,7 +45,7 @@ impl TestSymbolTable { let ast = LeoAst::new(&file_path, &*file_string).unwrap(); // Get typed syntax tree - let typed = LeoTypedAst::new(TEST_PROGRAM_PATH, &ast); + let typed = LeoCoreAst::new(TEST_PROGRAM_PATH, &ast); Self { typed } } diff --git a/typed/benches/typed_ast.rs b/typed/benches/typed_ast.rs index cee9a756d4..d7f473f14a 100644 --- a/typed/benches/typed_ast.rs +++ b/typed/benches/typed_ast.rs @@ -15,13 +15,13 @@ // along with the Leo library. If not, see . use leo_ast::LeoAst; -use leo_typed::LeoTypedAst; +use leo_typed::LeoCoreAst; use criterion::{criterion_group, criterion_main, Criterion}; use std::{path::Path, time::Duration}; -fn leo_typed_ast<'ast>(ast: &LeoAst<'ast>) -> LeoTypedAst { - LeoTypedAst::new("leo_typed_tree", &ast) +fn leo_core_ast<'ast>(ast: &LeoAst<'ast>) -> LeoCoreAst { + LeoCoreAst::new("leo_core_tree", &ast) } fn bench_big_if_else(c: &mut Criterion) { @@ -29,7 +29,7 @@ fn bench_big_if_else(c: &mut Criterion) { let program_string = include_str!("./big_if_else.leo"); let ast = LeoAst::new(&filepath, program_string).unwrap(); - c.bench_function("LeoTypedAst::big_if_else", |b| b.iter(|| leo_typed_ast(&ast))); + c.bench_function("LeoCoreAst::big_if_else", |b| b.iter(|| leo_core_ast(&ast))); } fn bench_big_ternary(c: &mut Criterion) { @@ -37,7 +37,7 @@ fn bench_big_ternary(c: &mut Criterion) { let program_string = include_str!("./big_ternary.leo"); let ast = LeoAst::new(&filepath, program_string).unwrap(); - c.bench_function("LeoTypedAst::big_ternary", |b| b.iter(|| leo_typed_ast(&ast))); + c.bench_function("LeoCoreAst::big_ternary", |b| b.iter(|| leo_core_ast(&ast))); } fn bench_big_circuit(c: &mut Criterion) { @@ -45,7 +45,7 @@ fn bench_big_circuit(c: &mut Criterion) { let program_string = include_str!("./big_circuit.leo"); let ast = LeoAst::new(&filepath, program_string).unwrap(); - c.bench_function("LeoTypedAst::big_circuit", |b| b.iter(|| leo_typed_ast(&ast))); + c.bench_function("LeoCoreAst::big_circuit", |b| b.iter(|| leo_core_ast(&ast))); } fn bench_long_expr(c: &mut Criterion) { @@ -53,7 +53,7 @@ fn bench_long_expr(c: &mut Criterion) { let program_string = include_str!("./long_expr.leo"); let ast = LeoAst::new(&filepath, program_string).unwrap(); - c.bench_function("LeoTypedAst::long_expr", |b| b.iter(|| leo_typed_ast(&ast))); + c.bench_function("LeoCoreAst::long_expr", |b| b.iter(|| leo_core_ast(&ast))); } fn bench_long_array(c: &mut Criterion) { @@ -61,7 +61,7 @@ fn bench_long_array(c: &mut Criterion) { let program_string = include_str!("./long_array.leo"); let ast = LeoAst::new(&filepath, program_string).unwrap(); - c.bench_function("LeoTypedAst::long_array", |b| b.iter(|| leo_typed_ast(&ast))); + c.bench_function("LeoCoreAst::long_array", |b| b.iter(|| leo_core_ast(&ast))); } fn bench_many_foos(c: &mut Criterion) { @@ -69,7 +69,7 @@ fn bench_many_foos(c: &mut Criterion) { let program_string = include_str!("./many_foos.leo"); let ast = LeoAst::new(&filepath, program_string).unwrap(); - c.bench_function("LeoTypedAst::many_foos", |b| b.iter(|| leo_typed_ast(&ast))); + c.bench_function("LeoCoreAst::many_foos", |b| b.iter(|| leo_core_ast(&ast))); } fn bench_many_assigns(c: &mut Criterion) { @@ -77,7 +77,7 @@ fn bench_many_assigns(c: &mut Criterion) { let program_string = include_str!("./many_assigns.leo"); let ast = LeoAst::new(&filepath, program_string).unwrap(); - c.bench_function("LeoTypedAst::many_assigns", |b| b.iter(|| leo_typed_ast(&ast))); + c.bench_function("LeoCoreAst::many_assigns", |b| b.iter(|| leo_core_ast(&ast))); } criterion_group!( diff --git a/typed/src/lib.rs b/typed/src/lib.rs index 12fb1699f5..4fd6b30468 100644 --- a/typed/src/lib.rs +++ b/typed/src/lib.rs @@ -59,29 +59,29 @@ pub use self::types::*; use leo_ast::LeoAst; #[derive(Debug, Eq, PartialEq)] -pub struct LeoTypedAst { +pub struct LeoCoreAst { typed_ast: Program, } -impl LeoTypedAst { - /// Creates a new typed syntax tree from a given program name and abstract syntax tree. +impl LeoCoreAst { + /// Creates a new core syntax tree from a given program name and abstract syntax tree. pub fn new<'ast>(program_name: &str, ast: &LeoAst<'ast>) -> Self { Self { typed_ast: Program::from(program_name, ast.as_repr()), } } - /// Returns a reference to the inner typed syntax tree representation. + /// Returns a reference to the inner program syntax tree representation. pub fn into_repr(self) -> Program { self.typed_ast } - /// Serializes the typed syntax tree into a JSON string. + /// Serializes the core syntax tree into a JSON string. pub fn to_json_string(&self) -> Result { Ok(serde_json::to_string_pretty(&self.typed_ast)?) } - /// Deserializes the JSON string into a typed syntax tree. + /// Deserializes the JSON string into a core syntax tree. pub fn from_json_string(json: &str) -> Result { let typed_ast: Program = serde_json::from_str(json)?; Ok(Self { typed_ast }) diff --git a/typed/src/main.rs b/typed/src/main.rs index 38b928785c..34005aa110 100644 --- a/typed/src/main.rs +++ b/typed/src/main.rs @@ -15,10 +15,10 @@ // along with the Leo library. If not, see . use leo_ast::{LeoAst, ParserError}; -use leo_typed::LeoTypedAst; +use leo_typed::LeoCoreAst; use std::{env, fs, path::Path}; -fn to_leo_typed_tree(filepath: &Path) -> Result { +fn to_leo_core_tree(filepath: &Path) -> Result { // Loads the Leo code as a string from the given file path. let program_filepath = filepath.to_path_buf(); let program_string = LeoAst::load_file(&program_filepath)?; @@ -26,11 +26,11 @@ fn to_leo_typed_tree(filepath: &Path) -> Result { // Parses the Leo file and constructs an abstract syntax tree. let ast = LeoAst::new(&program_filepath, &program_string)?; - // Parse the abstract syntax tree and constructs a typed syntax tree. - let typed_ast = LeoTypedAst::new("leo_typed_tree", &ast); + // Parse the abstract core tree and constructs a typed core tree. + let typed_ast = LeoCoreAst::new("leo_typed_tree", &ast); - // Serializes the typed syntax tree into JSON format. - let serialized_typed_tree = LeoTypedAst::to_json_string(&typed_ast)?; + // Serializes the typed core tree into JSON format. + let serialized_typed_tree = LeoCoreAst::to_json_string(&typed_ast)?; Ok(serialized_typed_tree) } @@ -51,9 +51,9 @@ fn main() -> Result<(), ParserError> { // Construct the input filepath. let input_filepath = Path::new(&cli_arguments[1]); - // Construct the serialized typed syntax tree. - let serialized_typed_tree = to_leo_typed_tree(&input_filepath)?; - println!("{}", serialized_typed_tree); + // Construct the serialized core syntax tree. + let serialized_core_tree = to_leo_core_tree(&input_filepath)?; + println!("{}", serialized_core_tree); // Determine the output directory. let output_directory = match cli_arguments.len() == 3 { @@ -65,8 +65,8 @@ fn main() -> Result<(), ParserError> { false => format!("./{}.json", input_filepath.file_stem().unwrap().to_str().unwrap()), }; - // Write the serialized abstract syntax tree to the output directory. - fs::write(Path::new(&output_directory), serialized_typed_tree)?; + // Write the serialized core syntax tree to the output directory. + fs::write(Path::new(&output_directory), serialized_core_tree)?; Ok(()) } diff --git a/typed/src/program.rs b/typed/src/program.rs index 6dd3339ea6..6db317a82b 100644 --- a/typed/src/program.rs +++ b/typed/src/program.rs @@ -23,7 +23,7 @@ use leo_ast::{definitions::Definition, files::File}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -/// A simple program with statement expressions, program arguments and program returns. +/// Stores the Leo program abstract syntax tree. #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] pub struct Program { pub name: String, diff --git a/typed/tests/serialization/json.rs b/typed/tests/serialization/json.rs index c952a8b992..ac83828675 100644 --- a/typed/tests/serialization/json.rs +++ b/typed/tests/serialization/json.rs @@ -15,13 +15,13 @@ // along with the Leo library. If not, see . use leo_ast::LeoAst; -use leo_typed::LeoTypedAst; +use leo_typed::LeoCoreAst; #[cfg(not(feature = "ci_skip"))] use leo_typed::Program; use std::path::{Path, PathBuf}; -fn to_typed_ast(program_filepath: &Path) -> LeoTypedAst { +fn to_typed_ast(program_filepath: &Path) -> LeoCoreAst { // Loads the Leo code as a string from the given file path. let program_string = LeoAst::load_file(program_filepath).unwrap(); @@ -29,7 +29,7 @@ fn to_typed_ast(program_filepath: &Path) -> LeoTypedAst { let ast = LeoAst::new(&program_filepath, &program_string).unwrap(); // Parse the abstract syntax tree and constructs a typed syntax tree. - LeoTypedAst::new("leo_typed_tree", &ast) + LeoCoreAst::new("leo_typed_tree", &ast) } #[test] @@ -66,7 +66,7 @@ fn test_deserialize() { // Construct a typed syntax tree by deserializing a typed syntax tree JSON file. let serialized_typed_ast = include_str!("expected_typed_ast.json"); - let typed_ast = LeoTypedAst::from_json_string(serialized_typed_ast).unwrap(); + let typed_ast = LeoCoreAst::from_json_string(serialized_typed_ast).unwrap(); assert_eq!(expected_typed_ast, typed_ast); } @@ -85,7 +85,7 @@ fn test_serialize_deserialize_serialize() { let serialized_typed_ast = typed_ast.to_json_string().unwrap(); // Deserializes the typed syntax tree into a LeoTypedAst. - let typed_ast = LeoTypedAst::from_json_string(&serialized_typed_ast).unwrap(); + let typed_ast = LeoCoreAst::from_json_string(&serialized_typed_ast).unwrap(); // Reserializes the typed syntax tree into JSON format. let reserialized_typed_ast = typed_ast.to_json_string().unwrap(); From 7e7d1e58a0a35fd88845aa6b2edbfb074b4171e6 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 11:48:40 -0700 Subject: [PATCH 112/139] rename typed -> core-ast 2 --- Cargo.lock | 41 ++++++++++--------- Cargo.toml | 6 ++- compiler/Cargo.toml | 6 +-- compiler/src/compiler.rs | 2 +- compiler/src/console/assert.rs | 2 +- compiler/src/console/console.rs | 2 +- compiler/src/console/format.rs | 2 +- compiler/src/constraints/constraints.rs | 2 +- compiler/src/definition/definition.rs | 2 +- compiler/src/definition/definitions.rs | 2 +- compiler/src/errors/console.rs | 2 +- compiler/src/errors/expression.rs | 2 +- compiler/src/errors/function.rs | 2 +- compiler/src/errors/import.rs | 2 +- compiler/src/errors/output_bytes.rs | 2 +- compiler/src/errors/statement.rs | 2 +- compiler/src/errors/value/address.rs | 2 +- compiler/src/errors/value/boolean.rs | 2 +- compiler/src/errors/value/field.rs | 2 +- compiler/src/errors/value/group.rs | 2 +- compiler/src/errors/value/integer.rs | 2 +- compiler/src/errors/value/value.rs | 2 +- compiler/src/expression/arithmetic/add.rs | 2 +- compiler/src/expression/arithmetic/div.rs | 2 +- compiler/src/expression/arithmetic/mul.rs | 2 +- compiler/src/expression/arithmetic/negate.rs | 2 +- compiler/src/expression/arithmetic/pow.rs | 2 +- compiler/src/expression/arithmetic/sub.rs | 2 +- compiler/src/expression/array/access.rs | 2 +- compiler/src/expression/array/array.rs | 2 +- compiler/src/expression/array/index.rs | 2 +- compiler/src/expression/binary/binary.rs | 2 +- compiler/src/expression/binary/operand.rs | 2 +- compiler/src/expression/circuit/access.rs | 2 +- compiler/src/expression/circuit/circuit.rs | 2 +- .../src/expression/circuit/static_access.rs | 2 +- .../src/expression/conditional/conditional.rs | 2 +- compiler/src/expression/expression.rs | 2 +- .../src/expression/function/core_circuit.rs | 2 +- compiler/src/expression/function/function.rs | 2 +- .../src/expression/identifier/identifier.rs | 2 +- compiler/src/expression/logical/and.rs | 2 +- compiler/src/expression/logical/not.rs | 2 +- compiler/src/expression/logical/or.rs | 2 +- compiler/src/expression/relational/eq.rs | 2 +- compiler/src/expression/relational/ge.rs | 2 +- compiler/src/expression/relational/gt.rs | 2 +- compiler/src/expression/relational/le.rs | 2 +- compiler/src/expression/relational/lt.rs | 2 +- compiler/src/expression/tuple/access.rs | 2 +- compiler/src/expression/tuple/tuple.rs | 2 +- compiler/src/function/function.rs | 2 +- compiler/src/function/input/array.rs | 2 +- compiler/src/function/input/function_input.rs | 2 +- compiler/src/function/input/input_keyword.rs | 2 +- compiler/src/function/input/input_section.rs | 2 +- .../src/function/input/main_function_input.rs | 2 +- compiler/src/function/input/tuple.rs | 2 +- compiler/src/function/main_function.rs | 2 +- compiler/src/function/result/result.rs | 2 +- compiler/src/import/parser/import_parser.rs | 2 +- compiler/src/import/store/core_package.rs | 2 +- compiler/src/import/store/import.rs | 2 +- compiler/src/import/store/symbol.rs | 2 +- compiler/src/output/output_bytes.rs | 2 +- compiler/src/statement/assign/array.rs | 2 +- compiler/src/statement/assign/assign.rs | 2 +- compiler/src/statement/assign/assignee.rs | 2 +- .../src/statement/assign/circuit_variable.rs | 2 +- compiler/src/statement/assign/tuple.rs | 2 +- compiler/src/statement/branch/branch.rs | 2 +- .../src/statement/conditional/conditional.rs | 2 +- .../src/statement/definition/definition.rs | 2 +- compiler/src/statement/iteration/iteration.rs | 2 +- compiler/src/statement/return_/return_.rs | 2 +- compiler/src/statement/statement.rs | 2 +- compiler/src/value/address/address.rs | 2 +- compiler/src/value/boolean/input.rs | 2 +- compiler/src/value/field/field_type.rs | 2 +- compiler/src/value/field/input.rs | 2 +- compiler/src/value/group/group_type.rs | 2 +- compiler/src/value/group/input.rs | 2 +- .../src/value/group/targets/edwards_bls12.rs | 2 +- compiler/src/value/implicit/implicit.rs | 2 +- compiler/src/value/integer/integer.rs | 2 +- compiler/src/value/value.rs | 2 +- compiler/tests/address/mod.rs | 2 +- compiler/tests/console/mod.rs | 2 +- .../core/packages/unstable/blake2s/mod.rs | 2 +- compiler/tests/field/mod.rs | 2 +- compiler/tests/group/mod.rs | 11 ++--- compiler/tests/integers/i128/mod.rs | 2 +- compiler/tests/integers/i16/mod.rs | 2 +- compiler/tests/integers/i32/mod.rs | 2 +- compiler/tests/integers/i64/mod.rs | 2 +- compiler/tests/integers/i8/mod.rs | 2 +- compiler/tests/integers/u128/mod.rs | 2 +- compiler/tests/integers/u16/mod.rs | 2 +- compiler/tests/integers/u32/mod.rs | 2 +- compiler/tests/integers/u64/mod.rs | 2 +- compiler/tests/integers/u8/mod.rs | 2 +- compiler/tests/mod.rs | 2 +- compiler/tests/mutability/mod.rs | 2 +- compiler/tests/statements/conditional/mod.rs | 2 +- compiler/tests/statements/mod.rs | 2 +- {typed => core-ast}/Cargo.toml | 10 ++--- {typed => core-ast}/benches/big_circuit.leo | 0 {typed => core-ast}/benches/big_if_else.leo | 0 {typed => core-ast}/benches/big_ternary.leo | 0 .../benches/core_ast.rs | 2 +- {typed => core-ast}/benches/long_array.leo | 0 {typed => core-ast}/benches/long_expr.leo | 0 {typed => core-ast}/benches/many_assigns.leo | 0 {typed => core-ast}/benches/many_foos.leo | 0 {typed => core-ast}/src/annotation.rs | 0 {typed => core-ast}/src/circuits/circuit.rs | 0 .../src/circuits/circuit_member.rs | 0 .../circuits/circuit_variable_definition.rs | 0 {typed => core-ast}/src/circuits/mod.rs | 0 {typed => core-ast}/src/common/assignee.rs | 0 {typed => core-ast}/src/common/declare.rs | 0 {typed => core-ast}/src/common/identifier.rs | 0 {typed => core-ast}/src/common/mod.rs | 0 .../src/common/range_or_expression.rs | 0 {typed => core-ast}/src/common/span.rs | 0 .../src/common/spread_or_expression.rs | 0 .../src/common/variable_name.rs | 0 {typed => core-ast}/src/common/variables.rs | 0 .../src/console/console_function.rs | 0 .../src/console/console_function_call.rs | 0 .../src/console/formatted_container.rs | 0 .../src/console/formatted_parameter.rs | 0 .../src/console/formatted_string.rs | 0 {typed => core-ast}/src/console/mod.rs | 0 {typed => core-ast}/src/errors/error.rs | 0 {typed => core-ast}/src/errors/mod.rs | 0 {typed => core-ast}/src/expression.rs | 0 {typed => core-ast}/src/functions/function.rs | 0 .../src/functions/input/function_input.rs | 0 .../src/functions/input/input_variable.rs | 0 .../src/functions/input/mod.rs | 0 {typed => core-ast}/src/functions/mod.rs | 0 .../src/functions/test_function.rs | 0 .../src/groups/group_coordinate.rs | 0 {typed => core-ast}/src/groups/group_value.rs | 0 {typed => core-ast}/src/groups/mod.rs | 0 {typed => core-ast}/src/imports/import.rs | 0 .../src/imports/import_symbol.rs | 0 {typed => core-ast}/src/imports/mod.rs | 0 {typed => core-ast}/src/imports/package.rs | 0 .../src/imports/package_access.rs | 0 {typed => core-ast}/src/input/input.rs | 0 {typed => core-ast}/src/input/input_value.rs | 0 {typed => core-ast}/src/input/macros.rs | 0 {typed => core-ast}/src/input/mod.rs | 0 .../src/input/parameters/mod.rs | 0 .../src/input/parameters/parameter.rs | 0 .../src/input/program_input/main_input.rs | 0 .../src/input/program_input/mod.rs | 0 .../src/input/program_input/program_input.rs | 0 .../src/input/program_input/registers.rs | 0 .../src/input/program_state/mod.rs | 0 .../input/program_state/private_state/mod.rs | 0 .../private_state/private_state.rs | 0 .../program_state/private_state/record.rs | 0 .../program_state/private_state/state_leaf.rs | 0 .../src/input/program_state/program_state.rs | 0 .../input/program_state/public_state/mod.rs | 0 .../public_state/public_state.rs | 0 .../input/program_state/public_state/state.rs | 0 {typed => core-ast}/src/lib.rs | 0 {typed => core-ast}/src/main.rs | 6 +-- {typed => core-ast}/src/program.rs | 0 .../conditional_nested_or_end_statement.rs | 0 .../src/statements/conditional_statement.rs | 0 {typed => core-ast}/src/statements/mod.rs | 0 .../src/statements/statement.rs | 0 {typed => core-ast}/src/types/integer_type.rs | 0 {typed => core-ast}/src/types/mod.rs | 0 {typed => core-ast}/src/types/type_.rs | 0 {typed => core-ast}/tests/mod.rs | 0 .../serialization/expected_typed_ast.json | 2 +- .../tests/serialization/json.rs | 6 +-- .../tests/serialization/main.leo | 0 .../tests/serialization/mod.rs | 0 core/Cargo.toml | 4 +- core/src/errors/core_circuit.rs | 2 +- core/src/errors/core_package.rs | 2 +- core/src/errors/core_package_list.rs | 2 +- core/src/errors/leo_core.rs | 2 +- core/src/lib.rs | 2 +- core/src/packages/unstable/blake2s.rs | 2 +- core/src/types/core_circuit.rs | 2 +- core/src/types/core_circuit_struct_list.rs | 2 +- core/src/types/core_package.rs | 2 +- core/src/types/core_package_list.rs | 2 +- dynamic-check/Cargo.toml | 4 +- .../src/assertions/type_assertion.rs | 2 +- dynamic-check/src/assertions/type_equality.rs | 2 +- .../src/assertions/type_membership.rs | 2 +- .../src/assertions/type_variable_pair.rs | 2 +- dynamic-check/src/dynamic_check.rs | 2 +- dynamic-check/src/errors/dynamic_check.rs | 2 +- dynamic-check/src/errors/frame.rs | 2 +- dynamic-check/src/errors/scope.rs | 2 +- dynamic-check/src/errors/type_assertion.rs | 2 +- dynamic-check/src/errors/variable_table.rs | 2 +- dynamic-check/src/objects/frame.rs | 4 +- dynamic-check/tests/mod.rs | 2 +- imports/Cargo.toml | 4 +- imports/src/errors/import_parser.rs | 2 +- imports/src/parser/core_package.rs | 2 +- imports/src/parser/import_parser.rs | 2 +- imports/src/parser/parse_package.rs | 2 +- imports/src/parser/parse_symbol.rs | 2 +- state/Cargo.toml | 4 +- .../local_data_commitment.rs | 2 +- .../state_leaf_values.rs | 2 +- .../src/local_data_commitment/state_values.rs | 2 +- .../record_commitment/dpc_record_values.rs | 2 +- .../record_commitment/record_commitment.rs | 2 +- state/src/utilities/input_value.rs | 2 +- .../test_verify_local_data_commitment.rs | 2 +- state/tests/test_verify_record_commitment.rs | 2 +- symbol-table/Cargo.toml | 4 +- symbol-table/src/errors/symbol_table.rs | 2 +- symbol-table/src/errors/type_.rs | 2 +- symbol-table/src/imports/imported_symbols.rs | 2 +- symbol-table/src/symbol_table.rs | 2 +- symbol-table/src/types/circuits/circuit.rs | 2 +- .../src/types/circuits/circuit_variable.rs | 2 +- symbol-table/src/types/functions/function.rs | 2 +- .../src/types/functions/function_input.rs | 2 +- .../functions/function_input_variable.rs | 2 +- .../src/types/functions/function_output.rs | 2 +- symbol-table/src/types/type_.rs | 2 +- symbol-table/src/types/type_variable.rs | 2 +- .../types/user_defined/user_defined_type.rs | 2 +- symbol-table/tests/mod.rs | 2 +- 239 files changed, 206 insertions(+), 206 deletions(-) rename {typed => core-ast}/Cargo.toml (86%) rename {typed => core-ast}/benches/big_circuit.leo (100%) rename {typed => core-ast}/benches/big_if_else.leo (100%) rename {typed => core-ast}/benches/big_ternary.leo (100%) rename typed/benches/typed_ast.rs => core-ast/benches/core_ast.rs (99%) rename {typed => core-ast}/benches/long_array.leo (100%) rename {typed => core-ast}/benches/long_expr.leo (100%) rename {typed => core-ast}/benches/many_assigns.leo (100%) rename {typed => core-ast}/benches/many_foos.leo (100%) rename {typed => core-ast}/src/annotation.rs (100%) rename {typed => core-ast}/src/circuits/circuit.rs (100%) rename {typed => core-ast}/src/circuits/circuit_member.rs (100%) rename {typed => core-ast}/src/circuits/circuit_variable_definition.rs (100%) rename {typed => core-ast}/src/circuits/mod.rs (100%) rename {typed => core-ast}/src/common/assignee.rs (100%) rename {typed => core-ast}/src/common/declare.rs (100%) rename {typed => core-ast}/src/common/identifier.rs (100%) rename {typed => core-ast}/src/common/mod.rs (100%) rename {typed => core-ast}/src/common/range_or_expression.rs (100%) rename {typed => core-ast}/src/common/span.rs (100%) rename {typed => core-ast}/src/common/spread_or_expression.rs (100%) rename {typed => core-ast}/src/common/variable_name.rs (100%) rename {typed => core-ast}/src/common/variables.rs (100%) rename {typed => core-ast}/src/console/console_function.rs (100%) rename {typed => core-ast}/src/console/console_function_call.rs (100%) rename {typed => core-ast}/src/console/formatted_container.rs (100%) rename {typed => core-ast}/src/console/formatted_parameter.rs (100%) rename {typed => core-ast}/src/console/formatted_string.rs (100%) rename {typed => core-ast}/src/console/mod.rs (100%) rename {typed => core-ast}/src/errors/error.rs (100%) rename {typed => core-ast}/src/errors/mod.rs (100%) rename {typed => core-ast}/src/expression.rs (100%) rename {typed => core-ast}/src/functions/function.rs (100%) rename {typed => core-ast}/src/functions/input/function_input.rs (100%) rename {typed => core-ast}/src/functions/input/input_variable.rs (100%) rename {typed => core-ast}/src/functions/input/mod.rs (100%) rename {typed => core-ast}/src/functions/mod.rs (100%) rename {typed => core-ast}/src/functions/test_function.rs (100%) rename {typed => core-ast}/src/groups/group_coordinate.rs (100%) rename {typed => core-ast}/src/groups/group_value.rs (100%) rename {typed => core-ast}/src/groups/mod.rs (100%) rename {typed => core-ast}/src/imports/import.rs (100%) rename {typed => core-ast}/src/imports/import_symbol.rs (100%) rename {typed => core-ast}/src/imports/mod.rs (100%) rename {typed => core-ast}/src/imports/package.rs (100%) rename {typed => core-ast}/src/imports/package_access.rs (100%) rename {typed => core-ast}/src/input/input.rs (100%) rename {typed => core-ast}/src/input/input_value.rs (100%) rename {typed => core-ast}/src/input/macros.rs (100%) rename {typed => core-ast}/src/input/mod.rs (100%) rename {typed => core-ast}/src/input/parameters/mod.rs (100%) rename {typed => core-ast}/src/input/parameters/parameter.rs (100%) rename {typed => core-ast}/src/input/program_input/main_input.rs (100%) rename {typed => core-ast}/src/input/program_input/mod.rs (100%) rename {typed => core-ast}/src/input/program_input/program_input.rs (100%) rename {typed => core-ast}/src/input/program_input/registers.rs (100%) rename {typed => core-ast}/src/input/program_state/mod.rs (100%) rename {typed => core-ast}/src/input/program_state/private_state/mod.rs (100%) rename {typed => core-ast}/src/input/program_state/private_state/private_state.rs (100%) rename {typed => core-ast}/src/input/program_state/private_state/record.rs (100%) rename {typed => core-ast}/src/input/program_state/private_state/state_leaf.rs (100%) rename {typed => core-ast}/src/input/program_state/program_state.rs (100%) rename {typed => core-ast}/src/input/program_state/public_state/mod.rs (100%) rename {typed => core-ast}/src/input/program_state/public_state/public_state.rs (100%) rename {typed => core-ast}/src/input/program_state/public_state/state.rs (100%) rename {typed => core-ast}/src/lib.rs (100%) rename {typed => core-ast}/src/main.rs (92%) rename {typed => core-ast}/src/program.rs (100%) rename {typed => core-ast}/src/statements/conditional_nested_or_end_statement.rs (100%) rename {typed => core-ast}/src/statements/conditional_statement.rs (100%) rename {typed => core-ast}/src/statements/mod.rs (100%) rename {typed => core-ast}/src/statements/statement.rs (100%) rename {typed => core-ast}/src/types/integer_type.rs (100%) rename {typed => core-ast}/src/types/mod.rs (100%) rename {typed => core-ast}/src/types/type_.rs (100%) rename {typed => core-ast}/tests/mod.rs (100%) rename {typed => core-ast}/tests/serialization/expected_typed_ast.json (98%) rename {typed => core-ast}/tests/serialization/json.rs (97%) rename {typed => core-ast}/tests/serialization/main.leo (100%) rename {typed => core-ast}/tests/serialization/mod.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index cdf38c7bed..aaeb4f691d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1253,6 +1253,7 @@ dependencies = [ "hex", "leo-ast", "leo-core", + "leo-core-ast", "leo-dynamic-check", "leo-gadgets", "leo-imports", @@ -1260,7 +1261,6 @@ dependencies = [ "leo-package", "leo-state", "leo-symbol-table", - "leo-typed", "num-bigint", "pest", "rand", @@ -1284,8 +1284,8 @@ dependencies = [ name = "leo-core" version = "1.0.3" dependencies = [ + "leo-core-ast", "leo-gadgets", - "leo-typed", "rand", "rand_xorshift", "snarkos-curves", @@ -1296,14 +1296,28 @@ dependencies = [ "thiserror", ] +[[package]] +name = "leo-core-ast" +version = "1.0.3" +dependencies = [ + "criterion", + "leo-ast", + "leo-input", + "pest", + "serde", + "serde_json", + "snarkos-errors", + "snarkos-models", +] + [[package]] name = "leo-dynamic-check" version = "1.0.3" dependencies = [ "leo-ast", + "leo-core-ast", "leo-imports", "leo-symbol-table", - "leo-typed", "serde", "serde_json", "thiserror", @@ -1327,7 +1341,7 @@ name = "leo-imports" version = "1.0.3" dependencies = [ "leo-ast", - "leo-typed", + "leo-core-ast", "thiserror", "tracing", ] @@ -1363,6 +1377,7 @@ dependencies = [ "lazy_static", "leo-compiler", "leo-core", + "leo-core-ast", "leo-dynamic-check", "leo-gadgets", "leo-imports", @@ -1414,8 +1429,8 @@ dependencies = [ name = "leo-state" version = "1.0.3" dependencies = [ + "leo-core-ast", "leo-input", - "leo-typed", "rand", "rand_xorshift", "snarkos-algorithms", @@ -1435,26 +1450,12 @@ version = "1.0.3" dependencies = [ "leo-ast", "leo-core", + "leo-core-ast", "leo-imports", - "leo-typed", "serde", "thiserror", ] -[[package]] -name = "leo-typed" -version = "1.0.3" -dependencies = [ - "criterion", - "leo-ast", - "leo-input", - "pest", - "serde", - "serde_json", - "snarkos-errors", - "snarkos-models", -] - [[package]] name = "libc" version = "0.2.76" diff --git a/Cargo.toml b/Cargo.toml index 6becd8320c..5abc2a48f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ path = "leo/main.rs" members = [ "ast", "compiler", + "core-ast", "core", "dynamic-check", "gadgets", @@ -35,7 +36,6 @@ members = [ "input", "linter", "package", - "typed", "state", "symbol-table", ] @@ -48,6 +48,10 @@ version = "1.0.3" path = "./core" version = "1.0.1" +[dependencies.leo-core-ast] +path = "./core-ast" +version = "1.0.3" + [dependencies.leo-dynamic-check] path = "./dynamic-check" version = "1.0.3" diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 9944c1551a..d115e19902 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -45,8 +45,8 @@ version = "1.0.3" path = "../package" version = "1.0.3" -[dependencies.leo-typed] -path = "../typed" +[dependencies.leo-core-ast] +path = "../core-ast" version = "1.0.3" [dependencies.leo-state] @@ -124,4 +124,4 @@ default-features = false [features] default = [ ] -ci_skip = [ "leo-ast/ci_skip", "leo-typed/ci_skip" ] +ci_skip = [ "leo-ast/ci_skip", "leo-core-ast/ci_skip" ] diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index c83e7a5b03..bbd495c111 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -24,13 +24,13 @@ use crate::{ OutputFile, }; use leo_ast::LeoAst; +use leo_core_ast::{Input, LeoCoreAst, MainInput, Program}; use leo_dynamic_check::DynamicCheck; use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; use leo_state::verify_local_data_commitment; use leo_symbol_table::SymbolTable; -use leo_typed::{Input, LeoCoreAst, MainInput, Program}; use snarkos_dpc::{base_dpc::instantiated::Components, SystemParameters}; use snarkos_errors::gadgets::SynthesisError; diff --git a/compiler/src/console/assert.rs b/compiler/src/console/assert.rs index 6e407c215b..9845e51fd4 100644 --- a/compiler/src/console/assert.rs +++ b/compiler/src/console/assert.rs @@ -17,7 +17,7 @@ //! Enforces an assert equals statement in a compiled Leo program. use crate::{errors::ConsoleError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, Span, Type}; +use leo_core_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/console/console.rs b/compiler/src/console/console.rs index af8da4ac25..43023a1294 100644 --- a/compiler/src/console/console.rs +++ b/compiler/src/console/console.rs @@ -17,7 +17,7 @@ //! Evaluates a macro in a compiled Leo program. use crate::{errors::ConsoleError, program::ConstrainedProgram, GroupType}; -use leo_typed::{ConsoleFunction, ConsoleFunctionCall}; +use leo_core_ast::{ConsoleFunction, ConsoleFunctionCall}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/console/format.rs b/compiler/src/console/format.rs index 87f2db1fb5..0545539607 100644 --- a/compiler/src/console/format.rs +++ b/compiler/src/console/format.rs @@ -17,7 +17,7 @@ //! Evaluates a formatted string in a compiled Leo program. use crate::{errors::ConsoleError, program::ConstrainedProgram, GroupType}; -use leo_typed::FormattedString; +use leo_core_ast::FormattedString; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/constraints/constraints.rs b/compiler/src/constraints/constraints.rs index 35d2dba2a3..a96339e4f9 100644 --- a/compiler/src/constraints/constraints.rs +++ b/compiler/src/constraints/constraints.rs @@ -25,10 +25,10 @@ use crate::{ OutputBytes, OutputFile, }; +use leo_core_ast::{Input, Program}; use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; -use leo_typed::{Input, Program}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/definition/definition.rs b/compiler/src/definition/definition.rs index d78aa90aa0..4ed4cbbd6f 100644 --- a/compiler/src/definition/definition.rs +++ b/compiler/src/definition/definition.rs @@ -21,7 +21,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_typed::Identifier; +use leo_core_ast::Identifier; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/definition/definitions.rs b/compiler/src/definition/definitions.rs index 4769570352..d15ecd07c2 100644 --- a/compiler/src/definition/definitions.rs +++ b/compiler/src/definition/definitions.rs @@ -22,8 +22,8 @@ use crate::{ value::ConstrainedValue, GroupType, }; +use leo_core_ast::Program; use leo_imports::ImportParser; -use leo_typed::Program; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/errors/console.rs b/compiler/src/errors/console.rs index 330dd15d52..2d0b636c28 100644 --- a/compiler/src/errors/console.rs +++ b/compiler/src/errors/console.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::ExpressionError; -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/compiler/src/errors/expression.rs b/compiler/src/errors/expression.rs index bb0ee8577f..705bb5fcd4 100644 --- a/compiler/src/errors/expression.rs +++ b/compiler/src/errors/expression.rs @@ -16,7 +16,7 @@ use crate::errors::{AddressError, BooleanError, FieldError, FunctionError, GroupError, IntegerError, ValueError}; use leo_core::LeoCoreError; -use leo_typed::{Error as FormattedError, Identifier, Span}; +use leo_core_ast::{Error as FormattedError, Identifier, Span}; use snarkos_errors::gadgets::SynthesisError; use std::path::Path; diff --git a/compiler/src/errors/function.rs b/compiler/src/errors/function.rs index f4ccd09231..87919fe0ca 100644 --- a/compiler/src/errors/function.rs +++ b/compiler/src/errors/function.rs @@ -25,7 +25,7 @@ use crate::errors::{ StatementError, ValueError, }; -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/compiler/src/errors/import.rs b/compiler/src/errors/import.rs index b6a6e51180..45f7885828 100644 --- a/compiler/src/errors/import.rs +++ b/compiler/src/errors/import.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use leo_core::LeoCoreError; -use leo_typed::{Error as FormattedError, Identifier, ImportSymbol, Span}; +use leo_core_ast::{Error as FormattedError, Identifier, ImportSymbol, Span}; #[derive(Debug, Error)] pub enum ImportError { diff --git a/compiler/src/errors/output_bytes.rs b/compiler/src/errors/output_bytes.rs index d9ef930f35..5cf212572e 100644 --- a/compiler/src/errors/output_bytes.rs +++ b/compiler/src/errors/output_bytes.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/compiler/src/errors/statement.rs b/compiler/src/errors/statement.rs index e39dd2e53d..adc04cfc06 100644 --- a/compiler/src/errors/statement.rs +++ b/compiler/src/errors/statement.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::{AddressError, BooleanError, ConsoleError, ExpressionError, IntegerError, ValueError}; -use leo_typed::{Error as FormattedError, Span, Type}; +use leo_core_ast::{Error as FormattedError, Span, Type}; use std::path::Path; diff --git a/compiler/src/errors/value/address.rs b/compiler/src/errors/value/address.rs index 52e84aaccd..1d308d90b1 100644 --- a/compiler/src/errors/value/address.rs +++ b/compiler/src/errors/value/address.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use snarkos_errors::{gadgets::SynthesisError, objects::account::AccountError}; use std::path::Path; diff --git a/compiler/src/errors/value/boolean.rs b/compiler/src/errors/value/boolean.rs index cafdc4e3f3..897e461a35 100644 --- a/compiler/src/errors/value/boolean.rs +++ b/compiler/src/errors/value/boolean.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use snarkos_errors::gadgets::SynthesisError; use std::path::Path; diff --git a/compiler/src/errors/value/field.rs b/compiler/src/errors/value/field.rs index 200749be95..452335bedb 100644 --- a/compiler/src/errors/value/field.rs +++ b/compiler/src/errors/value/field.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use snarkos_errors::gadgets::SynthesisError; use std::path::Path; diff --git a/compiler/src/errors/value/group.rs b/compiler/src/errors/value/group.rs index 63c20d5aad..3e7b148654 100644 --- a/compiler/src/errors/value/group.rs +++ b/compiler/src/errors/value/group.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use snarkos_errors::gadgets::SynthesisError; use std::path::Path; diff --git a/compiler/src/errors/value/integer.rs b/compiler/src/errors/value/integer.rs index 1133a487f9..4672635cd1 100644 --- a/compiler/src/errors/value/integer.rs +++ b/compiler/src/errors/value/integer.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +use leo_core_ast::{error::Error as FormattedError, Span}; use leo_gadgets::errors::SignedIntegerError; -use leo_typed::{error::Error as FormattedError, Span}; use snarkos_errors::gadgets::SynthesisError; use std::path::Path; diff --git a/compiler/src/errors/value/value.rs b/compiler/src/errors/value/value.rs index 8f4a3248fa..fa469919c5 100644 --- a/compiler/src/errors/value/value.rs +++ b/compiler/src/errors/value/value.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::{AddressError, BooleanError, FieldError, GroupError, IntegerError}; -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/compiler/src/expression/arithmetic/add.rs b/compiler/src/expression/arithmetic/add.rs index ba4f09a33a..a52e33756a 100644 --- a/compiler/src/expression/arithmetic/add.rs +++ b/compiler/src/expression/arithmetic/add.rs @@ -17,7 +17,7 @@ //! Enforces an arithmetic `+` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/arithmetic/div.rs b/compiler/src/expression/arithmetic/div.rs index daf79b142c..1564b16305 100644 --- a/compiler/src/expression/arithmetic/div.rs +++ b/compiler/src/expression/arithmetic/div.rs @@ -17,7 +17,7 @@ //! Enforces an arithmetic `/` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/arithmetic/mul.rs b/compiler/src/expression/arithmetic/mul.rs index 0849d7ccd4..cf3f0bb833 100644 --- a/compiler/src/expression/arithmetic/mul.rs +++ b/compiler/src/expression/arithmetic/mul.rs @@ -17,7 +17,7 @@ //! Enforces an arithmetic `*` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/arithmetic/negate.rs b/compiler/src/expression/arithmetic/negate.rs index 2996283ae0..a3318532bd 100644 --- a/compiler/src/expression/arithmetic/negate.rs +++ b/compiler/src/expression/arithmetic/negate.rs @@ -17,7 +17,7 @@ //! Enforces a unary negate `-` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/arithmetic/pow.rs b/compiler/src/expression/arithmetic/pow.rs index a416e58ce6..3607d4756c 100644 --- a/compiler/src/expression/arithmetic/pow.rs +++ b/compiler/src/expression/arithmetic/pow.rs @@ -17,7 +17,7 @@ //! Enforces an arithmetic `**` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/arithmetic/sub.rs b/compiler/src/expression/arithmetic/sub.rs index bbad8a4262..20502ca597 100644 --- a/compiler/src/expression/arithmetic/sub.rs +++ b/compiler/src/expression/arithmetic/sub.rs @@ -17,7 +17,7 @@ //! Enforces an arithmetic `-` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/array/access.rs b/compiler/src/expression/array/access.rs index 7f7b64d7be..c7f7fa827a 100644 --- a/compiler/src/expression/array/access.rs +++ b/compiler/src/expression/array/access.rs @@ -17,7 +17,7 @@ //! Enforces array access in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, RangeOrExpression, Span, Type}; +use leo_core_ast::{Expression, RangeOrExpression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/array/array.rs b/compiler/src/expression/array/array.rs index 9ff67a1ea7..d5e6f762d8 100644 --- a/compiler/src/expression/array/array.rs +++ b/compiler/src/expression/array/array.rs @@ -22,7 +22,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_typed::{Expression, Span, SpreadOrExpression, Type}; +use leo_core_ast::{Expression, Span, SpreadOrExpression, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/array/index.rs b/compiler/src/expression/array/index.rs index 575d4f5103..54b62f169e 100644 --- a/compiler/src/expression/array/index.rs +++ b/compiler/src/expression/array/index.rs @@ -17,7 +17,7 @@ //! Enforces an array index expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, IntegerType, Span, Type}; +use leo_core_ast::{Expression, IntegerType, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/binary/binary.rs b/compiler/src/expression/binary/binary.rs index 91d9f98cbd..ee580bfbe8 100644 --- a/compiler/src/expression/binary/binary.rs +++ b/compiler/src/expression/binary/binary.rs @@ -17,7 +17,7 @@ //! Enforces a binary expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, Span, Type}; +use leo_core_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/binary/operand.rs b/compiler/src/expression/binary/operand.rs index e6ff9530b6..d15156c73a 100644 --- a/compiler/src/expression/binary/operand.rs +++ b/compiler/src/expression/binary/operand.rs @@ -17,7 +17,7 @@ //! Enforces one operand in a binary expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, Span, Type}; +use leo_core_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/circuit/access.rs b/compiler/src/expression/circuit/access.rs index d0c2f806c2..53d57c51b4 100644 --- a/compiler/src/expression/circuit/access.rs +++ b/compiler/src/expression/circuit/access.rs @@ -22,7 +22,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_typed::{Expression, Identifier, Span, Type}; +use leo_core_ast::{Expression, Identifier, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/circuit/circuit.rs b/compiler/src/expression/circuit/circuit.rs index c70ae61107..b1e7b8d421 100644 --- a/compiler/src/expression/circuit/circuit.rs +++ b/compiler/src/expression/circuit/circuit.rs @@ -22,7 +22,7 @@ use crate::{ value::{ConstrainedCircuitMember, ConstrainedValue}, GroupType, }; -use leo_typed::{CircuitMember, CircuitVariableDefinition, Identifier, Span}; +use leo_core_ast::{CircuitMember, CircuitVariableDefinition, Identifier, Span}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/circuit/static_access.rs b/compiler/src/expression/circuit/static_access.rs index 1f01fce5dd..7bf3d67df4 100644 --- a/compiler/src/expression/circuit/static_access.rs +++ b/compiler/src/expression/circuit/static_access.rs @@ -17,7 +17,7 @@ //! Enforces a circuit static access expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{CircuitMember, Expression, Identifier, Span, Type}; +use leo_core_ast::{CircuitMember, Expression, Identifier, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/conditional/conditional.rs b/compiler/src/expression/conditional/conditional.rs index cfae42dbb3..c332b791ba 100644 --- a/compiler/src/expression/conditional/conditional.rs +++ b/compiler/src/expression/conditional/conditional.rs @@ -17,7 +17,7 @@ //! Enforces a conditional expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, Span, Type}; +use leo_core_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/expression.rs b/compiler/src/expression/expression.rs index 9c0d98c41f..e5b90b0641 100644 --- a/compiler/src/expression/expression.rs +++ b/compiler/src/expression/expression.rs @@ -28,7 +28,7 @@ use crate::{ GroupType, Integer, }; -use leo_typed::{Expression, Type}; +use leo_core_ast::{Expression, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/function/core_circuit.rs b/compiler/src/expression/function/core_circuit.rs index c0314e775f..31e48d8a52 100644 --- a/compiler/src/expression/function/core_circuit.rs +++ b/compiler/src/expression/function/core_circuit.rs @@ -17,7 +17,7 @@ use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType}; use crate::errors::{ExpressionError, FunctionError}; use leo_core::call_core_circuit; -use leo_typed::{Expression, Span, Type}; +use leo_core_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::ConstraintSystem, diff --git a/compiler/src/expression/function/function.rs b/compiler/src/expression/function/function.rs index f24bcc84c6..35b324218b 100644 --- a/compiler/src/expression/function/function.rs +++ b/compiler/src/expression/function/function.rs @@ -17,7 +17,7 @@ //! Enforce a function call expression in a compiled Leo program. use crate::{errors::ExpressionError, new_scope, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, Span, Type}; +use leo_core_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/identifier/identifier.rs b/compiler/src/expression/identifier/identifier.rs index f1c8c4662d..9dde05d491 100644 --- a/compiler/src/expression/identifier/identifier.rs +++ b/compiler/src/expression/identifier/identifier.rs @@ -23,7 +23,7 @@ use crate::{ Address, GroupType, }; -use leo_typed::{Identifier, Type}; +use leo_core_ast::{Identifier, Type}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/expression/logical/and.rs b/compiler/src/expression/logical/and.rs index 60d6f58eae..cef99fcf7c 100644 --- a/compiler/src/expression/logical/and.rs +++ b/compiler/src/expression/logical/and.rs @@ -17,7 +17,7 @@ //! Enforces a logical `&&` operator in a resolved Leo program. use crate::{errors::BooleanError, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/logical/not.rs b/compiler/src/expression/logical/not.rs index 7f23b4651d..cdf84c051a 100644 --- a/compiler/src/expression/logical/not.rs +++ b/compiler/src/expression/logical/not.rs @@ -17,7 +17,7 @@ //! Enforces a logical `!` operator in a resolved Leo program. use crate::{errors::BooleanError, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/expression/logical/or.rs b/compiler/src/expression/logical/or.rs index 6ba45a3050..1f86254f48 100644 --- a/compiler/src/expression/logical/or.rs +++ b/compiler/src/expression/logical/or.rs @@ -17,7 +17,7 @@ //! Enforces a logical `||` operator in a resolved Leo program. use crate::{errors::BooleanError, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/relational/eq.rs b/compiler/src/expression/relational/eq.rs index 69d8d1370f..114a66c65e 100644 --- a/compiler/src/expression/relational/eq.rs +++ b/compiler/src/expression/relational/eq.rs @@ -17,7 +17,7 @@ //! Enforces a relational `==` operator in a resolved Leo program. use crate::{enforce_and, errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/relational/ge.rs b/compiler/src/expression/relational/ge.rs index 15e91f9e27..fdd4ed723c 100644 --- a/compiler/src/expression/relational/ge.rs +++ b/compiler/src/expression/relational/ge.rs @@ -17,8 +17,8 @@ //! Enforces a relational `>=` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; +use leo_core_ast::Span; use leo_gadgets::bits::ComparatorGadget; -use leo_typed::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/relational/gt.rs b/compiler/src/expression/relational/gt.rs index 45351cc999..3939d624c2 100644 --- a/compiler/src/expression/relational/gt.rs +++ b/compiler/src/expression/relational/gt.rs @@ -17,8 +17,8 @@ //! Enforces a relational `>` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; +use leo_core_ast::Span; use leo_gadgets::bits::ComparatorGadget; -use leo_typed::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/relational/le.rs b/compiler/src/expression/relational/le.rs index 91fbd5e6f9..4849f3d829 100644 --- a/compiler/src/expression/relational/le.rs +++ b/compiler/src/expression/relational/le.rs @@ -17,8 +17,8 @@ //! Enforces a relational `<=` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; +use leo_core_ast::Span; use leo_gadgets::bits::ComparatorGadget; -use leo_typed::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/relational/lt.rs b/compiler/src/expression/relational/lt.rs index ef9dd01e93..b78d40d638 100644 --- a/compiler/src/expression/relational/lt.rs +++ b/compiler/src/expression/relational/lt.rs @@ -17,8 +17,8 @@ //! Enforces a relational `<` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; +use leo_core_ast::Span; use leo_gadgets::bits::comparator::EvaluateLtGadget; -use leo_typed::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/tuple/access.rs b/compiler/src/expression/tuple/access.rs index c628ac4243..6d736047ea 100644 --- a/compiler/src/expression/tuple/access.rs +++ b/compiler/src/expression/tuple/access.rs @@ -17,7 +17,7 @@ //! Enforces array access in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, Span, Type}; +use leo_core_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/tuple/tuple.rs b/compiler/src/expression/tuple/tuple.rs index 3295fb4fe3..70f9b00dc7 100644 --- a/compiler/src/expression/tuple/tuple.rs +++ b/compiler/src/expression/tuple/tuple.rs @@ -17,7 +17,7 @@ //! Enforces an tuple expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, Span, Type}; +use leo_core_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index fcce12247f..13be254322 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -23,7 +23,7 @@ use crate::{ GroupType, }; -use leo_typed::{Expression, Function, FunctionInput, Span, Type}; +use leo_core_ast::{Expression, Function, FunctionInput, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/input/array.rs b/compiler/src/function/input/array.rs index 6317fde9c3..881bea90c7 100644 --- a/compiler/src/function/input/array.rs +++ b/compiler/src/function/input/array.rs @@ -23,7 +23,7 @@ use crate::{ GroupType, }; -use leo_typed::{InputValue, Span, Type}; +use leo_core_ast::{InputValue, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/input/function_input.rs b/compiler/src/function/input/function_input.rs index a588d778c8..1b4e08f7b8 100644 --- a/compiler/src/function/input/function_input.rs +++ b/compiler/src/function/input/function_input.rs @@ -18,7 +18,7 @@ use crate::{errors::FunctionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, Type}; +use leo_core_ast::{Expression, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/input/input_keyword.rs b/compiler/src/function/input/input_keyword.rs index 10025484bd..f657ca854f 100644 --- a/compiler/src/function/input/input_keyword.rs +++ b/compiler/src/function/input/input_keyword.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::FunctionError, ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_typed::{Identifier, Input}; +use leo_core_ast::{Identifier, Input}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/input/input_section.rs b/compiler/src/function/input/input_section.rs index 96d24bfbd6..2f104e682b 100644 --- a/compiler/src/function/input/input_section.rs +++ b/compiler/src/function/input/input_section.rs @@ -16,7 +16,7 @@ use crate::{errors::FunctionError, ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_typed::{Identifier, InputValue, Parameter}; +use leo_core_ast::{Identifier, InputValue, Parameter}; use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::ConstraintSystem, diff --git a/compiler/src/function/input/main_function_input.rs b/compiler/src/function/input/main_function_input.rs index ef9db4092a..9fe4675810 100644 --- a/compiler/src/function/input/main_function_input.rs +++ b/compiler/src/function/input/main_function_input.rs @@ -30,7 +30,7 @@ use crate::{ Integer, }; -use leo_typed::{InputValue, Span, Type}; +use leo_core_ast::{InputValue, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/input/tuple.rs b/compiler/src/function/input/tuple.rs index 77ee183309..ab273b6746 100644 --- a/compiler/src/function/input/tuple.rs +++ b/compiler/src/function/input/tuple.rs @@ -23,7 +23,7 @@ use crate::{ GroupType, }; -use leo_typed::{InputValue, Span, Type}; +use leo_core_ast::{InputValue, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/main_function.rs b/compiler/src/function/main_function.rs index e07aa4a775..c6a89cd85f 100644 --- a/compiler/src/function/main_function.rs +++ b/compiler/src/function/main_function.rs @@ -23,7 +23,7 @@ use crate::{ OutputBytes, }; -use leo_typed::{Expression, Function, FunctionInput, Input}; +use leo_core_ast::{Expression, Function, FunctionInput, Input}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/result/result.rs b/compiler/src/function/result/result.rs index cceafc612a..04dc3f243a 100644 --- a/compiler/src/function/result/result.rs +++ b/compiler/src/function/result/result.rs @@ -18,7 +18,7 @@ use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/import/parser/import_parser.rs b/compiler/src/import/parser/import_parser.rs index 7d5bbfce20..b9ad13a87f 100644 --- a/compiler/src/import/parser/import_parser.rs +++ b/compiler/src/import/parser/import_parser.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::ImportError; -use leo_typed::{Package, Program}; +use leo_core_ast::{Package, Program}; use std::{collections::HashMap, env::current_dir}; diff --git a/compiler/src/import/store/core_package.rs b/compiler/src/import/store/core_package.rs index 2357c1d7b6..940b6da46f 100644 --- a/compiler/src/import/store/core_package.rs +++ b/compiler/src/import/store/core_package.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{new_scope, ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_typed::Package; +use leo_core_ast::Package; use leo_core::{CorePackageList, LeoCoreError}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/import/store/import.rs b/compiler/src/import/store/import.rs index 094d7c0ca0..9d0501af33 100644 --- a/compiler/src/import/store/import.rs +++ b/compiler/src/import/store/import.rs @@ -15,9 +15,9 @@ // along with the Leo library. If not, see . use crate::{errors::ImportError, ConstrainedProgram, GroupType}; +use leo_core_ast::ImportStatement; use leo_imports::ImportParser; use leo_symbol_table::imported_symbols::ImportedSymbols; -use leo_typed::ImportStatement; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/import/store/symbol.rs b/compiler/src/import/store/symbol.rs index dfb9244cc2..ad63689c3c 100644 --- a/compiler/src/import/store/symbol.rs +++ b/compiler/src/import/store/symbol.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::ImportError, new_scope, ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_typed::{ImportSymbol, Program}; +use leo_core_ast::{ImportSymbol, Program}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/output/output_bytes.rs b/compiler/src/output/output_bytes.rs index a451c2fc4d..4e8fab7e68 100644 --- a/compiler/src/output/output_bytes.rs +++ b/compiler/src/output/output_bytes.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::OutputBytesError, ConstrainedValue, GroupType, REGISTERS_VARIABLE_NAME}; -use leo_typed::{Parameter, Registers, Span}; +use leo_core_ast::{Parameter, Registers, Span}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/statement/assign/array.rs b/compiler/src/statement/assign/array.rs index c282ca0fee..222913893d 100644 --- a/compiler/src/statement/assign/array.rs +++ b/compiler/src/statement/assign/array.rs @@ -17,7 +17,7 @@ //! Enforces an array assignment statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{RangeOrExpression, Span}; +use leo_core_ast::{RangeOrExpression, Span}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/assign/assign.rs b/compiler/src/statement/assign/assign.rs index 8fb78c6f02..f757fefab3 100644 --- a/compiler/src/statement/assign/assign.rs +++ b/compiler/src/statement/assign/assign.rs @@ -24,7 +24,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_typed::{Assignee, AssigneeAccess, Expression, Span}; +use leo_core_ast::{Assignee, AssigneeAccess, Expression, Span}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/assign/assignee.rs b/compiler/src/statement/assign/assignee.rs index 3a15996cdd..217a055892 100644 --- a/compiler/src/statement/assign/assignee.rs +++ b/compiler/src/statement/assign/assignee.rs @@ -17,7 +17,7 @@ //! Resolves assignees in a compiled Leo program. use crate::{errors::StatementError, new_scope, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Assignee, Span}; +use leo_core_ast::{Assignee, Span}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/statement/assign/circuit_variable.rs b/compiler/src/statement/assign/circuit_variable.rs index 2aea133662..1362849875 100644 --- a/compiler/src/statement/assign/circuit_variable.rs +++ b/compiler/src/statement/assign/circuit_variable.rs @@ -17,7 +17,7 @@ //! Enforces a circuit variable assignment statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Identifier, Span}; +use leo_core_ast::{Identifier, Span}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/assign/tuple.rs b/compiler/src/statement/assign/tuple.rs index a8a8a0a7fb..307aef4d87 100644 --- a/compiler/src/statement/assign/tuple.rs +++ b/compiler/src/statement/assign/tuple.rs @@ -17,7 +17,7 @@ //! Enforces a tuple assignment statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/branch/branch.rs b/compiler/src/statement/branch/branch.rs index ddb6e91838..96edc1aec9 100644 --- a/compiler/src/statement/branch/branch.rs +++ b/compiler/src/statement/branch/branch.rs @@ -17,7 +17,7 @@ //! Enforces a branch of a conditional or iteration statement in a compiled Leo program. use crate::{program::ConstrainedProgram, GroupType, IndicatorAndConstrainedValue, StatementResult}; -use leo_typed::{Statement, Type}; +use leo_core_ast::{Statement, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/conditional/conditional.rs b/compiler/src/statement/conditional/conditional.rs index db83d57ffb..ccc86141f9 100644 --- a/compiler/src/statement/conditional/conditional.rs +++ b/compiler/src/statement/conditional/conditional.rs @@ -24,7 +24,7 @@ use crate::{ IndicatorAndConstrainedValue, StatementResult, }; -use leo_typed::{ConditionalNestedOrEndStatement, ConditionalStatement, Span, Type}; +use leo_core_ast::{ConditionalNestedOrEndStatement, ConditionalStatement, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/definition/definition.rs b/compiler/src/statement/definition/definition.rs index f2642883ba..4de710251c 100644 --- a/compiler/src/statement/definition/definition.rs +++ b/compiler/src/statement/definition/definition.rs @@ -17,7 +17,7 @@ //! Enforces a definition statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_typed::{Declare, Expression, Span, VariableName, Variables}; +use leo_core_ast::{Declare, Expression, Span, VariableName, Variables}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/iteration/iteration.rs b/compiler/src/statement/iteration/iteration.rs index f9c658ad1e..bdf7f43f97 100644 --- a/compiler/src/statement/iteration/iteration.rs +++ b/compiler/src/statement/iteration/iteration.rs @@ -25,7 +25,7 @@ use crate::{ Integer, StatementResult, }; -use leo_typed::{Expression, Identifier, Span, Statement, Type}; +use leo_core_ast::{Expression, Identifier, Span, Statement, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/return_/return_.rs b/compiler/src/statement/return_/return_.rs index 4c1cb083c6..85f7e6caaf 100644 --- a/compiler/src/statement/return_/return_.rs +++ b/compiler/src/statement/return_/return_.rs @@ -17,7 +17,7 @@ //! Enforces a return statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Expression, Span, Type}; +use leo_core_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/statement.rs b/compiler/src/statement/statement.rs index 8ceffe9e7f..1c23bee4dd 100644 --- a/compiler/src/statement/statement.rs +++ b/compiler/src/statement/statement.rs @@ -17,7 +17,7 @@ //! Enforces a statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_typed::{Statement, Type}; +use leo_core_ast::{Statement, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/value/address/address.rs b/compiler/src/value/address/address.rs index e385138402..3bbdda41cd 100644 --- a/compiler/src/value/address/address.rs +++ b/compiler/src/value/address/address.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::AddressError, ConstrainedValue, GroupType}; -use leo_typed::{InputValue, Span}; +use leo_core_ast::{InputValue, Span}; use snarkos_dpc::base_dpc::instantiated::Components; use snarkos_errors::gadgets::SynthesisError; diff --git a/compiler/src/value/boolean/input.rs b/compiler/src/value/boolean/input.rs index 9b712b95d6..25a9b915f2 100644 --- a/compiler/src/value/boolean/input.rs +++ b/compiler/src/value/boolean/input.rs @@ -17,7 +17,7 @@ //! Methods to enforce constraints on input boolean values in a resolved Leo program. use crate::{errors::BooleanError, value::ConstrainedValue, GroupType}; -use leo_typed::{InputValue, Span}; +use leo_core_ast::{InputValue, Span}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/value/field/field_type.rs b/compiler/src/value/field/field_type.rs index c22bed7600..f2423ff0e3 100644 --- a/compiler/src/value/field/field_type.rs +++ b/compiler/src/value/field/field_type.rs @@ -17,7 +17,7 @@ //! A data type that represents a field value use crate::errors::FieldError; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/value/field/input.rs b/compiler/src/value/field/input.rs index 34d14d0f75..6cf4339192 100644 --- a/compiler/src/value/field/input.rs +++ b/compiler/src/value/field/input.rs @@ -17,7 +17,7 @@ //! Methods to enforce constraints on input field values in a compiled Leo program. use crate::{errors::FieldError, value::ConstrainedValue, FieldType, GroupType}; -use leo_typed::{InputValue, Span}; +use leo_core_ast::{InputValue, Span}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/value/group/group_type.rs b/compiler/src/value/group/group_type.rs index 3dc2a0250d..3521abecee 100644 --- a/compiler/src/value/group/group_type.rs +++ b/compiler/src/value/group/group_type.rs @@ -17,7 +17,7 @@ //! A data type that represents members in the group formed by the set of affine points on a curve. use crate::errors::GroupError; -use leo_typed::{GroupValue, Span}; +use leo_core_ast::{GroupValue, Span}; use snarkos_models::{ curves::{Field, One}, diff --git a/compiler/src/value/group/input.rs b/compiler/src/value/group/input.rs index 293ffd92a0..a4cdae715c 100644 --- a/compiler/src/value/group/input.rs +++ b/compiler/src/value/group/input.rs @@ -17,7 +17,7 @@ //! Methods to enforce constraints on input group values in a Leo program. use crate::{errors::GroupError, ConstrainedValue, GroupType}; -use leo_typed::{GroupValue, InputValue, Span}; +use leo_core_ast::{GroupValue, InputValue, Span}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/value/group/targets/edwards_bls12.rs b/compiler/src/value/group/targets/edwards_bls12.rs index c146e04564..66cbc8cae3 100644 --- a/compiler/src/value/group/targets/edwards_bls12.rs +++ b/compiler/src/value/group/targets/edwards_bls12.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::GroupError, GroupType}; -use leo_typed::{GroupCoordinate, GroupTuple, GroupValue, Span}; +use leo_core_ast::{GroupCoordinate, GroupTuple, GroupValue, Span}; use snarkos_curves::{ edwards_bls12::{EdwardsAffine, EdwardsParameters, Fq}, diff --git a/compiler/src/value/implicit/implicit.rs b/compiler/src/value/implicit/implicit.rs index 27b6cb76c6..b838a4a689 100644 --- a/compiler/src/value/implicit/implicit.rs +++ b/compiler/src/value/implicit/implicit.rs @@ -17,7 +17,7 @@ //! Enforces constraints on an implicit number in a compiled Leo program. use crate::{errors::ValueError, value::ConstrainedValue, GroupType}; -use leo_typed::{Span, Type}; +use leo_core_ast::{Span, Type}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/value/integer/integer.rs b/compiler/src/value/integer/integer.rs index 0384248624..f859caf69a 100644 --- a/compiler/src/value/integer/integer.rs +++ b/compiler/src/value/integer/integer.rs @@ -16,12 +16,12 @@ //! Conversion of integer declarations to constraints in Leo. use crate::{errors::IntegerError, IntegerTrait}; +use leo_core_ast::{InputValue, IntegerType, Span}; use leo_gadgets::{ arithmetic::*, bits::comparator::{ComparatorGadget, EvaluateLtGadget}, signed_integer::*, }; -use leo_typed::{InputValue, IntegerType, Span}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/value/value.rs b/compiler/src/value/value.rs index de2d80f524..cf194e1460 100644 --- a/compiler/src/value/value.rs +++ b/compiler/src/value/value.rs @@ -27,7 +27,7 @@ use crate::{ Integer, }; use leo_core::Value; -use leo_typed::{Circuit, Function, GroupValue, Identifier, Span, Type}; +use leo_core_ast::{Circuit, Function, GroupValue, Identifier, Span, Type}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/tests/address/mod.rs b/compiler/tests/address/mod.rs index c3c2167cd4..fac98eb643 100644 --- a/compiler/tests/address/mod.rs +++ b/compiler/tests/address/mod.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program}; -use leo_typed::InputValue; +use leo_core_ast::InputValue; static TEST_ADDRESS_1: &str = "aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8"; static TEST_ADDRESS_2: &str = "aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r"; diff --git a/compiler/tests/console/mod.rs b/compiler/tests/console/mod.rs index 2716f815a5..73f0b41fe6 100644 --- a/compiler/tests/console/mod.rs +++ b/compiler/tests/console/mod.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program}; -use leo_typed::InputValue; +use leo_core_ast::InputValue; #[test] fn test_log() { diff --git a/compiler/tests/core/packages/unstable/blake2s/mod.rs b/compiler/tests/core/packages/unstable/blake2s/mod.rs index 83ec7d15a1..3d367dcf89 100644 --- a/compiler/tests/core/packages/unstable/blake2s/mod.rs +++ b/compiler/tests/core/packages/unstable/blake2s/mod.rs @@ -23,8 +23,8 @@ use crate::{ parse_program_with_input, }; +use leo_core_ast::InputValue; use leo_input::types::{IntegerType, U8Type, UnsignedIntegerType}; -use leo_typed::InputValue; use rand::{Rng, SeedableRng}; use rand_xorshift::XorShiftRng; use snarkos_algorithms::prf::blake2s::Blake2s as B2SPRF; diff --git a/compiler/tests/field/mod.rs b/compiler/tests/field/mod.rs index a57817b2f7..706c5bd70d 100644 --- a/compiler/tests/field/mod.rs +++ b/compiler/tests/field/mod.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program}; -use leo_typed::InputValue; +use leo_core_ast::InputValue; use snarkos_curves::edwards_bls12::Fq; use snarkos_utilities::bytes::ToBytes; diff --git a/compiler/tests/group/mod.rs b/compiler/tests/group/mod.rs index 7606a738d3..901597806f 100644 --- a/compiler/tests/group/mod.rs +++ b/compiler/tests/group/mod.rs @@ -15,15 +15,10 @@ // along with the Leo library. If not, see . use crate::{ - assert_satisfied, - expect_compiler_error, - expect_synthesis_error, - field::field_to_decimal_string, - generate_main_input, - parse_program, - parse_program_with_input, + assert_satisfied, expect_compiler_error, expect_synthesis_error, field::field_to_decimal_string, + generate_main_input, parse_program, parse_program_with_input, }; -use leo_typed::{GroupCoordinate, GroupTuple, GroupValue, InputValue, Span}; +use leo_core_ast::{GroupCoordinate, GroupTuple, GroupValue, InputValue, Span}; use snarkos_curves::edwards_bls12::EdwardsAffine; diff --git a/compiler/tests/integers/i128/mod.rs b/compiler/tests/integers/i128/mod.rs index 9139cd5ec4..8f4023a99a 100644 --- a/compiler/tests/integers/i128/mod.rs +++ b/compiler/tests/integers/i128/mod.rs @@ -21,8 +21,8 @@ use crate::{ integers::{expect_computation_error, expect_parsing_error, IntegerTester}, parse_program, }; +use leo_core_ast::InputValue; use leo_input::types::{I128Type, IntegerType, SignedIntegerType}; -use leo_typed::InputValue; test_int!( TestI128, diff --git a/compiler/tests/integers/i16/mod.rs b/compiler/tests/integers/i16/mod.rs index 9348352276..73519f487a 100644 --- a/compiler/tests/integers/i16/mod.rs +++ b/compiler/tests/integers/i16/mod.rs @@ -21,8 +21,8 @@ use crate::{ integers::{expect_computation_error, expect_parsing_error, IntegerTester}, parse_program, }; +use leo_core_ast::InputValue; use leo_input::types::{I16Type, IntegerType, SignedIntegerType}; -use leo_typed::InputValue; test_int!( TestI16, diff --git a/compiler/tests/integers/i32/mod.rs b/compiler/tests/integers/i32/mod.rs index 73e4e4a2f5..6c18449559 100644 --- a/compiler/tests/integers/i32/mod.rs +++ b/compiler/tests/integers/i32/mod.rs @@ -21,8 +21,8 @@ use crate::{ integers::{expect_computation_error, expect_parsing_error, IntegerTester}, parse_program, }; +use leo_core_ast::InputValue; use leo_input::types::{I32Type, IntegerType, SignedIntegerType}; -use leo_typed::InputValue; test_int!( TestI32, diff --git a/compiler/tests/integers/i64/mod.rs b/compiler/tests/integers/i64/mod.rs index 218842b3ad..1d61ef1bca 100644 --- a/compiler/tests/integers/i64/mod.rs +++ b/compiler/tests/integers/i64/mod.rs @@ -21,8 +21,8 @@ use crate::{ integers::{expect_computation_error, expect_parsing_error, IntegerTester}, parse_program, }; +use leo_core_ast::InputValue; use leo_input::types::{I64Type, IntegerType, SignedIntegerType}; -use leo_typed::InputValue; test_int!( TestI64, diff --git a/compiler/tests/integers/i8/mod.rs b/compiler/tests/integers/i8/mod.rs index a17896c05d..6a8f535b72 100644 --- a/compiler/tests/integers/i8/mod.rs +++ b/compiler/tests/integers/i8/mod.rs @@ -21,8 +21,8 @@ use crate::{ integers::{expect_computation_error, expect_parsing_error, IntegerTester}, parse_program, }; +use leo_core_ast::InputValue; use leo_input::types::{I8Type, IntegerType, SignedIntegerType}; -use leo_typed::InputValue; test_int!( TestI8, diff --git a/compiler/tests/integers/u128/mod.rs b/compiler/tests/integers/u128/mod.rs index e5fd5f2d44..84e72e27c7 100644 --- a/compiler/tests/integers/u128/mod.rs +++ b/compiler/tests/integers/u128/mod.rs @@ -21,8 +21,8 @@ use crate::{ integers::{expect_parsing_error, IntegerTester}, parse_program, }; +use leo_core_ast::InputValue; use leo_input::types::{IntegerType, U128Type, UnsignedIntegerType}; -use leo_typed::InputValue; test_uint!( TestU128, diff --git a/compiler/tests/integers/u16/mod.rs b/compiler/tests/integers/u16/mod.rs index 1c2c45889b..c6a3388505 100644 --- a/compiler/tests/integers/u16/mod.rs +++ b/compiler/tests/integers/u16/mod.rs @@ -21,8 +21,8 @@ use crate::{ integers::{expect_parsing_error, IntegerTester}, parse_program, }; +use leo_core_ast::InputValue; use leo_input::types::{IntegerType, U16Type, UnsignedIntegerType}; -use leo_typed::InputValue; test_uint!( TestU16, diff --git a/compiler/tests/integers/u32/mod.rs b/compiler/tests/integers/u32/mod.rs index 3ffb792f4d..fc4cd16eb8 100644 --- a/compiler/tests/integers/u32/mod.rs +++ b/compiler/tests/integers/u32/mod.rs @@ -21,8 +21,8 @@ use crate::{ integers::{expect_parsing_error, IntegerTester}, parse_program, }; +use leo_core_ast::InputValue; use leo_input::types::{IntegerType, U32Type, UnsignedIntegerType}; -use leo_typed::InputValue; test_uint!( TestU32, diff --git a/compiler/tests/integers/u64/mod.rs b/compiler/tests/integers/u64/mod.rs index 06fad4baa3..bd18a0fd09 100644 --- a/compiler/tests/integers/u64/mod.rs +++ b/compiler/tests/integers/u64/mod.rs @@ -21,8 +21,8 @@ use crate::{ integers::{expect_parsing_error, IntegerTester}, parse_program, }; +use leo_core_ast::InputValue; use leo_input::types::{IntegerType, U64Type, UnsignedIntegerType}; -use leo_typed::InputValue; test_uint!( TestU64, diff --git a/compiler/tests/integers/u8/mod.rs b/compiler/tests/integers/u8/mod.rs index 335e4146ff..f9d6a5e1bb 100644 --- a/compiler/tests/integers/u8/mod.rs +++ b/compiler/tests/integers/u8/mod.rs @@ -21,8 +21,8 @@ use crate::{ integers::{expect_parsing_error, IntegerTester}, parse_program, }; +use leo_core_ast::InputValue; use leo_input::types::{IntegerType, U8Type, UnsignedIntegerType}; -use leo_typed::InputValue; test_uint!( TestU8, diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index e34d048dbb..1d9bbc69c2 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -42,8 +42,8 @@ use leo_compiler::{ ConstrainedValue, OutputBytes, }; +use leo_core_ast::{InputValue, MainInput}; use leo_input::types::{IntegerType, U32Type, UnsignedIntegerType}; -use leo_typed::{InputValue, MainInput}; use snarkos_curves::edwards_bls12::Fq; use snarkos_models::gadgets::r1cs::TestConstraintSystem; diff --git a/compiler/tests/mutability/mod.rs b/compiler/tests/mutability/mod.rs index c36cd10b14..60b3d31ec8 100644 --- a/compiler/tests/mutability/mod.rs +++ b/compiler/tests/mutability/mod.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{assert_satisfied, expect_compiler_error, expect_dynamic_check_error, generate_main_input, parse_program}; -use leo_typed::InputValue; +use leo_core_ast::InputValue; #[test] fn test_let() { diff --git a/compiler/tests/statements/conditional/mod.rs b/compiler/tests/statements/conditional/mod.rs index 9b6ae2fe2b..d6b5ab8c14 100644 --- a/compiler/tests/statements/conditional/mod.rs +++ b/compiler/tests/statements/conditional/mod.rs @@ -24,7 +24,7 @@ use crate::{ parse_program_with_input, EdwardsTestCompiler, }; -use leo_typed::InputValue; +use leo_core_ast::InputValue; #[test] fn test_assert() { diff --git a/compiler/tests/statements/mod.rs b/compiler/tests/statements/mod.rs index cb6efc3552..b3322ce785 100644 --- a/compiler/tests/statements/mod.rs +++ b/compiler/tests/statements/mod.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{assert_satisfied, expect_dynamic_check_error, generate_main_input, parse_program}; -use leo_typed::InputValue; +use leo_core_ast::InputValue; pub mod conditional; diff --git a/typed/Cargo.toml b/core-ast/Cargo.toml similarity index 86% rename from typed/Cargo.toml rename to core-ast/Cargo.toml index 7836002d6f..9da4243a77 100644 --- a/typed/Cargo.toml +++ b/core-ast/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "leo-typed" +name = "leo-core-ast" version = "1.0.3" authors = [ "The Aleo Team " ] -description = "Typed AST of the Leo programming language" +description = "Core AST of the Leo programming language" homepage = "https://aleo.org" repository = "https://github.com/AleoHQ/leo" keywords = [ @@ -18,12 +18,12 @@ license = "GPL-3.0" edition = "2018" [[bin]] -name = "leo_typed_ast" +name = "leo_core_ast" path = "src/main.rs" [[bench]] -name = "typed_ast" -path = "benches/typed_ast.rs" +name = "core_ast" +path = "benches/core_ast.rs" harness = false [dependencies.leo-ast] diff --git a/typed/benches/big_circuit.leo b/core-ast/benches/big_circuit.leo similarity index 100% rename from typed/benches/big_circuit.leo rename to core-ast/benches/big_circuit.leo diff --git a/typed/benches/big_if_else.leo b/core-ast/benches/big_if_else.leo similarity index 100% rename from typed/benches/big_if_else.leo rename to core-ast/benches/big_if_else.leo diff --git a/typed/benches/big_ternary.leo b/core-ast/benches/big_ternary.leo similarity index 100% rename from typed/benches/big_ternary.leo rename to core-ast/benches/big_ternary.leo diff --git a/typed/benches/typed_ast.rs b/core-ast/benches/core_ast.rs similarity index 99% rename from typed/benches/typed_ast.rs rename to core-ast/benches/core_ast.rs index d7f473f14a..9b9d0cfb32 100644 --- a/typed/benches/typed_ast.rs +++ b/core-ast/benches/core_ast.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use leo_ast::LeoAst; -use leo_typed::LeoCoreAst; +use leo_core_ast::LeoCoreAst; use criterion::{criterion_group, criterion_main, Criterion}; use std::{path::Path, time::Duration}; diff --git a/typed/benches/long_array.leo b/core-ast/benches/long_array.leo similarity index 100% rename from typed/benches/long_array.leo rename to core-ast/benches/long_array.leo diff --git a/typed/benches/long_expr.leo b/core-ast/benches/long_expr.leo similarity index 100% rename from typed/benches/long_expr.leo rename to core-ast/benches/long_expr.leo diff --git a/typed/benches/many_assigns.leo b/core-ast/benches/many_assigns.leo similarity index 100% rename from typed/benches/many_assigns.leo rename to core-ast/benches/many_assigns.leo diff --git a/typed/benches/many_foos.leo b/core-ast/benches/many_foos.leo similarity index 100% rename from typed/benches/many_foos.leo rename to core-ast/benches/many_foos.leo diff --git a/typed/src/annotation.rs b/core-ast/src/annotation.rs similarity index 100% rename from typed/src/annotation.rs rename to core-ast/src/annotation.rs diff --git a/typed/src/circuits/circuit.rs b/core-ast/src/circuits/circuit.rs similarity index 100% rename from typed/src/circuits/circuit.rs rename to core-ast/src/circuits/circuit.rs diff --git a/typed/src/circuits/circuit_member.rs b/core-ast/src/circuits/circuit_member.rs similarity index 100% rename from typed/src/circuits/circuit_member.rs rename to core-ast/src/circuits/circuit_member.rs diff --git a/typed/src/circuits/circuit_variable_definition.rs b/core-ast/src/circuits/circuit_variable_definition.rs similarity index 100% rename from typed/src/circuits/circuit_variable_definition.rs rename to core-ast/src/circuits/circuit_variable_definition.rs diff --git a/typed/src/circuits/mod.rs b/core-ast/src/circuits/mod.rs similarity index 100% rename from typed/src/circuits/mod.rs rename to core-ast/src/circuits/mod.rs diff --git a/typed/src/common/assignee.rs b/core-ast/src/common/assignee.rs similarity index 100% rename from typed/src/common/assignee.rs rename to core-ast/src/common/assignee.rs diff --git a/typed/src/common/declare.rs b/core-ast/src/common/declare.rs similarity index 100% rename from typed/src/common/declare.rs rename to core-ast/src/common/declare.rs diff --git a/typed/src/common/identifier.rs b/core-ast/src/common/identifier.rs similarity index 100% rename from typed/src/common/identifier.rs rename to core-ast/src/common/identifier.rs diff --git a/typed/src/common/mod.rs b/core-ast/src/common/mod.rs similarity index 100% rename from typed/src/common/mod.rs rename to core-ast/src/common/mod.rs diff --git a/typed/src/common/range_or_expression.rs b/core-ast/src/common/range_or_expression.rs similarity index 100% rename from typed/src/common/range_or_expression.rs rename to core-ast/src/common/range_or_expression.rs diff --git a/typed/src/common/span.rs b/core-ast/src/common/span.rs similarity index 100% rename from typed/src/common/span.rs rename to core-ast/src/common/span.rs diff --git a/typed/src/common/spread_or_expression.rs b/core-ast/src/common/spread_or_expression.rs similarity index 100% rename from typed/src/common/spread_or_expression.rs rename to core-ast/src/common/spread_or_expression.rs diff --git a/typed/src/common/variable_name.rs b/core-ast/src/common/variable_name.rs similarity index 100% rename from typed/src/common/variable_name.rs rename to core-ast/src/common/variable_name.rs diff --git a/typed/src/common/variables.rs b/core-ast/src/common/variables.rs similarity index 100% rename from typed/src/common/variables.rs rename to core-ast/src/common/variables.rs diff --git a/typed/src/console/console_function.rs b/core-ast/src/console/console_function.rs similarity index 100% rename from typed/src/console/console_function.rs rename to core-ast/src/console/console_function.rs diff --git a/typed/src/console/console_function_call.rs b/core-ast/src/console/console_function_call.rs similarity index 100% rename from typed/src/console/console_function_call.rs rename to core-ast/src/console/console_function_call.rs diff --git a/typed/src/console/formatted_container.rs b/core-ast/src/console/formatted_container.rs similarity index 100% rename from typed/src/console/formatted_container.rs rename to core-ast/src/console/formatted_container.rs diff --git a/typed/src/console/formatted_parameter.rs b/core-ast/src/console/formatted_parameter.rs similarity index 100% rename from typed/src/console/formatted_parameter.rs rename to core-ast/src/console/formatted_parameter.rs diff --git a/typed/src/console/formatted_string.rs b/core-ast/src/console/formatted_string.rs similarity index 100% rename from typed/src/console/formatted_string.rs rename to core-ast/src/console/formatted_string.rs diff --git a/typed/src/console/mod.rs b/core-ast/src/console/mod.rs similarity index 100% rename from typed/src/console/mod.rs rename to core-ast/src/console/mod.rs diff --git a/typed/src/errors/error.rs b/core-ast/src/errors/error.rs similarity index 100% rename from typed/src/errors/error.rs rename to core-ast/src/errors/error.rs diff --git a/typed/src/errors/mod.rs b/core-ast/src/errors/mod.rs similarity index 100% rename from typed/src/errors/mod.rs rename to core-ast/src/errors/mod.rs diff --git a/typed/src/expression.rs b/core-ast/src/expression.rs similarity index 100% rename from typed/src/expression.rs rename to core-ast/src/expression.rs diff --git a/typed/src/functions/function.rs b/core-ast/src/functions/function.rs similarity index 100% rename from typed/src/functions/function.rs rename to core-ast/src/functions/function.rs diff --git a/typed/src/functions/input/function_input.rs b/core-ast/src/functions/input/function_input.rs similarity index 100% rename from typed/src/functions/input/function_input.rs rename to core-ast/src/functions/input/function_input.rs diff --git a/typed/src/functions/input/input_variable.rs b/core-ast/src/functions/input/input_variable.rs similarity index 100% rename from typed/src/functions/input/input_variable.rs rename to core-ast/src/functions/input/input_variable.rs diff --git a/typed/src/functions/input/mod.rs b/core-ast/src/functions/input/mod.rs similarity index 100% rename from typed/src/functions/input/mod.rs rename to core-ast/src/functions/input/mod.rs diff --git a/typed/src/functions/mod.rs b/core-ast/src/functions/mod.rs similarity index 100% rename from typed/src/functions/mod.rs rename to core-ast/src/functions/mod.rs diff --git a/typed/src/functions/test_function.rs b/core-ast/src/functions/test_function.rs similarity index 100% rename from typed/src/functions/test_function.rs rename to core-ast/src/functions/test_function.rs diff --git a/typed/src/groups/group_coordinate.rs b/core-ast/src/groups/group_coordinate.rs similarity index 100% rename from typed/src/groups/group_coordinate.rs rename to core-ast/src/groups/group_coordinate.rs diff --git a/typed/src/groups/group_value.rs b/core-ast/src/groups/group_value.rs similarity index 100% rename from typed/src/groups/group_value.rs rename to core-ast/src/groups/group_value.rs diff --git a/typed/src/groups/mod.rs b/core-ast/src/groups/mod.rs similarity index 100% rename from typed/src/groups/mod.rs rename to core-ast/src/groups/mod.rs diff --git a/typed/src/imports/import.rs b/core-ast/src/imports/import.rs similarity index 100% rename from typed/src/imports/import.rs rename to core-ast/src/imports/import.rs diff --git a/typed/src/imports/import_symbol.rs b/core-ast/src/imports/import_symbol.rs similarity index 100% rename from typed/src/imports/import_symbol.rs rename to core-ast/src/imports/import_symbol.rs diff --git a/typed/src/imports/mod.rs b/core-ast/src/imports/mod.rs similarity index 100% rename from typed/src/imports/mod.rs rename to core-ast/src/imports/mod.rs diff --git a/typed/src/imports/package.rs b/core-ast/src/imports/package.rs similarity index 100% rename from typed/src/imports/package.rs rename to core-ast/src/imports/package.rs diff --git a/typed/src/imports/package_access.rs b/core-ast/src/imports/package_access.rs similarity index 100% rename from typed/src/imports/package_access.rs rename to core-ast/src/imports/package_access.rs diff --git a/typed/src/input/input.rs b/core-ast/src/input/input.rs similarity index 100% rename from typed/src/input/input.rs rename to core-ast/src/input/input.rs diff --git a/typed/src/input/input_value.rs b/core-ast/src/input/input_value.rs similarity index 100% rename from typed/src/input/input_value.rs rename to core-ast/src/input/input_value.rs diff --git a/typed/src/input/macros.rs b/core-ast/src/input/macros.rs similarity index 100% rename from typed/src/input/macros.rs rename to core-ast/src/input/macros.rs diff --git a/typed/src/input/mod.rs b/core-ast/src/input/mod.rs similarity index 100% rename from typed/src/input/mod.rs rename to core-ast/src/input/mod.rs diff --git a/typed/src/input/parameters/mod.rs b/core-ast/src/input/parameters/mod.rs similarity index 100% rename from typed/src/input/parameters/mod.rs rename to core-ast/src/input/parameters/mod.rs diff --git a/typed/src/input/parameters/parameter.rs b/core-ast/src/input/parameters/parameter.rs similarity index 100% rename from typed/src/input/parameters/parameter.rs rename to core-ast/src/input/parameters/parameter.rs diff --git a/typed/src/input/program_input/main_input.rs b/core-ast/src/input/program_input/main_input.rs similarity index 100% rename from typed/src/input/program_input/main_input.rs rename to core-ast/src/input/program_input/main_input.rs diff --git a/typed/src/input/program_input/mod.rs b/core-ast/src/input/program_input/mod.rs similarity index 100% rename from typed/src/input/program_input/mod.rs rename to core-ast/src/input/program_input/mod.rs diff --git a/typed/src/input/program_input/program_input.rs b/core-ast/src/input/program_input/program_input.rs similarity index 100% rename from typed/src/input/program_input/program_input.rs rename to core-ast/src/input/program_input/program_input.rs diff --git a/typed/src/input/program_input/registers.rs b/core-ast/src/input/program_input/registers.rs similarity index 100% rename from typed/src/input/program_input/registers.rs rename to core-ast/src/input/program_input/registers.rs diff --git a/typed/src/input/program_state/mod.rs b/core-ast/src/input/program_state/mod.rs similarity index 100% rename from typed/src/input/program_state/mod.rs rename to core-ast/src/input/program_state/mod.rs diff --git a/typed/src/input/program_state/private_state/mod.rs b/core-ast/src/input/program_state/private_state/mod.rs similarity index 100% rename from typed/src/input/program_state/private_state/mod.rs rename to core-ast/src/input/program_state/private_state/mod.rs diff --git a/typed/src/input/program_state/private_state/private_state.rs b/core-ast/src/input/program_state/private_state/private_state.rs similarity index 100% rename from typed/src/input/program_state/private_state/private_state.rs rename to core-ast/src/input/program_state/private_state/private_state.rs diff --git a/typed/src/input/program_state/private_state/record.rs b/core-ast/src/input/program_state/private_state/record.rs similarity index 100% rename from typed/src/input/program_state/private_state/record.rs rename to core-ast/src/input/program_state/private_state/record.rs diff --git a/typed/src/input/program_state/private_state/state_leaf.rs b/core-ast/src/input/program_state/private_state/state_leaf.rs similarity index 100% rename from typed/src/input/program_state/private_state/state_leaf.rs rename to core-ast/src/input/program_state/private_state/state_leaf.rs diff --git a/typed/src/input/program_state/program_state.rs b/core-ast/src/input/program_state/program_state.rs similarity index 100% rename from typed/src/input/program_state/program_state.rs rename to core-ast/src/input/program_state/program_state.rs diff --git a/typed/src/input/program_state/public_state/mod.rs b/core-ast/src/input/program_state/public_state/mod.rs similarity index 100% rename from typed/src/input/program_state/public_state/mod.rs rename to core-ast/src/input/program_state/public_state/mod.rs diff --git a/typed/src/input/program_state/public_state/public_state.rs b/core-ast/src/input/program_state/public_state/public_state.rs similarity index 100% rename from typed/src/input/program_state/public_state/public_state.rs rename to core-ast/src/input/program_state/public_state/public_state.rs diff --git a/typed/src/input/program_state/public_state/state.rs b/core-ast/src/input/program_state/public_state/state.rs similarity index 100% rename from typed/src/input/program_state/public_state/state.rs rename to core-ast/src/input/program_state/public_state/state.rs diff --git a/typed/src/lib.rs b/core-ast/src/lib.rs similarity index 100% rename from typed/src/lib.rs rename to core-ast/src/lib.rs diff --git a/typed/src/main.rs b/core-ast/src/main.rs similarity index 92% rename from typed/src/main.rs rename to core-ast/src/main.rs index 34005aa110..31d5c244b9 100644 --- a/typed/src/main.rs +++ b/core-ast/src/main.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use leo_ast::{LeoAst, ParserError}; -use leo_typed::LeoCoreAst; +use leo_core_ast::LeoCoreAst; use std::{env, fs, path::Path}; fn to_leo_core_tree(filepath: &Path) -> Result { @@ -27,7 +27,7 @@ fn to_leo_core_tree(filepath: &Path) -> Result { let ast = LeoAst::new(&program_filepath, &program_string)?; // Parse the abstract core tree and constructs a typed core tree. - let typed_ast = LeoCoreAst::new("leo_typed_tree", &ast); + let typed_ast = LeoCoreAst::new("leo_core_tree", &ast); // Serializes the typed core tree into JSON format. let serialized_typed_tree = LeoCoreAst::to_json_string(&typed_ast)?; @@ -43,7 +43,7 @@ fn main() -> Result<(), ParserError> { if cli_arguments.len() < 2 || cli_arguments.len() > 3 { eprintln!("Warning - an invalid number of command-line arguments were provided."); println!( - "\nCommand-line usage:\n\n\tleo_typed_ast {{PATH/TO/INPUT_FILENAME}}.leo {{PATH/TO/OUTPUT_DIRECTORY (optional)}}\n" + "\nCommand-line usage:\n\n\tleo_core_ast {{PATH/TO/INPUT_FILENAME}}.leo {{PATH/TO/OUTPUT_DIRECTORY (optional)}}\n" ); return Ok(()); // Exit innocently } diff --git a/typed/src/program.rs b/core-ast/src/program.rs similarity index 100% rename from typed/src/program.rs rename to core-ast/src/program.rs diff --git a/typed/src/statements/conditional_nested_or_end_statement.rs b/core-ast/src/statements/conditional_nested_or_end_statement.rs similarity index 100% rename from typed/src/statements/conditional_nested_or_end_statement.rs rename to core-ast/src/statements/conditional_nested_or_end_statement.rs diff --git a/typed/src/statements/conditional_statement.rs b/core-ast/src/statements/conditional_statement.rs similarity index 100% rename from typed/src/statements/conditional_statement.rs rename to core-ast/src/statements/conditional_statement.rs diff --git a/typed/src/statements/mod.rs b/core-ast/src/statements/mod.rs similarity index 100% rename from typed/src/statements/mod.rs rename to core-ast/src/statements/mod.rs diff --git a/typed/src/statements/statement.rs b/core-ast/src/statements/statement.rs similarity index 100% rename from typed/src/statements/statement.rs rename to core-ast/src/statements/statement.rs diff --git a/typed/src/types/integer_type.rs b/core-ast/src/types/integer_type.rs similarity index 100% rename from typed/src/types/integer_type.rs rename to core-ast/src/types/integer_type.rs diff --git a/typed/src/types/mod.rs b/core-ast/src/types/mod.rs similarity index 100% rename from typed/src/types/mod.rs rename to core-ast/src/types/mod.rs diff --git a/typed/src/types/type_.rs b/core-ast/src/types/type_.rs similarity index 100% rename from typed/src/types/type_.rs rename to core-ast/src/types/type_.rs diff --git a/typed/tests/mod.rs b/core-ast/tests/mod.rs similarity index 100% rename from typed/tests/mod.rs rename to core-ast/tests/mod.rs diff --git a/typed/tests/serialization/expected_typed_ast.json b/core-ast/tests/serialization/expected_typed_ast.json similarity index 98% rename from typed/tests/serialization/expected_typed_ast.json rename to core-ast/tests/serialization/expected_typed_ast.json index f12100d78d..8d3060e20f 100644 --- a/typed/tests/serialization/expected_typed_ast.json +++ b/core-ast/tests/serialization/expected_typed_ast.json @@ -1,5 +1,5 @@ { - "name": "leo_typed_tree", + "name": "leo_core_tree", "expected_input": [], "imports": [], "circuits": {}, diff --git a/typed/tests/serialization/json.rs b/core-ast/tests/serialization/json.rs similarity index 97% rename from typed/tests/serialization/json.rs rename to core-ast/tests/serialization/json.rs index ac83828675..6ee4c62a54 100644 --- a/typed/tests/serialization/json.rs +++ b/core-ast/tests/serialization/json.rs @@ -15,9 +15,9 @@ // along with the Leo library. If not, see . use leo_ast::LeoAst; -use leo_typed::LeoCoreAst; +use leo_core_ast::LeoCoreAst; #[cfg(not(feature = "ci_skip"))] -use leo_typed::Program; +use leo_core_ast::Program; use std::path::{Path, PathBuf}; @@ -29,7 +29,7 @@ fn to_typed_ast(program_filepath: &Path) -> LeoCoreAst { let ast = LeoAst::new(&program_filepath, &program_string).unwrap(); // Parse the abstract syntax tree and constructs a typed syntax tree. - LeoCoreAst::new("leo_typed_tree", &ast) + LeoCoreAst::new("leo_core_tree", &ast) } #[test] diff --git a/typed/tests/serialization/main.leo b/core-ast/tests/serialization/main.leo similarity index 100% rename from typed/tests/serialization/main.leo rename to core-ast/tests/serialization/main.leo diff --git a/typed/tests/serialization/mod.rs b/core-ast/tests/serialization/mod.rs similarity index 100% rename from typed/tests/serialization/mod.rs rename to core-ast/tests/serialization/mod.rs diff --git a/core/Cargo.toml b/core/Cargo.toml index aa59743d09..98ba2197e5 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -21,8 +21,8 @@ edition = "2018" path = "../gadgets" version = "1.0.3" -[dependencies.leo-typed] -path = "../typed" +[dependencies.leo-core-ast] +path = "../core-ast" version = "1.0.3" [dependencies.snarkos-errors] diff --git a/core/src/errors/core_circuit.rs b/core/src/errors/core_circuit.rs index 408d9617df..5b2e81c70f 100644 --- a/core/src/errors/core_circuit.rs +++ b/core/src/errors/core_circuit.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Value; -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use snarkos_errors::gadgets::SynthesisError; diff --git a/core/src/errors/core_package.rs b/core/src/errors/core_package.rs index 2a285abfb7..6c8726b906 100644 --- a/core/src/errors/core_package.rs +++ b/core/src/errors/core_package.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/core/src/errors/core_package_list.rs b/core/src/errors/core_package_list.rs index cc23101924..57e4b292e7 100644 --- a/core/src/errors/core_package_list.rs +++ b/core/src/errors/core_package_list.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::{Error as FormattedError, ImportSymbol, Span}; +use leo_core_ast::{Error as FormattedError, ImportSymbol, Span}; use crate::CorePackageError; use std::path::Path; diff --git a/core/src/errors/leo_core.rs b/core/src/errors/leo_core.rs index 1c59ed9bc8..e5d42bf283 100644 --- a/core/src/errors/leo_core.rs +++ b/core/src/errors/leo_core.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CoreCircuitError, CorePackageListError}; -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/core/src/lib.rs b/core/src/lib.rs index 73317cc472..810ab32d47 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -27,7 +27,7 @@ pub mod types; pub use self::types::*; use crate::CoreCircuit; -use leo_typed::Span; +use leo_core_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::ConstraintSystem, diff --git a/core/src/packages/unstable/blake2s.rs b/core/src/packages/unstable/blake2s.rs index a25c0e2739..f9ede1f7e2 100644 --- a/core/src/packages/unstable/blake2s.rs +++ b/core/src/packages/unstable/blake2s.rs @@ -16,7 +16,7 @@ use crate::{CoreCircuit, CoreCircuitError, Value}; -use leo_typed::{ +use leo_core_ast::{ Circuit, CircuitMember, Expression, diff --git a/core/src/types/core_circuit.rs b/core/src/types/core_circuit.rs index e1c3096e71..7d58d6b3c7 100644 --- a/core/src/types/core_circuit.rs +++ b/core/src/types/core_circuit.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CoreCircuitError, Value}; -use leo_typed::{Circuit, Identifier, Span}; +use leo_core_ast::{Circuit, Identifier, Span}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/core/src/types/core_circuit_struct_list.rs b/core/src/types/core_circuit_struct_list.rs index 4a93867bf4..f8dd653ecc 100644 --- a/core/src/types/core_circuit_struct_list.rs +++ b/core/src/types/core_circuit_struct_list.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::Circuit; +use leo_core_ast::Circuit; /// List of imported core circuit structs. /// This struct is created from a `CorePackageList` diff --git a/core/src/types/core_package.rs b/core/src/types/core_package.rs index fa9a4e7a00..9435910765 100644 --- a/core/src/types/core_package.rs +++ b/core/src/types/core_package.rs @@ -20,7 +20,7 @@ use crate::{ CoreCircuitStructList, CorePackageError, }; -use leo_typed::{Identifier, ImportSymbol, Package, PackageAccess}; +use leo_core_ast::{Identifier, ImportSymbol, Package, PackageAccess}; use std::convert::TryFrom; /// A core package dependency to be imported into a Leo program. diff --git a/core/src/types/core_package_list.rs b/core/src/types/core_package_list.rs index 142e9f9089..a70c8f886b 100644 --- a/core/src/types/core_package_list.rs +++ b/core/src/types/core_package_list.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CoreCircuitStructList, CorePackage, CorePackageListError, UNSTABLE_CORE_PACKAGE_KEYWORD}; -use leo_typed::PackageAccess; +use leo_core_ast::PackageAccess; use std::convert::TryFrom; /// A list of core package dependencies. diff --git a/dynamic-check/Cargo.toml b/dynamic-check/Cargo.toml index cd4bf2b8f4..37d1f1313c 100644 --- a/dynamic-check/Cargo.toml +++ b/dynamic-check/Cargo.toml @@ -32,8 +32,8 @@ version = "1.0" path = "../symbol-table" version = "1.0.3" -[dependencies.leo-typed] -path = "../typed" +[dependencies.leo-core-ast] +path = "../core-ast" version = "1.0.3" [dependencies.serde] diff --git a/dynamic-check/src/assertions/type_assertion.rs b/dynamic-check/src/assertions/type_assertion.rs index 030603cb22..fd01a4aaba 100644 --- a/dynamic-check/src/assertions/type_assertion.rs +++ b/dynamic-check/src/assertions/type_assertion.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::{TypeAssertionError, TypeEquality, TypeMembership, TypeVariablePairs}; +use leo_core_ast::Span; use leo_symbol_table::{Type, TypeVariable}; -use leo_typed::Span; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/assertions/type_equality.rs b/dynamic-check/src/assertions/type_equality.rs index d8380ee085..baeddd9ddd 100644 --- a/dynamic-check/src/assertions/type_equality.rs +++ b/dynamic-check/src/assertions/type_equality.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::{TypeAssertionError, TypeVariablePairs}; +use leo_core_ast::Span; use leo_symbol_table::{Type, TypeVariable}; -use leo_typed::Span; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/assertions/type_membership.rs b/dynamic-check/src/assertions/type_membership.rs index b1590a21f2..c31e22ce01 100644 --- a/dynamic-check/src/assertions/type_membership.rs +++ b/dynamic-check/src/assertions/type_membership.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::TypeAssertionError; +use leo_core_ast::Span; use leo_symbol_table::{Type, TypeVariable}; -use leo_typed::Span; use serde::{Deserialize, Serialize}; diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/dynamic-check/src/assertions/type_variable_pair.rs index 446413f435..abde4984fe 100644 --- a/dynamic-check/src/assertions/type_variable_pair.rs +++ b/dynamic-check/src/assertions/type_variable_pair.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::TypeAssertionError; +use leo_core_ast::Span; use leo_symbol_table::{flatten_array_type, Type, TypeVariable}; -use leo_typed::Span; use std::borrow::Cow; /// A type variable -> type pair. diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/dynamic_check.rs index 797084ce49..e5e31596b5 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/dynamic_check.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::{DynamicCheckError, Frame, Scope}; +use leo_core_ast::{Circuit, CircuitMember, Function, Program}; use leo_symbol_table::SymbolTable; -use leo_typed::{Circuit, CircuitMember, Function, Program}; /// Performs a dynamic type inference check over a program. pub struct DynamicCheck { diff --git a/dynamic-check/src/errors/dynamic_check.rs b/dynamic-check/src/errors/dynamic_check.rs index 8d0f29de94..a165a87a8d 100644 --- a/dynamic-check/src/errors/dynamic_check.rs +++ b/dynamic-check/src/errors/dynamic_check.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::FrameError; -use leo_typed::Error as FormattedError; +use leo_core_ast::Error as FormattedError; use std::path::Path; diff --git a/dynamic-check/src/errors/frame.rs b/dynamic-check/src/errors/frame.rs index 14e2914457..59c1bdeb96 100644 --- a/dynamic-check/src/errors/frame.rs +++ b/dynamic-check/src/errors/frame.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::{ScopeError, TypeAssertionError}; +use leo_core_ast::{Error as FormattedError, Expression, Identifier, Span}; use leo_symbol_table::{Type, TypeError}; -use leo_typed::{Error as FormattedError, Expression, Identifier, Span}; use std::path::Path; diff --git a/dynamic-check/src/errors/scope.rs b/dynamic-check/src/errors/scope.rs index 125ad71c9f..1d834a8073 100644 --- a/dynamic-check/src/errors/scope.rs +++ b/dynamic-check/src/errors/scope.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::VariableTableError; -use leo_typed::Error as FormattedError; +use leo_core_ast::Error as FormattedError; use std::path::Path; diff --git a/dynamic-check/src/errors/type_assertion.rs b/dynamic-check/src/errors/type_assertion.rs index eca87557ab..0f55bd22d2 100644 --- a/dynamic-check/src/errors/type_assertion.rs +++ b/dynamic-check/src/errors/type_assertion.rs @@ -16,8 +16,8 @@ use crate::TypeMembership; +use leo_core_ast::{Error as FormattedError, Span}; use leo_symbol_table::Type; -use leo_typed::{Error as FormattedError, Span}; use std::path::Path; diff --git a/dynamic-check/src/errors/variable_table.rs b/dynamic-check/src/errors/variable_table.rs index d89432f0a0..cc359db3f9 100644 --- a/dynamic-check/src/errors/variable_table.rs +++ b/dynamic-check/src/errors/variable_table.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::{Error as FormattedError, Span}; +use leo_core_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index 5ae47b1b44..ea2494f39a 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -15,8 +15,7 @@ // along with the Leo library. If not, see . use crate::{FrameError, Scope, TypeAssertion}; -use leo_symbol_table::{Attribute, CircuitFunctionType, CircuitType, FunctionType, SymbolTable, Type, TypeVariable}; -use leo_typed::{ +use leo_core_ast::{ Assignee, AssigneeAccess, CircuitVariableDefinition, @@ -33,6 +32,7 @@ use leo_typed::{ Statement, Variables, }; +use leo_symbol_table::{Attribute, CircuitFunctionType, CircuitType, FunctionType, SymbolTable, Type, TypeVariable}; /// A vector of `TypeAssertion` predicates created from a function body. #[derive(Clone)] diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index dcb4638f0d..576be6d5e2 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -23,9 +23,9 @@ pub mod variables; use leo_ast::LeoAst; use leo_dynamic_check::DynamicCheck; +use leo_core_ast::{Input, LeoCoreAst, Program}; use leo_imports::ImportParser; use leo_symbol_table::SymbolTable; -use leo_typed::{Input, LeoCoreAst, Program}; use std::path::PathBuf; const TEST_PROGRAM_PATH: &str = ""; diff --git a/imports/Cargo.toml b/imports/Cargo.toml index 6ef01f1426..a72bc81490 100644 --- a/imports/Cargo.toml +++ b/imports/Cargo.toml @@ -21,8 +21,8 @@ edition = "2018" path = "../ast" version = "1.0.3" -[dependencies.leo-typed] -path = "../typed" +[dependencies.leo-core-ast] +path = "../core-ast" version = "1.0.3" [dependencies.thiserror] diff --git a/imports/src/errors/import_parser.rs b/imports/src/errors/import_parser.rs index cb3ea1f4b1..3d745e135b 100644 --- a/imports/src/errors/import_parser.rs +++ b/imports/src/errors/import_parser.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use leo_ast::ParserError; -use leo_typed::{Error as FormattedError, Identifier, Span}; +use leo_core_ast::{Error as FormattedError, Identifier, Span}; use std::{io, path::Path}; diff --git a/imports/src/parser/core_package.rs b/imports/src/parser/core_package.rs index 3173257552..8227bbab7a 100644 --- a/imports/src/parser/core_package.rs +++ b/imports/src/parser/core_package.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::ImportParserError, ImportParser}; -use leo_typed::Package; +use leo_core_ast::Package; pub static CORE_PACKAGE_NAME: &str = "core"; diff --git a/imports/src/parser/import_parser.rs b/imports/src/parser/import_parser.rs index 35540c4d73..f5da49856b 100644 --- a/imports/src/parser/import_parser.rs +++ b/imports/src/parser/import_parser.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::ImportParserError; -use leo_typed::{Package, Program}; +use leo_core_ast::{Package, Program}; use std::{ collections::{HashMap, HashSet}, diff --git a/imports/src/parser/parse_package.rs b/imports/src/parser/parse_package.rs index 53749784e9..5656119d39 100644 --- a/imports/src/parser/parse_package.rs +++ b/imports/src/parser/parse_package.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::ImportParserError, ImportParser, CORE_PACKAGE_NAME}; -use leo_typed::{Package, PackageAccess}; +use leo_core_ast::{Package, PackageAccess}; use std::{fs, fs::DirEntry, path::PathBuf}; diff --git a/imports/src/parser/parse_symbol.rs b/imports/src/parser/parse_symbol.rs index 1b98912b27..f196b77cfe 100644 --- a/imports/src/parser/parse_symbol.rs +++ b/imports/src/parser/parse_symbol.rs @@ -16,7 +16,7 @@ use crate::{errors::ImportParserError, ImportParser}; use leo_ast::LeoAst; -use leo_typed::{ImportSymbol, Program, Span}; +use leo_core_ast::{ImportSymbol, Program, Span}; use std::{ffi::OsString, fs::DirEntry, path::PathBuf}; diff --git a/state/Cargo.toml b/state/Cargo.toml index be7db6f08d..36f172edd9 100644 --- a/state/Cargo.toml +++ b/state/Cargo.toml @@ -21,8 +21,8 @@ edition = "2018" path = "../input" version = "1.0.3" -[dependencies.leo-typed] -path = "../typed" +[dependencies.leo-core-ast] +path = "../core-ast" version = "1.0.3" [dependencies.snarkos-algorithms] diff --git a/state/src/local_data_commitment/local_data_commitment.rs b/state/src/local_data_commitment/local_data_commitment.rs index 6a8f2906b3..0b3d33ee9a 100644 --- a/state/src/local_data_commitment/local_data_commitment.rs +++ b/state/src/local_data_commitment/local_data_commitment.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{verify_record_commitment, LocalDataVerificationError, StateLeafValues, StateValues}; -use leo_typed::Input as TypedInput; +use leo_core_ast::Input as TypedInput; use snarkos_algorithms::commitment_tree::CommitmentMerklePath; use snarkos_dpc::base_dpc::{ diff --git a/state/src/local_data_commitment/state_leaf_values.rs b/state/src/local_data_commitment/state_leaf_values.rs index f7ca617ba4..4f01fad3fd 100644 --- a/state/src/local_data_commitment/state_leaf_values.rs +++ b/state/src/local_data_commitment/state_leaf_values.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{find_input, input_to_integer_string, input_to_u8_vec, StateLeafValuesError}; -use leo_typed::StateLeaf as TypedStateLeaf; +use leo_core_ast::StateLeaf as TypedStateLeaf; use std::convert::TryFrom; diff --git a/state/src/local_data_commitment/state_values.rs b/state/src/local_data_commitment/state_values.rs index 7fbba3dd6e..7dcdc9c783 100644 --- a/state/src/local_data_commitment/state_values.rs +++ b/state/src/local_data_commitment/state_values.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{find_input, input_to_integer_string, input_to_u8_vec, StateValuesError}; -use leo_typed::State as TypedState; +use leo_core_ast::State as TypedState; use std::convert::TryFrom; diff --git a/state/src/record_commitment/dpc_record_values.rs b/state/src/record_commitment/dpc_record_values.rs index 4137267d40..1b61660f60 100644 --- a/state/src/record_commitment/dpc_record_values.rs +++ b/state/src/record_commitment/dpc_record_values.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{utilities::*, DPCRecordValuesError}; -use leo_typed::Record as TypedRecord; +use leo_core_ast::Record as TypedRecord; use snarkos_dpc::base_dpc::instantiated::Components; use snarkos_objects::AccountAddress; diff --git a/state/src/record_commitment/record_commitment.rs b/state/src/record_commitment/record_commitment.rs index 1908c5a3da..c42cac2d48 100644 --- a/state/src/record_commitment/record_commitment.rs +++ b/state/src/record_commitment/record_commitment.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{DPCRecordValues, RecordVerificationError}; -use leo_typed::Record as TypedRecord; +use leo_core_ast::Record as TypedRecord; use snarkos_dpc::base_dpc::{ instantiated::{Components, RecordCommitment}, diff --git a/state/src/utilities/input_value.rs b/state/src/utilities/input_value.rs index 9e1cc9421b..2500acde9b 100644 --- a/state/src/utilities/input_value.rs +++ b/state/src/utilities/input_value.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::InputValueError; -use leo_typed::{InputValue, Parameter}; +use leo_core_ast::{InputValue, Parameter}; use std::collections::HashMap; diff --git a/state/tests/test_verify_local_data_commitment.rs b/state/tests/test_verify_local_data_commitment.rs index 89b8db06a3..226fbbfb71 100644 --- a/state/tests/test_verify_local_data_commitment.rs +++ b/state/tests/test_verify_local_data_commitment.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +use leo_core_ast::Input; use leo_input::LeoInputParser; use leo_state::verify_local_data_commitment; -use leo_typed::Input; use snarkos_dpc::base_dpc::{instantiated::*, record_payload::RecordPayload, DPC}; use snarkos_models::{ diff --git a/state/tests/test_verify_record_commitment.rs b/state/tests/test_verify_record_commitment.rs index 63dda73cb1..be03b32094 100644 --- a/state/tests/test_verify_record_commitment.rs +++ b/state/tests/test_verify_record_commitment.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +use leo_core_ast::Input; use leo_input::LeoInputParser; use leo_state::verify_record_commitment; -use leo_typed::Input; use snarkos_dpc::base_dpc::instantiated::*; diff --git a/symbol-table/Cargo.toml b/symbol-table/Cargo.toml index 8527bf14e8..53f94a769e 100644 --- a/symbol-table/Cargo.toml +++ b/symbol-table/Cargo.toml @@ -29,8 +29,8 @@ version = "1.0.3" path = "../imports" version = "1.0.3" -[dependencies.leo-typed] -path = "../typed" +[dependencies.leo-core-ast] +path = "../core-ast" version = "1.0.3" [dependencies.serde] diff --git a/symbol-table/src/errors/symbol_table.rs b/symbol-table/src/errors/symbol_table.rs index 57efaec0b8..839d3b357f 100644 --- a/symbol-table/src/errors/symbol_table.rs +++ b/symbol-table/src/errors/symbol_table.rs @@ -16,7 +16,7 @@ use crate::{TypeError, UserDefinedType}; use leo_core::{CorePackageListError, LeoCoreError}; -use leo_typed::{Error as FormattedError, ImportSymbol, Program, Span}; +use leo_core_ast::{Error as FormattedError, ImportSymbol, Program, Span}; use std::path::Path; diff --git a/symbol-table/src/errors/type_.rs b/symbol-table/src/errors/type_.rs index 5bdaff6cf0..487b323b4a 100644 --- a/symbol-table/src/errors/type_.rs +++ b/symbol-table/src/errors/type_.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Type; -use leo_typed::{Error as FormattedError, Identifier, Span}; +use leo_core_ast::{Error as FormattedError, Identifier, Span}; use std::path::Path; diff --git a/symbol-table/src/imports/imported_symbols.rs b/symbol-table/src/imports/imported_symbols.rs index f42542471a..a68d6f5f31 100644 --- a/symbol-table/src/imports/imported_symbols.rs +++ b/symbol-table/src/imports/imported_symbols.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::{ImportStatement, ImportSymbol, Package, PackageAccess}; +use leo_core_ast::{ImportStatement, ImportSymbol, Package, PackageAccess}; /// Stores the the package file name and imported symbol from an import statement #[derive(Debug)] diff --git a/symbol-table/src/symbol_table.rs b/symbol-table/src/symbol_table.rs index eb6bf1a8da..2e2a8e0409 100644 --- a/symbol-table/src/symbol_table.rs +++ b/symbol-table/src/symbol_table.rs @@ -16,8 +16,8 @@ use crate::{CircuitType, CircuitVariableType, FunctionType, ImportedSymbols, SymbolTableError, UserDefinedType}; use leo_core::CorePackageList; +use leo_core_ast::{Circuit, Function, Identifier, ImportStatement, ImportSymbol, Input, Package, Program}; use leo_imports::ImportParser; -use leo_typed::{Circuit, Function, Identifier, ImportStatement, ImportSymbol, Input, Package, Program}; use std::collections::{HashMap, HashSet}; diff --git a/symbol-table/src/types/circuits/circuit.rs b/symbol-table/src/types/circuits/circuit.rs index 270d0a9805..5a1b6e0f4b 100644 --- a/symbol-table/src/types/circuits/circuit.rs +++ b/symbol-table/src/types/circuits/circuit.rs @@ -22,7 +22,7 @@ use crate::{ Type, TypeError, }; -use leo_typed::{Circuit, CircuitMember, Identifier, InputValue, Parameter, Span}; +use leo_core_ast::{Circuit, CircuitMember, Identifier, InputValue, Parameter, Span}; use serde::{Deserialize, Serialize}; use std::{ diff --git a/symbol-table/src/types/circuits/circuit_variable.rs b/symbol-table/src/types/circuits/circuit_variable.rs index 275687203d..dfc19e7336 100644 --- a/symbol-table/src/types/circuits/circuit_variable.rs +++ b/symbol-table/src/types/circuits/circuit_variable.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Attribute, CircuitType, Type}; -use leo_typed::Identifier; +use leo_core_ast::Identifier; use serde::{Deserialize, Serialize}; diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs index 9531b45a90..2cddcdef4b 100644 --- a/symbol-table/src/types/functions/function.rs +++ b/symbol-table/src/types/functions/function.rs @@ -19,7 +19,7 @@ use crate::{ SymbolTable, TypeError, }; -use leo_typed::{Function, Identifier}; +use leo_core_ast::{Function, Identifier}; use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; diff --git a/symbol-table/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs index 40a45024fd..7d04ecd643 100644 --- a/symbol-table/src/types/functions/function_input.rs +++ b/symbol-table/src/types/functions/function_input.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{FunctionInputVariableType, SymbolTable, Type, TypeError}; -use leo_typed::{FunctionInput, Identifier}; +use leo_core_ast::{FunctionInput, Identifier}; use serde::{Deserialize, Serialize}; diff --git a/symbol-table/src/types/functions/function_input_variable.rs b/symbol-table/src/types/functions/function_input_variable.rs index 1dde943094..53069b43a1 100644 --- a/symbol-table/src/types/functions/function_input_variable.rs +++ b/symbol-table/src/types/functions/function_input_variable.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Attribute, SymbolTable, Type, TypeError, UserDefinedType}; -use leo_typed::{FunctionInputVariable, Identifier, Span}; +use leo_core_ast::{FunctionInputVariable, Identifier, Span}; use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; diff --git a/symbol-table/src/types/functions/function_output.rs b/symbol-table/src/types/functions/function_output.rs index c0bae87201..dcefe2b207 100644 --- a/symbol-table/src/types/functions/function_output.rs +++ b/symbol-table/src/types/functions/function_output.rs @@ -16,7 +16,7 @@ use crate::{SymbolTable, Type, TypeError}; -use leo_typed::{Identifier, Span, Type as UnresolvedType}; +use leo_core_ast::{Identifier, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; diff --git a/symbol-table/src/types/type_.rs b/symbol-table/src/types/type_.rs index c3f55b55a4..110a2607bc 100644 --- a/symbol-table/src/types/type_.rs +++ b/symbol-table/src/types/type_.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{SymbolTable, TypeError, TypeVariable}; -use leo_typed::{Identifier, IntegerType, Span, Type as UnresolvedType}; +use leo_core_ast::{Identifier, IntegerType, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; use std::{ diff --git a/symbol-table/src/types/type_variable.rs b/symbol-table/src/types/type_variable.rs index 7e19139324..f9e5420433 100644 --- a/symbol-table/src/types/type_variable.rs +++ b/symbol-table/src/types/type_variable.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_typed::Identifier; +use leo_core_ast::Identifier; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/symbol-table/src/types/user_defined/user_defined_type.rs b/symbol-table/src/types/user_defined/user_defined_type.rs index 7aae9530fb..3a536f0d08 100644 --- a/symbol-table/src/types/user_defined/user_defined_type.rs +++ b/symbol-table/src/types/user_defined/user_defined_type.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{Attribute, FunctionInputVariableType, Type}; -use leo_typed::{Circuit, Function, Identifier}; +use leo_core_ast::{Circuit, Function, Identifier}; use std::{ fmt, diff --git a/symbol-table/tests/mod.rs b/symbol-table/tests/mod.rs index a9aea958a7..f262716685 100644 --- a/symbol-table/tests/mod.rs +++ b/symbol-table/tests/mod.rs @@ -17,8 +17,8 @@ pub mod symbol_table; use leo_ast::LeoAst; +use leo_core_ast::{Input, LeoCoreAst}; use leo_symbol_table::{SymbolTable, SymbolTableError}; -use leo_typed::{Input, LeoCoreAst}; use leo_imports::ImportParser; use std::path::PathBuf; From f1e393a9ab73ef936938430ff840270c9ebb225a Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 12:39:02 -0700 Subject: [PATCH 113/139] rename dynamic-check -> type-inference 1 --- compiler/src/compiler.rs | 6 ++-- compiler/src/errors/compiler.rs | 4 +-- compiler/tests/syntax/mod.rs | 4 +-- dynamic-check/src/errors/mod.rs | 6 ++-- .../{dynamic_check.rs => type_inference.rs} | 10 +++---- dynamic-check/src/lib.rs | 4 +-- dynamic-check/src/objects/frame.rs | 2 +- .../{dynamic_check.rs => type_inference.rs} | 30 +++++++++---------- dynamic-check/tests/arrays/mod.rs | 8 ++--- dynamic-check/tests/circuits/mod.rs | 4 +-- dynamic-check/tests/functions/mod.rs | 4 +-- dynamic-check/tests/mod.rs | 20 ++++++------- dynamic-check/tests/tuples/mod.rs | 4 +-- dynamic-check/tests/variables/mod.rs | 10 +++---- 14 files changed, 58 insertions(+), 58 deletions(-) rename dynamic-check/src/errors/{dynamic_check.rs => type_inference.rs} (80%) rename dynamic-check/src/{dynamic_check.rs => type_inference.rs} (85%) diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index bbd495c111..68352746af 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -25,7 +25,7 @@ use crate::{ }; use leo_ast::LeoAst; use leo_core_ast::{Input, LeoCoreAst, MainInput, Program}; -use leo_dynamic_check::DynamicCheck; +use leo_dynamic_check::TypeInference; use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; @@ -199,7 +199,7 @@ impl> Compiler { })?; // Run dynamic check on program. - DynamicCheck::new(&self.program, symbol_table).map_err(|mut e| { + TypeInference::new(&self.program, symbol_table).map_err(|mut e| { e.set_path(&self.main_file_path); e @@ -236,7 +236,7 @@ impl> Compiler { let symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; // Run dynamic check on program. - DynamicCheck::new(&self.program, symbol_table)?; + TypeInference::new(&self.program, symbol_table)?; tracing::debug!("Program parsing complete\n{:#?}", self.program); diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index c82569dccb..d771721852 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -16,7 +16,7 @@ use crate::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError}; use leo_ast::ParserError; -use leo_dynamic_check::DynamicCheckError; +use leo_dynamic_check::TypeInferenceError; use leo_imports::ImportParserError; use leo_input::InputParserError; use leo_state::LocalDataVerificationError; @@ -28,7 +28,7 @@ use std::path::{Path, PathBuf}; #[derive(Debug, Error)] pub enum CompilerError { #[error("{}", _0)] - DynamicCheckError(#[from] DynamicCheckError), + DynamicCheckError(#[from] TypeInferenceError), #[error("{}", _0)] ImportError(#[from] ImportError), diff --git a/compiler/tests/syntax/mod.rs b/compiler/tests/syntax/mod.rs index f597dd50a9..2d3e1826f5 100644 --- a/compiler/tests/syntax/mod.rs +++ b/compiler/tests/syntax/mod.rs @@ -17,7 +17,7 @@ use crate::{expect_compiler_error, parse_input, parse_program}; use leo_ast::ParserError; use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError}; -use leo_dynamic_check::errors::{DynamicCheckError, FrameError, TypeAssertionError}; +use leo_dynamic_check::errors::{FrameError, TypeAssertionError, TypeInferenceError}; use leo_input::InputParserError; pub mod identifiers; @@ -82,7 +82,7 @@ fn test_compare_mismatched_types() { // Expect a dynamic check error. match error { - CompilerError::DynamicCheckError(DynamicCheckError::FrameError(FrameError::TypeAssertionError( + CompilerError::DynamicCheckError(TypeInferenceError::FrameError(FrameError::TypeAssertionError( TypeAssertionError::Error(_), ))) => {} error => panic!("Expected dynamic check error, found {}", error), diff --git a/dynamic-check/src/errors/mod.rs b/dynamic-check/src/errors/mod.rs index 12128a8127..629a558e2f 100644 --- a/dynamic-check/src/errors/mod.rs +++ b/dynamic-check/src/errors/mod.rs @@ -14,9 +14,6 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -pub mod dynamic_check; -pub use self::dynamic_check::*; - pub mod frame; pub use self::frame::*; @@ -26,5 +23,8 @@ pub use self::scope::*; pub mod type_assertion; pub use self::type_assertion::*; +pub mod type_inference; +pub use self::type_inference::*; + pub mod variable_table; pub use self::variable_table::*; diff --git a/dynamic-check/src/errors/dynamic_check.rs b/dynamic-check/src/errors/type_inference.rs similarity index 80% rename from dynamic-check/src/errors/dynamic_check.rs rename to dynamic-check/src/errors/type_inference.rs index a165a87a8d..83c7dde93e 100644 --- a/dynamic-check/src/errors/dynamic_check.rs +++ b/dynamic-check/src/errors/type_inference.rs @@ -19,9 +19,9 @@ use leo_core_ast::Error as FormattedError; use std::path::Path; -/// Errors encountered when running dynamic type inference checks. +/// Errors encountered when running type inference checks. #[derive(Debug, Error)] -pub enum DynamicCheckError { +pub enum TypeInferenceError { #[error("{}", _0)] Error(#[from] FormattedError), @@ -29,14 +29,14 @@ pub enum DynamicCheckError { FrameError(#[from] FrameError), } -impl DynamicCheckError { +impl TypeInferenceError { /// /// Set the filepath for the error stacktrace. /// pub fn set_path(&mut self, path: &Path) { match self { - DynamicCheckError::Error(error) => error.set_path(path), - DynamicCheckError::FrameError(error) => error.set_path(path), + TypeInferenceError::Error(error) => error.set_path(path), + TypeInferenceError::FrameError(error) => error.set_path(path), } } } diff --git a/dynamic-check/src/lib.rs b/dynamic-check/src/lib.rs index 3c1f97a363..cbe7bdd069 100644 --- a/dynamic-check/src/lib.rs +++ b/dynamic-check/src/lib.rs @@ -20,8 +20,8 @@ extern crate thiserror; pub mod assertions; pub use self::assertions::*; -pub mod dynamic_check; -pub use self::dynamic_check::*; +pub mod type_inference; +pub use self::type_inference::*; pub mod errors; pub use self::errors::*; diff --git a/dynamic-check/src/objects/frame.rs b/dynamic-check/src/objects/frame.rs index ea2494f39a..1148a619ea 100644 --- a/dynamic-check/src/objects/frame.rs +++ b/dynamic-check/src/objects/frame.rs @@ -288,7 +288,7 @@ impl Frame { // Check if an explicit type is given. if let Some(type_) = variables.type_.clone() { - // Convert the expected type into a dynamic check type. + // Check the expected type. let expected_type = match self.self_type { Some(ref circuit_type) => Type::new_from_circuit( &self.user_defined_types, diff --git a/dynamic-check/src/dynamic_check.rs b/dynamic-check/src/type_inference.rs similarity index 85% rename from dynamic-check/src/dynamic_check.rs rename to dynamic-check/src/type_inference.rs index e5e31596b5..4f9e7fcc48 100644 --- a/dynamic-check/src/dynamic_check.rs +++ b/dynamic-check/src/type_inference.rs @@ -14,37 +14,37 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{DynamicCheckError, Frame, Scope}; +use crate::{Frame, Scope, TypeInferenceError}; use leo_core_ast::{Circuit, CircuitMember, Function, Program}; use leo_symbol_table::SymbolTable; -/// Performs a dynamic type inference check over a program. -pub struct DynamicCheck { +/// Stores information need to run a type inference check over a program. +pub struct TypeInference { table: SymbolTable, frames: Vec, } -impl DynamicCheck { +impl TypeInference { /// - /// Creates a new `DynamicCheck` on a given program and symbol table. + /// Creates and runs a new `TypeInference` check on a given program and symbol table. /// /// Evaluates all `TypeAssertion` predicates. /// - pub fn new(program: &Program, symbol_table: SymbolTable) -> Result<(), DynamicCheckError> { - let mut dynamic_check = Self { + pub fn new(program: &Program, symbol_table: SymbolTable) -> Result<(), TypeInferenceError> { + let mut type_inference = Self { table: symbol_table, frames: Vec::new(), }; - dynamic_check.parse_program(program)?; + type_inference.parse_program(program)?; - dynamic_check.check() + type_inference.check() } /// /// Collects a vector of `TypeAssertion` predicates from a program. /// - fn parse_program(&mut self, program: &Program) -> Result<(), DynamicCheckError> { + fn parse_program(&mut self, program: &Program) -> Result<(), TypeInferenceError> { // Parse circuit types in program context. self.parse_circuits(program.circuits.iter().map(|(_identifier, circuit)| circuit))?; @@ -55,7 +55,7 @@ impl DynamicCheck { /// /// Collects a vector of `Frames`s from a vector of circuit functions. /// - fn parse_circuits<'a>(&mut self, circuits: impl Iterator) -> Result<(), DynamicCheckError> { + fn parse_circuits<'a>(&mut self, circuits: impl Iterator) -> Result<(), TypeInferenceError> { for circuit in circuits { self.parse_circuit(circuit)?; } @@ -68,7 +68,7 @@ impl DynamicCheck { /// /// Each frame collects a vector of `TypeAssertion` predicates from each function. /// - fn parse_circuit(&mut self, circuit: &Circuit) -> Result<(), DynamicCheckError> { + fn parse_circuit(&mut self, circuit: &Circuit) -> Result<(), TypeInferenceError> { let name = &circuit.circuit_name.name; // Get circuit type from circuit symbol table. @@ -97,7 +97,7 @@ impl DynamicCheck { /// /// Collects a vector of `TypeAssertion` predicates from a vector of functions. /// - fn parse_functions<'a>(&mut self, functions: impl Iterator) -> Result<(), DynamicCheckError> { + fn parse_functions<'a>(&mut self, functions: impl Iterator) -> Result<(), TypeInferenceError> { for function in functions { self.parse_function(function)?; } @@ -108,7 +108,7 @@ impl DynamicCheck { /// /// Collects a vector of `TypeAssertion` predicates from a function. /// - fn parse_function(&mut self, function: &Function) -> Result<(), DynamicCheckError> { + fn parse_function(&mut self, function: &Function) -> Result<(), TypeInferenceError> { let frame = Frame::new_function(function.to_owned(), None, None, self.table.clone())?; self.frames.push(frame); @@ -123,7 +123,7 @@ impl DynamicCheck { /// Returns a `LeoResolvedAst` if all `TypeAssertion` predicates are true. /// Returns ERROR if a `TypeAssertion` predicate is false or a solution does not exist. /// - pub fn check(self) -> Result<(), DynamicCheckError> { + pub fn check(self) -> Result<(), TypeInferenceError> { for frame in self.frames { frame.check()?; } diff --git a/dynamic-check/tests/arrays/mod.rs b/dynamic-check/tests/arrays/mod.rs index 72a2845b3f..72ab79478e 100644 --- a/dynamic-check/tests/arrays/mod.rs +++ b/dynamic-check/tests/arrays/mod.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::TestDynamicCheck; +use crate::TestTypeInference; #[test] fn test_empty_array() { let bytes = include_bytes!("empty_array.leo"); - let check = TestDynamicCheck::new(bytes); + let check = TestTypeInference::new(bytes); check.expect_error(); } @@ -29,7 +29,7 @@ fn test_empty_array() { fn test_invalid_array_access() { let bytes = include_bytes!("invalid_array_access.leo"); - let check = TestDynamicCheck::new(bytes); + let check = TestTypeInference::new(bytes); check.expect_error(); } @@ -38,7 +38,7 @@ fn test_invalid_array_access() { fn test_invalid_spread() { let bytes = include_bytes!("invalid_spread.leo"); - let check = TestDynamicCheck::new(bytes); + let check = TestTypeInference::new(bytes); check.expect_error(); } diff --git a/dynamic-check/tests/circuits/mod.rs b/dynamic-check/tests/circuits/mod.rs index d82726197b..8b8d585bd6 100644 --- a/dynamic-check/tests/circuits/mod.rs +++ b/dynamic-check/tests/circuits/mod.rs @@ -14,12 +14,12 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::TestDynamicCheck; +use crate::TestTypeInference; #[test] fn test_invalid_circuit() { let bytes = include_bytes!("invalid_circuit.leo"); - let check = TestDynamicCheck::new(bytes); + let check = TestTypeInference::new(bytes); check.expect_error(); } diff --git a/dynamic-check/tests/functions/mod.rs b/dynamic-check/tests/functions/mod.rs index 5599451646..20e873cbaf 100644 --- a/dynamic-check/tests/functions/mod.rs +++ b/dynamic-check/tests/functions/mod.rs @@ -14,12 +14,12 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::TestDynamicCheck; +use crate::TestTypeInference; #[test] fn test_invalid_function() { let bytes = include_bytes!("invalid_function.leo"); - let check = TestDynamicCheck::new(bytes); + let check = TestTypeInference::new(bytes); check.expect_error(); } diff --git a/dynamic-check/tests/mod.rs b/dynamic-check/tests/mod.rs index 576be6d5e2..10dac2f0ad 100644 --- a/dynamic-check/tests/mod.rs +++ b/dynamic-check/tests/mod.rs @@ -21,7 +21,7 @@ pub mod tuples; pub mod variables; use leo_ast::LeoAst; -use leo_dynamic_check::DynamicCheck; +use leo_dynamic_check::TypeInference; use leo_core_ast::{Input, LeoCoreAst, Program}; use leo_imports::ImportParser; @@ -31,13 +31,13 @@ use std::path::PathBuf; const TEST_PROGRAM_PATH: &str = ""; const TEST_PROGRAM_NAME: &str = "test"; -/// A helper struct to test a `DynamicCheck`. -pub struct TestDynamicCheck { +/// A helper struct to test a `TypeInference` check. +pub struct TestTypeInference { program: Program, symbol_table: SymbolTable, } -impl TestDynamicCheck { +impl TestTypeInference { pub fn new(bytes: &[u8]) -> Self { // Get file string from bytes. let file_string = String::from_utf8_lossy(bytes); @@ -61,16 +61,16 @@ impl TestDynamicCheck { // Create symbol table. let symbol_table = SymbolTable::new(&program, &import_parser, &input).unwrap(); - // Store fields for new dynamic check. + // Store fields for new type inference check. Self { program, symbol_table } } - pub fn run(self) { - DynamicCheck::new(&self.program, self.symbol_table).unwrap(); + pub fn check(self) { + TypeInference::new(&self.program, self.symbol_table).unwrap(); } pub fn expect_error(self) { - assert!(DynamicCheck::new(&self.program, self.symbol_table).is_err()); + assert!(TypeInference::new(&self.program, self.symbol_table).is_err()); } } @@ -78,7 +78,7 @@ impl TestDynamicCheck { fn test_new() { let bytes = include_bytes!("empty.leo"); - let dynamic_check = TestDynamicCheck::new(bytes); + let type_inference = TestTypeInference::new(bytes); - dynamic_check.run() + type_inference.check() } diff --git a/dynamic-check/tests/tuples/mod.rs b/dynamic-check/tests/tuples/mod.rs index 31b18ffa45..cc0549cffe 100644 --- a/dynamic-check/tests/tuples/mod.rs +++ b/dynamic-check/tests/tuples/mod.rs @@ -14,12 +14,12 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::TestDynamicCheck; +use crate::TestTypeInference; #[test] fn test_invalid_tuple_access() { let bytes = include_bytes!("invalid_tuple_access.leo"); - let check = TestDynamicCheck::new(bytes); + let check = TestTypeInference::new(bytes); check.expect_error(); } diff --git a/dynamic-check/tests/variables/mod.rs b/dynamic-check/tests/variables/mod.rs index 2712890704..9e7b3dd1ea 100644 --- a/dynamic-check/tests/variables/mod.rs +++ b/dynamic-check/tests/variables/mod.rs @@ -14,12 +14,12 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::TestDynamicCheck; +use crate::TestTypeInference; #[test] fn test_duplicate_variable() { let bytes = include_bytes!("duplicate_variable.leo"); - let check = TestDynamicCheck::new(bytes); + let check = TestTypeInference::new(bytes); check.expect_error(); } @@ -27,7 +27,7 @@ fn test_duplicate_variable() { #[test] fn test_duplicate_variable_multi() { let bytes = include_bytes!("duplicate_variable_multi.leo"); - let check = TestDynamicCheck::new(bytes); + let check = TestTypeInference::new(bytes); check.expect_error(); } @@ -35,7 +35,7 @@ fn test_duplicate_variable_multi() { #[test] fn test_not_enough_values() { let bytes = include_bytes!("not_enough_values.leo"); - let check = TestDynamicCheck::new(bytes); + let check = TestTypeInference::new(bytes); check.expect_error(); } @@ -43,7 +43,7 @@ fn test_not_enough_values() { #[test] fn test_too_many_values() { let bytes = include_bytes!("too_many_values.leo"); - let check = TestDynamicCheck::new(bytes); + let check = TestTypeInference::new(bytes); check.expect_error(); } From 7589fa65c5bd70e5e99a6e586b3593eb1bcb1699 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 12:49:01 -0700 Subject: [PATCH 114/139] rename dynamic-check -> type-inference 2 --- Cargo.lock | 29 +++++++++---------- Cargo.toml | 6 +--- compiler/Cargo.toml | 12 ++++---- compiler/src/compiler.rs | 12 +++++--- compiler/src/errors/compiler.rs | 6 ++-- compiler/tests/array/mod.rs | 28 +++++++++--------- compiler/tests/boolean/mod.rs | 6 ++-- compiler/tests/circuits/mod.rs | 26 ++++++++--------- .../core/packages/unstable/blake2s/mod.rs | 6 ++-- compiler/tests/function/mod.rs | 10 +++---- compiler/tests/mod.rs | 4 +-- compiler/tests/mutability/mod.rs | 6 ++-- compiler/tests/statements/mod.rs | 4 +-- compiler/tests/syntax/mod.rs | 8 ++--- {dynamic-check => type-inference}/Cargo.toml | 14 ++++----- .../src/assertions/mod.rs | 0 .../src/assertions/type_assertion.rs | 0 .../src/assertions/type_equality.rs | 0 .../src/assertions/type_membership.rs | 0 .../src/assertions/type_variable_pair.rs | 0 .../src/errors/frame.rs | 0 .../src/errors/mod.rs | 0 .../src/errors/scope.rs | 0 .../src/errors/type_assertion.rs | 0 .../src/errors/type_inference.rs | 0 .../src/errors/variable_table.rs | 0 {dynamic-check => type-inference}/src/lib.rs | 0 .../src/objects/frame.rs | 0 .../src/objects/mod.rs | 0 .../src/objects/scope.rs | 0 .../src/objects/variable_table.rs | 0 .../src/type_inference.rs | 0 .../tests/arrays/empty_array.leo | 0 .../tests/arrays/invalid_array_access.leo | 0 .../tests/arrays/invalid_spread.leo | 0 .../tests/arrays/mod.rs | 0 .../tests/circuits/invalid_circuit.leo | 0 .../tests/circuits/mod.rs | 0 .../tests/empty.leo | 0 .../tests/functions/invalid_function.leo | 0 .../tests/functions/mod.rs | 0 .../tests/mod.rs | 2 +- .../tests/tuples/invalid_tuple_access.leo | 0 .../tests/tuples/mod.rs | 0 .../tests/variables/duplicate_variable.leo | 0 .../variables/duplicate_variable_multi.leo | 0 .../tests/variables/mod.rs | 0 .../tests/variables/not_enough_values.leo | 0 .../tests/variables/too_many_values.leo | 0 49 files changed, 89 insertions(+), 90 deletions(-) rename {dynamic-check => type-inference}/Cargo.toml (96%) rename {dynamic-check => type-inference}/src/assertions/mod.rs (100%) rename {dynamic-check => type-inference}/src/assertions/type_assertion.rs (100%) rename {dynamic-check => type-inference}/src/assertions/type_equality.rs (100%) rename {dynamic-check => type-inference}/src/assertions/type_membership.rs (100%) rename {dynamic-check => type-inference}/src/assertions/type_variable_pair.rs (100%) rename {dynamic-check => type-inference}/src/errors/frame.rs (100%) rename {dynamic-check => type-inference}/src/errors/mod.rs (100%) rename {dynamic-check => type-inference}/src/errors/scope.rs (100%) rename {dynamic-check => type-inference}/src/errors/type_assertion.rs (100%) rename {dynamic-check => type-inference}/src/errors/type_inference.rs (100%) rename {dynamic-check => type-inference}/src/errors/variable_table.rs (100%) rename {dynamic-check => type-inference}/src/lib.rs (100%) rename {dynamic-check => type-inference}/src/objects/frame.rs (100%) rename {dynamic-check => type-inference}/src/objects/mod.rs (100%) rename {dynamic-check => type-inference}/src/objects/scope.rs (100%) rename {dynamic-check => type-inference}/src/objects/variable_table.rs (100%) rename {dynamic-check => type-inference}/src/type_inference.rs (100%) rename {dynamic-check => type-inference}/tests/arrays/empty_array.leo (100%) rename {dynamic-check => type-inference}/tests/arrays/invalid_array_access.leo (100%) rename {dynamic-check => type-inference}/tests/arrays/invalid_spread.leo (100%) rename {dynamic-check => type-inference}/tests/arrays/mod.rs (100%) rename {dynamic-check => type-inference}/tests/circuits/invalid_circuit.leo (100%) rename {dynamic-check => type-inference}/tests/circuits/mod.rs (100%) rename {dynamic-check => type-inference}/tests/empty.leo (100%) rename {dynamic-check => type-inference}/tests/functions/invalid_function.leo (100%) rename {dynamic-check => type-inference}/tests/functions/mod.rs (100%) rename {dynamic-check => type-inference}/tests/mod.rs (98%) rename {dynamic-check => type-inference}/tests/tuples/invalid_tuple_access.leo (100%) rename {dynamic-check => type-inference}/tests/tuples/mod.rs (100%) rename {dynamic-check => type-inference}/tests/variables/duplicate_variable.leo (100%) rename {dynamic-check => type-inference}/tests/variables/duplicate_variable_multi.leo (100%) rename {dynamic-check => type-inference}/tests/variables/mod.rs (100%) rename {dynamic-check => type-inference}/tests/variables/not_enough_values.leo (100%) rename {dynamic-check => type-inference}/tests/variables/too_many_values.leo (100%) diff --git a/Cargo.lock b/Cargo.lock index aaeb4f691d..d66ecac8a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1254,13 +1254,13 @@ dependencies = [ "leo-ast", "leo-core", "leo-core-ast", - "leo-dynamic-check", "leo-gadgets", "leo-imports", "leo-input", "leo-package", "leo-state", "leo-symbol-table", + "leo-type-inference", "num-bigint", "pest", "rand", @@ -1310,19 +1310,6 @@ dependencies = [ "snarkos-models", ] -[[package]] -name = "leo-dynamic-check" -version = "1.0.3" -dependencies = [ - "leo-ast", - "leo-core-ast", - "leo-imports", - "leo-symbol-table", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "leo-gadgets" version = "1.0.3" @@ -1378,7 +1365,6 @@ dependencies = [ "leo-compiler", "leo-core", "leo-core-ast", - "leo-dynamic-check", "leo-gadgets", "leo-imports", "leo-input", @@ -1456,6 +1442,19 @@ dependencies = [ "thiserror", ] +[[package]] +name = "leo-type-inference" +version = "1.0.3" +dependencies = [ + "leo-ast", + "leo-core-ast", + "leo-imports", + "leo-symbol-table", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "libc" version = "0.2.76" diff --git a/Cargo.toml b/Cargo.toml index 5abc2a48f8..b95bcbc4b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,6 @@ members = [ "compiler", "core-ast", "core", - "dynamic-check", "gadgets", "imports", "input", @@ -38,6 +37,7 @@ members = [ "package", "state", "symbol-table", + "type-inference", ] [dependencies.leo-compiler] @@ -52,10 +52,6 @@ version = "1.0.1" path = "./core-ast" version = "1.0.3" -[dependencies.leo-dynamic-check] -path = "./dynamic-check" -version = "1.0.3" - [dependencies.leo-gadgets] path = "./gadgets" version = "1.0.3" diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index d115e19902..485719aba4 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -25,8 +25,8 @@ version = "1.0.3" path = "../core" version = "1.0.3" -[dependencies.leo-dynamic-check] -path = "../dynamic-check" +[dependencies.leo-core-ast] +path = "../core-ast" version = "1.0.3" [dependencies.leo-gadgets] @@ -45,10 +45,6 @@ version = "1.0.3" path = "../package" version = "1.0.3" -[dependencies.leo-core-ast] -path = "../core-ast" -version = "1.0.3" - [dependencies.leo-state] path = "../state" version = "1.0.3" @@ -57,6 +53,10 @@ version = "1.0.3" path = "../symbol-table" version = "1.0.3" +[dependencies.leo-type-inference] +path = "../type-inference" +version = "1.0.3" + [dependencies.snarkos-curves] version = "1.1.3" default-features = false diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 68352746af..60f6af701b 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -25,12 +25,12 @@ use crate::{ }; use leo_ast::LeoAst; use leo_core_ast::{Input, LeoCoreAst, MainInput, Program}; -use leo_dynamic_check::TypeInference; use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; use leo_state::verify_local_data_commitment; use leo_symbol_table::SymbolTable; +use leo_type_inference::TypeInference; use snarkos_dpc::{base_dpc::instantiated::Components, SystemParameters}; use snarkos_errors::gadgets::SynthesisError; @@ -187,7 +187,11 @@ impl> Compiler { } /// - /// Runs static and dynamic type checks on the program, imports, and input. + /// Runs a type check on the program, imports, and input. + /// + /// First, a symbol table of all user defined types is created. + /// Second, a type inference check is run on the program - inferring a data type for all implicit types and + /// catching type mismatch errors. /// pub(crate) fn check_program(&self) -> Result<(), CompilerError> { // Create a new symbol table from the program, imported_programs, and program_input. @@ -198,7 +202,7 @@ impl> Compiler { e })?; - // Run dynamic check on program. + // Run type inference check on program. TypeInference::new(&self.program, symbol_table).map_err(|mut e| { e.set_path(&self.main_file_path); @@ -235,7 +239,7 @@ impl> Compiler { // Create a new symbol table from the program, imported programs, and program input. let symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; - // Run dynamic check on program. + // Run type inference check on program. TypeInference::new(&self.program, symbol_table)?; tracing::debug!("Program parsing complete\n{:#?}", self.program); diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index d771721852..7ab49c5c34 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -16,11 +16,11 @@ use crate::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError}; use leo_ast::ParserError; -use leo_dynamic_check::TypeInferenceError; use leo_imports::ImportParserError; use leo_input::InputParserError; use leo_state::LocalDataVerificationError; use leo_symbol_table::SymbolTableError; +use leo_type_inference::TypeInferenceError; use bincode::Error as SerdeError; use std::path::{Path, PathBuf}; @@ -28,7 +28,7 @@ use std::path::{Path, PathBuf}; #[derive(Debug, Error)] pub enum CompilerError { #[error("{}", _0)] - DynamicCheckError(#[from] TypeInferenceError), + TypeInferenceError(#[from] TypeInferenceError), #[error("{}", _0)] ImportError(#[from] ImportError), @@ -79,7 +79,7 @@ pub enum CompilerError { impl CompilerError { pub fn set_path(&mut self, path: &Path) { match self { - CompilerError::DynamicCheckError(error) => error.set_path(path), + CompilerError::TypeInferenceError(error) => error.set_path(path), CompilerError::InputParserError(error) => error.set_path(path), CompilerError::FunctionError(error) => error.set_path(path), CompilerError::OutputStringError(error) => error.set_path(path), diff --git a/compiler/tests/array/mod.rs b/compiler/tests/array/mod.rs index a4e37b66cb..6c8aa8988c 100644 --- a/compiler/tests/array/mod.rs +++ b/compiler/tests/array/mod.rs @@ -17,7 +17,7 @@ use crate::{ assert_satisfied, expect_compiler_error, - expect_dynamic_check_error, + expect_type_inference_error, get_output, parse_program, parse_program_with_input, @@ -153,7 +153,7 @@ fn test_multi_fail_initializer() { let program_bytes = include_bytes!("multi_fail_initializer.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -161,7 +161,7 @@ fn test_multi_inline_fail() { let program_bytes = include_bytes!("multi_fail_inline.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -177,7 +177,7 @@ fn test_multi_initializer_fail() { let program_bytes = include_bytes!("multi_initializer_fail.leo"); let err = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(err); + expect_type_inference_error(err); } #[test] @@ -193,7 +193,7 @@ fn test_nested_3x2_value_fail() { let program_bytes = include_bytes!("nested_3x2_value_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -209,7 +209,7 @@ fn test_tuple_3x2_value_fail() { let program_bytes = include_bytes!("tuple_3x2_value_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -253,7 +253,7 @@ fn test_type_nested_value_nested_3x2_fail() { let program_bytes = include_bytes!("type_nested_value_nested_3x2_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -269,7 +269,7 @@ fn test_type_nested_value_nested_4x3x2_fail() { let program_bytes = include_bytes!("type_nested_value_nested_4x3x2_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -285,7 +285,7 @@ fn test_type_nested_value_tuple_3x2_fail() { let program_bytes = include_bytes!("type_nested_value_tuple_3x2_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -301,7 +301,7 @@ fn test_type_nested_value_tuple_4x3x2_fail() { let program_bytes = include_bytes!("type_nested_value_tuple_4x3x2_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -317,7 +317,7 @@ fn test_type_tuple_value_nested_3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_nested_3x2_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -333,7 +333,7 @@ fn test_type_tuple_value_nested_4x3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_nested_4x3x2_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -349,7 +349,7 @@ fn test_type_tuple_value_tuple_3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_tuple_3x2_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -365,7 +365,7 @@ fn test_type_tuple_value_tuple_4x3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_tuple_4x3x2_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } // Tests for nested multi-dimensional arrays as input to the program diff --git a/compiler/tests/boolean/mod.rs b/compiler/tests/boolean/mod.rs index 6901c2a15b..8015cfd335 100644 --- a/compiler/tests/boolean/mod.rs +++ b/compiler/tests/boolean/mod.rs @@ -17,7 +17,7 @@ use crate::{ assert_satisfied, expect_compiler_error, - expect_dynamic_check_error, + expect_type_inference_error, get_output, parse_program, parse_program_with_input, @@ -132,7 +132,7 @@ fn test_true_or_u32() { let bytes = include_bytes!("true_or_u32.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } // Boolean and && @@ -166,7 +166,7 @@ fn test_true_and_u32() { let bytes = include_bytes!("true_and_u32.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } // All diff --git a/compiler/tests/circuits/mod.rs b/compiler/tests/circuits/mod.rs index 4790c5fff2..33d0d41ea9 100644 --- a/compiler/tests/circuits/mod.rs +++ b/compiler/tests/circuits/mod.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_compiler_error, expect_dynamic_check_error, parse_program}; +use crate::{assert_satisfied, expect_compiler_error, expect_type_inference_error, parse_program}; // Expressions @@ -39,7 +39,7 @@ fn test_inline_undefined() { let bytes = include_bytes!("inline_undefined.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } // Members @@ -57,7 +57,7 @@ fn test_member_variable_fail() { let bytes = include_bytes!("member_variable_fail.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -81,7 +81,7 @@ fn test_member_function_fail() { let bytes = include_bytes!("member_function_fail.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -89,7 +89,7 @@ fn test_member_function_invalid() { let bytes = include_bytes!("member_function_invalid.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -121,7 +121,7 @@ fn test_member_static_function_invalid() { let bytes = include_bytes!("member_static_function_invalid.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error) + expect_type_inference_error(error) } #[test] @@ -129,7 +129,7 @@ fn test_member_static_function_undefined() { let bytes = include_bytes!("member_static_function_undefined.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error) + expect_type_inference_error(error) } // Mutability @@ -139,7 +139,7 @@ fn test_mutate_function_fail() { let bytes = include_bytes!("mut_function_fail.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -163,7 +163,7 @@ fn test_mutate_self_function_fail() { let bytes = include_bytes!("mut_self_function_fail.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -171,7 +171,7 @@ fn test_mutate_self_static_function_fail() { let bytes = include_bytes!("mut_self_static_function_fail.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -179,7 +179,7 @@ fn test_mutate_static_function_fail() { let bytes = include_bytes!("mut_static_function_fail.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -205,7 +205,7 @@ fn test_self_fail() { let bytes = include_bytes!("self_fail.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -229,7 +229,7 @@ fn test_self_member_undefined() { let bytes = include_bytes!("self_member_undefined.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } // All diff --git a/compiler/tests/core/packages/unstable/blake2s/mod.rs b/compiler/tests/core/packages/unstable/blake2s/mod.rs index 3d367dcf89..edbbc2e8bf 100644 --- a/compiler/tests/core/packages/unstable/blake2s/mod.rs +++ b/compiler/tests/core/packages/unstable/blake2s/mod.rs @@ -16,7 +16,7 @@ use crate::{ assert_satisfied, - expect_dynamic_check_error, + expect_type_inference_error, generate_main_input, get_output, parse_program, @@ -35,7 +35,7 @@ fn test_arguments_length_fail() { let program_bytes = include_bytes!("arguments_length_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -43,7 +43,7 @@ fn test_arguments_type_fail() { let program_bytes = include_bytes!("arguments_type_fail.leo"); let error = parse_program(program_bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] diff --git a/compiler/tests/function/mod.rs b/compiler/tests/function/mod.rs index 7b9cfdd750..ccbb6be68d 100644 --- a/compiler/tests/function/mod.rs +++ b/compiler/tests/function/mod.rs @@ -17,7 +17,7 @@ use crate::{ assert_satisfied, expect_compiler_error, - expect_dynamic_check_error, + expect_type_inference_error, get_output, parse_program, parse_program_with_input, @@ -122,7 +122,7 @@ fn test_undefined() { let bytes = include_bytes!("undefined.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -138,7 +138,7 @@ fn test_array_input() { let bytes = include_bytes!("array_input.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error) + expect_type_inference_error(error) } // Test return multidimensional arrays @@ -148,7 +148,7 @@ fn test_return_array_nested_fail() { let bytes = include_bytes!("return_array_nested_fail.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -164,7 +164,7 @@ fn test_return_array_tuple_fail() { let bytes = include_bytes!("return_array_tuple_fail.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index 1d9bbc69c2..fd16809cf0 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -181,8 +181,8 @@ pub(crate) fn expect_compiler_error(program: EdwardsTestCompiler) -> CompilerErr program.generate_constraints_helper(&mut cs).unwrap_err() } -pub(crate) fn expect_dynamic_check_error(error: CompilerError) { - assert!(matches!(error, CompilerError::DynamicCheckError(_))) +pub(crate) fn expect_type_inference_error(error: CompilerError) { + assert!(matches!(error, CompilerError::TypeInferenceError(_))) } pub(crate) fn expect_symbol_table_error(error: CompilerError) { diff --git a/compiler/tests/mutability/mod.rs b/compiler/tests/mutability/mod.rs index 60b3d31ec8..3ac48f07d4 100644 --- a/compiler/tests/mutability/mod.rs +++ b/compiler/tests/mutability/mod.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_compiler_error, expect_dynamic_check_error, generate_main_input, parse_program}; +use crate::{assert_satisfied, expect_compiler_error, expect_type_inference_error, generate_main_input, parse_program}; use leo_core_ast::InputValue; #[test] @@ -94,7 +94,7 @@ fn test_circuit_function_mut() { let bytes = include_bytes!("circuit_function_mut.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] @@ -102,7 +102,7 @@ fn test_circuit_static_function_mut() { let bytes = include_bytes!("circuit_static_function_mut.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } #[test] diff --git a/compiler/tests/statements/mod.rs b/compiler/tests/statements/mod.rs index b3322ce785..c6b7efdd2f 100644 --- a/compiler/tests/statements/mod.rs +++ b/compiler/tests/statements/mod.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_dynamic_check_error, generate_main_input, parse_program}; +use crate::{assert_satisfied, expect_type_inference_error, generate_main_input, parse_program}; use leo_core_ast::InputValue; pub mod conditional; @@ -62,5 +62,5 @@ fn test_num_returns_fail() { let bytes = include_bytes!("num_returns_fail.leo"); let error = parse_program(bytes).err().unwrap(); - expect_dynamic_check_error(error); + expect_type_inference_error(error); } diff --git a/compiler/tests/syntax/mod.rs b/compiler/tests/syntax/mod.rs index 2d3e1826f5..ec39dfc10a 100644 --- a/compiler/tests/syntax/mod.rs +++ b/compiler/tests/syntax/mod.rs @@ -17,8 +17,8 @@ use crate::{expect_compiler_error, parse_input, parse_program}; use leo_ast::ParserError; use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError}; -use leo_dynamic_check::errors::{FrameError, TypeAssertionError, TypeInferenceError}; use leo_input::InputParserError; +use leo_type_inference::errors::{FrameError, TypeAssertionError, TypeInferenceError}; pub mod identifiers; @@ -80,11 +80,11 @@ fn test_compare_mismatched_types() { let bytes = include_bytes!("compare_mismatched_types.leo"); let error = parse_program(bytes).err().unwrap(); - // Expect a dynamic check error. + // Expect a type inference error. match error { - CompilerError::DynamicCheckError(TypeInferenceError::FrameError(FrameError::TypeAssertionError( + CompilerError::TypeInferenceError(TypeInferenceError::FrameError(FrameError::TypeAssertionError( TypeAssertionError::Error(_), ))) => {} - error => panic!("Expected dynamic check error, found {}", error), + error => panic!("Expected type inference error, found {}", error), } } diff --git a/dynamic-check/Cargo.toml b/type-inference/Cargo.toml similarity index 96% rename from dynamic-check/Cargo.toml rename to type-inference/Cargo.toml index 37d1f1313c..7d9e0446e5 100644 --- a/dynamic-check/Cargo.toml +++ b/type-inference/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "leo-dynamic-check" +name = "leo-type-inference" version = "1.0.3" authors = [ "The Aleo Team " ] description = "Checks that a program is correct using type inference" @@ -21,20 +21,20 @@ edition = "2018" path = "../ast" version = "1.0.3" +[dependencies.leo-core-ast] +path = "../core-ast" +version = "1.0.3" + [dependencies.leo-imports] path = "../imports" version = "1.0.3" -[dependencies.serde_json] -version = "1.0" - [dependencies.leo-symbol-table] path = "../symbol-table" version = "1.0.3" -[dependencies.leo-core-ast] -path = "../core-ast" -version = "1.0.3" +[dependencies.serde_json] +version = "1.0" [dependencies.serde] version = "1.0" diff --git a/dynamic-check/src/assertions/mod.rs b/type-inference/src/assertions/mod.rs similarity index 100% rename from dynamic-check/src/assertions/mod.rs rename to type-inference/src/assertions/mod.rs diff --git a/dynamic-check/src/assertions/type_assertion.rs b/type-inference/src/assertions/type_assertion.rs similarity index 100% rename from dynamic-check/src/assertions/type_assertion.rs rename to type-inference/src/assertions/type_assertion.rs diff --git a/dynamic-check/src/assertions/type_equality.rs b/type-inference/src/assertions/type_equality.rs similarity index 100% rename from dynamic-check/src/assertions/type_equality.rs rename to type-inference/src/assertions/type_equality.rs diff --git a/dynamic-check/src/assertions/type_membership.rs b/type-inference/src/assertions/type_membership.rs similarity index 100% rename from dynamic-check/src/assertions/type_membership.rs rename to type-inference/src/assertions/type_membership.rs diff --git a/dynamic-check/src/assertions/type_variable_pair.rs b/type-inference/src/assertions/type_variable_pair.rs similarity index 100% rename from dynamic-check/src/assertions/type_variable_pair.rs rename to type-inference/src/assertions/type_variable_pair.rs diff --git a/dynamic-check/src/errors/frame.rs b/type-inference/src/errors/frame.rs similarity index 100% rename from dynamic-check/src/errors/frame.rs rename to type-inference/src/errors/frame.rs diff --git a/dynamic-check/src/errors/mod.rs b/type-inference/src/errors/mod.rs similarity index 100% rename from dynamic-check/src/errors/mod.rs rename to type-inference/src/errors/mod.rs diff --git a/dynamic-check/src/errors/scope.rs b/type-inference/src/errors/scope.rs similarity index 100% rename from dynamic-check/src/errors/scope.rs rename to type-inference/src/errors/scope.rs diff --git a/dynamic-check/src/errors/type_assertion.rs b/type-inference/src/errors/type_assertion.rs similarity index 100% rename from dynamic-check/src/errors/type_assertion.rs rename to type-inference/src/errors/type_assertion.rs diff --git a/dynamic-check/src/errors/type_inference.rs b/type-inference/src/errors/type_inference.rs similarity index 100% rename from dynamic-check/src/errors/type_inference.rs rename to type-inference/src/errors/type_inference.rs diff --git a/dynamic-check/src/errors/variable_table.rs b/type-inference/src/errors/variable_table.rs similarity index 100% rename from dynamic-check/src/errors/variable_table.rs rename to type-inference/src/errors/variable_table.rs diff --git a/dynamic-check/src/lib.rs b/type-inference/src/lib.rs similarity index 100% rename from dynamic-check/src/lib.rs rename to type-inference/src/lib.rs diff --git a/dynamic-check/src/objects/frame.rs b/type-inference/src/objects/frame.rs similarity index 100% rename from dynamic-check/src/objects/frame.rs rename to type-inference/src/objects/frame.rs diff --git a/dynamic-check/src/objects/mod.rs b/type-inference/src/objects/mod.rs similarity index 100% rename from dynamic-check/src/objects/mod.rs rename to type-inference/src/objects/mod.rs diff --git a/dynamic-check/src/objects/scope.rs b/type-inference/src/objects/scope.rs similarity index 100% rename from dynamic-check/src/objects/scope.rs rename to type-inference/src/objects/scope.rs diff --git a/dynamic-check/src/objects/variable_table.rs b/type-inference/src/objects/variable_table.rs similarity index 100% rename from dynamic-check/src/objects/variable_table.rs rename to type-inference/src/objects/variable_table.rs diff --git a/dynamic-check/src/type_inference.rs b/type-inference/src/type_inference.rs similarity index 100% rename from dynamic-check/src/type_inference.rs rename to type-inference/src/type_inference.rs diff --git a/dynamic-check/tests/arrays/empty_array.leo b/type-inference/tests/arrays/empty_array.leo similarity index 100% rename from dynamic-check/tests/arrays/empty_array.leo rename to type-inference/tests/arrays/empty_array.leo diff --git a/dynamic-check/tests/arrays/invalid_array_access.leo b/type-inference/tests/arrays/invalid_array_access.leo similarity index 100% rename from dynamic-check/tests/arrays/invalid_array_access.leo rename to type-inference/tests/arrays/invalid_array_access.leo diff --git a/dynamic-check/tests/arrays/invalid_spread.leo b/type-inference/tests/arrays/invalid_spread.leo similarity index 100% rename from dynamic-check/tests/arrays/invalid_spread.leo rename to type-inference/tests/arrays/invalid_spread.leo diff --git a/dynamic-check/tests/arrays/mod.rs b/type-inference/tests/arrays/mod.rs similarity index 100% rename from dynamic-check/tests/arrays/mod.rs rename to type-inference/tests/arrays/mod.rs diff --git a/dynamic-check/tests/circuits/invalid_circuit.leo b/type-inference/tests/circuits/invalid_circuit.leo similarity index 100% rename from dynamic-check/tests/circuits/invalid_circuit.leo rename to type-inference/tests/circuits/invalid_circuit.leo diff --git a/dynamic-check/tests/circuits/mod.rs b/type-inference/tests/circuits/mod.rs similarity index 100% rename from dynamic-check/tests/circuits/mod.rs rename to type-inference/tests/circuits/mod.rs diff --git a/dynamic-check/tests/empty.leo b/type-inference/tests/empty.leo similarity index 100% rename from dynamic-check/tests/empty.leo rename to type-inference/tests/empty.leo diff --git a/dynamic-check/tests/functions/invalid_function.leo b/type-inference/tests/functions/invalid_function.leo similarity index 100% rename from dynamic-check/tests/functions/invalid_function.leo rename to type-inference/tests/functions/invalid_function.leo diff --git a/dynamic-check/tests/functions/mod.rs b/type-inference/tests/functions/mod.rs similarity index 100% rename from dynamic-check/tests/functions/mod.rs rename to type-inference/tests/functions/mod.rs diff --git a/dynamic-check/tests/mod.rs b/type-inference/tests/mod.rs similarity index 98% rename from dynamic-check/tests/mod.rs rename to type-inference/tests/mod.rs index 10dac2f0ad..6fdff9ef97 100644 --- a/dynamic-check/tests/mod.rs +++ b/type-inference/tests/mod.rs @@ -21,7 +21,7 @@ pub mod tuples; pub mod variables; use leo_ast::LeoAst; -use leo_dynamic_check::TypeInference; +use leo_type_inference::TypeInference; use leo_core_ast::{Input, LeoCoreAst, Program}; use leo_imports::ImportParser; diff --git a/dynamic-check/tests/tuples/invalid_tuple_access.leo b/type-inference/tests/tuples/invalid_tuple_access.leo similarity index 100% rename from dynamic-check/tests/tuples/invalid_tuple_access.leo rename to type-inference/tests/tuples/invalid_tuple_access.leo diff --git a/dynamic-check/tests/tuples/mod.rs b/type-inference/tests/tuples/mod.rs similarity index 100% rename from dynamic-check/tests/tuples/mod.rs rename to type-inference/tests/tuples/mod.rs diff --git a/dynamic-check/tests/variables/duplicate_variable.leo b/type-inference/tests/variables/duplicate_variable.leo similarity index 100% rename from dynamic-check/tests/variables/duplicate_variable.leo rename to type-inference/tests/variables/duplicate_variable.leo diff --git a/dynamic-check/tests/variables/duplicate_variable_multi.leo b/type-inference/tests/variables/duplicate_variable_multi.leo similarity index 100% rename from dynamic-check/tests/variables/duplicate_variable_multi.leo rename to type-inference/tests/variables/duplicate_variable_multi.leo diff --git a/dynamic-check/tests/variables/mod.rs b/type-inference/tests/variables/mod.rs similarity index 100% rename from dynamic-check/tests/variables/mod.rs rename to type-inference/tests/variables/mod.rs diff --git a/dynamic-check/tests/variables/not_enough_values.leo b/type-inference/tests/variables/not_enough_values.leo similarity index 100% rename from dynamic-check/tests/variables/not_enough_values.leo rename to type-inference/tests/variables/not_enough_values.leo diff --git a/dynamic-check/tests/variables/too_many_values.leo b/type-inference/tests/variables/too_many_values.leo similarity index 100% rename from dynamic-check/tests/variables/too_many_values.leo rename to type-inference/tests/variables/too_many_values.leo From 5a46cb5bb00e84a295c50bfe0b90e877545c9307 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 13:02:44 -0700 Subject: [PATCH 115/139] rename leo-core -> leo-core-packages --- Cargo.lock | 35 +++++++++---------- Cargo.toml | 6 +--- compiler/Cargo.toml | 8 ++--- compiler/src/errors/expression.rs | 4 +-- compiler/src/errors/import.rs | 4 +-- .../src/expression/function/core_circuit.rs | 2 +- compiler/src/import/store/core_package.rs | 4 +-- compiler/src/value/value.rs | 2 +- {core => core-packages}/Cargo.toml | 2 +- .../src/errors/core_circuit.rs | 0 .../src/errors/core_package.rs | 0 .../src/errors/core_package_list.rs | 0 .../src/errors/leo_core_package.rs | 12 +++---- {core => core-packages}/src/errors/mod.rs | 4 +-- {core => core-packages}/src/lib.rs | 5 +-- {core => core-packages}/src/packages/mod.rs | 0 .../src/packages/unstable/blake2s.rs | 0 .../src/packages/unstable/mod.rs | 0 .../src/types/core_circuit.rs | 0 .../src/types/core_circuit_struct_list.rs | 0 .../src/types/core_package.rs | 0 .../src/types/core_package_list.rs | 0 {core => core-packages}/src/types/mod.rs | 0 {core => core-packages}/src/types/value.rs | 0 symbol-table/Cargo.toml | 12 +++---- symbol-table/src/errors/symbol_table.rs | 6 ++-- symbol-table/src/symbol_table.rs | 2 +- 27 files changed, 52 insertions(+), 56 deletions(-) rename {core => core-packages}/Cargo.toml (97%) rename {core => core-packages}/src/errors/core_circuit.rs (100%) rename {core => core-packages}/src/errors/core_package.rs (100%) rename {core => core-packages}/src/errors/core_package_list.rs (100%) rename core/src/errors/leo_core.rs => core-packages/src/errors/leo_core_package.rs (79%) rename {core => core-packages}/src/errors/mod.rs (93%) rename {core => core-packages}/src/lib.rs (91%) rename {core => core-packages}/src/packages/mod.rs (100%) rename {core => core-packages}/src/packages/unstable/blake2s.rs (100%) rename {core => core-packages}/src/packages/unstable/mod.rs (100%) rename {core => core-packages}/src/types/core_circuit.rs (100%) rename {core => core-packages}/src/types/core_circuit_struct_list.rs (100%) rename {core => core-packages}/src/types/core_package.rs (100%) rename {core => core-packages}/src/types/core_package_list.rs (100%) rename {core => core-packages}/src/types/mod.rs (100%) rename {core => core-packages}/src/types/value.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index d66ecac8a5..1c494a5931 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1252,8 +1252,8 @@ dependencies = [ "bincode", "hex", "leo-ast", - "leo-core", "leo-core-ast", + "leo-core-packages", "leo-gadgets", "leo-imports", "leo-input", @@ -1281,7 +1281,21 @@ dependencies = [ ] [[package]] -name = "leo-core" +name = "leo-core-ast" +version = "1.0.3" +dependencies = [ + "criterion", + "leo-ast", + "leo-input", + "pest", + "serde", + "serde_json", + "snarkos-errors", + "snarkos-models", +] + +[[package]] +name = "leo-core-packages" version = "1.0.3" dependencies = [ "leo-core-ast", @@ -1296,20 +1310,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "leo-core-ast" -version = "1.0.3" -dependencies = [ - "criterion", - "leo-ast", - "leo-input", - "pest", - "serde", - "serde_json", - "snarkos-errors", - "snarkos-models", -] - [[package]] name = "leo-gadgets" version = "1.0.3" @@ -1363,7 +1363,6 @@ dependencies = [ "from-pest", "lazy_static", "leo-compiler", - "leo-core", "leo-core-ast", "leo-gadgets", "leo-imports", @@ -1435,8 +1434,8 @@ name = "leo-symbol-table" version = "1.0.3" dependencies = [ "leo-ast", - "leo-core", "leo-core-ast", + "leo-core-packages", "leo-imports", "serde", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index b95bcbc4b8..3e3be939df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ members = [ "ast", "compiler", "core-ast", - "core", + "core-packages", "gadgets", "imports", "input", @@ -44,10 +44,6 @@ members = [ path = "./compiler" version = "1.0.3" -[dependencies.leo-core] -path = "./core" -version = "1.0.1" - [dependencies.leo-core-ast] path = "./core-ast" version = "1.0.3" diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 485719aba4..5f56fa33bf 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -21,14 +21,14 @@ edition = "2018" path = "../ast" version = "1.0.3" -[dependencies.leo-core] -path = "../core" -version = "1.0.3" - [dependencies.leo-core-ast] path = "../core-ast" version = "1.0.3" +[dependencies.leo-core-packages] +path = "../core-packages" +version = "1.0.3" + [dependencies.leo-gadgets] path = "../gadgets" version = "1.0.3" diff --git a/compiler/src/errors/expression.rs b/compiler/src/errors/expression.rs index 705bb5fcd4..91a162b163 100644 --- a/compiler/src/errors/expression.rs +++ b/compiler/src/errors/expression.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::errors::{AddressError, BooleanError, FieldError, FunctionError, GroupError, IntegerError, ValueError}; -use leo_core::LeoCoreError; use leo_core_ast::{Error as FormattedError, Identifier, Span}; +use leo_core_packages::LeoCorePackageError; use snarkos_errors::gadgets::SynthesisError; use std::path::Path; @@ -45,7 +45,7 @@ pub enum ExpressionError { IntegerError(#[from] IntegerError), #[error("{}", _0)] - LeoCoreError(#[from] LeoCoreError), + LeoCoreError(#[from] LeoCorePackageError), #[error("{}", _0)] ValueError(#[from] ValueError), diff --git a/compiler/src/errors/import.rs b/compiler/src/errors/import.rs index 45f7885828..6bb9407c9d 100644 --- a/compiler/src/errors/import.rs +++ b/compiler/src/errors/import.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core::LeoCoreError; use leo_core_ast::{Error as FormattedError, Identifier, ImportSymbol, Span}; +use leo_core_packages::LeoCorePackageError; #[derive(Debug, Error)] pub enum ImportError { @@ -23,7 +23,7 @@ pub enum ImportError { Error(#[from] FormattedError), #[error("{}", _0)] - LeoCoreError(#[from] LeoCoreError), + LeoCoreError(#[from] LeoCorePackageError), } impl ImportError { diff --git a/compiler/src/expression/function/core_circuit.rs b/compiler/src/expression/function/core_circuit.rs index 31e48d8a52..8a43ae8bac 100644 --- a/compiler/src/expression/function/core_circuit.rs +++ b/compiler/src/expression/function/core_circuit.rs @@ -16,8 +16,8 @@ use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType}; use crate::errors::{ExpressionError, FunctionError}; -use leo_core::call_core_circuit; use leo_core_ast::{Expression, Span, Type}; +use leo_core_packages::call_core_circuit; use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::ConstraintSystem, diff --git a/compiler/src/import/store/core_package.rs b/compiler/src/import/store/core_package.rs index 940b6da46f..92741ffe85 100644 --- a/compiler/src/import/store/core_package.rs +++ b/compiler/src/import/store/core_package.rs @@ -17,11 +17,11 @@ use crate::{new_scope, ConstrainedProgram, ConstrainedValue, GroupType}; use leo_core_ast::Package; -use leo_core::{CorePackageList, LeoCoreError}; +use leo_core_packages::{CorePackageList, LeoCorePackageError}; use snarkos_models::curves::{Field, PrimeField}; impl> ConstrainedProgram { - pub(crate) fn store_core_package(&mut self, scope: &str, package: Package) -> Result<(), LeoCoreError> { + pub(crate) fn store_core_package(&mut self, scope: &str, package: Package) -> Result<(), LeoCorePackageError> { // Create list of imported core packages. let list = CorePackageList::from_package_access(package.access)?; diff --git a/compiler/src/value/value.rs b/compiler/src/value/value.rs index cf194e1460..e74a688ddb 100644 --- a/compiler/src/value/value.rs +++ b/compiler/src/value/value.rs @@ -26,8 +26,8 @@ use crate::{ GroupType, Integer, }; -use leo_core::Value; use leo_core_ast::{Circuit, Function, GroupValue, Identifier, Span, Type}; +use leo_core_packages::Value; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/core/Cargo.toml b/core-packages/Cargo.toml similarity index 97% rename from core/Cargo.toml rename to core-packages/Cargo.toml index 98ba2197e5..b0d93dc423 100644 --- a/core/Cargo.toml +++ b/core-packages/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "leo-core" +name = "leo-core-packages" version = "1.0.3" authors = [ "The Aleo Team " ] description = "Core package dependencies of the Leo programming language" diff --git a/core/src/errors/core_circuit.rs b/core-packages/src/errors/core_circuit.rs similarity index 100% rename from core/src/errors/core_circuit.rs rename to core-packages/src/errors/core_circuit.rs diff --git a/core/src/errors/core_package.rs b/core-packages/src/errors/core_package.rs similarity index 100% rename from core/src/errors/core_package.rs rename to core-packages/src/errors/core_package.rs diff --git a/core/src/errors/core_package_list.rs b/core-packages/src/errors/core_package_list.rs similarity index 100% rename from core/src/errors/core_package_list.rs rename to core-packages/src/errors/core_package_list.rs diff --git a/core/src/errors/leo_core.rs b/core-packages/src/errors/leo_core_package.rs similarity index 79% rename from core/src/errors/leo_core.rs rename to core-packages/src/errors/leo_core_package.rs index e5d42bf283..be5bed0ffb 100644 --- a/core/src/errors/leo_core.rs +++ b/core-packages/src/errors/leo_core_package.rs @@ -20,7 +20,7 @@ use leo_core_ast::{Error as FormattedError, Span}; use std::path::Path; #[derive(Debug, Error)] -pub enum LeoCoreError { +pub enum LeoCorePackageError { #[error("{}", _0)] CoreCircuitError(#[from] CoreCircuitError), @@ -31,17 +31,17 @@ pub enum LeoCoreError { Error(#[from] FormattedError), } -impl LeoCoreError { +impl LeoCorePackageError { pub fn set_path(&mut self, path: &Path) { match self { - LeoCoreError::CoreCircuitError(error) => error.set_path(path), - LeoCoreError::CorePackageListError(error) => error.set_path(path), - LeoCoreError::Error(error) => error.set_path(path), + LeoCorePackageError::CoreCircuitError(error) => error.set_path(path), + LeoCorePackageError::CorePackageListError(error) => error.set_path(path), + LeoCorePackageError::Error(error) => error.set_path(path), } } fn new_from_span(message: String, span: Span) -> Self { - LeoCoreError::Error(FormattedError::new_from_span(message, span)) + LeoCorePackageError::Error(FormattedError::new_from_span(message, span)) } pub fn undefined_core_circuit(circuit_name: String, span: Span) -> Self { diff --git a/core/src/errors/mod.rs b/core-packages/src/errors/mod.rs similarity index 93% rename from core/src/errors/mod.rs rename to core-packages/src/errors/mod.rs index 9bfb03c2ba..a99f9e8f47 100644 --- a/core/src/errors/mod.rs +++ b/core-packages/src/errors/mod.rs @@ -23,5 +23,5 @@ pub use self::core_package::*; pub mod core_package_list; pub use self::core_package_list::*; -pub mod leo_core; -pub use self::leo_core::*; +pub mod leo_core_package; +pub use self::leo_core_package::*; diff --git a/core/src/lib.rs b/core-packages/src/lib.rs similarity index 91% rename from core/src/lib.rs rename to core-packages/src/lib.rs index 810ab32d47..1293becee1 100644 --- a/core/src/lib.rs +++ b/core-packages/src/lib.rs @@ -28,6 +28,7 @@ pub use self::types::*; use crate::CoreCircuit; use leo_core_ast::Span; + use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::ConstraintSystem, @@ -40,10 +41,10 @@ pub fn call_core_circuit>( circuit_name: String, arguments: Vec, span: Span, -) -> Result, LeoCoreError> { +) -> Result, LeoCorePackageError> { // Match core circuit name Ok(match circuit_name.as_str() { CORE_UNSTABLE_BLAKE2S_NAME => Blake2sCircuit::call(cs, arguments, span)?, - _ => return Err(LeoCoreError::undefined_core_circuit(circuit_name, span)), + _ => return Err(LeoCorePackageError::undefined_core_circuit(circuit_name, span)), }) } diff --git a/core/src/packages/mod.rs b/core-packages/src/packages/mod.rs similarity index 100% rename from core/src/packages/mod.rs rename to core-packages/src/packages/mod.rs diff --git a/core/src/packages/unstable/blake2s.rs b/core-packages/src/packages/unstable/blake2s.rs similarity index 100% rename from core/src/packages/unstable/blake2s.rs rename to core-packages/src/packages/unstable/blake2s.rs diff --git a/core/src/packages/unstable/mod.rs b/core-packages/src/packages/unstable/mod.rs similarity index 100% rename from core/src/packages/unstable/mod.rs rename to core-packages/src/packages/unstable/mod.rs diff --git a/core/src/types/core_circuit.rs b/core-packages/src/types/core_circuit.rs similarity index 100% rename from core/src/types/core_circuit.rs rename to core-packages/src/types/core_circuit.rs diff --git a/core/src/types/core_circuit_struct_list.rs b/core-packages/src/types/core_circuit_struct_list.rs similarity index 100% rename from core/src/types/core_circuit_struct_list.rs rename to core-packages/src/types/core_circuit_struct_list.rs diff --git a/core/src/types/core_package.rs b/core-packages/src/types/core_package.rs similarity index 100% rename from core/src/types/core_package.rs rename to core-packages/src/types/core_package.rs diff --git a/core/src/types/core_package_list.rs b/core-packages/src/types/core_package_list.rs similarity index 100% rename from core/src/types/core_package_list.rs rename to core-packages/src/types/core_package_list.rs diff --git a/core/src/types/mod.rs b/core-packages/src/types/mod.rs similarity index 100% rename from core/src/types/mod.rs rename to core-packages/src/types/mod.rs diff --git a/core/src/types/value.rs b/core-packages/src/types/value.rs similarity index 100% rename from core/src/types/value.rs rename to core-packages/src/types/value.rs diff --git a/symbol-table/Cargo.toml b/symbol-table/Cargo.toml index 53f94a769e..29349208db 100644 --- a/symbol-table/Cargo.toml +++ b/symbol-table/Cargo.toml @@ -21,18 +21,18 @@ edition = "2018" path = "../ast" version = "1.0.3" -[dependencies.leo-core] -path = "../core" +[dependencies.leo-core-ast] +path = "../core-ast" +version = "1.0.3" + +[dependencies.leo-core-packages] +path = "../core-packages" version = "1.0.3" [dependencies.leo-imports] path = "../imports" version = "1.0.3" -[dependencies.leo-core-ast] -path = "../core-ast" -version = "1.0.3" - [dependencies.serde] version = "1.0" diff --git a/symbol-table/src/errors/symbol_table.rs b/symbol-table/src/errors/symbol_table.rs index 839d3b357f..0b1f61ef88 100644 --- a/symbol-table/src/errors/symbol_table.rs +++ b/symbol-table/src/errors/symbol_table.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::{TypeError, UserDefinedType}; -use leo_core::{CorePackageListError, LeoCoreError}; use leo_core_ast::{Error as FormattedError, ImportSymbol, Program, Span}; +use leo_core_packages::{CorePackageListError, LeoCorePackageError}; use std::path::Path; @@ -30,7 +30,7 @@ pub enum SymbolTableError { Error(#[from] FormattedError), #[error("{}", _0)] - LeoCoreError(#[from] LeoCoreError), + LeoCorePackageError(#[from] LeoCorePackageError), #[error("{}", _0)] TypeError(#[from] TypeError), @@ -44,7 +44,7 @@ impl SymbolTableError { match self { SymbolTableError::CorePackageListError(error) => error.set_path(path), SymbolTableError::Error(error) => error.set_path(path), - SymbolTableError::LeoCoreError(error) => error.set_path(path), + SymbolTableError::LeoCorePackageError(error) => error.set_path(path), SymbolTableError::TypeError(error) => error.set_path(path), } } diff --git a/symbol-table/src/symbol_table.rs b/symbol-table/src/symbol_table.rs index 2e2a8e0409..054adbd200 100644 --- a/symbol-table/src/symbol_table.rs +++ b/symbol-table/src/symbol_table.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::{CircuitType, CircuitVariableType, FunctionType, ImportedSymbols, SymbolTableError, UserDefinedType}; -use leo_core::CorePackageList; use leo_core_ast::{Circuit, Function, Identifier, ImportStatement, ImportSymbol, Input, Package, Program}; +use leo_core_packages::CorePackageList; use leo_imports::ImportParser; use std::collections::{HashMap, HashSet}; From 61f4189483f881a060514b165483795f334786f0 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 16:23:18 -0700 Subject: [PATCH 116/139] Add documentation for renamed modules --- ast/src/lib.rs | 13 ++++ compiler/src/compiler.rs | 64 +++++++++++++------ core-ast/src/lib.rs | 23 +++++-- core-ast/src/main.rs | 12 ++-- core-ast/src/program.rs | 2 +- ..._typed_ast.json => expected_core_ast.json} | 0 core-ast/tests/serialization/json.rs | 58 ++++++++--------- symbol-table/src/lib.rs | 5 ++ symbol-table/src/symbol_table.rs | 7 +- type-inference/src/lib.rs | 5 ++ type-inference/src/type_inference.rs | 6 +- 11 files changed, 127 insertions(+), 68 deletions(-) rename core-ast/tests/serialization/{expected_typed_ast.json => expected_core_ast.json} (100%) diff --git a/ast/src/lib.rs b/ast/src/lib.rs index 19e29aa73b..0958b11514 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -14,6 +14,13 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +//! The pest abstract syntax tree (ast) for a Leo program. +//! +//! This module contains the [`LeoAst`] type, a wrapper around the [`File`] type. +//! The [`LeoAst`] type is the datatype generated by the pest parser using grammar from `leo.pest`. +//! The [`LeoAst`] type is intended to be parsed into a [`LeoCoreAst`]. It should not be parsed by +//! any other pass of the compiler. + #[macro_use] extern crate lazy_static; #[macro_use] @@ -47,6 +54,12 @@ pub(crate) use span::*; use from_pest::FromPest; use std::{fs, path::Path}; +/// The pest abstract syntax tree (ast) for a Leo program. +/// +/// The [`LeoAst`] type represents a Leo program as a series of recursive data types. +/// These data types form a tree that begins from a [`File`] type root. +/// +/// A new [`LeoAst`] can be created from a `*.leo` file at a [`Path`]. pub struct LeoAst<'ast> { ast: files::File<'ast>, } diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 60f6af701b..5a7e64d627 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -46,6 +46,7 @@ use std::{ path::{Path, PathBuf}, }; +/// Stores information to compile a Leo program. #[derive(Clone)] pub struct Compiler> { package_name: String, @@ -76,9 +77,11 @@ impl> Compiler { } /// - /// Parses program files. + /// Returns a new `Compiler` from the given main file path. /// - /// Returns a compiler struct that stores the typed program abstract syntax trees (ast). + /// Parses and stores a program from the main file path. + /// Parses and stores all imported programs. + /// Performs type inference checking on the program and imported programs. /// pub fn parse_program_without_input( package_name: String, @@ -93,9 +96,12 @@ impl> Compiler { } /// - /// Parses input, state, and program files. + /// Returns a new `Compiler` from the given main file path. /// - /// Returns a compiler struct that stores the typed input and typed program abstract syntax trees (ast). + /// Parses and stores program input from from the input file path and state file path + /// Parses and stores a program from the main file path. + /// Parses and stores all imported programs. + /// Performs type inference checking on the program, imported programs, and program input. /// pub fn parse_program_with_input( package_name: String, @@ -116,9 +122,9 @@ impl> Compiler { } /// - /// Parse the input and state files. + /// Parses and stores program input from from the input file path and state file path /// - /// Stores a typed ast of all input variables to the program. + /// Calls `set_path()` on compiler errors with the given input file path or state file path /// pub fn parse_input( &mut self, @@ -153,7 +159,7 @@ impl> Compiler { } /// - /// Runs program parser and program checker consecutively. + /// Runs program parser and type inference checker consecutively. /// pub(crate) fn parse_and_check_program(&mut self) -> Result<(), CompilerError> { self.parse_program()?; @@ -162,23 +168,28 @@ impl> Compiler { } /// - /// Parses the Leo program file, constructs a syntax tree, and generates a program. + /// Parses and stores the main program file, constructs a syntax tree, and generates a program. + /// + /// Parses and stores all programs imported by the main program file. /// pub(crate) fn parse_program(&mut self) -> Result<(), CompilerError> { // Load the program file. let program_string = LeoAst::load_file(&self.main_file_path)?; - // Use the parser to construct the abstract syntax tree. - let ast = LeoAst::new(&self.main_file_path, &program_string).map_err(|mut e| { + // Use the parser to construct the pest abstract syntax tree (ast). + let pest_ast = LeoAst::new(&self.main_file_path, &program_string).map_err(|mut e| { e.set_path(&self.main_file_path); e })?; - // Use the typed parser to construct the typed syntax tree. - let typed_tree = LeoCoreAst::new(&self.package_name, &ast); + // Construct the core ast from the pest ast. + let core_ast = LeoCoreAst::new(&self.package_name, &pest_ast); - self.program = typed_tree.into_repr(); + // Store the main program file. + self.program = core_ast.into_repr(); + + // Parse and store all programs imported by the main program file. self.imported_programs = ImportParser::parse(&self.program)?; tracing::debug!("Program parsing complete\n{:#?}", self.program); @@ -215,7 +226,9 @@ impl> Compiler { } /// - /// Parses the Leo program string, constructs a syntax tree, and generates a program. + /// Equivalent to parse_and_check_program but uses the given program_string instead of a main + /// file path. + /// /// Used for testing only. /// #[deprecated(note = "Please use the 'parse_program' method instead.")] @@ -230,10 +243,13 @@ impl> Compiler { // Derive the package name. let package_name = &self.package_name; - // Use the typed parser to construct the typed syntax tree. - let typed_tree = LeoCoreAst::new(package_name, &ast); + // Construct the core ast from the pest ast. + let core_ast = LeoCoreAst::new(package_name, &ast); - self.program = typed_tree.into_repr(); + // Store the main program file. + self.program = core_ast.into_repr(); + + // Parse and store all programs imported by the main program file. self.imported_programs = ImportParser::parse(&self.program)?; // Create a new symbol table from the program, imported programs, and program input. @@ -248,14 +264,16 @@ impl> Compiler { } /// - /// Manually sets main function input + /// Manually sets main function input. + /// + /// Used for testing only. /// pub fn set_main_input(&mut self, input: MainInput) { self.program_input.set_main_input(input); } /// - /// Verifies the input to the program + /// Verifies the input to the program. /// pub fn verify_local_data_commitment( &self, @@ -297,7 +315,9 @@ impl> Compiler { ) } + /// /// Synthesizes the circuit for test functions with program input. + /// pub fn compile_test_constraints(self, input_pairs: InputPairs) -> Result<(u32, u32), CompilerError> { generate_test_constraints::( self.program, @@ -308,7 +328,9 @@ impl> Compiler { ) } - /// Calls the internal generate_constraints method with arguments + /// + /// Calls the internal generate_constraints method with arguments. + /// pub fn generate_constraints_helper>( self, cs: &mut CS, @@ -324,7 +346,9 @@ impl> Compiler { } impl> ConstraintSynthesizer for Compiler { + /// /// Synthesizes the circuit with program input. + /// fn generate_constraints>(self, cs: &mut CS) -> Result<(), SynthesisError> { let output_directory = self.output_directory.clone(); let package_name = self.package_name.clone(); diff --git a/core-ast/src/lib.rs b/core-ast/src/lib.rs index 4fd6b30468..de3f71d91b 100644 --- a/core-ast/src/lib.rs +++ b/core-ast/src/lib.rs @@ -14,8 +14,11 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -//! A typed syntax tree is represented as a `Program` and consists of import, circuit, and function definitions. -//! Each defined type consists of typed statements and expressions. +//! The core abstract syntax tree (ast) for a Leo program. +//! +//! This module contains the [`LeoCoreAst`] type, a wrapper around the [`Program`] type. +//! The [`LeoCoreAst`] type is intended to be parsed and modified by different passes +//! of the Leo compiler. The Leo compiler can generate a set of R1CS constraints from any [`LeoCoreAst`]. pub mod annotation; pub use self::annotation::*; @@ -58,32 +61,38 @@ pub use self::types::*; use leo_ast::LeoAst; +/// The core abstract syntax tree (ast) for a Leo program. +/// +/// The [`LeoCoreAst`] type represents a Leo program as a series of recursive data types. +/// These data types form a tree that begins from a [`Program`] type root. +/// +/// A new [`LeoCoreAst`] can be created from a [`LeoAst`] generated by the pest parser in the `ast` module. #[derive(Debug, Eq, PartialEq)] pub struct LeoCoreAst { - typed_ast: Program, + core_ast: Program, } impl LeoCoreAst { /// Creates a new core syntax tree from a given program name and abstract syntax tree. pub fn new<'ast>(program_name: &str, ast: &LeoAst<'ast>) -> Self { Self { - typed_ast: Program::from(program_name, ast.as_repr()), + core_ast: Program::from(program_name, ast.as_repr()), } } /// Returns a reference to the inner program syntax tree representation. pub fn into_repr(self) -> Program { - self.typed_ast + self.core_ast } /// Serializes the core syntax tree into a JSON string. pub fn to_json_string(&self) -> Result { - Ok(serde_json::to_string_pretty(&self.typed_ast)?) + Ok(serde_json::to_string_pretty(&self.core_ast)?) } /// Deserializes the JSON string into a core syntax tree. pub fn from_json_string(json: &str) -> Result { let typed_ast: Program = serde_json::from_str(json)?; - Ok(Self { typed_ast }) + Ok(Self { core_ast: typed_ast }) } } diff --git a/core-ast/src/main.rs b/core-ast/src/main.rs index 31d5c244b9..0c32254a7a 100644 --- a/core-ast/src/main.rs +++ b/core-ast/src/main.rs @@ -23,16 +23,16 @@ fn to_leo_core_tree(filepath: &Path) -> Result { let program_filepath = filepath.to_path_buf(); let program_string = LeoAst::load_file(&program_filepath)?; - // Parses the Leo file and constructs an abstract syntax tree. + // Parses the Leo file and constructs a pest ast. let ast = LeoAst::new(&program_filepath, &program_string)?; - // Parse the abstract core tree and constructs a typed core tree. - let typed_ast = LeoCoreAst::new("leo_core_tree", &ast); + // Parse the pest ast and constructs a core ast. + let core_ast = LeoCoreAst::new("leo_core_tree", &ast); - // Serializes the typed core tree into JSON format. - let serialized_typed_tree = LeoCoreAst::to_json_string(&typed_ast)?; + // Serializes the core tree into JSON format. + let serialized_core_ast = LeoCoreAst::to_json_string(&core_ast)?; - Ok(serialized_typed_tree) + Ok(serialized_core_ast) } fn main() -> Result<(), ParserError> { diff --git a/core-ast/src/program.rs b/core-ast/src/program.rs index 6db317a82b..8e7226ebb1 100644 --- a/core-ast/src/program.rs +++ b/core-ast/src/program.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -//! A typed Leo program consists of import, circuit, and function definitions. +//! A 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, ImportStatement, TestFunction}; diff --git a/core-ast/tests/serialization/expected_typed_ast.json b/core-ast/tests/serialization/expected_core_ast.json similarity index 100% rename from core-ast/tests/serialization/expected_typed_ast.json rename to core-ast/tests/serialization/expected_core_ast.json diff --git a/core-ast/tests/serialization/json.rs b/core-ast/tests/serialization/json.rs index 6ee4c62a54..66ea7f06fc 100644 --- a/core-ast/tests/serialization/json.rs +++ b/core-ast/tests/serialization/json.rs @@ -21,74 +21,74 @@ use leo_core_ast::Program; use std::path::{Path, PathBuf}; -fn to_typed_ast(program_filepath: &Path) -> LeoCoreAst { +fn to_core_ast(program_filepath: &Path) -> LeoCoreAst { // Loads the Leo code as a string from the given file path. let program_string = LeoAst::load_file(program_filepath).unwrap(); - // Parses the Leo file and constructs an abstract syntax tree. + // Parses the Leo file and constructs a pest ast. let ast = LeoAst::new(&program_filepath, &program_string).unwrap(); - // Parse the abstract syntax tree and constructs a typed syntax tree. + // Parses the pest ast and constructs a core ast. LeoCoreAst::new("leo_core_tree", &ast) } #[test] #[cfg(not(feature = "ci_skip"))] fn test_serialize() { - // Construct a typed syntax tree from the given test file. - let typed_ast = { + // Construct a core ast from the given test file. + let core_ast = { let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR")); program_filepath.push("tests/serialization/main.leo"); - to_typed_ast(&program_filepath) + to_core_ast(&program_filepath) }; - // Serializes the typed syntax tree into JSON format. - let serialized_typed_ast: Program = - serde_json::from_value(serde_json::to_value(typed_ast.into_repr()).unwrap()).unwrap(); + // Serializes the core ast into JSON format. + let serialized_core_ast: Program = + serde_json::from_value(serde_json::to_value(core_ast.into_repr()).unwrap()).unwrap(); - // Load the expected typed syntax tree. - let expected: Program = serde_json::from_str(include_str!("expected_typed_ast.json")).unwrap(); + // Load the expected core ast. + let expected: Program = serde_json::from_str(include_str!("expected_core_ast.json")).unwrap(); - assert_eq!(expected, serialized_typed_ast); + assert_eq!(expected, serialized_core_ast); } #[test] #[cfg(not(feature = "ci_skip"))] fn test_deserialize() { - // Load the expected typed syntax tree. - let expected_typed_ast = { + // Load the expected core ast. + let expected_core_ast = { let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR")); program_filepath.push("tests/serialization/main.leo"); - to_typed_ast(&program_filepath) + to_core_ast(&program_filepath) }; - // Construct a typed syntax tree by deserializing a typed syntax tree JSON file. - let serialized_typed_ast = include_str!("expected_typed_ast.json"); - let typed_ast = LeoCoreAst::from_json_string(serialized_typed_ast).unwrap(); + // Construct a core ast by deserializing a core ast JSON file. + let serialized_typed_ast = include_str!("expected_core_ast.json"); + let core_ast = LeoCoreAst::from_json_string(serialized_typed_ast).unwrap(); - assert_eq!(expected_typed_ast, typed_ast); + assert_eq!(expected_core_ast, core_ast); } #[test] fn test_serialize_deserialize_serialize() { - // Construct a typed syntax tree from the given test file. - let typed_ast = { + // Construct a core ast from the given test file. + let core_ast = { let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR")); program_filepath.push("tests/serialization/main.leo"); - to_typed_ast(&program_filepath) + to_core_ast(&program_filepath) }; - // Serializes the typed syntax tree into JSON format. - let serialized_typed_ast = typed_ast.to_json_string().unwrap(); + // Serializes the core ast into JSON format. + let serialized_core_ast = core_ast.to_json_string().unwrap(); - // Deserializes the typed syntax tree into a LeoTypedAst. - let typed_ast = LeoCoreAst::from_json_string(&serialized_typed_ast).unwrap(); + // Deserializes the serialized core ast into a LeoCoreAst. + let core_ast = LeoCoreAst::from_json_string(&serialized_core_ast).unwrap(); - // Reserializes the typed syntax tree into JSON format. - let reserialized_typed_ast = typed_ast.to_json_string().unwrap(); + // Reserializes the core ast into JSON format. + let reserialized_core_ast = core_ast.to_json_string().unwrap(); - assert_eq!(serialized_typed_ast, reserialized_typed_ast); + assert_eq!(serialized_core_ast, reserialized_core_ast); } diff --git a/symbol-table/src/lib.rs b/symbol-table/src/lib.rs index 2497e304eb..c2d801653c 100644 --- a/symbol-table/src/lib.rs +++ b/symbol-table/src/lib.rs @@ -14,6 +14,11 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +//! The symbol table for a Leo program. +//! +//! This module contains the [`SymbolTable`] type, an abstract data type that tracks the current +//! bindings for functions and circuits in a Leo program. + #[macro_use] extern crate thiserror; diff --git a/symbol-table/src/symbol_table.rs b/symbol-table/src/symbol_table.rs index 054adbd200..7af8f9a530 100644 --- a/symbol-table/src/symbol_table.rs +++ b/symbol-table/src/symbol_table.rs @@ -27,12 +27,11 @@ pub const REGISTERS_VARIABLE_NAME: &str = "registers"; pub const STATE_VARIABLE_NAME: &str = "state"; pub const STATE_LEAF_VARIABLE_NAME: &str = "state_leaf"; -/// A abstract data type that tracks the current bindings for functions and circuits. +/// The symbol table for a Leo program. /// -/// A symbol table has access to all function and circuit names in its -/// parent's symbol table. +/// A symbol table has access to all function and circuit names in its parent's symbol table. /// A symbol table cannot access names in its child's symbol table. -/// Children cannot access names in another sibling's symbol table. +/// A child symbol table cannot access names in another sibling's symbol table. #[derive(Clone, Default)] pub struct SymbolTable { /// Maps name -> parameter type. diff --git a/type-inference/src/lib.rs b/type-inference/src/lib.rs index cbe7bdd069..488cd38d30 100644 --- a/type-inference/src/lib.rs +++ b/type-inference/src/lib.rs @@ -14,6 +14,11 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +//! A type inference check for a Leo program. +//! +//! This module contains the [`TypeInference`] type, which stores information needed to run a type +//! inference check over a program. + #[macro_use] extern crate thiserror; diff --git a/type-inference/src/type_inference.rs b/type-inference/src/type_inference.rs index 4f9e7fcc48..1984203e7e 100644 --- a/type-inference/src/type_inference.rs +++ b/type-inference/src/type_inference.rs @@ -18,7 +18,11 @@ use crate::{Frame, Scope, TypeInferenceError}; use leo_core_ast::{Circuit, CircuitMember, Function, Program}; use leo_symbol_table::SymbolTable; -/// Stores information need to run a type inference check over a program. +/// A type inference check for a Leo program. +/// +/// A [`TypeInference`] type stores a stack of frames. A new frame is created for every +/// function. Frames store type assertions that assert an expression is a type. +/// Calling the `check()` method on a [`TypeInference`] checks that all type assertions are satisfied. pub struct TypeInference { table: SymbolTable, frames: Vec, From ffcd93f781e9afaeb2273e33d3bb097da2fc12cd Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 17:17:17 -0700 Subject: [PATCH 117/139] rename ast -> grammar 1 --- Cargo.lock | 42 +++++++++---------- Cargo.toml | 2 +- compiler/Cargo.toml | 10 ++--- compiler/src/compiler.rs | 8 ++-- compiler/src/errors/compiler.rs | 2 +- compiler/tests/syntax/mod.rs | 2 +- core-ast/Cargo.toml | 6 +-- core-ast/benches/core_ast.rs | 18 ++++---- core-ast/src/annotation.rs | 2 +- core-ast/src/circuits/circuit.rs | 2 +- core-ast/src/circuits/circuit_member.rs | 2 +- .../circuits/circuit_variable_definition.rs | 2 +- core-ast/src/common/assignee.rs | 2 +- core-ast/src/common/declare.rs | 2 +- core-ast/src/common/identifier.rs | 2 +- core-ast/src/common/range_or_expression.rs | 2 +- core-ast/src/common/spread_or_expression.rs | 2 +- core-ast/src/common/variable_name.rs | 2 +- core-ast/src/common/variables.rs | 2 +- core-ast/src/console/console_function.rs | 2 +- core-ast/src/console/console_function_call.rs | 2 +- core-ast/src/console/formatted_container.rs | 2 +- core-ast/src/console/formatted_parameter.rs | 2 +- core-ast/src/console/formatted_string.rs | 2 +- core-ast/src/expression.rs | 4 +- core-ast/src/functions/function.rs | 2 +- .../src/functions/input/function_input.rs | 2 +- .../src/functions/input/input_variable.rs | 2 +- core-ast/src/functions/test_function.rs | 2 +- core-ast/src/groups/group_coordinate.rs | 2 +- core-ast/src/groups/group_value.rs | 2 +- core-ast/src/imports/import.rs | 2 +- core-ast/src/imports/import_symbol.rs | 2 +- core-ast/src/imports/package.rs | 2 +- core-ast/src/imports/package_access.rs | 2 +- core-ast/src/lib.rs | 4 +- core-ast/src/main.rs | 6 +-- core-ast/src/program.rs | 2 +- .../conditional_nested_or_end_statement.rs | 2 +- .../src/statements/conditional_statement.rs | 2 +- core-ast/src/statements/statement.rs | 2 +- core-ast/src/types/integer_type.rs | 2 +- core-ast/src/types/type_.rs | 2 +- core-ast/tests/serialization/json.rs | 6 +-- {ast => grammar}/Cargo.toml | 4 +- {ast => grammar}/README.md | 4 +- {ast => grammar}/benches/ast.rs | 8 ++-- {ast => grammar}/benches/main.leo | 0 {ast => grammar}/src/access/access.rs | 0 {ast => grammar}/src/access/array_access.rs | 0 .../src/access/assignee_access.rs | 0 {ast => grammar}/src/access/call_access.rs | 0 {ast => grammar}/src/access/member_access.rs | 0 {ast => grammar}/src/access/mod.rs | 0 .../src/access/static_member_access.rs | 0 {ast => grammar}/src/access/tuple_access.rs | 0 .../src/annotations/annotation_arguments.rs | 0 .../src/annotations/annotation_name.rs | 0 .../src/annotations/annotation_symbol.rs | 0 .../src/annotations/annotations.rs | 0 {ast => grammar}/src/annotations/mod.rs | 0 {ast => grammar}/src/ast.rs | 0 {ast => grammar}/src/circuits/circuit.rs | 0 .../src/circuits/circuit_function.rs | 0 .../src/circuits/circuit_member.rs | 0 .../src/circuits/circuit_variable.rs | 0 .../circuits/circuit_variable_definition.rs | 0 {ast => grammar}/src/circuits/mod.rs | 0 {ast => grammar}/src/common/assignee.rs | 0 {ast => grammar}/src/common/declare.rs | 0 {ast => grammar}/src/common/eoi.rs | 0 {ast => grammar}/src/common/identifier.rs | 0 .../src/common/keyword_or_identifier.rs | 0 {ast => grammar}/src/common/line_end.rs | 0 {ast => grammar}/src/common/mod.rs | 0 {ast => grammar}/src/common/mutable.rs | 0 {ast => grammar}/src/common/range.rs | 0 .../src/common/range_or_expression.rs | 0 {ast => grammar}/src/common/self_keyword.rs | 0 .../src/common/self_keyword_or_identifier.rs | 0 {ast => grammar}/src/common/spread.rs | 0 .../src/common/spread_or_expression.rs | 0 {ast => grammar}/src/common/static_.rs | 0 {ast => grammar}/src/common/variable_name.rs | 0 {ast => grammar}/src/common/variables.rs | 0 .../src/console/console_assert.rs | 0 {ast => grammar}/src/console/console_debug.rs | 0 {ast => grammar}/src/console/console_error.rs | 0 .../src/console/console_function.rs | 0 .../src/console/console_function_call.rs | 0 .../src/console/console_keyword.rs | 0 {ast => grammar}/src/console/console_log.rs | 0 .../src/console/formatted_container.rs | 0 .../src/console/formatted_parameter.rs | 0 .../src/console/formatted_string.rs | 0 {ast => grammar}/src/console/mod.rs | 0 .../src/definitions/annotated_definition.rs | 0 .../src/definitions/definition.rs | 0 {ast => grammar}/src/definitions/mod.rs | 0 {ast => grammar}/src/errors/mod.rs | 0 {ast => grammar}/src/errors/parser.rs | 0 {ast => grammar}/src/errors/syntax.rs | 0 .../array_initializer_expression.rs | 0 .../expressions/array_inline_expression.rs | 0 .../src/expressions/binary_expression.rs | 0 .../expressions/circuit_inline_expression.rs | 0 .../src/expressions/expression.rs | 0 {ast => grammar}/src/expressions/mod.rs | 0 .../src/expressions/postfix_expression.rs | 0 .../src/expressions/ternary_expression.rs | 0 .../src/expressions/tuple_expression.rs | 0 .../src/expressions/unary_expression.rs | 0 {ast => grammar}/src/files/file.rs | 0 {ast => grammar}/src/files/mod.rs | 0 {ast => grammar}/src/functions/function.rs | 0 .../src/functions/input/function_input.rs | 0 {ast => grammar}/src/functions/input/input.rs | 0 .../src/functions/input/input_keyword.rs | 0 {ast => grammar}/src/functions/input/mod.rs | 0 {ast => grammar}/src/functions/mod.rs | 0 .../src/functions/test_function.rs | 0 {ast => grammar}/src/imports/import.rs | 0 {ast => grammar}/src/imports/import_symbol.rs | 0 {ast => grammar}/src/imports/mod.rs | 0 {ast => grammar}/src/imports/package.rs | 0 .../src/imports/package_access.rs | 0 {ast => grammar}/src/imports/package_name.rs | 0 {ast => grammar}/src/imports/star.rs | 0 {ast => grammar}/src/leo.pest | 0 {ast => grammar}/src/lib.rs | 14 +++---- {ast => grammar}/src/main.rs | 14 +++---- .../src/operations/assign_operation.rs | 0 .../src/operations/binary_operation.rs | 0 {ast => grammar}/src/operations/mod.rs | 0 .../src/operations/unary_operation.rs | 0 {ast => grammar}/src/span.rs | 0 .../src/statements/assign_statement.rs | 0 .../conditional_nested_or_end_statement.rs | 0 .../src/statements/conditional_statement.rs | 0 .../src/statements/definition_statement.rs | 0 .../src/statements/expression_statement.rs | 0 .../src/statements/for_statement.rs | 0 {ast => grammar}/src/statements/mod.rs | 0 .../src/statements/return_statement.rs | 0 {ast => grammar}/src/statements/statement.rs | 0 {ast => grammar}/src/types/address_type.rs | 0 .../src/types/array_dimensions.rs | 0 {ast => grammar}/src/types/array_type.rs | 0 {ast => grammar}/src/types/boolean_type.rs | 0 {ast => grammar}/src/types/circuit_type.rs | 0 {ast => grammar}/src/types/data_type.rs | 0 {ast => grammar}/src/types/field_type.rs | 0 {ast => grammar}/src/types/group_type.rs | 0 {ast => grammar}/src/types/integer_type.rs | 0 {ast => grammar}/src/types/mod.rs | 0 {ast => grammar}/src/types/self_type.rs | 0 .../src/types/signed_integer_type.rs | 0 {ast => grammar}/src/types/tuple_type.rs | 0 {ast => grammar}/src/types/type_.rs | 0 .../src/types/unsigned_integer_type.rs | 0 {ast => grammar}/src/values/address.rs | 0 {ast => grammar}/src/values/address_value.rs | 0 {ast => grammar}/src/values/boolean_value.rs | 0 {ast => grammar}/src/values/field_value.rs | 0 .../src/values/group_coordinate.rs | 0 {ast => grammar}/src/values/group_value.rs | 0 {ast => grammar}/src/values/integer_value.rs | 0 {ast => grammar}/src/values/mod.rs | 0 .../src/values/negative_number.rs | 0 {ast => grammar}/src/values/number_value.rs | 0 .../src/values/positive_number.rs | 0 .../src/values/signed_integer_value.rs | 0 .../src/values/unsigned_integer_value.rs | 0 {ast => grammar}/src/values/value.rs | 0 {ast => grammar}/tests/expression.rs | 2 +- {ast => grammar}/tests/function.rs | 2 +- {ast => grammar}/tests/mod.rs | 0 .../tests/serialization/expected_ast.json | 0 {ast => grammar}/tests/serialization/json.rs | 8 ++-- {ast => grammar}/tests/serialization/main.leo | 0 {ast => grammar}/tests/serialization/mod.rs | 0 {ast => grammar}/tests/tuple.rs | 2 +- imports/Cargo.toml | 8 ++-- imports/src/errors/import_parser.rs | 2 +- imports/src/parser/parse_symbol.rs | 6 +-- symbol-table/Cargo.toml | 4 +- symbol-table/tests/mod.rs | 4 +- type-inference/Cargo.toml | 8 ++-- type-inference/tests/mod.rs | 4 +- 189 files changed, 134 insertions(+), 134 deletions(-) rename {ast => grammar}/Cargo.toml (96%) rename {ast => grammar}/README.md (70%) rename {ast => grammar}/benches/ast.rs (80%) rename {ast => grammar}/benches/main.leo (100%) rename {ast => grammar}/src/access/access.rs (100%) rename {ast => grammar}/src/access/array_access.rs (100%) rename {ast => grammar}/src/access/assignee_access.rs (100%) rename {ast => grammar}/src/access/call_access.rs (100%) rename {ast => grammar}/src/access/member_access.rs (100%) rename {ast => grammar}/src/access/mod.rs (100%) rename {ast => grammar}/src/access/static_member_access.rs (100%) rename {ast => grammar}/src/access/tuple_access.rs (100%) rename {ast => grammar}/src/annotations/annotation_arguments.rs (100%) rename {ast => grammar}/src/annotations/annotation_name.rs (100%) rename {ast => grammar}/src/annotations/annotation_symbol.rs (100%) rename {ast => grammar}/src/annotations/annotations.rs (100%) rename {ast => grammar}/src/annotations/mod.rs (100%) rename {ast => grammar}/src/ast.rs (100%) rename {ast => grammar}/src/circuits/circuit.rs (100%) rename {ast => grammar}/src/circuits/circuit_function.rs (100%) rename {ast => grammar}/src/circuits/circuit_member.rs (100%) rename {ast => grammar}/src/circuits/circuit_variable.rs (100%) rename {ast => grammar}/src/circuits/circuit_variable_definition.rs (100%) rename {ast => grammar}/src/circuits/mod.rs (100%) rename {ast => grammar}/src/common/assignee.rs (100%) rename {ast => grammar}/src/common/declare.rs (100%) rename {ast => grammar}/src/common/eoi.rs (100%) rename {ast => grammar}/src/common/identifier.rs (100%) rename {ast => grammar}/src/common/keyword_or_identifier.rs (100%) rename {ast => grammar}/src/common/line_end.rs (100%) rename {ast => grammar}/src/common/mod.rs (100%) rename {ast => grammar}/src/common/mutable.rs (100%) rename {ast => grammar}/src/common/range.rs (100%) rename {ast => grammar}/src/common/range_or_expression.rs (100%) rename {ast => grammar}/src/common/self_keyword.rs (100%) rename {ast => grammar}/src/common/self_keyword_or_identifier.rs (100%) rename {ast => grammar}/src/common/spread.rs (100%) rename {ast => grammar}/src/common/spread_or_expression.rs (100%) rename {ast => grammar}/src/common/static_.rs (100%) rename {ast => grammar}/src/common/variable_name.rs (100%) rename {ast => grammar}/src/common/variables.rs (100%) rename {ast => grammar}/src/console/console_assert.rs (100%) rename {ast => grammar}/src/console/console_debug.rs (100%) rename {ast => grammar}/src/console/console_error.rs (100%) rename {ast => grammar}/src/console/console_function.rs (100%) rename {ast => grammar}/src/console/console_function_call.rs (100%) rename {ast => grammar}/src/console/console_keyword.rs (100%) rename {ast => grammar}/src/console/console_log.rs (100%) rename {ast => grammar}/src/console/formatted_container.rs (100%) rename {ast => grammar}/src/console/formatted_parameter.rs (100%) rename {ast => grammar}/src/console/formatted_string.rs (100%) rename {ast => grammar}/src/console/mod.rs (100%) rename {ast => grammar}/src/definitions/annotated_definition.rs (100%) rename {ast => grammar}/src/definitions/definition.rs (100%) rename {ast => grammar}/src/definitions/mod.rs (100%) rename {ast => grammar}/src/errors/mod.rs (100%) rename {ast => grammar}/src/errors/parser.rs (100%) rename {ast => grammar}/src/errors/syntax.rs (100%) rename {ast => grammar}/src/expressions/array_initializer_expression.rs (100%) rename {ast => grammar}/src/expressions/array_inline_expression.rs (100%) rename {ast => grammar}/src/expressions/binary_expression.rs (100%) rename {ast => grammar}/src/expressions/circuit_inline_expression.rs (100%) rename {ast => grammar}/src/expressions/expression.rs (100%) rename {ast => grammar}/src/expressions/mod.rs (100%) rename {ast => grammar}/src/expressions/postfix_expression.rs (100%) rename {ast => grammar}/src/expressions/ternary_expression.rs (100%) rename {ast => grammar}/src/expressions/tuple_expression.rs (100%) rename {ast => grammar}/src/expressions/unary_expression.rs (100%) rename {ast => grammar}/src/files/file.rs (100%) rename {ast => grammar}/src/files/mod.rs (100%) rename {ast => grammar}/src/functions/function.rs (100%) rename {ast => grammar}/src/functions/input/function_input.rs (100%) rename {ast => grammar}/src/functions/input/input.rs (100%) rename {ast => grammar}/src/functions/input/input_keyword.rs (100%) rename {ast => grammar}/src/functions/input/mod.rs (100%) rename {ast => grammar}/src/functions/mod.rs (100%) rename {ast => grammar}/src/functions/test_function.rs (100%) rename {ast => grammar}/src/imports/import.rs (100%) rename {ast => grammar}/src/imports/import_symbol.rs (100%) rename {ast => grammar}/src/imports/mod.rs (100%) rename {ast => grammar}/src/imports/package.rs (100%) rename {ast => grammar}/src/imports/package_access.rs (100%) rename {ast => grammar}/src/imports/package_name.rs (100%) rename {ast => grammar}/src/imports/star.rs (100%) rename {ast => grammar}/src/leo.pest (100%) rename {ast => grammar}/src/lib.rs (85%) rename {ast => grammar}/src/main.rs (82%) rename {ast => grammar}/src/operations/assign_operation.rs (100%) rename {ast => grammar}/src/operations/binary_operation.rs (100%) rename {ast => grammar}/src/operations/mod.rs (100%) rename {ast => grammar}/src/operations/unary_operation.rs (100%) rename {ast => grammar}/src/span.rs (100%) rename {ast => grammar}/src/statements/assign_statement.rs (100%) rename {ast => grammar}/src/statements/conditional_nested_or_end_statement.rs (100%) rename {ast => grammar}/src/statements/conditional_statement.rs (100%) rename {ast => grammar}/src/statements/definition_statement.rs (100%) rename {ast => grammar}/src/statements/expression_statement.rs (100%) rename {ast => grammar}/src/statements/for_statement.rs (100%) rename {ast => grammar}/src/statements/mod.rs (100%) rename {ast => grammar}/src/statements/return_statement.rs (100%) rename {ast => grammar}/src/statements/statement.rs (100%) rename {ast => grammar}/src/types/address_type.rs (100%) rename {ast => grammar}/src/types/array_dimensions.rs (100%) rename {ast => grammar}/src/types/array_type.rs (100%) rename {ast => grammar}/src/types/boolean_type.rs (100%) rename {ast => grammar}/src/types/circuit_type.rs (100%) rename {ast => grammar}/src/types/data_type.rs (100%) rename {ast => grammar}/src/types/field_type.rs (100%) rename {ast => grammar}/src/types/group_type.rs (100%) rename {ast => grammar}/src/types/integer_type.rs (100%) rename {ast => grammar}/src/types/mod.rs (100%) rename {ast => grammar}/src/types/self_type.rs (100%) rename {ast => grammar}/src/types/signed_integer_type.rs (100%) rename {ast => grammar}/src/types/tuple_type.rs (100%) rename {ast => grammar}/src/types/type_.rs (100%) rename {ast => grammar}/src/types/unsigned_integer_type.rs (100%) rename {ast => grammar}/src/values/address.rs (100%) rename {ast => grammar}/src/values/address_value.rs (100%) rename {ast => grammar}/src/values/boolean_value.rs (100%) rename {ast => grammar}/src/values/field_value.rs (100%) rename {ast => grammar}/src/values/group_coordinate.rs (100%) rename {ast => grammar}/src/values/group_value.rs (100%) rename {ast => grammar}/src/values/integer_value.rs (100%) rename {ast => grammar}/src/values/mod.rs (100%) rename {ast => grammar}/src/values/negative_number.rs (100%) rename {ast => grammar}/src/values/number_value.rs (100%) rename {ast => grammar}/src/values/positive_number.rs (100%) rename {ast => grammar}/src/values/signed_integer_value.rs (100%) rename {ast => grammar}/src/values/unsigned_integer_value.rs (100%) rename {ast => grammar}/src/values/value.rs (100%) rename {ast => grammar}/tests/expression.rs (95%) rename {ast => grammar}/tests/function.rs (98%) rename {ast => grammar}/tests/mod.rs (100%) rename {ast => grammar}/tests/serialization/expected_ast.json (100%) rename {ast => grammar}/tests/serialization/json.rs (83%) rename {ast => grammar}/tests/serialization/main.leo (100%) rename {ast => grammar}/tests/serialization/mod.rs (100%) rename {ast => grammar}/tests/tuple.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 1c494a5931..4c50516204 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1229,32 +1229,16 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" -[[package]] -name = "leo-ast" -version = "1.0.3" -dependencies = [ - "criterion", - "from-pest", - "lazy_static", - "pest", - "pest-ast", - "pest_derive", - "serde", - "serde_json", - "thiserror", - "tracing", -] - [[package]] name = "leo-compiler" version = "1.0.3" dependencies = [ "bincode", "hex", - "leo-ast", "leo-core-ast", "leo-core-packages", "leo-gadgets", + "leo-grammar", "leo-imports", "leo-input", "leo-package", @@ -1285,7 +1269,7 @@ name = "leo-core-ast" version = "1.0.3" dependencies = [ "criterion", - "leo-ast", + "leo-grammar", "leo-input", "pest", "serde", @@ -1323,12 +1307,28 @@ dependencies = [ "thiserror", ] +[[package]] +name = "leo-grammar" +version = "1.0.3" +dependencies = [ + "criterion", + "from-pest", + "lazy_static", + "pest", + "pest-ast", + "pest_derive", + "serde", + "serde_json", + "thiserror", + "tracing", +] + [[package]] name = "leo-imports" version = "1.0.3" dependencies = [ - "leo-ast", "leo-core-ast", + "leo-grammar", "thiserror", "tracing", ] @@ -1433,9 +1433,9 @@ dependencies = [ name = "leo-symbol-table" version = "1.0.3" dependencies = [ - "leo-ast", "leo-core-ast", "leo-core-packages", + "leo-grammar", "leo-imports", "serde", "thiserror", @@ -1445,8 +1445,8 @@ dependencies = [ name = "leo-type-inference" version = "1.0.3" dependencies = [ - "leo-ast", "leo-core-ast", + "leo-grammar", "leo-imports", "leo-symbol-table", "serde", diff --git a/Cargo.toml b/Cargo.toml index 3e3be939df..e79ed39390 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,11 +26,11 @@ path = "leo/main.rs" [workspace] members = [ - "ast", "compiler", "core-ast", "core-packages", "gadgets", + "grammar", "imports", "input", "linter", diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 5f56fa33bf..e48679a3d4 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -17,10 +17,6 @@ include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" -[dependencies.leo-ast] -path = "../ast" -version = "1.0.3" - [dependencies.leo-core-ast] path = "../core-ast" version = "1.0.3" @@ -33,6 +29,10 @@ version = "1.0.3" path = "../gadgets" version = "1.0.3" +[dependencies.leo-grammar] +path = "../grammar" +version = "1.0.3" + [dependencies.leo-imports] path = "../imports" version = "1.0.3" @@ -124,4 +124,4 @@ default-features = false [features] default = [ ] -ci_skip = [ "leo-ast/ci_skip", "leo-core-ast/ci_skip" ] +ci_skip = [ "leo-grammar/ci_skip", "leo-core-ast/ci_skip" ] diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 5a7e64d627..ffe6e98af8 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -23,8 +23,8 @@ use crate::{ OutputBytes, OutputFile, }; -use leo_ast::LeoAst; use leo_core_ast::{Input, LeoCoreAst, MainInput, Program}; +use leo_grammar::Grammar; use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; @@ -174,10 +174,10 @@ impl> Compiler { /// pub(crate) fn parse_program(&mut self) -> Result<(), CompilerError> { // Load the program file. - let program_string = LeoAst::load_file(&self.main_file_path)?; + let program_string = Grammar::load_file(&self.main_file_path)?; // Use the parser to construct the pest abstract syntax tree (ast). - let pest_ast = LeoAst::new(&self.main_file_path, &program_string).map_err(|mut e| { + let pest_ast = Grammar::new(&self.main_file_path, &program_string).map_err(|mut e| { e.set_path(&self.main_file_path); e @@ -234,7 +234,7 @@ impl> Compiler { #[deprecated(note = "Please use the 'parse_program' method instead.")] pub fn parse_program_from_string(&mut self, program_string: &str) -> Result<(), CompilerError> { // Use the given bytes to construct the abstract syntax tree. - let ast = LeoAst::new(&self.main_file_path, &program_string).map_err(|mut e| { + let ast = Grammar::new(&self.main_file_path, &program_string).map_err(|mut e| { e.set_path(&self.main_file_path); e diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index 7ab49c5c34..f5820ba127 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError}; -use leo_ast::ParserError; +use leo_grammar::ParserError; use leo_imports::ImportParserError; use leo_input::InputParserError; use leo_state::LocalDataVerificationError; diff --git a/compiler/tests/syntax/mod.rs b/compiler/tests/syntax/mod.rs index ec39dfc10a..55b7292d2a 100644 --- a/compiler/tests/syntax/mod.rs +++ b/compiler/tests/syntax/mod.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::{expect_compiler_error, parse_input, parse_program}; -use leo_ast::ParserError; use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError}; +use leo_grammar::ParserError; use leo_input::InputParserError; use leo_type_inference::errors::{FrameError, TypeAssertionError, TypeInferenceError}; diff --git a/core-ast/Cargo.toml b/core-ast/Cargo.toml index 9da4243a77..282c7cd4a5 100644 --- a/core-ast/Cargo.toml +++ b/core-ast/Cargo.toml @@ -26,8 +26,8 @@ name = "core_ast" path = "benches/core_ast.rs" harness = false -[dependencies.leo-ast] -path = "../ast" +[dependencies.leo-grammar] +path = "../grammar" version = "1.0.3" [dependencies.leo-input] @@ -56,4 +56,4 @@ version = "0.3" [features] default = [ ] -ci_skip = [ "leo-ast/ci_skip" ] +ci_skip = [ "leo-grammar/ci_skip" ] diff --git a/core-ast/benches/core_ast.rs b/core-ast/benches/core_ast.rs index 9b9d0cfb32..d95ee191d3 100644 --- a/core-ast/benches/core_ast.rs +++ b/core-ast/benches/core_ast.rs @@ -14,20 +14,20 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::LeoAst; use leo_core_ast::LeoCoreAst; +use leo_grammar::Grammar; use criterion::{criterion_group, criterion_main, Criterion}; use std::{path::Path, time::Duration}; -fn leo_core_ast<'ast>(ast: &LeoAst<'ast>) -> LeoCoreAst { +fn leo_core_ast<'ast>(ast: &Grammar<'ast>) -> LeoCoreAst { LeoCoreAst::new("leo_core_tree", &ast) } fn bench_big_if_else(c: &mut Criterion) { let filepath = Path::new("./big_if_else.leo").to_path_buf(); let program_string = include_str!("./big_if_else.leo"); - let ast = LeoAst::new(&filepath, program_string).unwrap(); + let ast = Grammar::new(&filepath, program_string).unwrap(); c.bench_function("LeoCoreAst::big_if_else", |b| b.iter(|| leo_core_ast(&ast))); } @@ -35,7 +35,7 @@ fn bench_big_if_else(c: &mut Criterion) { fn bench_big_ternary(c: &mut Criterion) { let filepath = Path::new("./big_ternary.leo").to_path_buf(); let program_string = include_str!("./big_ternary.leo"); - let ast = LeoAst::new(&filepath, program_string).unwrap(); + let ast = Grammar::new(&filepath, program_string).unwrap(); c.bench_function("LeoCoreAst::big_ternary", |b| b.iter(|| leo_core_ast(&ast))); } @@ -43,7 +43,7 @@ fn bench_big_ternary(c: &mut Criterion) { fn bench_big_circuit(c: &mut Criterion) { let filepath = Path::new("./big_circuit.leo").to_path_buf(); let program_string = include_str!("./big_circuit.leo"); - let ast = LeoAst::new(&filepath, program_string).unwrap(); + let ast = Grammar::new(&filepath, program_string).unwrap(); c.bench_function("LeoCoreAst::big_circuit", |b| b.iter(|| leo_core_ast(&ast))); } @@ -51,7 +51,7 @@ fn bench_big_circuit(c: &mut Criterion) { fn bench_long_expr(c: &mut Criterion) { let filepath = Path::new("./long_expr.leo").to_path_buf(); let program_string = include_str!("./long_expr.leo"); - let ast = LeoAst::new(&filepath, program_string).unwrap(); + let ast = Grammar::new(&filepath, program_string).unwrap(); c.bench_function("LeoCoreAst::long_expr", |b| b.iter(|| leo_core_ast(&ast))); } @@ -59,7 +59,7 @@ fn bench_long_expr(c: &mut Criterion) { fn bench_long_array(c: &mut Criterion) { let filepath = Path::new("./long_array.leo").to_path_buf(); let program_string = include_str!("./long_array.leo"); - let ast = LeoAst::new(&filepath, program_string).unwrap(); + let ast = Grammar::new(&filepath, program_string).unwrap(); c.bench_function("LeoCoreAst::long_array", |b| b.iter(|| leo_core_ast(&ast))); } @@ -67,7 +67,7 @@ fn bench_long_array(c: &mut Criterion) { fn bench_many_foos(c: &mut Criterion) { let filepath = Path::new("./many_foos.leo").to_path_buf(); let program_string = include_str!("./many_foos.leo"); - let ast = LeoAst::new(&filepath, program_string).unwrap(); + let ast = Grammar::new(&filepath, program_string).unwrap(); c.bench_function("LeoCoreAst::many_foos", |b| b.iter(|| leo_core_ast(&ast))); } @@ -75,7 +75,7 @@ fn bench_many_foos(c: &mut Criterion) { fn bench_many_assigns(c: &mut Criterion) { let filepath = Path::new("./many_assigns.leo").to_path_buf(); let program_string = include_str!("./many_assigns.leo"); - let ast = LeoAst::new(&filepath, program_string).unwrap(); + let ast = Grammar::new(&filepath, program_string).unwrap(); c.bench_function("LeoCoreAst::many_assigns", |b| b.iter(|| leo_core_ast(&ast))); } diff --git a/core-ast/src/annotation.rs b/core-ast/src/annotation.rs index 67439869b2..2a882c1fc0 100644 --- a/core-ast/src/annotation.rs +++ b/core-ast/src/annotation.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Circuit, Function, FunctionInput, Identifier, ImportStatement, TestFunction}; -use leo_ast::{ +use leo_grammar::{ annotations::{Annotation, AnnotationArguments, AnnotationName}, definitions::{AnnotatedDefinition, Definition}, }; diff --git a/core-ast/src/circuits/circuit.rs b/core-ast/src/circuits/circuit.rs index cc5c6216af..c6c27c846a 100644 --- a/core-ast/src/circuits/circuit.rs +++ b/core-ast/src/circuits/circuit.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CircuitMember, Identifier}; -use leo_ast::circuits::Circuit as AstCircuit; +use leo_grammar::circuits::Circuit as AstCircuit; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/circuits/circuit_member.rs b/core-ast/src/circuits/circuit_member.rs index 008806d3d3..b738901ad3 100644 --- a/core-ast/src/circuits/circuit_member.rs +++ b/core-ast/src/circuits/circuit_member.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Function, Identifier, Type}; -use leo_ast::circuits::{ +use leo_grammar::circuits::{ CircuitFunction as AstCircuitFunction, CircuitMember as AstCircuitMember, CircuitVariableDefinition as AstCircuitVariableDefinition, diff --git a/core-ast/src/circuits/circuit_variable_definition.rs b/core-ast/src/circuits/circuit_variable_definition.rs index 2abba2b377..efa345f9d5 100644 --- a/core-ast/src/circuits/circuit_variable_definition.rs +++ b/core-ast/src/circuits/circuit_variable_definition.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, Identifier}; -use leo_ast::circuits::CircuitVariable; +use leo_grammar::circuits::CircuitVariable; use serde::{Deserialize, Serialize}; diff --git a/core-ast/src/common/assignee.rs b/core-ast/src/common/assignee.rs index 9007420a6f..3d55d74985 100644 --- a/core-ast/src/common/assignee.rs +++ b/core-ast/src/common/assignee.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, Identifier, RangeOrExpression, Span}; -use leo_ast::{access::AssigneeAccess as AstAssigneeAccess, common::Assignee as AstAssignee}; +use leo_grammar::{access::AssigneeAccess as AstAssigneeAccess, common::Assignee as AstAssignee}; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/common/declare.rs b/core-ast/src/common/declare.rs index 4fb9d28d85..12ceceeebc 100644 --- a/core-ast/src/common/declare.rs +++ b/core-ast/src/common/declare.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::common::Declare as AstDeclare; +use leo_grammar::common::Declare as AstDeclare; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/common/identifier.rs b/core-ast/src/common/identifier.rs index b83fa5b557..97ce361644 100644 --- a/core-ast/src/common/identifier.rs +++ b/core-ast/src/common/identifier.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Span; -use leo_ast::{ +use leo_grammar::{ annotations::AnnotationArgument, common::{Identifier as AstIdentifier, KeywordOrIdentifier, SelfKeyword, SelfKeywordOrIdentifier}, expressions::CircuitName, diff --git a/core-ast/src/common/range_or_expression.rs b/core-ast/src/common/range_or_expression.rs index 60f1f97acd..0406497ff6 100644 --- a/core-ast/src/common/range_or_expression.rs +++ b/core-ast/src/common/range_or_expression.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Expression; -use leo_ast::common::RangeOrExpression as AstRangeOrExpression; +use leo_grammar::common::RangeOrExpression as AstRangeOrExpression; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/common/spread_or_expression.rs b/core-ast/src/common/spread_or_expression.rs index c6f817bdc4..d6e41861c9 100644 --- a/core-ast/src/common/spread_or_expression.rs +++ b/core-ast/src/common/spread_or_expression.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Expression; -use leo_ast::{common::SpreadOrExpression as AstSpreadOrExpression, expressions::Expression as AstExpression}; +use leo_grammar::{common::SpreadOrExpression as AstSpreadOrExpression, expressions::Expression as AstExpression}; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/common/variable_name.rs b/core-ast/src/common/variable_name.rs index bb0a92300f..2141207d0f 100644 --- a/core-ast/src/common/variable_name.rs +++ b/core-ast/src/common/variable_name.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::common::{Identifier, Span}; -use leo_ast::common::VariableName as AstVariableName; +use leo_grammar::common::VariableName as AstVariableName; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/common/variables.rs b/core-ast/src/common/variables.rs index f3c7efa68a..75c43c8a97 100644 --- a/core-ast/src/common/variables.rs +++ b/core-ast/src/common/variables.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Type, VariableName}; -use leo_ast::common::Variables as AstVariables; +use leo_grammar::common::Variables as AstVariables; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/console/console_function.rs b/core-ast/src/console/console_function.rs index 95d0a0c37d..781acefecd 100644 --- a/core-ast/src/console/console_function.rs +++ b/core-ast/src/console/console_function.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, FormattedString}; -use leo_ast::console::{ +use leo_grammar::console::{ ConsoleAssert as AstConsoleAssert, ConsoleDebug as AstConsoleDebug, ConsoleError as AstConsoleError, diff --git a/core-ast/src/console/console_function_call.rs b/core-ast/src/console/console_function_call.rs index b036528bd3..e2fa9293f2 100644 --- a/core-ast/src/console/console_function_call.rs +++ b/core-ast/src/console/console_function_call.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ConsoleFunction, Span}; -use leo_ast::console::ConsoleFunctionCall as AstConsoleFunctionCall; +use leo_grammar::console::ConsoleFunctionCall as AstConsoleFunctionCall; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/console/formatted_container.rs b/core-ast/src/console/formatted_container.rs index 5e2ce9e0b9..0647c5af56 100644 --- a/core-ast/src/console/formatted_container.rs +++ b/core-ast/src/console/formatted_container.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Span; -use leo_ast::console::FormattedContainer as AstFormattedContainer; +use leo_grammar::console::FormattedContainer as AstFormattedContainer; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/console/formatted_parameter.rs b/core-ast/src/console/formatted_parameter.rs index 79249e5fbc..c61c0122e2 100644 --- a/core-ast/src/console/formatted_parameter.rs +++ b/core-ast/src/console/formatted_parameter.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, Span}; -use leo_ast::console::FormattedParameter as AstFormattedParameter; +use leo_grammar::console::FormattedParameter as AstFormattedParameter; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/console/formatted_string.rs b/core-ast/src/console/formatted_string.rs index b3d41fe20f..a880220465 100644 --- a/core-ast/src/console/formatted_string.rs +++ b/core-ast/src/console/formatted_string.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{FormattedContainer, FormattedParameter, Span}; -use leo_ast::console::FormattedString as AstFormattedString; +use leo_grammar::console::FormattedString as AstFormattedString; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/expression.rs b/core-ast/src/expression.rs index 1a8734448c..7ab2018004 100644 --- a/core-ast/src/expression.rs +++ b/core-ast/src/expression.rs @@ -23,7 +23,7 @@ use crate::{ Span, SpreadOrExpression, }; -use leo_ast::{ +use leo_grammar::{ access::{Access, AssigneeAccess}, common::{Assignee, Identifier as AstIdentifier}, expressions::{ @@ -50,7 +50,7 @@ use leo_ast::{ }; use leo_input::{types::ArrayDimensions as InputArrayDimensions, values::PositiveNumber as InputAstPositiveNumber}; -use leo_ast::{expressions::TupleExpression, types::ArrayDimensions}; +use leo_grammar::{expressions::TupleExpression, types::ArrayDimensions}; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/functions/function.rs b/core-ast/src/functions/function.rs index 535d53415e..15cfcba9fc 100644 --- a/core-ast/src/functions/function.rs +++ b/core-ast/src/functions/function.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{FunctionInput, Identifier, Span, Statement, Type}; -use leo_ast::functions::Function as AstFunction; +use leo_grammar::functions::Function as AstFunction; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/functions/input/function_input.rs b/core-ast/src/functions/input/function_input.rs index 5de9468f94..03d8587d97 100644 --- a/core-ast/src/functions/input/function_input.rs +++ b/core-ast/src/functions/input/function_input.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Identifier, Span, Type}; -use leo_ast::functions::FunctionInput as AstFunctionInput; +use leo_grammar::functions::FunctionInput as AstFunctionInput; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/functions/input/input_variable.rs b/core-ast/src/functions/input/input_variable.rs index 01974dda8a..46b8d8b315 100644 --- a/core-ast/src/functions/input/input_variable.rs +++ b/core-ast/src/functions/input/input_variable.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{FunctionInputVariable, Identifier, Span}; -use leo_ast::functions::input::Input as AstInput; +use leo_grammar::functions::input::Input as AstInput; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/functions/test_function.rs b/core-ast/src/functions/test_function.rs index d4d2fec220..b567a48307 100644 --- a/core-ast/src/functions/test_function.rs +++ b/core-ast/src/functions/test_function.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Function, Identifier}; -use leo_ast::functions::TestFunction as AstTestFunction; +use leo_grammar::functions::TestFunction as AstTestFunction; use serde::{Deserialize, Serialize}; diff --git a/core-ast/src/groups/group_coordinate.rs b/core-ast/src/groups/group_coordinate.rs index 8b84d950e2..5b653b041d 100644 --- a/core-ast/src/groups/group_coordinate.rs +++ b/core-ast/src/groups/group_coordinate.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::common::span::Span; -use leo_ast::values::{ +use leo_grammar::values::{ GroupCoordinate as AstGroupCoordinate, Inferred as AstInferred, NumberValue as AstNumberValue, diff --git a/core-ast/src/groups/group_value.rs b/core-ast/src/groups/group_value.rs index ad4c19406e..83fdc35a57 100644 --- a/core-ast/src/groups/group_value.rs +++ b/core-ast/src/groups/group_value.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{common::span::Span, groups::GroupCoordinate}; -use leo_ast::values::{ +use leo_grammar::values::{ GroupRepresentation as AstGroupRepresentation, GroupTuple as AstGroupTuple, GroupValue as AstGroupValue, diff --git a/core-ast/src/imports/import.rs b/core-ast/src/imports/import.rs index 3c47d204ab..54135eba43 100644 --- a/core-ast/src/imports/import.rs +++ b/core-ast/src/imports/import.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Package, Span}; -use leo_ast::imports::Import as AstImport; +use leo_grammar::imports::Import as AstImport; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/imports/import_symbol.rs b/core-ast/src/imports/import_symbol.rs index d27904f0fb..bdd67843fc 100644 --- a/core-ast/src/imports/import_symbol.rs +++ b/core-ast/src/imports/import_symbol.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Identifier, Span}; -use leo_ast::imports::ImportSymbol as AstImportSymbol; +use leo_grammar::imports::ImportSymbol as AstImportSymbol; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/imports/package.rs b/core-ast/src/imports/package.rs index 79ddfb6cb9..de4e4b2a35 100644 --- a/core-ast/src/imports/package.rs +++ b/core-ast/src/imports/package.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{common::Identifier, PackageAccess, Span}; -use leo_ast::imports::Package as AstPackage; +use leo_grammar::imports::Package as AstPackage; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/imports/package_access.rs b/core-ast/src/imports/package_access.rs index 0af5b54820..a9c6817256 100644 --- a/core-ast/src/imports/package_access.rs +++ b/core-ast/src/imports/package_access.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ImportSymbol, Package, Span}; -use leo_ast::imports::PackageAccess as AstPackageAccess; +use leo_grammar::imports::PackageAccess as AstPackageAccess; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/lib.rs b/core-ast/src/lib.rs index de3f71d91b..59f42f94ef 100644 --- a/core-ast/src/lib.rs +++ b/core-ast/src/lib.rs @@ -59,7 +59,7 @@ pub use self::statements::*; pub mod types; pub use self::types::*; -use leo_ast::LeoAst; +use leo_grammar::Grammar; /// The core abstract syntax tree (ast) for a Leo program. /// @@ -74,7 +74,7 @@ pub struct LeoCoreAst { impl LeoCoreAst { /// Creates a new core syntax tree from a given program name and abstract syntax tree. - pub fn new<'ast>(program_name: &str, ast: &LeoAst<'ast>) -> Self { + pub fn new<'ast>(program_name: &str, ast: &Grammar<'ast>) -> Self { Self { core_ast: Program::from(program_name, ast.as_repr()), } diff --git a/core-ast/src/main.rs b/core-ast/src/main.rs index 0c32254a7a..1020575d33 100644 --- a/core-ast/src/main.rs +++ b/core-ast/src/main.rs @@ -14,17 +14,17 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::{LeoAst, ParserError}; use leo_core_ast::LeoCoreAst; +use leo_grammar::{Grammar, ParserError}; use std::{env, fs, path::Path}; fn to_leo_core_tree(filepath: &Path) -> Result { // Loads the Leo code as a string from the given file path. let program_filepath = filepath.to_path_buf(); - let program_string = LeoAst::load_file(&program_filepath)?; + let program_string = Grammar::load_file(&program_filepath)?; // Parses the Leo file and constructs a pest ast. - let ast = LeoAst::new(&program_filepath, &program_string)?; + let ast = Grammar::new(&program_filepath, &program_string)?; // Parse the pest ast and constructs a core ast. let core_ast = LeoCoreAst::new("leo_core_tree", &ast); diff --git a/core-ast/src/program.rs b/core-ast/src/program.rs index 8e7226ebb1..5b21a165ab 100644 --- a/core-ast/src/program.rs +++ b/core-ast/src/program.rs @@ -18,7 +18,7 @@ //! Each defined type consists of typed statements and expressions. use crate::{load_annotation, Circuit, Function, FunctionInput, Identifier, ImportStatement, TestFunction}; -use leo_ast::{definitions::Definition, files::File}; +use leo_grammar::{definitions::Definition, files::File}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; diff --git a/core-ast/src/statements/conditional_nested_or_end_statement.rs b/core-ast/src/statements/conditional_nested_or_end_statement.rs index 5dbe8b1c5d..2ee01c045c 100644 --- a/core-ast/src/statements/conditional_nested_or_end_statement.rs +++ b/core-ast/src/statements/conditional_nested_or_end_statement.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ConditionalStatement, Statement}; -use leo_ast::statements::ConditionalNestedOrEndStatement as AstConditionalNestedOrEndStatement; +use leo_grammar::statements::ConditionalNestedOrEndStatement as AstConditionalNestedOrEndStatement; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/statements/conditional_statement.rs b/core-ast/src/statements/conditional_statement.rs index 90983251e6..299fbbb1ae 100644 --- a/core-ast/src/statements/conditional_statement.rs +++ b/core-ast/src/statements/conditional_statement.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ConditionalNestedOrEndStatement, Expression, Statement}; -use leo_ast::statements::ConditionalStatement as AstConditionalStatement; +use leo_grammar::statements::ConditionalStatement as AstConditionalStatement; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/core-ast/src/statements/statement.rs b/core-ast/src/statements/statement.rs index af19425402..adf0eee4a1 100644 --- a/core-ast/src/statements/statement.rs +++ b/core-ast/src/statements/statement.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Assignee, ConditionalStatement, ConsoleFunctionCall, Declare, Expression, Identifier, Span, Variables}; -use leo_ast::{ +use leo_grammar::{ console::ConsoleFunctionCall as AstConsoleFunctionCall, operations::AssignOperation, statements::{ diff --git a/core-ast/src/types/integer_type.rs b/core-ast/src/types/integer_type.rs index e766c65168..cdf75e0f8a 100644 --- a/core-ast/src/types/integer_type.rs +++ b/core-ast/src/types/integer_type.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::types::{ +use leo_grammar::types::{ IntegerType as AstIntegerType, SignedIntegerType as AstSignedIntegerType, UnsignedIntegerType as AstUnsignedIntegerType, diff --git a/core-ast/src/types/type_.rs b/core-ast/src/types/type_.rs index e27918c020..aced7b5045 100644 --- a/core-ast/src/types/type_.rs +++ b/core-ast/src/types/type_.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, Identifier, IntegerType}; -use leo_ast::types::{ArrayType, CircuitType, DataType, TupleType, Type as AstType}; +use leo_grammar::types::{ArrayType, CircuitType, DataType, TupleType, Type as AstType}; use leo_input::types::{ ArrayType as InputArrayType, DataType as InputDataType, diff --git a/core-ast/tests/serialization/json.rs b/core-ast/tests/serialization/json.rs index 66ea7f06fc..c18ade9a05 100644 --- a/core-ast/tests/serialization/json.rs +++ b/core-ast/tests/serialization/json.rs @@ -14,19 +14,19 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::LeoAst; use leo_core_ast::LeoCoreAst; #[cfg(not(feature = "ci_skip"))] use leo_core_ast::Program; +use leo_grammar::Grammar; use std::path::{Path, PathBuf}; fn to_core_ast(program_filepath: &Path) -> LeoCoreAst { // Loads the Leo code as a string from the given file path. - let program_string = LeoAst::load_file(program_filepath).unwrap(); + let program_string = Grammar::load_file(program_filepath).unwrap(); // Parses the Leo file and constructs a pest ast. - let ast = LeoAst::new(&program_filepath, &program_string).unwrap(); + let ast = Grammar::new(&program_filepath, &program_string).unwrap(); // Parses the pest ast and constructs a core ast. LeoCoreAst::new("leo_core_tree", &ast) diff --git a/ast/Cargo.toml b/grammar/Cargo.toml similarity index 96% rename from ast/Cargo.toml rename to grammar/Cargo.toml index 8de1763207..f435e29b46 100644 --- a/ast/Cargo.toml +++ b/grammar/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "leo-ast" +name = "leo-grammar" version = "1.0.3" authors = [ "The Aleo Team " ] description = "AST of the Leo programming language" @@ -18,7 +18,7 @@ license = "GPL-3.0" edition = "2018" [[bin]] -name = "leo_ast" +name = "leo_grammar" path = "src/main.rs" [[bench]] diff --git a/ast/README.md b/grammar/README.md similarity index 70% rename from ast/README.md rename to grammar/README.md index 1752725766..b1b3c02f13 100644 --- a/ast/README.md +++ b/grammar/README.md @@ -1,9 +1,9 @@ -# leo-ast +# leo-grammar ## Command-line instructions To generate an AST of the Leo program and save it as a JSON file , run: ``` -leo_ast {PATH/TO/INPUT_FILENAME}.leo {PATH/TO/OUTPUT_DIRECTORY (optional)} +leo_grammar {PATH/TO/INPUT_FILENAME}.leo {PATH/TO/OUTPUT_DIRECTORY (optional)} ``` If no output directory is provided, then the program will store the JSON file in the local working directory. diff --git a/ast/benches/ast.rs b/grammar/benches/ast.rs similarity index 80% rename from ast/benches/ast.rs rename to grammar/benches/ast.rs index 1dc9fedf14..4b6d48b105 100644 --- a/ast/benches/ast.rs +++ b/grammar/benches/ast.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::LeoAst; +use leo_grammar::Grammar; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use std::path::Path; -fn leo_ast<'ast>(filepath: &'ast Path, program_string: &'ast str) { - let result = LeoAst::<'ast>::new(filepath, program_string).unwrap(); +fn leo_grammar<'ast>(filepath: &'ast Path, program_string: &'ast str) { + let result = Grammar::<'ast>::new(filepath, program_string).unwrap(); black_box(result); } @@ -28,7 +28,7 @@ fn criterion_benchmark(c: &mut Criterion) { let filepath = Path::new("./main.leo").to_path_buf(); let program_string = include_str!("./main.leo"); - c.bench_function("LeoAst::new", |b| b.iter(|| leo_ast(&filepath, program_string))); + c.bench_function("Grammar::new", |b| b.iter(|| leo_grammar(&filepath, program_string))); } criterion_group!(benches, criterion_benchmark); diff --git a/ast/benches/main.leo b/grammar/benches/main.leo similarity index 100% rename from ast/benches/main.leo rename to grammar/benches/main.leo diff --git a/ast/src/access/access.rs b/grammar/src/access/access.rs similarity index 100% rename from ast/src/access/access.rs rename to grammar/src/access/access.rs diff --git a/ast/src/access/array_access.rs b/grammar/src/access/array_access.rs similarity index 100% rename from ast/src/access/array_access.rs rename to grammar/src/access/array_access.rs diff --git a/ast/src/access/assignee_access.rs b/grammar/src/access/assignee_access.rs similarity index 100% rename from ast/src/access/assignee_access.rs rename to grammar/src/access/assignee_access.rs diff --git a/ast/src/access/call_access.rs b/grammar/src/access/call_access.rs similarity index 100% rename from ast/src/access/call_access.rs rename to grammar/src/access/call_access.rs diff --git a/ast/src/access/member_access.rs b/grammar/src/access/member_access.rs similarity index 100% rename from ast/src/access/member_access.rs rename to grammar/src/access/member_access.rs diff --git a/ast/src/access/mod.rs b/grammar/src/access/mod.rs similarity index 100% rename from ast/src/access/mod.rs rename to grammar/src/access/mod.rs diff --git a/ast/src/access/static_member_access.rs b/grammar/src/access/static_member_access.rs similarity index 100% rename from ast/src/access/static_member_access.rs rename to grammar/src/access/static_member_access.rs diff --git a/ast/src/access/tuple_access.rs b/grammar/src/access/tuple_access.rs similarity index 100% rename from ast/src/access/tuple_access.rs rename to grammar/src/access/tuple_access.rs diff --git a/ast/src/annotations/annotation_arguments.rs b/grammar/src/annotations/annotation_arguments.rs similarity index 100% rename from ast/src/annotations/annotation_arguments.rs rename to grammar/src/annotations/annotation_arguments.rs diff --git a/ast/src/annotations/annotation_name.rs b/grammar/src/annotations/annotation_name.rs similarity index 100% rename from ast/src/annotations/annotation_name.rs rename to grammar/src/annotations/annotation_name.rs diff --git a/ast/src/annotations/annotation_symbol.rs b/grammar/src/annotations/annotation_symbol.rs similarity index 100% rename from ast/src/annotations/annotation_symbol.rs rename to grammar/src/annotations/annotation_symbol.rs diff --git a/ast/src/annotations/annotations.rs b/grammar/src/annotations/annotations.rs similarity index 100% rename from ast/src/annotations/annotations.rs rename to grammar/src/annotations/annotations.rs diff --git a/ast/src/annotations/mod.rs b/grammar/src/annotations/mod.rs similarity index 100% rename from ast/src/annotations/mod.rs rename to grammar/src/annotations/mod.rs diff --git a/ast/src/ast.rs b/grammar/src/ast.rs similarity index 100% rename from ast/src/ast.rs rename to grammar/src/ast.rs diff --git a/ast/src/circuits/circuit.rs b/grammar/src/circuits/circuit.rs similarity index 100% rename from ast/src/circuits/circuit.rs rename to grammar/src/circuits/circuit.rs diff --git a/ast/src/circuits/circuit_function.rs b/grammar/src/circuits/circuit_function.rs similarity index 100% rename from ast/src/circuits/circuit_function.rs rename to grammar/src/circuits/circuit_function.rs diff --git a/ast/src/circuits/circuit_member.rs b/grammar/src/circuits/circuit_member.rs similarity index 100% rename from ast/src/circuits/circuit_member.rs rename to grammar/src/circuits/circuit_member.rs diff --git a/ast/src/circuits/circuit_variable.rs b/grammar/src/circuits/circuit_variable.rs similarity index 100% rename from ast/src/circuits/circuit_variable.rs rename to grammar/src/circuits/circuit_variable.rs diff --git a/ast/src/circuits/circuit_variable_definition.rs b/grammar/src/circuits/circuit_variable_definition.rs similarity index 100% rename from ast/src/circuits/circuit_variable_definition.rs rename to grammar/src/circuits/circuit_variable_definition.rs diff --git a/ast/src/circuits/mod.rs b/grammar/src/circuits/mod.rs similarity index 100% rename from ast/src/circuits/mod.rs rename to grammar/src/circuits/mod.rs diff --git a/ast/src/common/assignee.rs b/grammar/src/common/assignee.rs similarity index 100% rename from ast/src/common/assignee.rs rename to grammar/src/common/assignee.rs diff --git a/ast/src/common/declare.rs b/grammar/src/common/declare.rs similarity index 100% rename from ast/src/common/declare.rs rename to grammar/src/common/declare.rs diff --git a/ast/src/common/eoi.rs b/grammar/src/common/eoi.rs similarity index 100% rename from ast/src/common/eoi.rs rename to grammar/src/common/eoi.rs diff --git a/ast/src/common/identifier.rs b/grammar/src/common/identifier.rs similarity index 100% rename from ast/src/common/identifier.rs rename to grammar/src/common/identifier.rs diff --git a/ast/src/common/keyword_or_identifier.rs b/grammar/src/common/keyword_or_identifier.rs similarity index 100% rename from ast/src/common/keyword_or_identifier.rs rename to grammar/src/common/keyword_or_identifier.rs diff --git a/ast/src/common/line_end.rs b/grammar/src/common/line_end.rs similarity index 100% rename from ast/src/common/line_end.rs rename to grammar/src/common/line_end.rs diff --git a/ast/src/common/mod.rs b/grammar/src/common/mod.rs similarity index 100% rename from ast/src/common/mod.rs rename to grammar/src/common/mod.rs diff --git a/ast/src/common/mutable.rs b/grammar/src/common/mutable.rs similarity index 100% rename from ast/src/common/mutable.rs rename to grammar/src/common/mutable.rs diff --git a/ast/src/common/range.rs b/grammar/src/common/range.rs similarity index 100% rename from ast/src/common/range.rs rename to grammar/src/common/range.rs diff --git a/ast/src/common/range_or_expression.rs b/grammar/src/common/range_or_expression.rs similarity index 100% rename from ast/src/common/range_or_expression.rs rename to grammar/src/common/range_or_expression.rs diff --git a/ast/src/common/self_keyword.rs b/grammar/src/common/self_keyword.rs similarity index 100% rename from ast/src/common/self_keyword.rs rename to grammar/src/common/self_keyword.rs diff --git a/ast/src/common/self_keyword_or_identifier.rs b/grammar/src/common/self_keyword_or_identifier.rs similarity index 100% rename from ast/src/common/self_keyword_or_identifier.rs rename to grammar/src/common/self_keyword_or_identifier.rs diff --git a/ast/src/common/spread.rs b/grammar/src/common/spread.rs similarity index 100% rename from ast/src/common/spread.rs rename to grammar/src/common/spread.rs diff --git a/ast/src/common/spread_or_expression.rs b/grammar/src/common/spread_or_expression.rs similarity index 100% rename from ast/src/common/spread_or_expression.rs rename to grammar/src/common/spread_or_expression.rs diff --git a/ast/src/common/static_.rs b/grammar/src/common/static_.rs similarity index 100% rename from ast/src/common/static_.rs rename to grammar/src/common/static_.rs diff --git a/ast/src/common/variable_name.rs b/grammar/src/common/variable_name.rs similarity index 100% rename from ast/src/common/variable_name.rs rename to grammar/src/common/variable_name.rs diff --git a/ast/src/common/variables.rs b/grammar/src/common/variables.rs similarity index 100% rename from ast/src/common/variables.rs rename to grammar/src/common/variables.rs diff --git a/ast/src/console/console_assert.rs b/grammar/src/console/console_assert.rs similarity index 100% rename from ast/src/console/console_assert.rs rename to grammar/src/console/console_assert.rs diff --git a/ast/src/console/console_debug.rs b/grammar/src/console/console_debug.rs similarity index 100% rename from ast/src/console/console_debug.rs rename to grammar/src/console/console_debug.rs diff --git a/ast/src/console/console_error.rs b/grammar/src/console/console_error.rs similarity index 100% rename from ast/src/console/console_error.rs rename to grammar/src/console/console_error.rs diff --git a/ast/src/console/console_function.rs b/grammar/src/console/console_function.rs similarity index 100% rename from ast/src/console/console_function.rs rename to grammar/src/console/console_function.rs diff --git a/ast/src/console/console_function_call.rs b/grammar/src/console/console_function_call.rs similarity index 100% rename from ast/src/console/console_function_call.rs rename to grammar/src/console/console_function_call.rs diff --git a/ast/src/console/console_keyword.rs b/grammar/src/console/console_keyword.rs similarity index 100% rename from ast/src/console/console_keyword.rs rename to grammar/src/console/console_keyword.rs diff --git a/ast/src/console/console_log.rs b/grammar/src/console/console_log.rs similarity index 100% rename from ast/src/console/console_log.rs rename to grammar/src/console/console_log.rs diff --git a/ast/src/console/formatted_container.rs b/grammar/src/console/formatted_container.rs similarity index 100% rename from ast/src/console/formatted_container.rs rename to grammar/src/console/formatted_container.rs diff --git a/ast/src/console/formatted_parameter.rs b/grammar/src/console/formatted_parameter.rs similarity index 100% rename from ast/src/console/formatted_parameter.rs rename to grammar/src/console/formatted_parameter.rs diff --git a/ast/src/console/formatted_string.rs b/grammar/src/console/formatted_string.rs similarity index 100% rename from ast/src/console/formatted_string.rs rename to grammar/src/console/formatted_string.rs diff --git a/ast/src/console/mod.rs b/grammar/src/console/mod.rs similarity index 100% rename from ast/src/console/mod.rs rename to grammar/src/console/mod.rs diff --git a/ast/src/definitions/annotated_definition.rs b/grammar/src/definitions/annotated_definition.rs similarity index 100% rename from ast/src/definitions/annotated_definition.rs rename to grammar/src/definitions/annotated_definition.rs diff --git a/ast/src/definitions/definition.rs b/grammar/src/definitions/definition.rs similarity index 100% rename from ast/src/definitions/definition.rs rename to grammar/src/definitions/definition.rs diff --git a/ast/src/definitions/mod.rs b/grammar/src/definitions/mod.rs similarity index 100% rename from ast/src/definitions/mod.rs rename to grammar/src/definitions/mod.rs diff --git a/ast/src/errors/mod.rs b/grammar/src/errors/mod.rs similarity index 100% rename from ast/src/errors/mod.rs rename to grammar/src/errors/mod.rs diff --git a/ast/src/errors/parser.rs b/grammar/src/errors/parser.rs similarity index 100% rename from ast/src/errors/parser.rs rename to grammar/src/errors/parser.rs diff --git a/ast/src/errors/syntax.rs b/grammar/src/errors/syntax.rs similarity index 100% rename from ast/src/errors/syntax.rs rename to grammar/src/errors/syntax.rs diff --git a/ast/src/expressions/array_initializer_expression.rs b/grammar/src/expressions/array_initializer_expression.rs similarity index 100% rename from ast/src/expressions/array_initializer_expression.rs rename to grammar/src/expressions/array_initializer_expression.rs diff --git a/ast/src/expressions/array_inline_expression.rs b/grammar/src/expressions/array_inline_expression.rs similarity index 100% rename from ast/src/expressions/array_inline_expression.rs rename to grammar/src/expressions/array_inline_expression.rs diff --git a/ast/src/expressions/binary_expression.rs b/grammar/src/expressions/binary_expression.rs similarity index 100% rename from ast/src/expressions/binary_expression.rs rename to grammar/src/expressions/binary_expression.rs diff --git a/ast/src/expressions/circuit_inline_expression.rs b/grammar/src/expressions/circuit_inline_expression.rs similarity index 100% rename from ast/src/expressions/circuit_inline_expression.rs rename to grammar/src/expressions/circuit_inline_expression.rs diff --git a/ast/src/expressions/expression.rs b/grammar/src/expressions/expression.rs similarity index 100% rename from ast/src/expressions/expression.rs rename to grammar/src/expressions/expression.rs diff --git a/ast/src/expressions/mod.rs b/grammar/src/expressions/mod.rs similarity index 100% rename from ast/src/expressions/mod.rs rename to grammar/src/expressions/mod.rs diff --git a/ast/src/expressions/postfix_expression.rs b/grammar/src/expressions/postfix_expression.rs similarity index 100% rename from ast/src/expressions/postfix_expression.rs rename to grammar/src/expressions/postfix_expression.rs diff --git a/ast/src/expressions/ternary_expression.rs b/grammar/src/expressions/ternary_expression.rs similarity index 100% rename from ast/src/expressions/ternary_expression.rs rename to grammar/src/expressions/ternary_expression.rs diff --git a/ast/src/expressions/tuple_expression.rs b/grammar/src/expressions/tuple_expression.rs similarity index 100% rename from ast/src/expressions/tuple_expression.rs rename to grammar/src/expressions/tuple_expression.rs diff --git a/ast/src/expressions/unary_expression.rs b/grammar/src/expressions/unary_expression.rs similarity index 100% rename from ast/src/expressions/unary_expression.rs rename to grammar/src/expressions/unary_expression.rs diff --git a/ast/src/files/file.rs b/grammar/src/files/file.rs similarity index 100% rename from ast/src/files/file.rs rename to grammar/src/files/file.rs diff --git a/ast/src/files/mod.rs b/grammar/src/files/mod.rs similarity index 100% rename from ast/src/files/mod.rs rename to grammar/src/files/mod.rs diff --git a/ast/src/functions/function.rs b/grammar/src/functions/function.rs similarity index 100% rename from ast/src/functions/function.rs rename to grammar/src/functions/function.rs diff --git a/ast/src/functions/input/function_input.rs b/grammar/src/functions/input/function_input.rs similarity index 100% rename from ast/src/functions/input/function_input.rs rename to grammar/src/functions/input/function_input.rs diff --git a/ast/src/functions/input/input.rs b/grammar/src/functions/input/input.rs similarity index 100% rename from ast/src/functions/input/input.rs rename to grammar/src/functions/input/input.rs diff --git a/ast/src/functions/input/input_keyword.rs b/grammar/src/functions/input/input_keyword.rs similarity index 100% rename from ast/src/functions/input/input_keyword.rs rename to grammar/src/functions/input/input_keyword.rs diff --git a/ast/src/functions/input/mod.rs b/grammar/src/functions/input/mod.rs similarity index 100% rename from ast/src/functions/input/mod.rs rename to grammar/src/functions/input/mod.rs diff --git a/ast/src/functions/mod.rs b/grammar/src/functions/mod.rs similarity index 100% rename from ast/src/functions/mod.rs rename to grammar/src/functions/mod.rs diff --git a/ast/src/functions/test_function.rs b/grammar/src/functions/test_function.rs similarity index 100% rename from ast/src/functions/test_function.rs rename to grammar/src/functions/test_function.rs diff --git a/ast/src/imports/import.rs b/grammar/src/imports/import.rs similarity index 100% rename from ast/src/imports/import.rs rename to grammar/src/imports/import.rs diff --git a/ast/src/imports/import_symbol.rs b/grammar/src/imports/import_symbol.rs similarity index 100% rename from ast/src/imports/import_symbol.rs rename to grammar/src/imports/import_symbol.rs diff --git a/ast/src/imports/mod.rs b/grammar/src/imports/mod.rs similarity index 100% rename from ast/src/imports/mod.rs rename to grammar/src/imports/mod.rs diff --git a/ast/src/imports/package.rs b/grammar/src/imports/package.rs similarity index 100% rename from ast/src/imports/package.rs rename to grammar/src/imports/package.rs diff --git a/ast/src/imports/package_access.rs b/grammar/src/imports/package_access.rs similarity index 100% rename from ast/src/imports/package_access.rs rename to grammar/src/imports/package_access.rs diff --git a/ast/src/imports/package_name.rs b/grammar/src/imports/package_name.rs similarity index 100% rename from ast/src/imports/package_name.rs rename to grammar/src/imports/package_name.rs diff --git a/ast/src/imports/star.rs b/grammar/src/imports/star.rs similarity index 100% rename from ast/src/imports/star.rs rename to grammar/src/imports/star.rs diff --git a/ast/src/leo.pest b/grammar/src/leo.pest similarity index 100% rename from ast/src/leo.pest rename to grammar/src/leo.pest diff --git a/ast/src/lib.rs b/grammar/src/lib.rs similarity index 85% rename from ast/src/lib.rs rename to grammar/src/lib.rs index 0958b11514..f2e818788c 100644 --- a/ast/src/lib.rs +++ b/grammar/src/lib.rs @@ -16,9 +16,9 @@ //! The pest abstract syntax tree (ast) for a Leo program. //! -//! This module contains the [`LeoAst`] type, a wrapper around the [`File`] type. -//! The [`LeoAst`] type is the datatype generated by the pest parser using grammar from `leo.pest`. -//! The [`LeoAst`] type is intended to be parsed into a [`LeoCoreAst`]. It should not be parsed by +//! This module contains the [`Grammar`] type, a wrapper around the [`File`] type in this module. +//! The [`Grammar`] type is the datatype generated by the pest parser using grammar from `leo.pest`. +//! The [`Grammar`] type is intended to be parsed into a [`LeoCoreAst`]. It should not be parsed by //! any other pass of the compiler. #[macro_use] @@ -56,15 +56,15 @@ use std::{fs, path::Path}; /// The pest abstract syntax tree (ast) for a Leo program. /// -/// The [`LeoAst`] type represents a Leo program as a series of recursive data types. +/// The [`Grammar`] type represents a Leo program as a series of recursive data types. /// These data types form a tree that begins from a [`File`] type root. /// -/// A new [`LeoAst`] can be created from a `*.leo` file at a [`Path`]. -pub struct LeoAst<'ast> { +/// A new [`Grammar`] can be created from a `*.leo` file at a [`Path`]. +pub struct Grammar<'ast> { ast: files::File<'ast>, } -impl<'ast> LeoAst<'ast> { +impl<'ast> Grammar<'ast> { /// Creates a new abstract syntax tree given the file path. pub fn new(file_path: &'ast Path, program_string: &'ast str) -> Result { // TODO (howardwu): Turn this check back on after fixing the testing module. diff --git a/ast/src/main.rs b/grammar/src/main.rs similarity index 82% rename from ast/src/main.rs rename to grammar/src/main.rs index df420eac74..27f1f7f7a7 100644 --- a/ast/src/main.rs +++ b/grammar/src/main.rs @@ -14,19 +14,19 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::{LeoAst, ParserError}; +use leo_grammar::{Grammar, ParserError}; use std::{env, fs, path::Path}; -fn to_leo_ast(filepath: &Path) -> Result { +fn to_grammar(filepath: &Path) -> Result { // Loads the Leo code as a string from the given file path. let program_filepath = filepath.to_path_buf(); - let program_string = LeoAst::load_file(&program_filepath)?; + let program_string = Grammar::load_file(&program_filepath)?; // Parses the Leo file and constructs an abstract syntax tree. - let ast = LeoAst::new(&program_filepath, &program_string)?; + let ast = Grammar::new(&program_filepath, &program_string)?; // Serializes the abstract syntax tree into JSON format. - let serialized_ast = LeoAst::to_json_string(&ast)?; + let serialized_ast = Grammar::to_json_string(&ast)?; Ok(serialized_ast) } @@ -39,7 +39,7 @@ fn main() -> Result<(), ParserError> { if cli_arguments.len() < 2 || cli_arguments.len() > 3 { eprintln!("Warning - an invalid number of command-line arguments were provided."); println!( - "\nCommand-line usage:\n\n\tleo_ast {{PATH/TO/INPUT_FILENAME}}.leo {{PATH/TO/OUTPUT_DIRECTORY (optional)}}\n" + "\nCommand-line usage:\n\n\tleo_grammar {{PATH/TO/INPUT_FILENAME}}.leo {{PATH/TO/OUTPUT_DIRECTORY (optional)}}\n" ); return Ok(()); // Exit innocently } @@ -48,7 +48,7 @@ fn main() -> Result<(), ParserError> { let input_filepath = Path::new(&cli_arguments[1]); // Construct the serialized abstract syntax tree. - let serialized_ast = to_leo_ast(&input_filepath)?; + let serialized_ast = to_grammar(&input_filepath)?; println!("{}", serialized_ast); // Determine the output directory. diff --git a/ast/src/operations/assign_operation.rs b/grammar/src/operations/assign_operation.rs similarity index 100% rename from ast/src/operations/assign_operation.rs rename to grammar/src/operations/assign_operation.rs diff --git a/ast/src/operations/binary_operation.rs b/grammar/src/operations/binary_operation.rs similarity index 100% rename from ast/src/operations/binary_operation.rs rename to grammar/src/operations/binary_operation.rs diff --git a/ast/src/operations/mod.rs b/grammar/src/operations/mod.rs similarity index 100% rename from ast/src/operations/mod.rs rename to grammar/src/operations/mod.rs diff --git a/ast/src/operations/unary_operation.rs b/grammar/src/operations/unary_operation.rs similarity index 100% rename from ast/src/operations/unary_operation.rs rename to grammar/src/operations/unary_operation.rs diff --git a/ast/src/span.rs b/grammar/src/span.rs similarity index 100% rename from ast/src/span.rs rename to grammar/src/span.rs diff --git a/ast/src/statements/assign_statement.rs b/grammar/src/statements/assign_statement.rs similarity index 100% rename from ast/src/statements/assign_statement.rs rename to grammar/src/statements/assign_statement.rs diff --git a/ast/src/statements/conditional_nested_or_end_statement.rs b/grammar/src/statements/conditional_nested_or_end_statement.rs similarity index 100% rename from ast/src/statements/conditional_nested_or_end_statement.rs rename to grammar/src/statements/conditional_nested_or_end_statement.rs diff --git a/ast/src/statements/conditional_statement.rs b/grammar/src/statements/conditional_statement.rs similarity index 100% rename from ast/src/statements/conditional_statement.rs rename to grammar/src/statements/conditional_statement.rs diff --git a/ast/src/statements/definition_statement.rs b/grammar/src/statements/definition_statement.rs similarity index 100% rename from ast/src/statements/definition_statement.rs rename to grammar/src/statements/definition_statement.rs diff --git a/ast/src/statements/expression_statement.rs b/grammar/src/statements/expression_statement.rs similarity index 100% rename from ast/src/statements/expression_statement.rs rename to grammar/src/statements/expression_statement.rs diff --git a/ast/src/statements/for_statement.rs b/grammar/src/statements/for_statement.rs similarity index 100% rename from ast/src/statements/for_statement.rs rename to grammar/src/statements/for_statement.rs diff --git a/ast/src/statements/mod.rs b/grammar/src/statements/mod.rs similarity index 100% rename from ast/src/statements/mod.rs rename to grammar/src/statements/mod.rs diff --git a/ast/src/statements/return_statement.rs b/grammar/src/statements/return_statement.rs similarity index 100% rename from ast/src/statements/return_statement.rs rename to grammar/src/statements/return_statement.rs diff --git a/ast/src/statements/statement.rs b/grammar/src/statements/statement.rs similarity index 100% rename from ast/src/statements/statement.rs rename to grammar/src/statements/statement.rs diff --git a/ast/src/types/address_type.rs b/grammar/src/types/address_type.rs similarity index 100% rename from ast/src/types/address_type.rs rename to grammar/src/types/address_type.rs diff --git a/ast/src/types/array_dimensions.rs b/grammar/src/types/array_dimensions.rs similarity index 100% rename from ast/src/types/array_dimensions.rs rename to grammar/src/types/array_dimensions.rs diff --git a/ast/src/types/array_type.rs b/grammar/src/types/array_type.rs similarity index 100% rename from ast/src/types/array_type.rs rename to grammar/src/types/array_type.rs diff --git a/ast/src/types/boolean_type.rs b/grammar/src/types/boolean_type.rs similarity index 100% rename from ast/src/types/boolean_type.rs rename to grammar/src/types/boolean_type.rs diff --git a/ast/src/types/circuit_type.rs b/grammar/src/types/circuit_type.rs similarity index 100% rename from ast/src/types/circuit_type.rs rename to grammar/src/types/circuit_type.rs diff --git a/ast/src/types/data_type.rs b/grammar/src/types/data_type.rs similarity index 100% rename from ast/src/types/data_type.rs rename to grammar/src/types/data_type.rs diff --git a/ast/src/types/field_type.rs b/grammar/src/types/field_type.rs similarity index 100% rename from ast/src/types/field_type.rs rename to grammar/src/types/field_type.rs diff --git a/ast/src/types/group_type.rs b/grammar/src/types/group_type.rs similarity index 100% rename from ast/src/types/group_type.rs rename to grammar/src/types/group_type.rs diff --git a/ast/src/types/integer_type.rs b/grammar/src/types/integer_type.rs similarity index 100% rename from ast/src/types/integer_type.rs rename to grammar/src/types/integer_type.rs diff --git a/ast/src/types/mod.rs b/grammar/src/types/mod.rs similarity index 100% rename from ast/src/types/mod.rs rename to grammar/src/types/mod.rs diff --git a/ast/src/types/self_type.rs b/grammar/src/types/self_type.rs similarity index 100% rename from ast/src/types/self_type.rs rename to grammar/src/types/self_type.rs diff --git a/ast/src/types/signed_integer_type.rs b/grammar/src/types/signed_integer_type.rs similarity index 100% rename from ast/src/types/signed_integer_type.rs rename to grammar/src/types/signed_integer_type.rs diff --git a/ast/src/types/tuple_type.rs b/grammar/src/types/tuple_type.rs similarity index 100% rename from ast/src/types/tuple_type.rs rename to grammar/src/types/tuple_type.rs diff --git a/ast/src/types/type_.rs b/grammar/src/types/type_.rs similarity index 100% rename from ast/src/types/type_.rs rename to grammar/src/types/type_.rs diff --git a/ast/src/types/unsigned_integer_type.rs b/grammar/src/types/unsigned_integer_type.rs similarity index 100% rename from ast/src/types/unsigned_integer_type.rs rename to grammar/src/types/unsigned_integer_type.rs diff --git a/ast/src/values/address.rs b/grammar/src/values/address.rs similarity index 100% rename from ast/src/values/address.rs rename to grammar/src/values/address.rs diff --git a/ast/src/values/address_value.rs b/grammar/src/values/address_value.rs similarity index 100% rename from ast/src/values/address_value.rs rename to grammar/src/values/address_value.rs diff --git a/ast/src/values/boolean_value.rs b/grammar/src/values/boolean_value.rs similarity index 100% rename from ast/src/values/boolean_value.rs rename to grammar/src/values/boolean_value.rs diff --git a/ast/src/values/field_value.rs b/grammar/src/values/field_value.rs similarity index 100% rename from ast/src/values/field_value.rs rename to grammar/src/values/field_value.rs diff --git a/ast/src/values/group_coordinate.rs b/grammar/src/values/group_coordinate.rs similarity index 100% rename from ast/src/values/group_coordinate.rs rename to grammar/src/values/group_coordinate.rs diff --git a/ast/src/values/group_value.rs b/grammar/src/values/group_value.rs similarity index 100% rename from ast/src/values/group_value.rs rename to grammar/src/values/group_value.rs diff --git a/ast/src/values/integer_value.rs b/grammar/src/values/integer_value.rs similarity index 100% rename from ast/src/values/integer_value.rs rename to grammar/src/values/integer_value.rs diff --git a/ast/src/values/mod.rs b/grammar/src/values/mod.rs similarity index 100% rename from ast/src/values/mod.rs rename to grammar/src/values/mod.rs diff --git a/ast/src/values/negative_number.rs b/grammar/src/values/negative_number.rs similarity index 100% rename from ast/src/values/negative_number.rs rename to grammar/src/values/negative_number.rs diff --git a/ast/src/values/number_value.rs b/grammar/src/values/number_value.rs similarity index 100% rename from ast/src/values/number_value.rs rename to grammar/src/values/number_value.rs diff --git a/ast/src/values/positive_number.rs b/grammar/src/values/positive_number.rs similarity index 100% rename from ast/src/values/positive_number.rs rename to grammar/src/values/positive_number.rs diff --git a/ast/src/values/signed_integer_value.rs b/grammar/src/values/signed_integer_value.rs similarity index 100% rename from ast/src/values/signed_integer_value.rs rename to grammar/src/values/signed_integer_value.rs diff --git a/ast/src/values/unsigned_integer_value.rs b/grammar/src/values/unsigned_integer_value.rs similarity index 100% rename from ast/src/values/unsigned_integer_value.rs rename to grammar/src/values/unsigned_integer_value.rs diff --git a/ast/src/values/value.rs b/grammar/src/values/value.rs similarity index 100% rename from ast/src/values/value.rs rename to grammar/src/values/value.rs diff --git a/ast/tests/expression.rs b/grammar/tests/expression.rs similarity index 95% rename from ast/tests/expression.rs rename to grammar/tests/expression.rs index c168d34750..cc9bc472e5 100644 --- a/ast/tests/expression.rs +++ b/grammar/tests/expression.rs @@ -1,4 +1,4 @@ -use leo_ast::ast::{LanguageParser, Rule}; +use leo_grammar::ast::{LanguageParser, Rule}; use pest::*; diff --git a/ast/tests/function.rs b/grammar/tests/function.rs similarity index 98% rename from ast/tests/function.rs rename to grammar/tests/function.rs index f35ed1f47e..984d8a3ac8 100644 --- a/ast/tests/function.rs +++ b/grammar/tests/function.rs @@ -1,4 +1,4 @@ -use leo_ast::ast::{LanguageParser, Rule}; +use leo_grammar::ast::{LanguageParser, Rule}; use pest::*; diff --git a/ast/tests/mod.rs b/grammar/tests/mod.rs similarity index 100% rename from ast/tests/mod.rs rename to grammar/tests/mod.rs diff --git a/ast/tests/serialization/expected_ast.json b/grammar/tests/serialization/expected_ast.json similarity index 100% rename from ast/tests/serialization/expected_ast.json rename to grammar/tests/serialization/expected_ast.json diff --git a/ast/tests/serialization/json.rs b/grammar/tests/serialization/json.rs similarity index 83% rename from ast/tests/serialization/json.rs rename to grammar/tests/serialization/json.rs index 30f411a5d9..13a62c1b71 100644 --- a/ast/tests/serialization/json.rs +++ b/grammar/tests/serialization/json.rs @@ -17,7 +17,7 @@ #[test] #[cfg(not(feature = "ci_skip"))] fn test_serialize() { - use leo_ast::LeoAst; + use leo_grammar::Grammar; use std::path::PathBuf; let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -26,13 +26,13 @@ fn test_serialize() { let expected = include_str!("./expected_ast.json"); // Loads the Leo code as a string from the given file path. - let program_string = LeoAst::load_file(&program_filepath).unwrap(); + let program_string = Grammar::load_file(&program_filepath).unwrap(); // Parses the Leo file and constructs an abstract syntax tree. - let ast = LeoAst::new(&program_filepath, &program_string).unwrap(); + let ast = Grammar::new(&program_filepath, &program_string).unwrap(); // Serializes the abstract syntax tree into JSON format. - let serialized_ast = LeoAst::to_json_string(&ast).unwrap(); + let serialized_ast = Grammar::to_json_string(&ast).unwrap(); assert_eq!(expected, serialized_ast); } diff --git a/ast/tests/serialization/main.leo b/grammar/tests/serialization/main.leo similarity index 100% rename from ast/tests/serialization/main.leo rename to grammar/tests/serialization/main.leo diff --git a/ast/tests/serialization/mod.rs b/grammar/tests/serialization/mod.rs similarity index 100% rename from ast/tests/serialization/mod.rs rename to grammar/tests/serialization/mod.rs diff --git a/ast/tests/tuple.rs b/grammar/tests/tuple.rs similarity index 98% rename from ast/tests/tuple.rs rename to grammar/tests/tuple.rs index 4b550214fe..8f39444c0d 100644 --- a/ast/tests/tuple.rs +++ b/grammar/tests/tuple.rs @@ -1,4 +1,4 @@ -use leo_ast::ast::{LanguageParser, Rule}; +use leo_grammar::ast::{LanguageParser, Rule}; use pest::*; diff --git a/imports/Cargo.toml b/imports/Cargo.toml index a72bc81490..4dea07fb0e 100644 --- a/imports/Cargo.toml +++ b/imports/Cargo.toml @@ -17,14 +17,14 @@ include = ["Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" -[dependencies.leo-ast] -path = "../ast" -version = "1.0.3" - [dependencies.leo-core-ast] path = "../core-ast" version = "1.0.3" +[dependencies.leo-grammar] +path = "../grammar" +version = "1.0.3" + [dependencies.thiserror] version = "1.0" diff --git a/imports/src/errors/import_parser.rs b/imports/src/errors/import_parser.rs index 3d745e135b..5885eccbda 100644 --- a/imports/src/errors/import_parser.rs +++ b/imports/src/errors/import_parser.rs @@ -13,8 +13,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::ParserError; use leo_core_ast::{Error as FormattedError, Identifier, Span}; +use leo_grammar::ParserError; use std::{io, path::Path}; diff --git a/imports/src/parser/parse_symbol.rs b/imports/src/parser/parse_symbol.rs index f196b77cfe..8f09a1fbcc 100644 --- a/imports/src/parser/parse_symbol.rs +++ b/imports/src/parser/parse_symbol.rs @@ -15,8 +15,8 @@ // along with the Leo library. If not, see . use crate::{errors::ImportParserError, ImportParser}; -use leo_ast::LeoAst; use leo_core_ast::{ImportSymbol, Program, Span}; +use leo_grammar::Grammar; use std::{ffi::OsString, fs::DirEntry, path::PathBuf}; @@ -51,8 +51,8 @@ fn parse_import_file(package: &DirEntry, span: &Span) -> Result Date: Fri, 30 Oct 2020 17:31:09 -0700 Subject: [PATCH 118/139] rename core-ast -> ast --- Cargo.lock | 42 +++++++++---------- Cargo.toml | 10 ++--- {core-ast => ast}/Cargo.toml | 8 ++-- {core-ast => ast}/benches/big_circuit.leo | 0 {core-ast => ast}/benches/big_if_else.leo | 0 {core-ast => ast}/benches/big_ternary.leo | 0 .../core_ast.rs => ast/benches/leo_ast.rs | 20 ++++----- {core-ast => ast}/benches/long_array.leo | 0 {core-ast => ast}/benches/long_expr.leo | 0 {core-ast => ast}/benches/many_assigns.leo | 0 {core-ast => ast}/benches/many_foos.leo | 0 {core-ast => ast}/src/annotation.rs | 0 {core-ast => ast}/src/circuits/circuit.rs | 0 .../src/circuits/circuit_member.rs | 0 .../circuits/circuit_variable_definition.rs | 0 {core-ast => ast}/src/circuits/mod.rs | 0 {core-ast => ast}/src/common/assignee.rs | 0 {core-ast => ast}/src/common/declare.rs | 0 {core-ast => ast}/src/common/identifier.rs | 0 {core-ast => ast}/src/common/mod.rs | 0 .../src/common/range_or_expression.rs | 0 {core-ast => ast}/src/common/span.rs | 0 .../src/common/spread_or_expression.rs | 0 {core-ast => ast}/src/common/variable_name.rs | 0 {core-ast => ast}/src/common/variables.rs | 0 .../src/console/console_function.rs | 0 .../src/console/console_function_call.rs | 0 .../src/console/formatted_container.rs | 0 .../src/console/formatted_parameter.rs | 0 .../src/console/formatted_string.rs | 0 {core-ast => ast}/src/console/mod.rs | 0 {core-ast => ast}/src/errors/error.rs | 0 {core-ast => ast}/src/errors/mod.rs | 0 {core-ast => ast}/src/expression.rs | 0 {core-ast => ast}/src/functions/function.rs | 0 .../src/functions/input/function_input.rs | 0 .../src/functions/input/input_variable.rs | 0 {core-ast => ast}/src/functions/input/mod.rs | 0 {core-ast => ast}/src/functions/mod.rs | 0 .../src/functions/test_function.rs | 0 .../src/groups/group_coordinate.rs | 0 {core-ast => ast}/src/groups/group_value.rs | 0 {core-ast => ast}/src/groups/mod.rs | 0 {core-ast => ast}/src/imports/import.rs | 0 .../src/imports/import_symbol.rs | 0 {core-ast => ast}/src/imports/mod.rs | 0 {core-ast => ast}/src/imports/package.rs | 0 .../src/imports/package_access.rs | 0 {core-ast => ast}/src/input/input.rs | 0 {core-ast => ast}/src/input/input_value.rs | 0 {core-ast => ast}/src/input/macros.rs | 0 {core-ast => ast}/src/input/mod.rs | 0 {core-ast => ast}/src/input/parameters/mod.rs | 0 .../src/input/parameters/parameter.rs | 0 .../src/input/program_input/main_input.rs | 0 .../src/input/program_input/mod.rs | 0 .../src/input/program_input/program_input.rs | 0 .../src/input/program_input/registers.rs | 0 .../src/input/program_state/mod.rs | 0 .../input/program_state/private_state/mod.rs | 0 .../private_state/private_state.rs | 0 .../program_state/private_state/record.rs | 0 .../program_state/private_state/state_leaf.rs | 0 .../src/input/program_state/program_state.rs | 0 .../input/program_state/public_state/mod.rs | 0 .../public_state/public_state.rs | 0 .../input/program_state/public_state/state.rs | 0 {core-ast => ast}/src/lib.rs | 24 +++++------ {core-ast => ast}/src/main.rs | 8 ++-- {core-ast => ast}/src/program.rs | 0 .../conditional_nested_or_end_statement.rs | 0 .../src/statements/conditional_statement.rs | 0 {core-ast => ast}/src/statements/mod.rs | 0 {core-ast => ast}/src/statements/statement.rs | 0 {core-ast => ast}/src/types/integer_type.rs | 0 {core-ast => ast}/src/types/mod.rs | 0 {core-ast => ast}/src/types/type_.rs | 0 {core-ast => ast}/tests/mod.rs | 0 .../serialization/expected_core_ast.json | 0 {core-ast => ast}/tests/serialization/json.rs | 14 +++---- .../tests/serialization/main.leo | 0 {core-ast => ast}/tests/serialization/mod.rs | 0 compiler/Cargo.toml | 6 +-- compiler/src/compiler.rs | 6 +-- compiler/src/console/assert.rs | 2 +- compiler/src/console/console.rs | 2 +- compiler/src/console/format.rs | 2 +- compiler/src/constraints/constraints.rs | 2 +- compiler/src/definition/definition.rs | 2 +- compiler/src/definition/definitions.rs | 2 +- compiler/src/errors/console.rs | 2 +- compiler/src/errors/expression.rs | 2 +- compiler/src/errors/function.rs | 2 +- compiler/src/errors/import.rs | 2 +- compiler/src/errors/output_bytes.rs | 2 +- compiler/src/errors/statement.rs | 2 +- compiler/src/errors/value/address.rs | 2 +- compiler/src/errors/value/boolean.rs | 2 +- compiler/src/errors/value/field.rs | 2 +- compiler/src/errors/value/group.rs | 2 +- compiler/src/errors/value/integer.rs | 2 +- compiler/src/errors/value/value.rs | 2 +- compiler/src/expression/arithmetic/add.rs | 2 +- compiler/src/expression/arithmetic/div.rs | 2 +- compiler/src/expression/arithmetic/mul.rs | 2 +- compiler/src/expression/arithmetic/negate.rs | 2 +- compiler/src/expression/arithmetic/pow.rs | 2 +- compiler/src/expression/arithmetic/sub.rs | 2 +- compiler/src/expression/array/access.rs | 2 +- compiler/src/expression/array/array.rs | 2 +- compiler/src/expression/array/index.rs | 2 +- compiler/src/expression/binary/binary.rs | 2 +- compiler/src/expression/binary/operand.rs | 2 +- compiler/src/expression/circuit/access.rs | 2 +- compiler/src/expression/circuit/circuit.rs | 2 +- .../src/expression/circuit/static_access.rs | 2 +- .../src/expression/conditional/conditional.rs | 2 +- compiler/src/expression/expression.rs | 2 +- .../src/expression/function/core_circuit.rs | 2 +- compiler/src/expression/function/function.rs | 2 +- .../src/expression/identifier/identifier.rs | 2 +- compiler/src/expression/logical/and.rs | 2 +- compiler/src/expression/logical/not.rs | 2 +- compiler/src/expression/logical/or.rs | 2 +- compiler/src/expression/relational/eq.rs | 2 +- compiler/src/expression/relational/ge.rs | 2 +- compiler/src/expression/relational/gt.rs | 2 +- compiler/src/expression/relational/le.rs | 2 +- compiler/src/expression/relational/lt.rs | 2 +- compiler/src/expression/tuple/access.rs | 2 +- compiler/src/expression/tuple/tuple.rs | 2 +- compiler/src/function/function.rs | 2 +- compiler/src/function/input/array.rs | 2 +- compiler/src/function/input/function_input.rs | 2 +- compiler/src/function/input/input_keyword.rs | 2 +- compiler/src/function/input/input_section.rs | 2 +- .../src/function/input/main_function_input.rs | 2 +- compiler/src/function/input/tuple.rs | 2 +- compiler/src/function/main_function.rs | 2 +- compiler/src/function/result/result.rs | 2 +- compiler/src/import/parser/import_parser.rs | 2 +- compiler/src/import/store/core_package.rs | 2 +- compiler/src/import/store/import.rs | 2 +- compiler/src/import/store/symbol.rs | 2 +- compiler/src/output/output_bytes.rs | 2 +- compiler/src/statement/assign/array.rs | 2 +- compiler/src/statement/assign/assign.rs | 2 +- compiler/src/statement/assign/assignee.rs | 2 +- .../src/statement/assign/circuit_variable.rs | 2 +- compiler/src/statement/assign/tuple.rs | 2 +- compiler/src/statement/branch/branch.rs | 2 +- .../src/statement/conditional/conditional.rs | 2 +- .../src/statement/definition/definition.rs | 2 +- compiler/src/statement/iteration/iteration.rs | 2 +- compiler/src/statement/return_/return_.rs | 2 +- compiler/src/statement/statement.rs | 2 +- compiler/src/value/address/address.rs | 2 +- compiler/src/value/boolean/input.rs | 2 +- compiler/src/value/field/field_type.rs | 2 +- compiler/src/value/field/input.rs | 2 +- compiler/src/value/group/group_type.rs | 2 +- compiler/src/value/group/input.rs | 2 +- .../src/value/group/targets/edwards_bls12.rs | 2 +- compiler/src/value/implicit/implicit.rs | 2 +- compiler/src/value/integer/integer.rs | 2 +- compiler/src/value/value.rs | 2 +- compiler/tests/address/mod.rs | 2 +- compiler/tests/console/mod.rs | 2 +- .../core/packages/unstable/blake2s/mod.rs | 2 +- compiler/tests/field/mod.rs | 2 +- compiler/tests/group/mod.rs | 2 +- compiler/tests/integers/i128/mod.rs | 2 +- compiler/tests/integers/i16/mod.rs | 2 +- compiler/tests/integers/i32/mod.rs | 2 +- compiler/tests/integers/i64/mod.rs | 2 +- compiler/tests/integers/i8/mod.rs | 2 +- compiler/tests/integers/u128/mod.rs | 2 +- compiler/tests/integers/u16/mod.rs | 2 +- compiler/tests/integers/u32/mod.rs | 2 +- compiler/tests/integers/u64/mod.rs | 2 +- compiler/tests/integers/u8/mod.rs | 2 +- compiler/tests/mod.rs | 2 +- compiler/tests/mutability/mod.rs | 2 +- compiler/tests/statements/conditional/mod.rs | 2 +- compiler/tests/statements/mod.rs | 2 +- core-packages/Cargo.toml | 4 +- core-packages/src/errors/core_circuit.rs | 2 +- core-packages/src/errors/core_package.rs | 2 +- core-packages/src/errors/core_package_list.rs | 2 +- core-packages/src/errors/leo_core_package.rs | 2 +- core-packages/src/lib.rs | 2 +- .../src/packages/unstable/blake2s.rs | 2 +- core-packages/src/types/core_circuit.rs | 2 +- .../src/types/core_circuit_struct_list.rs | 2 +- core-packages/src/types/core_package.rs | 2 +- core-packages/src/types/core_package_list.rs | 2 +- grammar/src/lib.rs | 2 +- imports/Cargo.toml | 4 +- imports/src/errors/import_parser.rs | 2 +- imports/src/parser/core_package.rs | 2 +- imports/src/parser/import_parser.rs | 2 +- imports/src/parser/parse_package.rs | 2 +- imports/src/parser/parse_symbol.rs | 2 +- state/Cargo.toml | 4 +- .../local_data_commitment.rs | 2 +- .../state_leaf_values.rs | 2 +- .../src/local_data_commitment/state_values.rs | 2 +- .../record_commitment/dpc_record_values.rs | 2 +- .../record_commitment/record_commitment.rs | 2 +- state/src/utilities/input_value.rs | 2 +- .../test_verify_local_data_commitment.rs | 2 +- state/tests/test_verify_record_commitment.rs | 2 +- symbol-table/Cargo.toml | 4 +- symbol-table/src/errors/symbol_table.rs | 2 +- symbol-table/src/errors/type_.rs | 2 +- symbol-table/src/imports/imported_symbols.rs | 2 +- symbol-table/src/symbol_table.rs | 2 +- symbol-table/src/types/circuits/circuit.rs | 2 +- .../src/types/circuits/circuit_variable.rs | 2 +- symbol-table/src/types/functions/function.rs | 2 +- .../src/types/functions/function_input.rs | 2 +- .../functions/function_input_variable.rs | 2 +- .../src/types/functions/function_output.rs | 2 +- symbol-table/src/types/type_.rs | 2 +- symbol-table/src/types/type_variable.rs | 2 +- .../types/user_defined/user_defined_type.rs | 2 +- symbol-table/tests/mod.rs | 6 +-- type-inference/Cargo.toml | 4 +- .../src/assertions/type_assertion.rs | 2 +- .../src/assertions/type_equality.rs | 2 +- .../src/assertions/type_membership.rs | 2 +- .../src/assertions/type_variable_pair.rs | 2 +- type-inference/src/errors/frame.rs | 2 +- type-inference/src/errors/scope.rs | 2 +- type-inference/src/errors/type_assertion.rs | 2 +- type-inference/src/errors/type_inference.rs | 2 +- type-inference/src/errors/variable_table.rs | 2 +- type-inference/src/objects/frame.rs | 2 +- type-inference/src/type_inference.rs | 2 +- type-inference/tests/mod.rs | 4 +- 240 files changed, 233 insertions(+), 233 deletions(-) rename {core-ast => ast}/Cargo.toml (91%) rename {core-ast => ast}/benches/big_circuit.leo (100%) rename {core-ast => ast}/benches/big_if_else.leo (100%) rename {core-ast => ast}/benches/big_ternary.leo (100%) rename core-ast/benches/core_ast.rs => ast/benches/leo_ast.rs (79%) rename {core-ast => ast}/benches/long_array.leo (100%) rename {core-ast => ast}/benches/long_expr.leo (100%) rename {core-ast => ast}/benches/many_assigns.leo (100%) rename {core-ast => ast}/benches/many_foos.leo (100%) rename {core-ast => ast}/src/annotation.rs (100%) rename {core-ast => ast}/src/circuits/circuit.rs (100%) rename {core-ast => ast}/src/circuits/circuit_member.rs (100%) rename {core-ast => ast}/src/circuits/circuit_variable_definition.rs (100%) rename {core-ast => ast}/src/circuits/mod.rs (100%) rename {core-ast => ast}/src/common/assignee.rs (100%) rename {core-ast => ast}/src/common/declare.rs (100%) rename {core-ast => ast}/src/common/identifier.rs (100%) rename {core-ast => ast}/src/common/mod.rs (100%) rename {core-ast => ast}/src/common/range_or_expression.rs (100%) rename {core-ast => ast}/src/common/span.rs (100%) rename {core-ast => ast}/src/common/spread_or_expression.rs (100%) rename {core-ast => ast}/src/common/variable_name.rs (100%) rename {core-ast => ast}/src/common/variables.rs (100%) rename {core-ast => ast}/src/console/console_function.rs (100%) rename {core-ast => ast}/src/console/console_function_call.rs (100%) rename {core-ast => ast}/src/console/formatted_container.rs (100%) rename {core-ast => ast}/src/console/formatted_parameter.rs (100%) rename {core-ast => ast}/src/console/formatted_string.rs (100%) rename {core-ast => ast}/src/console/mod.rs (100%) rename {core-ast => ast}/src/errors/error.rs (100%) rename {core-ast => ast}/src/errors/mod.rs (100%) rename {core-ast => ast}/src/expression.rs (100%) rename {core-ast => ast}/src/functions/function.rs (100%) rename {core-ast => ast}/src/functions/input/function_input.rs (100%) rename {core-ast => ast}/src/functions/input/input_variable.rs (100%) rename {core-ast => ast}/src/functions/input/mod.rs (100%) rename {core-ast => ast}/src/functions/mod.rs (100%) rename {core-ast => ast}/src/functions/test_function.rs (100%) rename {core-ast => ast}/src/groups/group_coordinate.rs (100%) rename {core-ast => ast}/src/groups/group_value.rs (100%) rename {core-ast => ast}/src/groups/mod.rs (100%) rename {core-ast => ast}/src/imports/import.rs (100%) rename {core-ast => ast}/src/imports/import_symbol.rs (100%) rename {core-ast => ast}/src/imports/mod.rs (100%) rename {core-ast => ast}/src/imports/package.rs (100%) rename {core-ast => ast}/src/imports/package_access.rs (100%) rename {core-ast => ast}/src/input/input.rs (100%) rename {core-ast => ast}/src/input/input_value.rs (100%) rename {core-ast => ast}/src/input/macros.rs (100%) rename {core-ast => ast}/src/input/mod.rs (100%) rename {core-ast => ast}/src/input/parameters/mod.rs (100%) rename {core-ast => ast}/src/input/parameters/parameter.rs (100%) rename {core-ast => ast}/src/input/program_input/main_input.rs (100%) rename {core-ast => ast}/src/input/program_input/mod.rs (100%) rename {core-ast => ast}/src/input/program_input/program_input.rs (100%) rename {core-ast => ast}/src/input/program_input/registers.rs (100%) rename {core-ast => ast}/src/input/program_state/mod.rs (100%) rename {core-ast => ast}/src/input/program_state/private_state/mod.rs (100%) rename {core-ast => ast}/src/input/program_state/private_state/private_state.rs (100%) rename {core-ast => ast}/src/input/program_state/private_state/record.rs (100%) rename {core-ast => ast}/src/input/program_state/private_state/state_leaf.rs (100%) rename {core-ast => ast}/src/input/program_state/program_state.rs (100%) rename {core-ast => ast}/src/input/program_state/public_state/mod.rs (100%) rename {core-ast => ast}/src/input/program_state/public_state/public_state.rs (100%) rename {core-ast => ast}/src/input/program_state/public_state/state.rs (100%) rename {core-ast => ast}/src/lib.rs (77%) rename {core-ast => ast}/src/main.rs (89%) rename {core-ast => ast}/src/program.rs (100%) rename {core-ast => ast}/src/statements/conditional_nested_or_end_statement.rs (100%) rename {core-ast => ast}/src/statements/conditional_statement.rs (100%) rename {core-ast => ast}/src/statements/mod.rs (100%) rename {core-ast => ast}/src/statements/statement.rs (100%) rename {core-ast => ast}/src/types/integer_type.rs (100%) rename {core-ast => ast}/src/types/mod.rs (100%) rename {core-ast => ast}/src/types/type_.rs (100%) rename {core-ast => ast}/tests/mod.rs (100%) rename {core-ast => ast}/tests/serialization/expected_core_ast.json (100%) rename {core-ast => ast}/tests/serialization/json.rs (88%) rename {core-ast => ast}/tests/serialization/main.leo (100%) rename {core-ast => ast}/tests/serialization/mod.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 4c50516204..10f69761a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1229,13 +1229,27 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "leo-ast" +version = "1.0.3" +dependencies = [ + "criterion", + "leo-grammar", + "leo-input", + "pest", + "serde", + "serde_json", + "snarkos-errors", + "snarkos-models", +] + [[package]] name = "leo-compiler" version = "1.0.3" dependencies = [ "bincode", "hex", - "leo-core-ast", + "leo-ast", "leo-core-packages", "leo-gadgets", "leo-grammar", @@ -1264,25 +1278,11 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "leo-core-ast" -version = "1.0.3" -dependencies = [ - "criterion", - "leo-grammar", - "leo-input", - "pest", - "serde", - "serde_json", - "snarkos-errors", - "snarkos-models", -] - [[package]] name = "leo-core-packages" version = "1.0.3" dependencies = [ - "leo-core-ast", + "leo-ast", "leo-gadgets", "rand", "rand_xorshift", @@ -1327,7 +1327,7 @@ dependencies = [ name = "leo-imports" version = "1.0.3" dependencies = [ - "leo-core-ast", + "leo-ast", "leo-grammar", "thiserror", "tracing", @@ -1362,8 +1362,8 @@ dependencies = [ "env_logger 0.8.1", "from-pest", "lazy_static", + "leo-ast", "leo-compiler", - "leo-core-ast", "leo-gadgets", "leo-imports", "leo-input", @@ -1414,7 +1414,7 @@ dependencies = [ name = "leo-state" version = "1.0.3" dependencies = [ - "leo-core-ast", + "leo-ast", "leo-input", "rand", "rand_xorshift", @@ -1433,7 +1433,7 @@ dependencies = [ name = "leo-symbol-table" version = "1.0.3" dependencies = [ - "leo-core-ast", + "leo-ast", "leo-core-packages", "leo-grammar", "leo-imports", @@ -1445,7 +1445,7 @@ dependencies = [ name = "leo-type-inference" version = "1.0.3" dependencies = [ - "leo-core-ast", + "leo-ast", "leo-grammar", "leo-imports", "leo-symbol-table", diff --git a/Cargo.toml b/Cargo.toml index e79ed39390..52d6881e08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,8 +26,8 @@ path = "leo/main.rs" [workspace] members = [ + "ast", "compiler", - "core-ast", "core-packages", "gadgets", "grammar", @@ -40,12 +40,12 @@ members = [ "type-inference", ] -[dependencies.leo-compiler] -path = "./compiler" +[dependencies.leo-ast] +path = "./ast" version = "1.0.3" -[dependencies.leo-core-ast] -path = "./core-ast" +[dependencies.leo-compiler] +path = "./compiler" version = "1.0.3" [dependencies.leo-gadgets] diff --git a/core-ast/Cargo.toml b/ast/Cargo.toml similarity index 91% rename from core-ast/Cargo.toml rename to ast/Cargo.toml index 282c7cd4a5..47cf163d38 100644 --- a/core-ast/Cargo.toml +++ b/ast/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "leo-core-ast" +name = "leo-ast" version = "1.0.3" authors = [ "The Aleo Team " ] description = "Core AST of the Leo programming language" @@ -18,12 +18,12 @@ license = "GPL-3.0" edition = "2018" [[bin]] -name = "leo_core_ast" +name = "leo_ast" path = "src/main.rs" [[bench]] -name = "core_ast" -path = "benches/core_ast.rs" +name = "leo_ast" +path = "benches/leo_ast.rs" harness = false [dependencies.leo-grammar] diff --git a/core-ast/benches/big_circuit.leo b/ast/benches/big_circuit.leo similarity index 100% rename from core-ast/benches/big_circuit.leo rename to ast/benches/big_circuit.leo diff --git a/core-ast/benches/big_if_else.leo b/ast/benches/big_if_else.leo similarity index 100% rename from core-ast/benches/big_if_else.leo rename to ast/benches/big_if_else.leo diff --git a/core-ast/benches/big_ternary.leo b/ast/benches/big_ternary.leo similarity index 100% rename from core-ast/benches/big_ternary.leo rename to ast/benches/big_ternary.leo diff --git a/core-ast/benches/core_ast.rs b/ast/benches/leo_ast.rs similarity index 79% rename from core-ast/benches/core_ast.rs rename to ast/benches/leo_ast.rs index d95ee191d3..e510b4d7c8 100644 --- a/core-ast/benches/core_ast.rs +++ b/ast/benches/leo_ast.rs @@ -14,14 +14,14 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::LeoCoreAst; +use leo_ast::LeoAst; use leo_grammar::Grammar; use criterion::{criterion_group, criterion_main, Criterion}; use std::{path::Path, time::Duration}; -fn leo_core_ast<'ast>(ast: &Grammar<'ast>) -> LeoCoreAst { - LeoCoreAst::new("leo_core_tree", &ast) +fn leo_ast<'ast>(ast: &Grammar<'ast>) -> LeoAst { + LeoAst::new("leo_core_tree", &ast) } fn bench_big_if_else(c: &mut Criterion) { @@ -29,7 +29,7 @@ fn bench_big_if_else(c: &mut Criterion) { let program_string = include_str!("./big_if_else.leo"); let ast = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("LeoCoreAst::big_if_else", |b| b.iter(|| leo_core_ast(&ast))); + c.bench_function("LeoAst::big_if_else", |b| b.iter(|| leo_ast(&ast))); } fn bench_big_ternary(c: &mut Criterion) { @@ -37,7 +37,7 @@ fn bench_big_ternary(c: &mut Criterion) { let program_string = include_str!("./big_ternary.leo"); let ast = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("LeoCoreAst::big_ternary", |b| b.iter(|| leo_core_ast(&ast))); + c.bench_function("LeoAst::big_ternary", |b| b.iter(|| leo_ast(&ast))); } fn bench_big_circuit(c: &mut Criterion) { @@ -45,7 +45,7 @@ fn bench_big_circuit(c: &mut Criterion) { let program_string = include_str!("./big_circuit.leo"); let ast = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("LeoCoreAst::big_circuit", |b| b.iter(|| leo_core_ast(&ast))); + c.bench_function("LeoAst::big_circuit", |b| b.iter(|| leo_ast(&ast))); } fn bench_long_expr(c: &mut Criterion) { @@ -53,7 +53,7 @@ fn bench_long_expr(c: &mut Criterion) { let program_string = include_str!("./long_expr.leo"); let ast = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("LeoCoreAst::long_expr", |b| b.iter(|| leo_core_ast(&ast))); + c.bench_function("LeoAst::long_expr", |b| b.iter(|| leo_ast(&ast))); } fn bench_long_array(c: &mut Criterion) { @@ -61,7 +61,7 @@ fn bench_long_array(c: &mut Criterion) { let program_string = include_str!("./long_array.leo"); let ast = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("LeoCoreAst::long_array", |b| b.iter(|| leo_core_ast(&ast))); + c.bench_function("LeoAst::long_array", |b| b.iter(|| leo_ast(&ast))); } fn bench_many_foos(c: &mut Criterion) { @@ -69,7 +69,7 @@ fn bench_many_foos(c: &mut Criterion) { let program_string = include_str!("./many_foos.leo"); let ast = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("LeoCoreAst::many_foos", |b| b.iter(|| leo_core_ast(&ast))); + c.bench_function("LeoAst::many_foos", |b| b.iter(|| leo_ast(&ast))); } fn bench_many_assigns(c: &mut Criterion) { @@ -77,7 +77,7 @@ fn bench_many_assigns(c: &mut Criterion) { let program_string = include_str!("./many_assigns.leo"); let ast = Grammar::new(&filepath, program_string).unwrap(); - c.bench_function("LeoCoreAst::many_assigns", |b| b.iter(|| leo_core_ast(&ast))); + c.bench_function("LeoAst::many_assigns", |b| b.iter(|| leo_ast(&ast))); } criterion_group!( diff --git a/core-ast/benches/long_array.leo b/ast/benches/long_array.leo similarity index 100% rename from core-ast/benches/long_array.leo rename to ast/benches/long_array.leo diff --git a/core-ast/benches/long_expr.leo b/ast/benches/long_expr.leo similarity index 100% rename from core-ast/benches/long_expr.leo rename to ast/benches/long_expr.leo diff --git a/core-ast/benches/many_assigns.leo b/ast/benches/many_assigns.leo similarity index 100% rename from core-ast/benches/many_assigns.leo rename to ast/benches/many_assigns.leo diff --git a/core-ast/benches/many_foos.leo b/ast/benches/many_foos.leo similarity index 100% rename from core-ast/benches/many_foos.leo rename to ast/benches/many_foos.leo diff --git a/core-ast/src/annotation.rs b/ast/src/annotation.rs similarity index 100% rename from core-ast/src/annotation.rs rename to ast/src/annotation.rs diff --git a/core-ast/src/circuits/circuit.rs b/ast/src/circuits/circuit.rs similarity index 100% rename from core-ast/src/circuits/circuit.rs rename to ast/src/circuits/circuit.rs diff --git a/core-ast/src/circuits/circuit_member.rs b/ast/src/circuits/circuit_member.rs similarity index 100% rename from core-ast/src/circuits/circuit_member.rs rename to ast/src/circuits/circuit_member.rs diff --git a/core-ast/src/circuits/circuit_variable_definition.rs b/ast/src/circuits/circuit_variable_definition.rs similarity index 100% rename from core-ast/src/circuits/circuit_variable_definition.rs rename to ast/src/circuits/circuit_variable_definition.rs diff --git a/core-ast/src/circuits/mod.rs b/ast/src/circuits/mod.rs similarity index 100% rename from core-ast/src/circuits/mod.rs rename to ast/src/circuits/mod.rs diff --git a/core-ast/src/common/assignee.rs b/ast/src/common/assignee.rs similarity index 100% rename from core-ast/src/common/assignee.rs rename to ast/src/common/assignee.rs diff --git a/core-ast/src/common/declare.rs b/ast/src/common/declare.rs similarity index 100% rename from core-ast/src/common/declare.rs rename to ast/src/common/declare.rs diff --git a/core-ast/src/common/identifier.rs b/ast/src/common/identifier.rs similarity index 100% rename from core-ast/src/common/identifier.rs rename to ast/src/common/identifier.rs diff --git a/core-ast/src/common/mod.rs b/ast/src/common/mod.rs similarity index 100% rename from core-ast/src/common/mod.rs rename to ast/src/common/mod.rs diff --git a/core-ast/src/common/range_or_expression.rs b/ast/src/common/range_or_expression.rs similarity index 100% rename from core-ast/src/common/range_or_expression.rs rename to ast/src/common/range_or_expression.rs diff --git a/core-ast/src/common/span.rs b/ast/src/common/span.rs similarity index 100% rename from core-ast/src/common/span.rs rename to ast/src/common/span.rs diff --git a/core-ast/src/common/spread_or_expression.rs b/ast/src/common/spread_or_expression.rs similarity index 100% rename from core-ast/src/common/spread_or_expression.rs rename to ast/src/common/spread_or_expression.rs diff --git a/core-ast/src/common/variable_name.rs b/ast/src/common/variable_name.rs similarity index 100% rename from core-ast/src/common/variable_name.rs rename to ast/src/common/variable_name.rs diff --git a/core-ast/src/common/variables.rs b/ast/src/common/variables.rs similarity index 100% rename from core-ast/src/common/variables.rs rename to ast/src/common/variables.rs diff --git a/core-ast/src/console/console_function.rs b/ast/src/console/console_function.rs similarity index 100% rename from core-ast/src/console/console_function.rs rename to ast/src/console/console_function.rs diff --git a/core-ast/src/console/console_function_call.rs b/ast/src/console/console_function_call.rs similarity index 100% rename from core-ast/src/console/console_function_call.rs rename to ast/src/console/console_function_call.rs diff --git a/core-ast/src/console/formatted_container.rs b/ast/src/console/formatted_container.rs similarity index 100% rename from core-ast/src/console/formatted_container.rs rename to ast/src/console/formatted_container.rs diff --git a/core-ast/src/console/formatted_parameter.rs b/ast/src/console/formatted_parameter.rs similarity index 100% rename from core-ast/src/console/formatted_parameter.rs rename to ast/src/console/formatted_parameter.rs diff --git a/core-ast/src/console/formatted_string.rs b/ast/src/console/formatted_string.rs similarity index 100% rename from core-ast/src/console/formatted_string.rs rename to ast/src/console/formatted_string.rs diff --git a/core-ast/src/console/mod.rs b/ast/src/console/mod.rs similarity index 100% rename from core-ast/src/console/mod.rs rename to ast/src/console/mod.rs diff --git a/core-ast/src/errors/error.rs b/ast/src/errors/error.rs similarity index 100% rename from core-ast/src/errors/error.rs rename to ast/src/errors/error.rs diff --git a/core-ast/src/errors/mod.rs b/ast/src/errors/mod.rs similarity index 100% rename from core-ast/src/errors/mod.rs rename to ast/src/errors/mod.rs diff --git a/core-ast/src/expression.rs b/ast/src/expression.rs similarity index 100% rename from core-ast/src/expression.rs rename to ast/src/expression.rs diff --git a/core-ast/src/functions/function.rs b/ast/src/functions/function.rs similarity index 100% rename from core-ast/src/functions/function.rs rename to ast/src/functions/function.rs diff --git a/core-ast/src/functions/input/function_input.rs b/ast/src/functions/input/function_input.rs similarity index 100% rename from core-ast/src/functions/input/function_input.rs rename to ast/src/functions/input/function_input.rs diff --git a/core-ast/src/functions/input/input_variable.rs b/ast/src/functions/input/input_variable.rs similarity index 100% rename from core-ast/src/functions/input/input_variable.rs rename to ast/src/functions/input/input_variable.rs diff --git a/core-ast/src/functions/input/mod.rs b/ast/src/functions/input/mod.rs similarity index 100% rename from core-ast/src/functions/input/mod.rs rename to ast/src/functions/input/mod.rs diff --git a/core-ast/src/functions/mod.rs b/ast/src/functions/mod.rs similarity index 100% rename from core-ast/src/functions/mod.rs rename to ast/src/functions/mod.rs diff --git a/core-ast/src/functions/test_function.rs b/ast/src/functions/test_function.rs similarity index 100% rename from core-ast/src/functions/test_function.rs rename to ast/src/functions/test_function.rs diff --git a/core-ast/src/groups/group_coordinate.rs b/ast/src/groups/group_coordinate.rs similarity index 100% rename from core-ast/src/groups/group_coordinate.rs rename to ast/src/groups/group_coordinate.rs diff --git a/core-ast/src/groups/group_value.rs b/ast/src/groups/group_value.rs similarity index 100% rename from core-ast/src/groups/group_value.rs rename to ast/src/groups/group_value.rs diff --git a/core-ast/src/groups/mod.rs b/ast/src/groups/mod.rs similarity index 100% rename from core-ast/src/groups/mod.rs rename to ast/src/groups/mod.rs diff --git a/core-ast/src/imports/import.rs b/ast/src/imports/import.rs similarity index 100% rename from core-ast/src/imports/import.rs rename to ast/src/imports/import.rs diff --git a/core-ast/src/imports/import_symbol.rs b/ast/src/imports/import_symbol.rs similarity index 100% rename from core-ast/src/imports/import_symbol.rs rename to ast/src/imports/import_symbol.rs diff --git a/core-ast/src/imports/mod.rs b/ast/src/imports/mod.rs similarity index 100% rename from core-ast/src/imports/mod.rs rename to ast/src/imports/mod.rs diff --git a/core-ast/src/imports/package.rs b/ast/src/imports/package.rs similarity index 100% rename from core-ast/src/imports/package.rs rename to ast/src/imports/package.rs diff --git a/core-ast/src/imports/package_access.rs b/ast/src/imports/package_access.rs similarity index 100% rename from core-ast/src/imports/package_access.rs rename to ast/src/imports/package_access.rs diff --git a/core-ast/src/input/input.rs b/ast/src/input/input.rs similarity index 100% rename from core-ast/src/input/input.rs rename to ast/src/input/input.rs diff --git a/core-ast/src/input/input_value.rs b/ast/src/input/input_value.rs similarity index 100% rename from core-ast/src/input/input_value.rs rename to ast/src/input/input_value.rs diff --git a/core-ast/src/input/macros.rs b/ast/src/input/macros.rs similarity index 100% rename from core-ast/src/input/macros.rs rename to ast/src/input/macros.rs diff --git a/core-ast/src/input/mod.rs b/ast/src/input/mod.rs similarity index 100% rename from core-ast/src/input/mod.rs rename to ast/src/input/mod.rs diff --git a/core-ast/src/input/parameters/mod.rs b/ast/src/input/parameters/mod.rs similarity index 100% rename from core-ast/src/input/parameters/mod.rs rename to ast/src/input/parameters/mod.rs diff --git a/core-ast/src/input/parameters/parameter.rs b/ast/src/input/parameters/parameter.rs similarity index 100% rename from core-ast/src/input/parameters/parameter.rs rename to ast/src/input/parameters/parameter.rs diff --git a/core-ast/src/input/program_input/main_input.rs b/ast/src/input/program_input/main_input.rs similarity index 100% rename from core-ast/src/input/program_input/main_input.rs rename to ast/src/input/program_input/main_input.rs diff --git a/core-ast/src/input/program_input/mod.rs b/ast/src/input/program_input/mod.rs similarity index 100% rename from core-ast/src/input/program_input/mod.rs rename to ast/src/input/program_input/mod.rs diff --git a/core-ast/src/input/program_input/program_input.rs b/ast/src/input/program_input/program_input.rs similarity index 100% rename from core-ast/src/input/program_input/program_input.rs rename to ast/src/input/program_input/program_input.rs diff --git a/core-ast/src/input/program_input/registers.rs b/ast/src/input/program_input/registers.rs similarity index 100% rename from core-ast/src/input/program_input/registers.rs rename to ast/src/input/program_input/registers.rs diff --git a/core-ast/src/input/program_state/mod.rs b/ast/src/input/program_state/mod.rs similarity index 100% rename from core-ast/src/input/program_state/mod.rs rename to ast/src/input/program_state/mod.rs diff --git a/core-ast/src/input/program_state/private_state/mod.rs b/ast/src/input/program_state/private_state/mod.rs similarity index 100% rename from core-ast/src/input/program_state/private_state/mod.rs rename to ast/src/input/program_state/private_state/mod.rs diff --git a/core-ast/src/input/program_state/private_state/private_state.rs b/ast/src/input/program_state/private_state/private_state.rs similarity index 100% rename from core-ast/src/input/program_state/private_state/private_state.rs rename to ast/src/input/program_state/private_state/private_state.rs diff --git a/core-ast/src/input/program_state/private_state/record.rs b/ast/src/input/program_state/private_state/record.rs similarity index 100% rename from core-ast/src/input/program_state/private_state/record.rs rename to ast/src/input/program_state/private_state/record.rs diff --git a/core-ast/src/input/program_state/private_state/state_leaf.rs b/ast/src/input/program_state/private_state/state_leaf.rs similarity index 100% rename from core-ast/src/input/program_state/private_state/state_leaf.rs rename to ast/src/input/program_state/private_state/state_leaf.rs diff --git a/core-ast/src/input/program_state/program_state.rs b/ast/src/input/program_state/program_state.rs similarity index 100% rename from core-ast/src/input/program_state/program_state.rs rename to ast/src/input/program_state/program_state.rs diff --git a/core-ast/src/input/program_state/public_state/mod.rs b/ast/src/input/program_state/public_state/mod.rs similarity index 100% rename from core-ast/src/input/program_state/public_state/mod.rs rename to ast/src/input/program_state/public_state/mod.rs diff --git a/core-ast/src/input/program_state/public_state/public_state.rs b/ast/src/input/program_state/public_state/public_state.rs similarity index 100% rename from core-ast/src/input/program_state/public_state/public_state.rs rename to ast/src/input/program_state/public_state/public_state.rs diff --git a/core-ast/src/input/program_state/public_state/state.rs b/ast/src/input/program_state/public_state/state.rs similarity index 100% rename from core-ast/src/input/program_state/public_state/state.rs rename to ast/src/input/program_state/public_state/state.rs diff --git a/core-ast/src/lib.rs b/ast/src/lib.rs similarity index 77% rename from core-ast/src/lib.rs rename to ast/src/lib.rs index 59f42f94ef..4325698987 100644 --- a/core-ast/src/lib.rs +++ b/ast/src/lib.rs @@ -16,9 +16,9 @@ //! The core abstract syntax tree (ast) for a Leo program. //! -//! This module contains the [`LeoCoreAst`] type, a wrapper around the [`Program`] type. -//! The [`LeoCoreAst`] type is intended to be parsed and modified by different passes -//! of the Leo compiler. The Leo compiler can generate a set of R1CS constraints from any [`LeoCoreAst`]. +//! This module contains the [`LeoAst`] type, a wrapper around the [`Program`] type. +//! The [`LeoAst`] type is intended to be parsed and modified by different passes +//! of the Leo compiler. The Leo compiler can generate a set of R1CS constraints from any [`LeoAst`]. pub mod annotation; pub use self::annotation::*; @@ -63,36 +63,36 @@ use leo_grammar::Grammar; /// The core abstract syntax tree (ast) for a Leo program. /// -/// The [`LeoCoreAst`] type represents a Leo program as a series of recursive data types. +/// The [`LeoAst`] type represents a Leo program as a series of recursive data types. /// These data types form a tree that begins from a [`Program`] type root. /// -/// A new [`LeoCoreAst`] can be created from a [`LeoAst`] generated by the pest parser in the `ast` module. +/// A new [`LeoAst`] can be created from a [`Grammar`] generated by the pest parser in the `ast` module. #[derive(Debug, Eq, PartialEq)] -pub struct LeoCoreAst { - core_ast: Program, +pub struct LeoAst { + ast: Program, } -impl LeoCoreAst { +impl LeoAst { /// Creates a new core syntax tree from a given program name and abstract syntax tree. pub fn new<'ast>(program_name: &str, ast: &Grammar<'ast>) -> Self { Self { - core_ast: Program::from(program_name, ast.as_repr()), + ast: Program::from(program_name, ast.as_repr()), } } /// Returns a reference to the inner program syntax tree representation. pub fn into_repr(self) -> Program { - self.core_ast + self.ast } /// Serializes the core syntax tree into a JSON string. pub fn to_json_string(&self) -> Result { - Ok(serde_json::to_string_pretty(&self.core_ast)?) + Ok(serde_json::to_string_pretty(&self.ast)?) } /// Deserializes the JSON string into a core syntax tree. pub fn from_json_string(json: &str) -> Result { let typed_ast: Program = serde_json::from_str(json)?; - Ok(Self { core_ast: typed_ast }) + Ok(Self { ast: typed_ast }) } } diff --git a/core-ast/src/main.rs b/ast/src/main.rs similarity index 89% rename from core-ast/src/main.rs rename to ast/src/main.rs index 1020575d33..c231cc677b 100644 --- a/core-ast/src/main.rs +++ b/ast/src/main.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::LeoCoreAst; +use leo_ast::LeoAst; use leo_grammar::{Grammar, ParserError}; use std::{env, fs, path::Path}; @@ -27,10 +27,10 @@ fn to_leo_core_tree(filepath: &Path) -> Result { let ast = Grammar::new(&program_filepath, &program_string)?; // Parse the pest ast and constructs a core ast. - let core_ast = LeoCoreAst::new("leo_core_tree", &ast); + let core_ast = LeoAst::new("leo_core_tree", &ast); // Serializes the core tree into JSON format. - let serialized_core_ast = LeoCoreAst::to_json_string(&core_ast)?; + let serialized_core_ast = LeoAst::to_json_string(&core_ast)?; Ok(serialized_core_ast) } @@ -43,7 +43,7 @@ fn main() -> Result<(), ParserError> { if cli_arguments.len() < 2 || cli_arguments.len() > 3 { eprintln!("Warning - an invalid number of command-line arguments were provided."); println!( - "\nCommand-line usage:\n\n\tleo_core_ast {{PATH/TO/INPUT_FILENAME}}.leo {{PATH/TO/OUTPUT_DIRECTORY (optional)}}\n" + "\nCommand-line usage:\n\n\tleo_ast {{PATH/TO/INPUT_FILENAME}}.leo {{PATH/TO/OUTPUT_DIRECTORY (optional)}}\n" ); return Ok(()); // Exit innocently } diff --git a/core-ast/src/program.rs b/ast/src/program.rs similarity index 100% rename from core-ast/src/program.rs rename to ast/src/program.rs diff --git a/core-ast/src/statements/conditional_nested_or_end_statement.rs b/ast/src/statements/conditional_nested_or_end_statement.rs similarity index 100% rename from core-ast/src/statements/conditional_nested_or_end_statement.rs rename to ast/src/statements/conditional_nested_or_end_statement.rs diff --git a/core-ast/src/statements/conditional_statement.rs b/ast/src/statements/conditional_statement.rs similarity index 100% rename from core-ast/src/statements/conditional_statement.rs rename to ast/src/statements/conditional_statement.rs diff --git a/core-ast/src/statements/mod.rs b/ast/src/statements/mod.rs similarity index 100% rename from core-ast/src/statements/mod.rs rename to ast/src/statements/mod.rs diff --git a/core-ast/src/statements/statement.rs b/ast/src/statements/statement.rs similarity index 100% rename from core-ast/src/statements/statement.rs rename to ast/src/statements/statement.rs diff --git a/core-ast/src/types/integer_type.rs b/ast/src/types/integer_type.rs similarity index 100% rename from core-ast/src/types/integer_type.rs rename to ast/src/types/integer_type.rs diff --git a/core-ast/src/types/mod.rs b/ast/src/types/mod.rs similarity index 100% rename from core-ast/src/types/mod.rs rename to ast/src/types/mod.rs diff --git a/core-ast/src/types/type_.rs b/ast/src/types/type_.rs similarity index 100% rename from core-ast/src/types/type_.rs rename to ast/src/types/type_.rs diff --git a/core-ast/tests/mod.rs b/ast/tests/mod.rs similarity index 100% rename from core-ast/tests/mod.rs rename to ast/tests/mod.rs diff --git a/core-ast/tests/serialization/expected_core_ast.json b/ast/tests/serialization/expected_core_ast.json similarity index 100% rename from core-ast/tests/serialization/expected_core_ast.json rename to ast/tests/serialization/expected_core_ast.json diff --git a/core-ast/tests/serialization/json.rs b/ast/tests/serialization/json.rs similarity index 88% rename from core-ast/tests/serialization/json.rs rename to ast/tests/serialization/json.rs index c18ade9a05..8e9c2edf09 100644 --- a/core-ast/tests/serialization/json.rs +++ b/ast/tests/serialization/json.rs @@ -14,14 +14,14 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::LeoCoreAst; +use leo_ast::LeoAst; #[cfg(not(feature = "ci_skip"))] -use leo_core_ast::Program; +use leo_ast::Program; use leo_grammar::Grammar; use std::path::{Path, PathBuf}; -fn to_core_ast(program_filepath: &Path) -> LeoCoreAst { +fn to_core_ast(program_filepath: &Path) -> LeoAst { // Loads the Leo code as a string from the given file path. let program_string = Grammar::load_file(program_filepath).unwrap(); @@ -29,7 +29,7 @@ fn to_core_ast(program_filepath: &Path) -> LeoCoreAst { let ast = Grammar::new(&program_filepath, &program_string).unwrap(); // Parses the pest ast and constructs a core ast. - LeoCoreAst::new("leo_core_tree", &ast) + LeoAst::new("leo_core_tree", &ast) } #[test] @@ -66,7 +66,7 @@ fn test_deserialize() { // Construct a core ast by deserializing a core ast JSON file. let serialized_typed_ast = include_str!("expected_core_ast.json"); - let core_ast = LeoCoreAst::from_json_string(serialized_typed_ast).unwrap(); + let core_ast = LeoAst::from_json_string(serialized_typed_ast).unwrap(); assert_eq!(expected_core_ast, core_ast); } @@ -84,8 +84,8 @@ fn test_serialize_deserialize_serialize() { // Serializes the core ast into JSON format. let serialized_core_ast = core_ast.to_json_string().unwrap(); - // Deserializes the serialized core ast into a LeoCoreAst. - let core_ast = LeoCoreAst::from_json_string(&serialized_core_ast).unwrap(); + // Deserializes the serialized core ast into a LeoAst. + let core_ast = LeoAst::from_json_string(&serialized_core_ast).unwrap(); // Reserializes the core ast into JSON format. let reserialized_core_ast = core_ast.to_json_string().unwrap(); diff --git a/core-ast/tests/serialization/main.leo b/ast/tests/serialization/main.leo similarity index 100% rename from core-ast/tests/serialization/main.leo rename to ast/tests/serialization/main.leo diff --git a/core-ast/tests/serialization/mod.rs b/ast/tests/serialization/mod.rs similarity index 100% rename from core-ast/tests/serialization/mod.rs rename to ast/tests/serialization/mod.rs diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index e48679a3d4..3414ca840c 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -17,8 +17,8 @@ include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" -[dependencies.leo-core-ast] -path = "../core-ast" +[dependencies.leo-ast] +path = "../ast" version = "1.0.3" [dependencies.leo-core-packages] @@ -124,4 +124,4 @@ default-features = false [features] default = [ ] -ci_skip = [ "leo-grammar/ci_skip", "leo-core-ast/ci_skip" ] +ci_skip = [ "leo-grammar/ci_skip", "leo-ast/ci_skip" ] diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index ffe6e98af8..61a36acfa2 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -23,7 +23,7 @@ use crate::{ OutputBytes, OutputFile, }; -use leo_core_ast::{Input, LeoCoreAst, MainInput, Program}; +use leo_ast::{Input, LeoAst, MainInput, Program}; use leo_grammar::Grammar; use leo_imports::ImportParser; use leo_input::LeoInputParser; @@ -184,7 +184,7 @@ impl> Compiler { })?; // Construct the core ast from the pest ast. - let core_ast = LeoCoreAst::new(&self.package_name, &pest_ast); + let core_ast = LeoAst::new(&self.package_name, &pest_ast); // Store the main program file. self.program = core_ast.into_repr(); @@ -244,7 +244,7 @@ impl> Compiler { let package_name = &self.package_name; // Construct the core ast from the pest ast. - let core_ast = LeoCoreAst::new(package_name, &ast); + let core_ast = LeoAst::new(package_name, &ast); // Store the main program file. self.program = core_ast.into_repr(); diff --git a/compiler/src/console/assert.rs b/compiler/src/console/assert.rs index 9845e51fd4..66465bd11f 100644 --- a/compiler/src/console/assert.rs +++ b/compiler/src/console/assert.rs @@ -17,7 +17,7 @@ //! Enforces an assert equals statement in a compiled Leo program. use crate::{errors::ConsoleError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, Span, Type}; +use leo_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/console/console.rs b/compiler/src/console/console.rs index 43023a1294..1be1d801cb 100644 --- a/compiler/src/console/console.rs +++ b/compiler/src/console/console.rs @@ -17,7 +17,7 @@ //! Evaluates a macro in a compiled Leo program. use crate::{errors::ConsoleError, program::ConstrainedProgram, GroupType}; -use leo_core_ast::{ConsoleFunction, ConsoleFunctionCall}; +use leo_ast::{ConsoleFunction, ConsoleFunctionCall}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/console/format.rs b/compiler/src/console/format.rs index 0545539607..05cabbdc15 100644 --- a/compiler/src/console/format.rs +++ b/compiler/src/console/format.rs @@ -17,7 +17,7 @@ //! Evaluates a formatted string in a compiled Leo program. use crate::{errors::ConsoleError, program::ConstrainedProgram, GroupType}; -use leo_core_ast::FormattedString; +use leo_ast::FormattedString; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/constraints/constraints.rs b/compiler/src/constraints/constraints.rs index a96339e4f9..d8b067c9bd 100644 --- a/compiler/src/constraints/constraints.rs +++ b/compiler/src/constraints/constraints.rs @@ -25,7 +25,7 @@ use crate::{ OutputBytes, OutputFile, }; -use leo_core_ast::{Input, Program}; +use leo_ast::{Input, Program}; use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; diff --git a/compiler/src/definition/definition.rs b/compiler/src/definition/definition.rs index 4ed4cbbd6f..b684eadb75 100644 --- a/compiler/src/definition/definition.rs +++ b/compiler/src/definition/definition.rs @@ -21,7 +21,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_core_ast::Identifier; +use leo_ast::Identifier; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/definition/definitions.rs b/compiler/src/definition/definitions.rs index d15ecd07c2..46bfa7ea07 100644 --- a/compiler/src/definition/definitions.rs +++ b/compiler/src/definition/definitions.rs @@ -22,7 +22,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_core_ast::Program; +use leo_ast::Program; use leo_imports::ImportParser; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/errors/console.rs b/compiler/src/errors/console.rs index 2d0b636c28..7366bf806f 100644 --- a/compiler/src/errors/console.rs +++ b/compiler/src/errors/console.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::ExpressionError; -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/compiler/src/errors/expression.rs b/compiler/src/errors/expression.rs index 91a162b163..f2e2e8c97b 100644 --- a/compiler/src/errors/expression.rs +++ b/compiler/src/errors/expression.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::{AddressError, BooleanError, FieldError, FunctionError, GroupError, IntegerError, ValueError}; -use leo_core_ast::{Error as FormattedError, Identifier, Span}; +use leo_ast::{Error as FormattedError, Identifier, Span}; use leo_core_packages::LeoCorePackageError; use snarkos_errors::gadgets::SynthesisError; diff --git a/compiler/src/errors/function.rs b/compiler/src/errors/function.rs index 87919fe0ca..8f22e1fb87 100644 --- a/compiler/src/errors/function.rs +++ b/compiler/src/errors/function.rs @@ -25,7 +25,7 @@ use crate::errors::{ StatementError, ValueError, }; -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/compiler/src/errors/import.rs b/compiler/src/errors/import.rs index 6bb9407c9d..241154f83b 100644 --- a/compiler/src/errors/import.rs +++ b/compiler/src/errors/import.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{Error as FormattedError, Identifier, ImportSymbol, Span}; +use leo_ast::{Error as FormattedError, Identifier, ImportSymbol, Span}; use leo_core_packages::LeoCorePackageError; #[derive(Debug, Error)] diff --git a/compiler/src/errors/output_bytes.rs b/compiler/src/errors/output_bytes.rs index 5cf212572e..d07af02bfa 100644 --- a/compiler/src/errors/output_bytes.rs +++ b/compiler/src/errors/output_bytes.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/compiler/src/errors/statement.rs b/compiler/src/errors/statement.rs index adc04cfc06..a70770ca53 100644 --- a/compiler/src/errors/statement.rs +++ b/compiler/src/errors/statement.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::{AddressError, BooleanError, ConsoleError, ExpressionError, IntegerError, ValueError}; -use leo_core_ast::{Error as FormattedError, Span, Type}; +use leo_ast::{Error as FormattedError, Span, Type}; use std::path::Path; diff --git a/compiler/src/errors/value/address.rs b/compiler/src/errors/value/address.rs index 1d308d90b1..c48ae4a993 100644 --- a/compiler/src/errors/value/address.rs +++ b/compiler/src/errors/value/address.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use snarkos_errors::{gadgets::SynthesisError, objects::account::AccountError}; use std::path::Path; diff --git a/compiler/src/errors/value/boolean.rs b/compiler/src/errors/value/boolean.rs index 897e461a35..1160f38d7a 100644 --- a/compiler/src/errors/value/boolean.rs +++ b/compiler/src/errors/value/boolean.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use snarkos_errors::gadgets::SynthesisError; use std::path::Path; diff --git a/compiler/src/errors/value/field.rs b/compiler/src/errors/value/field.rs index 452335bedb..5dda86a677 100644 --- a/compiler/src/errors/value/field.rs +++ b/compiler/src/errors/value/field.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use snarkos_errors::gadgets::SynthesisError; use std::path::Path; diff --git a/compiler/src/errors/value/group.rs b/compiler/src/errors/value/group.rs index 3e7b148654..d03c6b502f 100644 --- a/compiler/src/errors/value/group.rs +++ b/compiler/src/errors/value/group.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use snarkos_errors::gadgets::SynthesisError; use std::path::Path; diff --git a/compiler/src/errors/value/integer.rs b/compiler/src/errors/value/integer.rs index 4672635cd1..23d9d847d9 100644 --- a/compiler/src/errors/value/integer.rs +++ b/compiler/src/errors/value/integer.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{error::Error as FormattedError, Span}; +use leo_ast::{error::Error as FormattedError, Span}; use leo_gadgets::errors::SignedIntegerError; use snarkos_errors::gadgets::SynthesisError; diff --git a/compiler/src/errors/value/value.rs b/compiler/src/errors/value/value.rs index fa469919c5..41c4c50e0c 100644 --- a/compiler/src/errors/value/value.rs +++ b/compiler/src/errors/value/value.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::{AddressError, BooleanError, FieldError, GroupError, IntegerError}; -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/compiler/src/expression/arithmetic/add.rs b/compiler/src/expression/arithmetic/add.rs index a52e33756a..504a4c99af 100644 --- a/compiler/src/expression/arithmetic/add.rs +++ b/compiler/src/expression/arithmetic/add.rs @@ -17,7 +17,7 @@ //! Enforces an arithmetic `+` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/arithmetic/div.rs b/compiler/src/expression/arithmetic/div.rs index 1564b16305..6120e1ecf3 100644 --- a/compiler/src/expression/arithmetic/div.rs +++ b/compiler/src/expression/arithmetic/div.rs @@ -17,7 +17,7 @@ //! Enforces an arithmetic `/` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/arithmetic/mul.rs b/compiler/src/expression/arithmetic/mul.rs index cf3f0bb833..71eea3a663 100644 --- a/compiler/src/expression/arithmetic/mul.rs +++ b/compiler/src/expression/arithmetic/mul.rs @@ -17,7 +17,7 @@ //! Enforces an arithmetic `*` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/arithmetic/negate.rs b/compiler/src/expression/arithmetic/negate.rs index a3318532bd..43c3483713 100644 --- a/compiler/src/expression/arithmetic/negate.rs +++ b/compiler/src/expression/arithmetic/negate.rs @@ -17,7 +17,7 @@ //! Enforces a unary negate `-` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/arithmetic/pow.rs b/compiler/src/expression/arithmetic/pow.rs index 3607d4756c..403e5f97d2 100644 --- a/compiler/src/expression/arithmetic/pow.rs +++ b/compiler/src/expression/arithmetic/pow.rs @@ -17,7 +17,7 @@ //! Enforces an arithmetic `**` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/arithmetic/sub.rs b/compiler/src/expression/arithmetic/sub.rs index 20502ca597..a21aea905b 100644 --- a/compiler/src/expression/arithmetic/sub.rs +++ b/compiler/src/expression/arithmetic/sub.rs @@ -17,7 +17,7 @@ //! Enforces an arithmetic `-` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/array/access.rs b/compiler/src/expression/array/access.rs index c7f7fa827a..71ecf71487 100644 --- a/compiler/src/expression/array/access.rs +++ b/compiler/src/expression/array/access.rs @@ -17,7 +17,7 @@ //! Enforces array access in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, RangeOrExpression, Span, Type}; +use leo_ast::{Expression, RangeOrExpression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/array/array.rs b/compiler/src/expression/array/array.rs index d5e6f762d8..7a0494fb9d 100644 --- a/compiler/src/expression/array/array.rs +++ b/compiler/src/expression/array/array.rs @@ -22,7 +22,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_core_ast::{Expression, Span, SpreadOrExpression, Type}; +use leo_ast::{Expression, Span, SpreadOrExpression, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/array/index.rs b/compiler/src/expression/array/index.rs index 54b62f169e..52d2e863c8 100644 --- a/compiler/src/expression/array/index.rs +++ b/compiler/src/expression/array/index.rs @@ -17,7 +17,7 @@ //! Enforces an array index expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, IntegerType, Span, Type}; +use leo_ast::{Expression, IntegerType, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/binary/binary.rs b/compiler/src/expression/binary/binary.rs index ee580bfbe8..fade74bb0b 100644 --- a/compiler/src/expression/binary/binary.rs +++ b/compiler/src/expression/binary/binary.rs @@ -17,7 +17,7 @@ //! Enforces a binary expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, Span, Type}; +use leo_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/binary/operand.rs b/compiler/src/expression/binary/operand.rs index d15156c73a..e9853b8adf 100644 --- a/compiler/src/expression/binary/operand.rs +++ b/compiler/src/expression/binary/operand.rs @@ -17,7 +17,7 @@ //! Enforces one operand in a binary expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, Span, Type}; +use leo_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/circuit/access.rs b/compiler/src/expression/circuit/access.rs index 53d57c51b4..0d3864c295 100644 --- a/compiler/src/expression/circuit/access.rs +++ b/compiler/src/expression/circuit/access.rs @@ -22,7 +22,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_core_ast::{Expression, Identifier, Span, Type}; +use leo_ast::{Expression, Identifier, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/circuit/circuit.rs b/compiler/src/expression/circuit/circuit.rs index b1e7b8d421..e78cd00e91 100644 --- a/compiler/src/expression/circuit/circuit.rs +++ b/compiler/src/expression/circuit/circuit.rs @@ -22,7 +22,7 @@ use crate::{ value::{ConstrainedCircuitMember, ConstrainedValue}, GroupType, }; -use leo_core_ast::{CircuitMember, CircuitVariableDefinition, Identifier, Span}; +use leo_ast::{CircuitMember, CircuitVariableDefinition, Identifier, Span}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/circuit/static_access.rs b/compiler/src/expression/circuit/static_access.rs index 7bf3d67df4..31ed5bb865 100644 --- a/compiler/src/expression/circuit/static_access.rs +++ b/compiler/src/expression/circuit/static_access.rs @@ -17,7 +17,7 @@ //! Enforces a circuit static access expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{CircuitMember, Expression, Identifier, Span, Type}; +use leo_ast::{CircuitMember, Expression, Identifier, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/conditional/conditional.rs b/compiler/src/expression/conditional/conditional.rs index c332b791ba..a0b8e5a090 100644 --- a/compiler/src/expression/conditional/conditional.rs +++ b/compiler/src/expression/conditional/conditional.rs @@ -17,7 +17,7 @@ //! Enforces a conditional expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, Span, Type}; +use leo_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/expression.rs b/compiler/src/expression/expression.rs index e5b90b0641..859175f8af 100644 --- a/compiler/src/expression/expression.rs +++ b/compiler/src/expression/expression.rs @@ -28,7 +28,7 @@ use crate::{ GroupType, Integer, }; -use leo_core_ast::{Expression, Type}; +use leo_ast::{Expression, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/function/core_circuit.rs b/compiler/src/expression/function/core_circuit.rs index 8a43ae8bac..e62ece9234 100644 --- a/compiler/src/expression/function/core_circuit.rs +++ b/compiler/src/expression/function/core_circuit.rs @@ -16,7 +16,7 @@ use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType}; use crate::errors::{ExpressionError, FunctionError}; -use leo_core_ast::{Expression, Span, Type}; +use leo_ast::{Expression, Span, Type}; use leo_core_packages::call_core_circuit; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/function/function.rs b/compiler/src/expression/function/function.rs index 35b324218b..a7fba95c49 100644 --- a/compiler/src/expression/function/function.rs +++ b/compiler/src/expression/function/function.rs @@ -17,7 +17,7 @@ //! Enforce a function call expression in a compiled Leo program. use crate::{errors::ExpressionError, new_scope, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, Span, Type}; +use leo_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/identifier/identifier.rs b/compiler/src/expression/identifier/identifier.rs index 9dde05d491..58abdddb30 100644 --- a/compiler/src/expression/identifier/identifier.rs +++ b/compiler/src/expression/identifier/identifier.rs @@ -23,7 +23,7 @@ use crate::{ Address, GroupType, }; -use leo_core_ast::{Identifier, Type}; +use leo_ast::{Identifier, Type}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/expression/logical/and.rs b/compiler/src/expression/logical/and.rs index cef99fcf7c..b58cdb614f 100644 --- a/compiler/src/expression/logical/and.rs +++ b/compiler/src/expression/logical/and.rs @@ -17,7 +17,7 @@ //! Enforces a logical `&&` operator in a resolved Leo program. use crate::{errors::BooleanError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/logical/not.rs b/compiler/src/expression/logical/not.rs index cdf84c051a..f40089f982 100644 --- a/compiler/src/expression/logical/not.rs +++ b/compiler/src/expression/logical/not.rs @@ -17,7 +17,7 @@ //! Enforces a logical `!` operator in a resolved Leo program. use crate::{errors::BooleanError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/expression/logical/or.rs b/compiler/src/expression/logical/or.rs index 1f86254f48..0915d3e77b 100644 --- a/compiler/src/expression/logical/or.rs +++ b/compiler/src/expression/logical/or.rs @@ -17,7 +17,7 @@ //! Enforces a logical `||` operator in a resolved Leo program. use crate::{errors::BooleanError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/relational/eq.rs b/compiler/src/expression/relational/eq.rs index 114a66c65e..75f8de4ae9 100644 --- a/compiler/src/expression/relational/eq.rs +++ b/compiler/src/expression/relational/eq.rs @@ -17,7 +17,7 @@ //! Enforces a relational `==` operator in a resolved Leo program. use crate::{enforce_and, errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/relational/ge.rs b/compiler/src/expression/relational/ge.rs index fdd4ed723c..c7ebb817d7 100644 --- a/compiler/src/expression/relational/ge.rs +++ b/compiler/src/expression/relational/ge.rs @@ -17,7 +17,7 @@ //! Enforces a relational `>=` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use leo_gadgets::bits::ComparatorGadget; use snarkos_models::{ diff --git a/compiler/src/expression/relational/gt.rs b/compiler/src/expression/relational/gt.rs index 3939d624c2..e7d1283b11 100644 --- a/compiler/src/expression/relational/gt.rs +++ b/compiler/src/expression/relational/gt.rs @@ -17,7 +17,7 @@ //! Enforces a relational `>` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use leo_gadgets::bits::ComparatorGadget; use snarkos_models::{ diff --git a/compiler/src/expression/relational/le.rs b/compiler/src/expression/relational/le.rs index 4849f3d829..d5794ca9bd 100644 --- a/compiler/src/expression/relational/le.rs +++ b/compiler/src/expression/relational/le.rs @@ -17,7 +17,7 @@ //! Enforces a relational `<=` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use leo_gadgets::bits::ComparatorGadget; use snarkos_models::{ diff --git a/compiler/src/expression/relational/lt.rs b/compiler/src/expression/relational/lt.rs index b78d40d638..17af89b832 100644 --- a/compiler/src/expression/relational/lt.rs +++ b/compiler/src/expression/relational/lt.rs @@ -17,7 +17,7 @@ //! Enforces a relational `<` operator in a resolved Leo program. use crate::{errors::ExpressionError, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use leo_gadgets::bits::comparator::EvaluateLtGadget; use snarkos_models::{ diff --git a/compiler/src/expression/tuple/access.rs b/compiler/src/expression/tuple/access.rs index 6d736047ea..33cc551c98 100644 --- a/compiler/src/expression/tuple/access.rs +++ b/compiler/src/expression/tuple/access.rs @@ -17,7 +17,7 @@ //! Enforces array access in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, Span, Type}; +use leo_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/expression/tuple/tuple.rs b/compiler/src/expression/tuple/tuple.rs index 70f9b00dc7..b002908a46 100644 --- a/compiler/src/expression/tuple/tuple.rs +++ b/compiler/src/expression/tuple/tuple.rs @@ -17,7 +17,7 @@ //! Enforces an tuple expression in a compiled Leo program. use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, Span, Type}; +use leo_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index 13be254322..ab944103f0 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -23,7 +23,7 @@ use crate::{ GroupType, }; -use leo_core_ast::{Expression, Function, FunctionInput, Span, Type}; +use leo_ast::{Expression, Function, FunctionInput, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/input/array.rs b/compiler/src/function/input/array.rs index 881bea90c7..8c3cf3a9e7 100644 --- a/compiler/src/function/input/array.rs +++ b/compiler/src/function/input/array.rs @@ -23,7 +23,7 @@ use crate::{ GroupType, }; -use leo_core_ast::{InputValue, Span, Type}; +use leo_ast::{InputValue, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/input/function_input.rs b/compiler/src/function/input/function_input.rs index 1b4e08f7b8..77624fbfc6 100644 --- a/compiler/src/function/input/function_input.rs +++ b/compiler/src/function/input/function_input.rs @@ -18,7 +18,7 @@ use crate::{errors::FunctionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, Type}; +use leo_ast::{Expression, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/input/input_keyword.rs b/compiler/src/function/input/input_keyword.rs index f657ca854f..5d74e55f70 100644 --- a/compiler/src/function/input/input_keyword.rs +++ b/compiler/src/function/input/input_keyword.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::FunctionError, ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_core_ast::{Identifier, Input}; +use leo_ast::{Identifier, Input}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/input/input_section.rs b/compiler/src/function/input/input_section.rs index 2f104e682b..88b3e77da6 100644 --- a/compiler/src/function/input/input_section.rs +++ b/compiler/src/function/input/input_section.rs @@ -16,7 +16,7 @@ use crate::{errors::FunctionError, ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_core_ast::{Identifier, InputValue, Parameter}; +use leo_ast::{Identifier, InputValue, Parameter}; use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::ConstraintSystem, diff --git a/compiler/src/function/input/main_function_input.rs b/compiler/src/function/input/main_function_input.rs index 9fe4675810..7bed5fc273 100644 --- a/compiler/src/function/input/main_function_input.rs +++ b/compiler/src/function/input/main_function_input.rs @@ -30,7 +30,7 @@ use crate::{ Integer, }; -use leo_core_ast::{InputValue, Span, Type}; +use leo_ast::{InputValue, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/input/tuple.rs b/compiler/src/function/input/tuple.rs index ab273b6746..8ad74507d0 100644 --- a/compiler/src/function/input/tuple.rs +++ b/compiler/src/function/input/tuple.rs @@ -23,7 +23,7 @@ use crate::{ GroupType, }; -use leo_core_ast::{InputValue, Span, Type}; +use leo_ast::{InputValue, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/main_function.rs b/compiler/src/function/main_function.rs index c6a89cd85f..7604a80b28 100644 --- a/compiler/src/function/main_function.rs +++ b/compiler/src/function/main_function.rs @@ -23,7 +23,7 @@ use crate::{ OutputBytes, }; -use leo_core_ast::{Expression, Function, FunctionInput, Input}; +use leo_ast::{Expression, Function, FunctionInput, Input}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/function/result/result.rs b/compiler/src/function/result/result.rs index 04dc3f243a..cec2a05810 100644 --- a/compiler/src/function/result/result.rs +++ b/compiler/src/function/result/result.rs @@ -18,7 +18,7 @@ use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/import/parser/import_parser.rs b/compiler/src/import/parser/import_parser.rs index b9ad13a87f..9e440436ad 100644 --- a/compiler/src/import/parser/import_parser.rs +++ b/compiler/src/import/parser/import_parser.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::ImportError; -use leo_core_ast::{Package, Program}; +use leo_ast::{Package, Program}; use std::{collections::HashMap, env::current_dir}; diff --git a/compiler/src/import/store/core_package.rs b/compiler/src/import/store/core_package.rs index 92741ffe85..99742bbcbd 100644 --- a/compiler/src/import/store/core_package.rs +++ b/compiler/src/import/store/core_package.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{new_scope, ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_core_ast::Package; +use leo_ast::Package; use leo_core_packages::{CorePackageList, LeoCorePackageError}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/import/store/import.rs b/compiler/src/import/store/import.rs index 9d0501af33..9453d2ef02 100644 --- a/compiler/src/import/store/import.rs +++ b/compiler/src/import/store/import.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::ImportError, ConstrainedProgram, GroupType}; -use leo_core_ast::ImportStatement; +use leo_ast::ImportStatement; use leo_imports::ImportParser; use leo_symbol_table::imported_symbols::ImportedSymbols; diff --git a/compiler/src/import/store/symbol.rs b/compiler/src/import/store/symbol.rs index ad63689c3c..e5ef574060 100644 --- a/compiler/src/import/store/symbol.rs +++ b/compiler/src/import/store/symbol.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::ImportError, new_scope, ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_core_ast::{ImportSymbol, Program}; +use leo_ast::{ImportSymbol, Program}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/output/output_bytes.rs b/compiler/src/output/output_bytes.rs index 4e8fab7e68..8a797dae73 100644 --- a/compiler/src/output/output_bytes.rs +++ b/compiler/src/output/output_bytes.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::OutputBytesError, ConstrainedValue, GroupType, REGISTERS_VARIABLE_NAME}; -use leo_core_ast::{Parameter, Registers, Span}; +use leo_ast::{Parameter, Registers, Span}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/statement/assign/array.rs b/compiler/src/statement/assign/array.rs index 222913893d..842cdefbfe 100644 --- a/compiler/src/statement/assign/array.rs +++ b/compiler/src/statement/assign/array.rs @@ -17,7 +17,7 @@ //! Enforces an array assignment statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{RangeOrExpression, Span}; +use leo_ast::{RangeOrExpression, Span}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/assign/assign.rs b/compiler/src/statement/assign/assign.rs index f757fefab3..2dad3ea1f8 100644 --- a/compiler/src/statement/assign/assign.rs +++ b/compiler/src/statement/assign/assign.rs @@ -24,7 +24,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_core_ast::{Assignee, AssigneeAccess, Expression, Span}; +use leo_ast::{Assignee, AssigneeAccess, Expression, Span}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/assign/assignee.rs b/compiler/src/statement/assign/assignee.rs index 217a055892..3a0fe2641c 100644 --- a/compiler/src/statement/assign/assignee.rs +++ b/compiler/src/statement/assign/assignee.rs @@ -17,7 +17,7 @@ //! Resolves assignees in a compiled Leo program. use crate::{errors::StatementError, new_scope, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Assignee, Span}; +use leo_ast::{Assignee, Span}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/statement/assign/circuit_variable.rs b/compiler/src/statement/assign/circuit_variable.rs index 1362849875..146c95f983 100644 --- a/compiler/src/statement/assign/circuit_variable.rs +++ b/compiler/src/statement/assign/circuit_variable.rs @@ -17,7 +17,7 @@ //! Enforces a circuit variable assignment statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Identifier, Span}; +use leo_ast::{Identifier, Span}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/assign/tuple.rs b/compiler/src/statement/assign/tuple.rs index 307aef4d87..6fb7885255 100644 --- a/compiler/src/statement/assign/tuple.rs +++ b/compiler/src/statement/assign/tuple.rs @@ -17,7 +17,7 @@ //! Enforces a tuple assignment statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/branch/branch.rs b/compiler/src/statement/branch/branch.rs index 96edc1aec9..9d0d208036 100644 --- a/compiler/src/statement/branch/branch.rs +++ b/compiler/src/statement/branch/branch.rs @@ -17,7 +17,7 @@ //! Enforces a branch of a conditional or iteration statement in a compiled Leo program. use crate::{program::ConstrainedProgram, GroupType, IndicatorAndConstrainedValue, StatementResult}; -use leo_core_ast::{Statement, Type}; +use leo_ast::{Statement, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/conditional/conditional.rs b/compiler/src/statement/conditional/conditional.rs index ccc86141f9..48bad283b8 100644 --- a/compiler/src/statement/conditional/conditional.rs +++ b/compiler/src/statement/conditional/conditional.rs @@ -24,7 +24,7 @@ use crate::{ IndicatorAndConstrainedValue, StatementResult, }; -use leo_core_ast::{ConditionalNestedOrEndStatement, ConditionalStatement, Span, Type}; +use leo_ast::{ConditionalNestedOrEndStatement, ConditionalStatement, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/definition/definition.rs b/compiler/src/statement/definition/definition.rs index 4de710251c..aae6d4f79a 100644 --- a/compiler/src/statement/definition/definition.rs +++ b/compiler/src/statement/definition/definition.rs @@ -17,7 +17,7 @@ //! Enforces a definition statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, ConstrainedValue, GroupType}; -use leo_core_ast::{Declare, Expression, Span, VariableName, Variables}; +use leo_ast::{Declare, Expression, Span, VariableName, Variables}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/iteration/iteration.rs b/compiler/src/statement/iteration/iteration.rs index bdf7f43f97..64104cbb45 100644 --- a/compiler/src/statement/iteration/iteration.rs +++ b/compiler/src/statement/iteration/iteration.rs @@ -25,7 +25,7 @@ use crate::{ Integer, StatementResult, }; -use leo_core_ast::{Expression, Identifier, Span, Statement, Type}; +use leo_ast::{Expression, Identifier, Span, Statement, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/return_/return_.rs b/compiler/src/statement/return_/return_.rs index 85f7e6caaf..ad8e6568c0 100644 --- a/compiler/src/statement/return_/return_.rs +++ b/compiler/src/statement/return_/return_.rs @@ -17,7 +17,7 @@ //! Enforces a return statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Expression, Span, Type}; +use leo_ast::{Expression, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/statement/statement.rs b/compiler/src/statement/statement.rs index 1c23bee4dd..6b3472c9b6 100644 --- a/compiler/src/statement/statement.rs +++ b/compiler/src/statement/statement.rs @@ -17,7 +17,7 @@ //! Enforces a statement in a compiled Leo program. use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Statement, Type}; +use leo_ast::{Statement, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/value/address/address.rs b/compiler/src/value/address/address.rs index 3bbdda41cd..95566475b0 100644 --- a/compiler/src/value/address/address.rs +++ b/compiler/src/value/address/address.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::AddressError, ConstrainedValue, GroupType}; -use leo_core_ast::{InputValue, Span}; +use leo_ast::{InputValue, Span}; use snarkos_dpc::base_dpc::instantiated::Components; use snarkos_errors::gadgets::SynthesisError; diff --git a/compiler/src/value/boolean/input.rs b/compiler/src/value/boolean/input.rs index 25a9b915f2..d35661f112 100644 --- a/compiler/src/value/boolean/input.rs +++ b/compiler/src/value/boolean/input.rs @@ -17,7 +17,7 @@ //! Methods to enforce constraints on input boolean values in a resolved Leo program. use crate::{errors::BooleanError, value::ConstrainedValue, GroupType}; -use leo_core_ast::{InputValue, Span}; +use leo_ast::{InputValue, Span}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/value/field/field_type.rs b/compiler/src/value/field/field_type.rs index f2423ff0e3..39146ae593 100644 --- a/compiler/src/value/field/field_type.rs +++ b/compiler/src/value/field/field_type.rs @@ -17,7 +17,7 @@ //! A data type that represents a field value use crate::errors::FieldError; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/value/field/input.rs b/compiler/src/value/field/input.rs index 6cf4339192..a498b25345 100644 --- a/compiler/src/value/field/input.rs +++ b/compiler/src/value/field/input.rs @@ -17,7 +17,7 @@ //! Methods to enforce constraints on input field values in a compiled Leo program. use crate::{errors::FieldError, value::ConstrainedValue, FieldType, GroupType}; -use leo_core_ast::{InputValue, Span}; +use leo_ast::{InputValue, Span}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/value/group/group_type.rs b/compiler/src/value/group/group_type.rs index 3521abecee..c80a6a8325 100644 --- a/compiler/src/value/group/group_type.rs +++ b/compiler/src/value/group/group_type.rs @@ -17,7 +17,7 @@ //! A data type that represents members in the group formed by the set of affine points on a curve. use crate::errors::GroupError; -use leo_core_ast::{GroupValue, Span}; +use leo_ast::{GroupValue, Span}; use snarkos_models::{ curves::{Field, One}, diff --git a/compiler/src/value/group/input.rs b/compiler/src/value/group/input.rs index a4cdae715c..2ff04b6095 100644 --- a/compiler/src/value/group/input.rs +++ b/compiler/src/value/group/input.rs @@ -17,7 +17,7 @@ //! Methods to enforce constraints on input group values in a Leo program. use crate::{errors::GroupError, ConstrainedValue, GroupType}; -use leo_core_ast::{GroupValue, InputValue, Span}; +use leo_ast::{GroupValue, InputValue, Span}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/value/group/targets/edwards_bls12.rs b/compiler/src/value/group/targets/edwards_bls12.rs index 66cbc8cae3..7a1ab306dc 100644 --- a/compiler/src/value/group/targets/edwards_bls12.rs +++ b/compiler/src/value/group/targets/edwards_bls12.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::GroupError, GroupType}; -use leo_core_ast::{GroupCoordinate, GroupTuple, GroupValue, Span}; +use leo_ast::{GroupCoordinate, GroupTuple, GroupValue, Span}; use snarkos_curves::{ edwards_bls12::{EdwardsAffine, EdwardsParameters, Fq}, diff --git a/compiler/src/value/implicit/implicit.rs b/compiler/src/value/implicit/implicit.rs index b838a4a689..d72c9f4648 100644 --- a/compiler/src/value/implicit/implicit.rs +++ b/compiler/src/value/implicit/implicit.rs @@ -17,7 +17,7 @@ //! Enforces constraints on an implicit number in a compiled Leo program. use crate::{errors::ValueError, value::ConstrainedValue, GroupType}; -use leo_core_ast::{Span, Type}; +use leo_ast::{Span, Type}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/value/integer/integer.rs b/compiler/src/value/integer/integer.rs index f859caf69a..1476f3a3bc 100644 --- a/compiler/src/value/integer/integer.rs +++ b/compiler/src/value/integer/integer.rs @@ -16,7 +16,7 @@ //! Conversion of integer declarations to constraints in Leo. use crate::{errors::IntegerError, IntegerTrait}; -use leo_core_ast::{InputValue, IntegerType, Span}; +use leo_ast::{InputValue, IntegerType, Span}; use leo_gadgets::{ arithmetic::*, bits::comparator::{ComparatorGadget, EvaluateLtGadget}, diff --git a/compiler/src/value/value.rs b/compiler/src/value/value.rs index e74a688ddb..1082e9c053 100644 --- a/compiler/src/value/value.rs +++ b/compiler/src/value/value.rs @@ -26,7 +26,7 @@ use crate::{ GroupType, Integer, }; -use leo_core_ast::{Circuit, Function, GroupValue, Identifier, Span, Type}; +use leo_ast::{Circuit, Function, GroupValue, Identifier, Span, Type}; use leo_core_packages::Value; use snarkos_errors::gadgets::SynthesisError; diff --git a/compiler/tests/address/mod.rs b/compiler/tests/address/mod.rs index fac98eb643..3d892a5fb7 100644 --- a/compiler/tests/address/mod.rs +++ b/compiler/tests/address/mod.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program}; -use leo_core_ast::InputValue; +use leo_ast::InputValue; static TEST_ADDRESS_1: &str = "aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8"; static TEST_ADDRESS_2: &str = "aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r"; diff --git a/compiler/tests/console/mod.rs b/compiler/tests/console/mod.rs index 73f0b41fe6..ba7c48aae9 100644 --- a/compiler/tests/console/mod.rs +++ b/compiler/tests/console/mod.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program}; -use leo_core_ast::InputValue; +use leo_ast::InputValue; #[test] fn test_log() { diff --git a/compiler/tests/core/packages/unstable/blake2s/mod.rs b/compiler/tests/core/packages/unstable/blake2s/mod.rs index edbbc2e8bf..2b308db42e 100644 --- a/compiler/tests/core/packages/unstable/blake2s/mod.rs +++ b/compiler/tests/core/packages/unstable/blake2s/mod.rs @@ -23,7 +23,7 @@ use crate::{ parse_program_with_input, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{IntegerType, U8Type, UnsignedIntegerType}; use rand::{Rng, SeedableRng}; use rand_xorshift::XorShiftRng; diff --git a/compiler/tests/field/mod.rs b/compiler/tests/field/mod.rs index 706c5bd70d..0cb5e4198c 100644 --- a/compiler/tests/field/mod.rs +++ b/compiler/tests/field/mod.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program}; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use snarkos_curves::edwards_bls12::Fq; use snarkos_utilities::bytes::ToBytes; diff --git a/compiler/tests/group/mod.rs b/compiler/tests/group/mod.rs index 901597806f..c560afdc57 100644 --- a/compiler/tests/group/mod.rs +++ b/compiler/tests/group/mod.rs @@ -18,7 +18,7 @@ use crate::{ assert_satisfied, expect_compiler_error, expect_synthesis_error, field::field_to_decimal_string, generate_main_input, parse_program, parse_program_with_input, }; -use leo_core_ast::{GroupCoordinate, GroupTuple, GroupValue, InputValue, Span}; +use leo_ast::{GroupCoordinate, GroupTuple, GroupValue, InputValue, Span}; use snarkos_curves::edwards_bls12::EdwardsAffine; diff --git a/compiler/tests/integers/i128/mod.rs b/compiler/tests/integers/i128/mod.rs index 8f4023a99a..8cb73fff1a 100644 --- a/compiler/tests/integers/i128/mod.rs +++ b/compiler/tests/integers/i128/mod.rs @@ -21,7 +21,7 @@ use crate::{ integers::{expect_computation_error, expect_parsing_error, IntegerTester}, parse_program, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{I128Type, IntegerType, SignedIntegerType}; test_int!( diff --git a/compiler/tests/integers/i16/mod.rs b/compiler/tests/integers/i16/mod.rs index 73519f487a..ad2988aad0 100644 --- a/compiler/tests/integers/i16/mod.rs +++ b/compiler/tests/integers/i16/mod.rs @@ -21,7 +21,7 @@ use crate::{ integers::{expect_computation_error, expect_parsing_error, IntegerTester}, parse_program, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{I16Type, IntegerType, SignedIntegerType}; test_int!( diff --git a/compiler/tests/integers/i32/mod.rs b/compiler/tests/integers/i32/mod.rs index 6c18449559..f4df3cc7ff 100644 --- a/compiler/tests/integers/i32/mod.rs +++ b/compiler/tests/integers/i32/mod.rs @@ -21,7 +21,7 @@ use crate::{ integers::{expect_computation_error, expect_parsing_error, IntegerTester}, parse_program, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{I32Type, IntegerType, SignedIntegerType}; test_int!( diff --git a/compiler/tests/integers/i64/mod.rs b/compiler/tests/integers/i64/mod.rs index 1d61ef1bca..713e02dd8e 100644 --- a/compiler/tests/integers/i64/mod.rs +++ b/compiler/tests/integers/i64/mod.rs @@ -21,7 +21,7 @@ use crate::{ integers::{expect_computation_error, expect_parsing_error, IntegerTester}, parse_program, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{I64Type, IntegerType, SignedIntegerType}; test_int!( diff --git a/compiler/tests/integers/i8/mod.rs b/compiler/tests/integers/i8/mod.rs index 6a8f535b72..813e2c13d2 100644 --- a/compiler/tests/integers/i8/mod.rs +++ b/compiler/tests/integers/i8/mod.rs @@ -21,7 +21,7 @@ use crate::{ integers::{expect_computation_error, expect_parsing_error, IntegerTester}, parse_program, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{I8Type, IntegerType, SignedIntegerType}; test_int!( diff --git a/compiler/tests/integers/u128/mod.rs b/compiler/tests/integers/u128/mod.rs index 84e72e27c7..5312c43e5a 100644 --- a/compiler/tests/integers/u128/mod.rs +++ b/compiler/tests/integers/u128/mod.rs @@ -21,7 +21,7 @@ use crate::{ integers::{expect_parsing_error, IntegerTester}, parse_program, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{IntegerType, U128Type, UnsignedIntegerType}; test_uint!( diff --git a/compiler/tests/integers/u16/mod.rs b/compiler/tests/integers/u16/mod.rs index c6a3388505..fac708a456 100644 --- a/compiler/tests/integers/u16/mod.rs +++ b/compiler/tests/integers/u16/mod.rs @@ -21,7 +21,7 @@ use crate::{ integers::{expect_parsing_error, IntegerTester}, parse_program, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{IntegerType, U16Type, UnsignedIntegerType}; test_uint!( diff --git a/compiler/tests/integers/u32/mod.rs b/compiler/tests/integers/u32/mod.rs index fc4cd16eb8..ac6b51f3fd 100644 --- a/compiler/tests/integers/u32/mod.rs +++ b/compiler/tests/integers/u32/mod.rs @@ -21,7 +21,7 @@ use crate::{ integers::{expect_parsing_error, IntegerTester}, parse_program, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{IntegerType, U32Type, UnsignedIntegerType}; test_uint!( diff --git a/compiler/tests/integers/u64/mod.rs b/compiler/tests/integers/u64/mod.rs index bd18a0fd09..d66ec56e64 100644 --- a/compiler/tests/integers/u64/mod.rs +++ b/compiler/tests/integers/u64/mod.rs @@ -21,7 +21,7 @@ use crate::{ integers::{expect_parsing_error, IntegerTester}, parse_program, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{IntegerType, U64Type, UnsignedIntegerType}; test_uint!( diff --git a/compiler/tests/integers/u8/mod.rs b/compiler/tests/integers/u8/mod.rs index f9d6a5e1bb..3eb3666263 100644 --- a/compiler/tests/integers/u8/mod.rs +++ b/compiler/tests/integers/u8/mod.rs @@ -21,7 +21,7 @@ use crate::{ integers::{expect_parsing_error, IntegerTester}, parse_program, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; use leo_input::types::{IntegerType, U8Type, UnsignedIntegerType}; test_uint!( diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index fd16809cf0..a18efa9428 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -35,6 +35,7 @@ pub mod statements; pub mod syntax; pub mod tuples; +use leo_ast::{InputValue, MainInput}; use leo_compiler::{ compiler::Compiler, errors::CompilerError, @@ -42,7 +43,6 @@ use leo_compiler::{ ConstrainedValue, OutputBytes, }; -use leo_core_ast::{InputValue, MainInput}; use leo_input::types::{IntegerType, U32Type, UnsignedIntegerType}; use snarkos_curves::edwards_bls12::Fq; diff --git a/compiler/tests/mutability/mod.rs b/compiler/tests/mutability/mod.rs index 3ac48f07d4..8442357044 100644 --- a/compiler/tests/mutability/mod.rs +++ b/compiler/tests/mutability/mod.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{assert_satisfied, expect_compiler_error, expect_type_inference_error, generate_main_input, parse_program}; -use leo_core_ast::InputValue; +use leo_ast::InputValue; #[test] fn test_let() { diff --git a/compiler/tests/statements/conditional/mod.rs b/compiler/tests/statements/conditional/mod.rs index d6b5ab8c14..3c243c9804 100644 --- a/compiler/tests/statements/conditional/mod.rs +++ b/compiler/tests/statements/conditional/mod.rs @@ -24,7 +24,7 @@ use crate::{ parse_program_with_input, EdwardsTestCompiler, }; -use leo_core_ast::InputValue; +use leo_ast::InputValue; #[test] fn test_assert() { diff --git a/compiler/tests/statements/mod.rs b/compiler/tests/statements/mod.rs index c6b7efdd2f..4680bee86d 100644 --- a/compiler/tests/statements/mod.rs +++ b/compiler/tests/statements/mod.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{assert_satisfied, expect_type_inference_error, generate_main_input, parse_program}; -use leo_core_ast::InputValue; +use leo_ast::InputValue; pub mod conditional; diff --git a/core-packages/Cargo.toml b/core-packages/Cargo.toml index b0d93dc423..abc77f3d5d 100644 --- a/core-packages/Cargo.toml +++ b/core-packages/Cargo.toml @@ -21,8 +21,8 @@ edition = "2018" path = "../gadgets" version = "1.0.3" -[dependencies.leo-core-ast] -path = "../core-ast" +[dependencies.leo-ast] +path = "../ast" version = "1.0.3" [dependencies.snarkos-errors] diff --git a/core-packages/src/errors/core_circuit.rs b/core-packages/src/errors/core_circuit.rs index 5b2e81c70f..ce394e18de 100644 --- a/core-packages/src/errors/core_circuit.rs +++ b/core-packages/src/errors/core_circuit.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Value; -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use snarkos_errors::gadgets::SynthesisError; diff --git a/core-packages/src/errors/core_package.rs b/core-packages/src/errors/core_package.rs index 6c8726b906..7ce7f150b8 100644 --- a/core-packages/src/errors/core_package.rs +++ b/core-packages/src/errors/core_package.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/core-packages/src/errors/core_package_list.rs b/core-packages/src/errors/core_package_list.rs index 57e4b292e7..f8c2f35026 100644 --- a/core-packages/src/errors/core_package_list.rs +++ b/core-packages/src/errors/core_package_list.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{Error as FormattedError, ImportSymbol, Span}; +use leo_ast::{Error as FormattedError, ImportSymbol, Span}; use crate::CorePackageError; use std::path::Path; diff --git a/core-packages/src/errors/leo_core_package.rs b/core-packages/src/errors/leo_core_package.rs index be5bed0ffb..30db8ef7d3 100644 --- a/core-packages/src/errors/leo_core_package.rs +++ b/core-packages/src/errors/leo_core_package.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CoreCircuitError, CorePackageListError}; -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/core-packages/src/lib.rs b/core-packages/src/lib.rs index 1293becee1..67533ae4a5 100644 --- a/core-packages/src/lib.rs +++ b/core-packages/src/lib.rs @@ -27,7 +27,7 @@ pub mod types; pub use self::types::*; use crate::CoreCircuit; -use leo_core_ast::Span; +use leo_ast::Span; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/core-packages/src/packages/unstable/blake2s.rs b/core-packages/src/packages/unstable/blake2s.rs index f9ede1f7e2..a9371cd070 100644 --- a/core-packages/src/packages/unstable/blake2s.rs +++ b/core-packages/src/packages/unstable/blake2s.rs @@ -16,7 +16,7 @@ use crate::{CoreCircuit, CoreCircuitError, Value}; -use leo_core_ast::{ +use leo_ast::{ Circuit, CircuitMember, Expression, diff --git a/core-packages/src/types/core_circuit.rs b/core-packages/src/types/core_circuit.rs index 7d58d6b3c7..b098db3970 100644 --- a/core-packages/src/types/core_circuit.rs +++ b/core-packages/src/types/core_circuit.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CoreCircuitError, Value}; -use leo_core_ast::{Circuit, Identifier, Span}; +use leo_ast::{Circuit, Identifier, Span}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/core-packages/src/types/core_circuit_struct_list.rs b/core-packages/src/types/core_circuit_struct_list.rs index f8dd653ecc..8da8f6f160 100644 --- a/core-packages/src/types/core_circuit_struct_list.rs +++ b/core-packages/src/types/core_circuit_struct_list.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::Circuit; +use leo_ast::Circuit; /// List of imported core circuit structs. /// This struct is created from a `CorePackageList` diff --git a/core-packages/src/types/core_package.rs b/core-packages/src/types/core_package.rs index 9435910765..814de215f5 100644 --- a/core-packages/src/types/core_package.rs +++ b/core-packages/src/types/core_package.rs @@ -20,7 +20,7 @@ use crate::{ CoreCircuitStructList, CorePackageError, }; -use leo_core_ast::{Identifier, ImportSymbol, Package, PackageAccess}; +use leo_ast::{Identifier, ImportSymbol, Package, PackageAccess}; use std::convert::TryFrom; /// A core package dependency to be imported into a Leo program. diff --git a/core-packages/src/types/core_package_list.rs b/core-packages/src/types/core_package_list.rs index a70c8f886b..cf2c760921 100644 --- a/core-packages/src/types/core_package_list.rs +++ b/core-packages/src/types/core_package_list.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CoreCircuitStructList, CorePackage, CorePackageListError, UNSTABLE_CORE_PACKAGE_KEYWORD}; -use leo_core_ast::PackageAccess; +use leo_ast::PackageAccess; use std::convert::TryFrom; /// A list of core package dependencies. diff --git a/grammar/src/lib.rs b/grammar/src/lib.rs index f2e818788c..201e053dc6 100644 --- a/grammar/src/lib.rs +++ b/grammar/src/lib.rs @@ -18,7 +18,7 @@ //! //! This module contains the [`Grammar`] type, a wrapper around the [`File`] type in this module. //! The [`Grammar`] type is the datatype generated by the pest parser using grammar from `leo.pest`. -//! The [`Grammar`] type is intended to be parsed into a [`LeoCoreAst`]. It should not be parsed by +//! The [`Grammar`] type is intended to be parsed into a [`LeoAst`]. It should not be parsed by //! any other pass of the compiler. #[macro_use] diff --git a/imports/Cargo.toml b/imports/Cargo.toml index 4dea07fb0e..6990d086c4 100644 --- a/imports/Cargo.toml +++ b/imports/Cargo.toml @@ -17,8 +17,8 @@ include = ["Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" -[dependencies.leo-core-ast] -path = "../core-ast" +[dependencies.leo-ast] +path = "../ast" version = "1.0.3" [dependencies.leo-grammar] diff --git a/imports/src/errors/import_parser.rs b/imports/src/errors/import_parser.rs index 5885eccbda..5638e867cd 100644 --- a/imports/src/errors/import_parser.rs +++ b/imports/src/errors/import_parser.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{Error as FormattedError, Identifier, Span}; +use leo_ast::{Error as FormattedError, Identifier, Span}; use leo_grammar::ParserError; use std::{io, path::Path}; diff --git a/imports/src/parser/core_package.rs b/imports/src/parser/core_package.rs index 8227bbab7a..67c3df8d47 100644 --- a/imports/src/parser/core_package.rs +++ b/imports/src/parser/core_package.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::ImportParserError, ImportParser}; -use leo_core_ast::Package; +use leo_ast::Package; pub static CORE_PACKAGE_NAME: &str = "core"; diff --git a/imports/src/parser/import_parser.rs b/imports/src/parser/import_parser.rs index f5da49856b..58a2ca8f19 100644 --- a/imports/src/parser/import_parser.rs +++ b/imports/src/parser/import_parser.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::ImportParserError; -use leo_core_ast::{Package, Program}; +use leo_ast::{Package, Program}; use std::{ collections::{HashMap, HashSet}, diff --git a/imports/src/parser/parse_package.rs b/imports/src/parser/parse_package.rs index 5656119d39..0ab54a84ca 100644 --- a/imports/src/parser/parse_package.rs +++ b/imports/src/parser/parse_package.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::ImportParserError, ImportParser, CORE_PACKAGE_NAME}; -use leo_core_ast::{Package, PackageAccess}; +use leo_ast::{Package, PackageAccess}; use std::{fs, fs::DirEntry, path::PathBuf}; diff --git a/imports/src/parser/parse_symbol.rs b/imports/src/parser/parse_symbol.rs index 8f09a1fbcc..4856862aad 100644 --- a/imports/src/parser/parse_symbol.rs +++ b/imports/src/parser/parse_symbol.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{errors::ImportParserError, ImportParser}; -use leo_core_ast::{ImportSymbol, Program, Span}; +use leo_ast::{ImportSymbol, Program, Span}; use leo_grammar::Grammar; use std::{ffi::OsString, fs::DirEntry, path::PathBuf}; diff --git a/state/Cargo.toml b/state/Cargo.toml index 36f172edd9..d49bc194d2 100644 --- a/state/Cargo.toml +++ b/state/Cargo.toml @@ -21,8 +21,8 @@ edition = "2018" path = "../input" version = "1.0.3" -[dependencies.leo-core-ast] -path = "../core-ast" +[dependencies.leo-ast] +path = "../ast" version = "1.0.3" [dependencies.snarkos-algorithms] diff --git a/state/src/local_data_commitment/local_data_commitment.rs b/state/src/local_data_commitment/local_data_commitment.rs index 0b3d33ee9a..fd6fc3cd64 100644 --- a/state/src/local_data_commitment/local_data_commitment.rs +++ b/state/src/local_data_commitment/local_data_commitment.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{verify_record_commitment, LocalDataVerificationError, StateLeafValues, StateValues}; -use leo_core_ast::Input as TypedInput; +use leo_ast::Input as TypedInput; use snarkos_algorithms::commitment_tree::CommitmentMerklePath; use snarkos_dpc::base_dpc::{ diff --git a/state/src/local_data_commitment/state_leaf_values.rs b/state/src/local_data_commitment/state_leaf_values.rs index 4f01fad3fd..4c7b743f7f 100644 --- a/state/src/local_data_commitment/state_leaf_values.rs +++ b/state/src/local_data_commitment/state_leaf_values.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{find_input, input_to_integer_string, input_to_u8_vec, StateLeafValuesError}; -use leo_core_ast::StateLeaf as TypedStateLeaf; +use leo_ast::StateLeaf as TypedStateLeaf; use std::convert::TryFrom; diff --git a/state/src/local_data_commitment/state_values.rs b/state/src/local_data_commitment/state_values.rs index 7dcdc9c783..eafc9d4f2f 100644 --- a/state/src/local_data_commitment/state_values.rs +++ b/state/src/local_data_commitment/state_values.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{find_input, input_to_integer_string, input_to_u8_vec, StateValuesError}; -use leo_core_ast::State as TypedState; +use leo_ast::State as TypedState; use std::convert::TryFrom; diff --git a/state/src/record_commitment/dpc_record_values.rs b/state/src/record_commitment/dpc_record_values.rs index 1b61660f60..5d0e9a271b 100644 --- a/state/src/record_commitment/dpc_record_values.rs +++ b/state/src/record_commitment/dpc_record_values.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{utilities::*, DPCRecordValuesError}; -use leo_core_ast::Record as TypedRecord; +use leo_ast::Record as TypedRecord; use snarkos_dpc::base_dpc::instantiated::Components; use snarkos_objects::AccountAddress; diff --git a/state/src/record_commitment/record_commitment.rs b/state/src/record_commitment/record_commitment.rs index c42cac2d48..5b9ebc38b7 100644 --- a/state/src/record_commitment/record_commitment.rs +++ b/state/src/record_commitment/record_commitment.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{DPCRecordValues, RecordVerificationError}; -use leo_core_ast::Record as TypedRecord; +use leo_ast::Record as TypedRecord; use snarkos_dpc::base_dpc::{ instantiated::{Components, RecordCommitment}, diff --git a/state/src/utilities/input_value.rs b/state/src/utilities/input_value.rs index 2500acde9b..a04fde7c78 100644 --- a/state/src/utilities/input_value.rs +++ b/state/src/utilities/input_value.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::InputValueError; -use leo_core_ast::{InputValue, Parameter}; +use leo_ast::{InputValue, Parameter}; use std::collections::HashMap; diff --git a/state/tests/test_verify_local_data_commitment.rs b/state/tests/test_verify_local_data_commitment.rs index 226fbbfb71..83dc69a46b 100644 --- a/state/tests/test_verify_local_data_commitment.rs +++ b/state/tests/test_verify_local_data_commitment.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::Input; +use leo_ast::Input; use leo_input::LeoInputParser; use leo_state::verify_local_data_commitment; diff --git a/state/tests/test_verify_record_commitment.rs b/state/tests/test_verify_record_commitment.rs index be03b32094..0a148a407f 100644 --- a/state/tests/test_verify_record_commitment.rs +++ b/state/tests/test_verify_record_commitment.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::Input; +use leo_ast::Input; use leo_input::LeoInputParser; use leo_state::verify_record_commitment; diff --git a/symbol-table/Cargo.toml b/symbol-table/Cargo.toml index ca61f72300..41a7c9437a 100644 --- a/symbol-table/Cargo.toml +++ b/symbol-table/Cargo.toml @@ -21,8 +21,8 @@ edition = "2018" path = "../grammar" version = "1.0.3" -[dependencies.leo-core-ast] -path = "../core-ast" +[dependencies.leo-ast] +path = "../ast" version = "1.0.3" [dependencies.leo-core-packages] diff --git a/symbol-table/src/errors/symbol_table.rs b/symbol-table/src/errors/symbol_table.rs index 0b1f61ef88..f281605ea6 100644 --- a/symbol-table/src/errors/symbol_table.rs +++ b/symbol-table/src/errors/symbol_table.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{TypeError, UserDefinedType}; -use leo_core_ast::{Error as FormattedError, ImportSymbol, Program, Span}; +use leo_ast::{Error as FormattedError, ImportSymbol, Program, Span}; use leo_core_packages::{CorePackageListError, LeoCorePackageError}; use std::path::Path; diff --git a/symbol-table/src/errors/type_.rs b/symbol-table/src/errors/type_.rs index 487b323b4a..5e3bed8102 100644 --- a/symbol-table/src/errors/type_.rs +++ b/symbol-table/src/errors/type_.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Type; -use leo_core_ast::{Error as FormattedError, Identifier, Span}; +use leo_ast::{Error as FormattedError, Identifier, Span}; use std::path::Path; diff --git a/symbol-table/src/imports/imported_symbols.rs b/symbol-table/src/imports/imported_symbols.rs index a68d6f5f31..c344b9457b 100644 --- a/symbol-table/src/imports/imported_symbols.rs +++ b/symbol-table/src/imports/imported_symbols.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{ImportStatement, ImportSymbol, Package, PackageAccess}; +use leo_ast::{ImportStatement, ImportSymbol, Package, PackageAccess}; /// Stores the the package file name and imported symbol from an import statement #[derive(Debug)] diff --git a/symbol-table/src/symbol_table.rs b/symbol-table/src/symbol_table.rs index 7af8f9a530..edabc6f772 100644 --- a/symbol-table/src/symbol_table.rs +++ b/symbol-table/src/symbol_table.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CircuitType, CircuitVariableType, FunctionType, ImportedSymbols, SymbolTableError, UserDefinedType}; -use leo_core_ast::{Circuit, Function, Identifier, ImportStatement, ImportSymbol, Input, Package, Program}; +use leo_ast::{Circuit, Function, Identifier, ImportStatement, ImportSymbol, Input, Package, Program}; use leo_core_packages::CorePackageList; use leo_imports::ImportParser; diff --git a/symbol-table/src/types/circuits/circuit.rs b/symbol-table/src/types/circuits/circuit.rs index 5a1b6e0f4b..2e6ea923f0 100644 --- a/symbol-table/src/types/circuits/circuit.rs +++ b/symbol-table/src/types/circuits/circuit.rs @@ -22,7 +22,7 @@ use crate::{ Type, TypeError, }; -use leo_core_ast::{Circuit, CircuitMember, Identifier, InputValue, Parameter, Span}; +use leo_ast::{Circuit, CircuitMember, Identifier, InputValue, Parameter, Span}; use serde::{Deserialize, Serialize}; use std::{ diff --git a/symbol-table/src/types/circuits/circuit_variable.rs b/symbol-table/src/types/circuits/circuit_variable.rs index dfc19e7336..dfbb4d94dc 100644 --- a/symbol-table/src/types/circuits/circuit_variable.rs +++ b/symbol-table/src/types/circuits/circuit_variable.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Attribute, CircuitType, Type}; -use leo_core_ast::Identifier; +use leo_ast::Identifier; use serde::{Deserialize, Serialize}; diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs index 2cddcdef4b..ca96be17e7 100644 --- a/symbol-table/src/types/functions/function.rs +++ b/symbol-table/src/types/functions/function.rs @@ -19,7 +19,7 @@ use crate::{ SymbolTable, TypeError, }; -use leo_core_ast::{Function, Identifier}; +use leo_ast::{Function, Identifier}; use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; diff --git a/symbol-table/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs index 7d04ecd643..42afe2a52a 100644 --- a/symbol-table/src/types/functions/function_input.rs +++ b/symbol-table/src/types/functions/function_input.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{FunctionInputVariableType, SymbolTable, Type, TypeError}; -use leo_core_ast::{FunctionInput, Identifier}; +use leo_ast::{FunctionInput, Identifier}; use serde::{Deserialize, Serialize}; diff --git a/symbol-table/src/types/functions/function_input_variable.rs b/symbol-table/src/types/functions/function_input_variable.rs index 53069b43a1..2cfd8275ec 100644 --- a/symbol-table/src/types/functions/function_input_variable.rs +++ b/symbol-table/src/types/functions/function_input_variable.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Attribute, SymbolTable, Type, TypeError, UserDefinedType}; -use leo_core_ast::{FunctionInputVariable, Identifier, Span}; +use leo_ast::{FunctionInputVariable, Identifier, Span}; use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; diff --git a/symbol-table/src/types/functions/function_output.rs b/symbol-table/src/types/functions/function_output.rs index dcefe2b207..2da52025cf 100644 --- a/symbol-table/src/types/functions/function_output.rs +++ b/symbol-table/src/types/functions/function_output.rs @@ -16,7 +16,7 @@ use crate::{SymbolTable, Type, TypeError}; -use leo_core_ast::{Identifier, Span, Type as UnresolvedType}; +use leo_ast::{Identifier, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; diff --git a/symbol-table/src/types/type_.rs b/symbol-table/src/types/type_.rs index 110a2607bc..ba819be1e7 100644 --- a/symbol-table/src/types/type_.rs +++ b/symbol-table/src/types/type_.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{SymbolTable, TypeError, TypeVariable}; -use leo_core_ast::{Identifier, IntegerType, Span, Type as UnresolvedType}; +use leo_ast::{Identifier, IntegerType, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; use std::{ diff --git a/symbol-table/src/types/type_variable.rs b/symbol-table/src/types/type_variable.rs index f9e5420433..161c5f3953 100644 --- a/symbol-table/src/types/type_variable.rs +++ b/symbol-table/src/types/type_variable.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::Identifier; +use leo_ast::Identifier; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/symbol-table/src/types/user_defined/user_defined_type.rs b/symbol-table/src/types/user_defined/user_defined_type.rs index 3a536f0d08..80e75eedf8 100644 --- a/symbol-table/src/types/user_defined/user_defined_type.rs +++ b/symbol-table/src/types/user_defined/user_defined_type.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{Attribute, FunctionInputVariableType, Type}; -use leo_core_ast::{Circuit, Function, Identifier}; +use leo_ast::{Circuit, Function, Identifier}; use std::{ fmt, diff --git a/symbol-table/tests/mod.rs b/symbol-table/tests/mod.rs index da0796f1f5..5e7646b25e 100644 --- a/symbol-table/tests/mod.rs +++ b/symbol-table/tests/mod.rs @@ -16,7 +16,7 @@ pub mod symbol_table; -use leo_core_ast::{Input, LeoCoreAst}; +use leo_ast::{Input, LeoAst}; use leo_grammar::Grammar; use leo_symbol_table::{SymbolTable, SymbolTableError}; @@ -27,7 +27,7 @@ const TEST_PROGRAM_PATH: &str = ""; /// A helper struct to test a `SymbolTable`. pub struct TestSymbolTable { - typed: LeoCoreAst, + typed: LeoAst, } impl TestSymbolTable { @@ -45,7 +45,7 @@ impl TestSymbolTable { let ast = Grammar::new(&file_path, &*file_string).unwrap(); // Get typed syntax tree - let typed = LeoCoreAst::new(TEST_PROGRAM_PATH, &ast); + let typed = LeoAst::new(TEST_PROGRAM_PATH, &ast); Self { typed } } diff --git a/type-inference/Cargo.toml b/type-inference/Cargo.toml index e448fab596..b8dee93e48 100644 --- a/type-inference/Cargo.toml +++ b/type-inference/Cargo.toml @@ -17,8 +17,8 @@ include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" -[dependencies.leo-core-ast] -path = "../core-ast" +[dependencies.leo-ast] +path = "../ast" version = "1.0.3" [dependencies.leo-imports] diff --git a/type-inference/src/assertions/type_assertion.rs b/type-inference/src/assertions/type_assertion.rs index fd01a4aaba..8baf98f5b0 100644 --- a/type-inference/src/assertions/type_assertion.rs +++ b/type-inference/src/assertions/type_assertion.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{TypeAssertionError, TypeEquality, TypeMembership, TypeVariablePairs}; -use leo_core_ast::Span; +use leo_ast::Span; use leo_symbol_table::{Type, TypeVariable}; use serde::{Deserialize, Serialize}; diff --git a/type-inference/src/assertions/type_equality.rs b/type-inference/src/assertions/type_equality.rs index baeddd9ddd..f20fd696ce 100644 --- a/type-inference/src/assertions/type_equality.rs +++ b/type-inference/src/assertions/type_equality.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{TypeAssertionError, TypeVariablePairs}; -use leo_core_ast::Span; +use leo_ast::Span; use leo_symbol_table::{Type, TypeVariable}; use serde::{Deserialize, Serialize}; diff --git a/type-inference/src/assertions/type_membership.rs b/type-inference/src/assertions/type_membership.rs index c31e22ce01..5df0edb0c7 100644 --- a/type-inference/src/assertions/type_membership.rs +++ b/type-inference/src/assertions/type_membership.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::TypeAssertionError; -use leo_core_ast::Span; +use leo_ast::Span; use leo_symbol_table::{Type, TypeVariable}; use serde::{Deserialize, Serialize}; diff --git a/type-inference/src/assertions/type_variable_pair.rs b/type-inference/src/assertions/type_variable_pair.rs index abde4984fe..b7e7f09552 100644 --- a/type-inference/src/assertions/type_variable_pair.rs +++ b/type-inference/src/assertions/type_variable_pair.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::TypeAssertionError; -use leo_core_ast::Span; +use leo_ast::Span; use leo_symbol_table::{flatten_array_type, Type, TypeVariable}; use std::borrow::Cow; diff --git a/type-inference/src/errors/frame.rs b/type-inference/src/errors/frame.rs index 59c1bdeb96..1d671fc40b 100644 --- a/type-inference/src/errors/frame.rs +++ b/type-inference/src/errors/frame.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ScopeError, TypeAssertionError}; -use leo_core_ast::{Error as FormattedError, Expression, Identifier, Span}; +use leo_ast::{Error as FormattedError, Expression, Identifier, Span}; use leo_symbol_table::{Type, TypeError}; use std::path::Path; diff --git a/type-inference/src/errors/scope.rs b/type-inference/src/errors/scope.rs index 1d834a8073..e31c3aaea4 100644 --- a/type-inference/src/errors/scope.rs +++ b/type-inference/src/errors/scope.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::VariableTableError; -use leo_core_ast::Error as FormattedError; +use leo_ast::Error as FormattedError; use std::path::Path; diff --git a/type-inference/src/errors/type_assertion.rs b/type-inference/src/errors/type_assertion.rs index 0f55bd22d2..a2da4a6c08 100644 --- a/type-inference/src/errors/type_assertion.rs +++ b/type-inference/src/errors/type_assertion.rs @@ -16,7 +16,7 @@ use crate::TypeMembership; -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use leo_symbol_table::Type; use std::path::Path; diff --git a/type-inference/src/errors/type_inference.rs b/type-inference/src/errors/type_inference.rs index 83c7dde93e..dac08fc59b 100644 --- a/type-inference/src/errors/type_inference.rs +++ b/type-inference/src/errors/type_inference.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::FrameError; -use leo_core_ast::Error as FormattedError; +use leo_ast::Error as FormattedError; use std::path::Path; diff --git a/type-inference/src/errors/variable_table.rs b/type-inference/src/errors/variable_table.rs index cc359db3f9..bb26dfb7e6 100644 --- a/type-inference/src/errors/variable_table.rs +++ b/type-inference/src/errors/variable_table.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_core_ast::{Error as FormattedError, Span}; +use leo_ast::{Error as FormattedError, Span}; use std::path::Path; diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index 1148a619ea..9fd37814d6 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{FrameError, Scope, TypeAssertion}; -use leo_core_ast::{ +use leo_ast::{ Assignee, AssigneeAccess, CircuitVariableDefinition, diff --git a/type-inference/src/type_inference.rs b/type-inference/src/type_inference.rs index 1984203e7e..ee485d1d47 100644 --- a/type-inference/src/type_inference.rs +++ b/type-inference/src/type_inference.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Frame, Scope, TypeInferenceError}; -use leo_core_ast::{Circuit, CircuitMember, Function, Program}; +use leo_ast::{Circuit, CircuitMember, Function, Program}; use leo_symbol_table::SymbolTable; /// A type inference check for a Leo program. diff --git a/type-inference/tests/mod.rs b/type-inference/tests/mod.rs index dedcdf7fda..0753812059 100644 --- a/type-inference/tests/mod.rs +++ b/type-inference/tests/mod.rs @@ -23,7 +23,7 @@ pub mod variables; use leo_grammar::Grammar; use leo_type_inference::TypeInference; -use leo_core_ast::{Input, LeoCoreAst, Program}; +use leo_ast::{Input, LeoAst, Program}; use leo_imports::ImportParser; use leo_symbol_table::SymbolTable; use std::path::PathBuf; @@ -49,7 +49,7 @@ impl TestTypeInference { let ast = Grammar::new(&file_path, &*file_string).unwrap(); // Get typed syntax tree. - let typed = LeoCoreAst::new(TEST_PROGRAM_NAME, &ast); + let typed = LeoAst::new(TEST_PROGRAM_NAME, &ast); let program = typed.into_repr(); // Create empty import parser. From 4da923eec4ee5d5812cd5f6f4f9ed8a4d71b2180 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 30 Oct 2020 17:36:48 -0700 Subject: [PATCH 119/139] rename core-packages -> core --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- compiler/Cargo.toml | 4 ++-- compiler/src/errors/expression.rs | 2 +- compiler/src/errors/import.rs | 2 +- compiler/src/expression/function/core_circuit.rs | 2 +- compiler/src/import/store/core_package.rs | 2 +- compiler/src/value/value.rs | 2 +- {core-packages => core}/Cargo.toml | 10 +++++----- {core-packages => core}/src/errors/core_circuit.rs | 0 {core-packages => core}/src/errors/core_package.rs | 0 .../src/errors/core_package_list.rs | 0 .../src/errors/leo_core_package.rs | 0 {core-packages => core}/src/errors/mod.rs | 0 {core-packages => core}/src/lib.rs | 0 {core-packages => core}/src/packages/mod.rs | 0 .../src/packages/unstable/blake2s.rs | 0 {core-packages => core}/src/packages/unstable/mod.rs | 0 {core-packages => core}/src/types/core_circuit.rs | 0 .../src/types/core_circuit_struct_list.rs | 0 {core-packages => core}/src/types/core_package.rs | 0 .../src/types/core_package_list.rs | 0 {core-packages => core}/src/types/mod.rs | 0 {core-packages => core}/src/types/value.rs | 0 symbol-table/Cargo.toml | 12 ++++++------ symbol-table/src/errors/symbol_table.rs | 2 +- symbol-table/src/symbol_table.rs | 2 +- 27 files changed, 24 insertions(+), 24 deletions(-) rename {core-packages => core}/Cargo.toml (97%) rename {core-packages => core}/src/errors/core_circuit.rs (100%) rename {core-packages => core}/src/errors/core_package.rs (100%) rename {core-packages => core}/src/errors/core_package_list.rs (100%) rename {core-packages => core}/src/errors/leo_core_package.rs (100%) rename {core-packages => core}/src/errors/mod.rs (100%) rename {core-packages => core}/src/lib.rs (100%) rename {core-packages => core}/src/packages/mod.rs (100%) rename {core-packages => core}/src/packages/unstable/blake2s.rs (100%) rename {core-packages => core}/src/packages/unstable/mod.rs (100%) rename {core-packages => core}/src/types/core_circuit.rs (100%) rename {core-packages => core}/src/types/core_circuit_struct_list.rs (100%) rename {core-packages => core}/src/types/core_package.rs (100%) rename {core-packages => core}/src/types/core_package_list.rs (100%) rename {core-packages => core}/src/types/mod.rs (100%) rename {core-packages => core}/src/types/value.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 10f69761a4..252f2c788a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1250,7 +1250,7 @@ dependencies = [ "bincode", "hex", "leo-ast", - "leo-core-packages", + "leo-core", "leo-gadgets", "leo-grammar", "leo-imports", @@ -1279,7 +1279,7 @@ dependencies = [ ] [[package]] -name = "leo-core-packages" +name = "leo-core" version = "1.0.3" dependencies = [ "leo-ast", @@ -1434,7 +1434,7 @@ name = "leo-symbol-table" version = "1.0.3" dependencies = [ "leo-ast", - "leo-core-packages", + "leo-core", "leo-grammar", "leo-imports", "serde", diff --git a/Cargo.toml b/Cargo.toml index 52d6881e08..b979e3411a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ path = "leo/main.rs" members = [ "ast", "compiler", - "core-packages", + "core", "gadgets", "grammar", "imports", diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 3414ca840c..3ad46da62e 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -21,8 +21,8 @@ edition = "2018" path = "../ast" version = "1.0.3" -[dependencies.leo-core-packages] -path = "../core-packages" +[dependencies.leo-core] +path = "../core" version = "1.0.3" [dependencies.leo-gadgets] diff --git a/compiler/src/errors/expression.rs b/compiler/src/errors/expression.rs index f2e2e8c97b..bde8d04f4d 100644 --- a/compiler/src/errors/expression.rs +++ b/compiler/src/errors/expression.rs @@ -16,7 +16,7 @@ use crate::errors::{AddressError, BooleanError, FieldError, FunctionError, GroupError, IntegerError, ValueError}; use leo_ast::{Error as FormattedError, Identifier, Span}; -use leo_core_packages::LeoCorePackageError; +use leo_core::LeoCorePackageError; use snarkos_errors::gadgets::SynthesisError; use std::path::Path; diff --git a/compiler/src/errors/import.rs b/compiler/src/errors/import.rs index 241154f83b..a38de223ad 100644 --- a/compiler/src/errors/import.rs +++ b/compiler/src/errors/import.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use leo_ast::{Error as FormattedError, Identifier, ImportSymbol, Span}; -use leo_core_packages::LeoCorePackageError; +use leo_core::LeoCorePackageError; #[derive(Debug, Error)] pub enum ImportError { diff --git a/compiler/src/expression/function/core_circuit.rs b/compiler/src/expression/function/core_circuit.rs index e62ece9234..7e9835f076 100644 --- a/compiler/src/expression/function/core_circuit.rs +++ b/compiler/src/expression/function/core_circuit.rs @@ -17,7 +17,7 @@ use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType}; use crate::errors::{ExpressionError, FunctionError}; use leo_ast::{Expression, Span, Type}; -use leo_core_packages::call_core_circuit; +use leo_core::call_core_circuit; use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::ConstraintSystem, diff --git a/compiler/src/import/store/core_package.rs b/compiler/src/import/store/core_package.rs index 99742bbcbd..4eb6b49924 100644 --- a/compiler/src/import/store/core_package.rs +++ b/compiler/src/import/store/core_package.rs @@ -17,7 +17,7 @@ use crate::{new_scope, ConstrainedProgram, ConstrainedValue, GroupType}; use leo_ast::Package; -use leo_core_packages::{CorePackageList, LeoCorePackageError}; +use leo_core::{CorePackageList, LeoCorePackageError}; use snarkos_models::curves::{Field, PrimeField}; impl> ConstrainedProgram { diff --git a/compiler/src/value/value.rs b/compiler/src/value/value.rs index 1082e9c053..b83cb79b71 100644 --- a/compiler/src/value/value.rs +++ b/compiler/src/value/value.rs @@ -27,7 +27,7 @@ use crate::{ Integer, }; use leo_ast::{Circuit, Function, GroupValue, Identifier, Span, Type}; -use leo_core_packages::Value; +use leo_core::Value; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/core-packages/Cargo.toml b/core/Cargo.toml similarity index 97% rename from core-packages/Cargo.toml rename to core/Cargo.toml index abc77f3d5d..52b2364671 100644 --- a/core-packages/Cargo.toml +++ b/core/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "leo-core-packages" +name = "leo-core" version = "1.0.3" authors = [ "The Aleo Team " ] description = "Core package dependencies of the Leo programming language" @@ -17,14 +17,14 @@ include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" -[dependencies.leo-gadgets] -path = "../gadgets" -version = "1.0.3" - [dependencies.leo-ast] path = "../ast" version = "1.0.3" +[dependencies.leo-gadgets] +path = "../gadgets" +version = "1.0.3" + [dependencies.snarkos-errors] version = "1.1.3" default-features = false diff --git a/core-packages/src/errors/core_circuit.rs b/core/src/errors/core_circuit.rs similarity index 100% rename from core-packages/src/errors/core_circuit.rs rename to core/src/errors/core_circuit.rs diff --git a/core-packages/src/errors/core_package.rs b/core/src/errors/core_package.rs similarity index 100% rename from core-packages/src/errors/core_package.rs rename to core/src/errors/core_package.rs diff --git a/core-packages/src/errors/core_package_list.rs b/core/src/errors/core_package_list.rs similarity index 100% rename from core-packages/src/errors/core_package_list.rs rename to core/src/errors/core_package_list.rs diff --git a/core-packages/src/errors/leo_core_package.rs b/core/src/errors/leo_core_package.rs similarity index 100% rename from core-packages/src/errors/leo_core_package.rs rename to core/src/errors/leo_core_package.rs diff --git a/core-packages/src/errors/mod.rs b/core/src/errors/mod.rs similarity index 100% rename from core-packages/src/errors/mod.rs rename to core/src/errors/mod.rs diff --git a/core-packages/src/lib.rs b/core/src/lib.rs similarity index 100% rename from core-packages/src/lib.rs rename to core/src/lib.rs diff --git a/core-packages/src/packages/mod.rs b/core/src/packages/mod.rs similarity index 100% rename from core-packages/src/packages/mod.rs rename to core/src/packages/mod.rs diff --git a/core-packages/src/packages/unstable/blake2s.rs b/core/src/packages/unstable/blake2s.rs similarity index 100% rename from core-packages/src/packages/unstable/blake2s.rs rename to core/src/packages/unstable/blake2s.rs diff --git a/core-packages/src/packages/unstable/mod.rs b/core/src/packages/unstable/mod.rs similarity index 100% rename from core-packages/src/packages/unstable/mod.rs rename to core/src/packages/unstable/mod.rs diff --git a/core-packages/src/types/core_circuit.rs b/core/src/types/core_circuit.rs similarity index 100% rename from core-packages/src/types/core_circuit.rs rename to core/src/types/core_circuit.rs diff --git a/core-packages/src/types/core_circuit_struct_list.rs b/core/src/types/core_circuit_struct_list.rs similarity index 100% rename from core-packages/src/types/core_circuit_struct_list.rs rename to core/src/types/core_circuit_struct_list.rs diff --git a/core-packages/src/types/core_package.rs b/core/src/types/core_package.rs similarity index 100% rename from core-packages/src/types/core_package.rs rename to core/src/types/core_package.rs diff --git a/core-packages/src/types/core_package_list.rs b/core/src/types/core_package_list.rs similarity index 100% rename from core-packages/src/types/core_package_list.rs rename to core/src/types/core_package_list.rs diff --git a/core-packages/src/types/mod.rs b/core/src/types/mod.rs similarity index 100% rename from core-packages/src/types/mod.rs rename to core/src/types/mod.rs diff --git a/core-packages/src/types/value.rs b/core/src/types/value.rs similarity index 100% rename from core-packages/src/types/value.rs rename to core/src/types/value.rs diff --git a/symbol-table/Cargo.toml b/symbol-table/Cargo.toml index 41a7c9437a..f8ada52ec1 100644 --- a/symbol-table/Cargo.toml +++ b/symbol-table/Cargo.toml @@ -17,16 +17,16 @@ include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" -[dependencies.leo-grammar] -path = "../grammar" -version = "1.0.3" - [dependencies.leo-ast] path = "../ast" version = "1.0.3" -[dependencies.leo-core-packages] -path = "../core-packages" +[dependencies.leo-core] +path = "../core" +version = "1.0.3" + +[dependencies.leo-grammar] +path = "../grammar" version = "1.0.3" [dependencies.leo-imports] diff --git a/symbol-table/src/errors/symbol_table.rs b/symbol-table/src/errors/symbol_table.rs index f281605ea6..7ec93ee2b1 100644 --- a/symbol-table/src/errors/symbol_table.rs +++ b/symbol-table/src/errors/symbol_table.rs @@ -16,7 +16,7 @@ use crate::{TypeError, UserDefinedType}; use leo_ast::{Error as FormattedError, ImportSymbol, Program, Span}; -use leo_core_packages::{CorePackageListError, LeoCorePackageError}; +use leo_core::{CorePackageListError, LeoCorePackageError}; use std::path::Path; diff --git a/symbol-table/src/symbol_table.rs b/symbol-table/src/symbol_table.rs index edabc6f772..2214e66b36 100644 --- a/symbol-table/src/symbol_table.rs +++ b/symbol-table/src/symbol_table.rs @@ -16,7 +16,7 @@ use crate::{CircuitType, CircuitVariableType, FunctionType, ImportedSymbols, SymbolTableError, UserDefinedType}; use leo_ast::{Circuit, Function, Identifier, ImportStatement, ImportSymbol, Input, Package, Program}; -use leo_core_packages::CorePackageList; +use leo_core::CorePackageList; use leo_imports::ImportParser; use std::collections::{HashMap, HashSet}; From 2fdcb043fcb63242ceaa2d9d0ffb73fe0fabd1aa Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 2 Nov 2020 09:19:11 -0800 Subject: [PATCH 120/139] Improve doc comments for compiler phases --- ast/src/lib.rs | 2 +- compiler/src/lib.rs | 4 +++- grammar/src/lib.rs | 3 ++- symbol-table/src/lib.rs | 3 +++ type-inference/src/lib.rs | 2 ++ 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ast/src/lib.rs b/ast/src/lib.rs index 4325698987..7d08ba7a15 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -66,7 +66,7 @@ use leo_grammar::Grammar; /// The [`LeoAst`] type represents a Leo program as a series of recursive data types. /// These data types form a tree that begins from a [`Program`] type root. /// -/// A new [`LeoAst`] can be created from a [`Grammar`] generated by the pest parser in the `ast` module. +/// A new [`LeoAst`] can be created from a [`Grammar`] generated by the pest parser in the `grammar` module. #[derive(Debug, Eq, PartialEq)] pub struct LeoAst { ast: Program, diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 9e93ead53e..03abbf4457 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -14,7 +14,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -//! Module containing structs and types that make up a Leo program. +//! The compiler for Leo programs. +//! +//! The [`Compiler`] type compiles Leo programs into R1CS circuits. #![allow(clippy::module_inception)] diff --git a/grammar/src/lib.rs b/grammar/src/lib.rs index 201e053dc6..77224db03e 100644 --- a/grammar/src/lib.rs +++ b/grammar/src/lib.rs @@ -59,7 +59,8 @@ use std::{fs, path::Path}; /// The [`Grammar`] type represents a Leo program as a series of recursive data types. /// These data types form a tree that begins from a [`File`] type root. /// -/// A new [`Grammar`] can be created from a `*.leo` file at a [`Path`]. +/// A new [`Grammar`] type can be created from a `*.leo` file at a [`Path`]. +/// A [`Grammar`] type can be used to create a new [`LeoAst`] type. pub struct Grammar<'ast> { ast: files::File<'ast>, } diff --git a/symbol-table/src/lib.rs b/symbol-table/src/lib.rs index c2d801653c..2156653e13 100644 --- a/symbol-table/src/lib.rs +++ b/symbol-table/src/lib.rs @@ -18,6 +18,9 @@ //! //! This module contains the [`SymbolTable`] type, an abstract data type that tracks the current //! bindings for functions and circuits in a Leo program. +//! +//! A new [`Symbol Table`] type can be created from a reference to a [`LeoAst`]. +//! A [`Symbol Table`] type can be used to create a new [`TypeInference`] type. #[macro_use] extern crate thiserror; diff --git a/type-inference/src/lib.rs b/type-inference/src/lib.rs index 488cd38d30..ab20d42409 100644 --- a/type-inference/src/lib.rs +++ b/type-inference/src/lib.rs @@ -18,6 +18,8 @@ //! //! This module contains the [`TypeInference`] type, which stores information needed to run a type //! inference check over a program. +//! +//! A new [`TypeInference`] type can be created from a [`LeoAst`] type and a [`Symbol Table`]. #[macro_use] extern crate thiserror; From cfb3cb734484990aa69870db20b10b07a9429636 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 2 Nov 2020 12:11:53 -0800 Subject: [PATCH 121/139] Refactor array type parsing --- ast/src/common/array_dimensions.rs | 74 +++++++++++++++++++ ast/src/common/assignee.rs | 24 +++--- ast/src/common/mod.rs | 6 ++ ast/src/common/positive_number.rs | 55 ++++++++++++++ ast/src/expression.rs | 105 +++++++++----------------- ast/src/input/input_value.rs | 75 ++++++++++++++++--- ast/src/types/type_.rs | 115 +++++++++++++++-------------- 7 files changed, 303 insertions(+), 151 deletions(-) create mode 100644 ast/src/common/array_dimensions.rs create mode 100644 ast/src/common/positive_number.rs diff --git a/ast/src/common/array_dimensions.rs b/ast/src/common/array_dimensions.rs new file mode 100644 index 0000000000..ced54792c1 --- /dev/null +++ b/ast/src/common/array_dimensions.rs @@ -0,0 +1,74 @@ +// 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 . + +use crate::PositiveNumber; +use leo_grammar::types::ArrayDimensions as GrammarArrayDimensions; +use leo_input::types::ArrayDimensions as InputArrayDimensions; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// A vector of positive numbers that represent array dimensions. +/// Can be used in an array [`Type`] or an array initializer [`Expression`]. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct ArrayDimensions(pub Vec); + +impl ArrayDimensions { + /// + /// Returns the array dimensions as strings. + /// + pub fn to_strings(&self) -> Vec { + self.0.iter().map(|number| number.to_string()).collect() + } +} + +/// Create a new [`ArrayDimensions`] from a [`GrammarArrayDimensions`] in a Leo program file. +impl<'ast> From> for ArrayDimensions { + fn from(dimensions: GrammarArrayDimensions<'ast>) -> Self { + Self(match dimensions { + GrammarArrayDimensions::Single(single) => vec![PositiveNumber::from(single.number)], + GrammarArrayDimensions::Multiple(multiple) => { + multiple.numbers.into_iter().map(PositiveNumber::from).collect() + } + }) + } +} + +/// Create a new [`ArrayDimensions`] from a [`InputArrayDimensions`] in a Leo program file. +impl<'ast> From> for ArrayDimensions { + fn from(dimensions: InputArrayDimensions<'ast>) -> Self { + Self(match dimensions { + InputArrayDimensions::Single(single) => vec![PositiveNumber::from(single.number)], + InputArrayDimensions::Multiple(multiple) => { + multiple.numbers.into_iter().map(PositiveNumber::from).collect() + } + }) + } +} + +impl fmt::Display for ArrayDimensions { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.0.len() == 1 { + // Write dimensions without parenthesis. + write!(f, "{}", self.0[0]) + } else { + // Write dimensions with parenthesis. + let dimensions = self.0.iter().map(|x| x.to_string()).collect::>().join(", "); + + write!(f, "({})", dimensions) + } + } +} diff --git a/ast/src/common/assignee.rs b/ast/src/common/assignee.rs index 3d55d74985..399af914c8 100644 --- a/ast/src/common/assignee.rs +++ b/ast/src/common/assignee.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, Identifier, RangeOrExpression, Span}; -use leo_grammar::{access::AssigneeAccess as AstAssigneeAccess, common::Assignee as AstAssignee}; +use crate::{Identifier, PositiveNumber, RangeOrExpression, Span}; +use leo_grammar::{access::AssigneeAccess as GrammarAssigneeAccess, common::Assignee as GrammarAssignee}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -23,16 +23,18 @@ use std::fmt; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum AssigneeAccess { Array(RangeOrExpression), - Tuple(usize), + Tuple(PositiveNumber, Span), Member(Identifier), } -impl<'ast> From> for AssigneeAccess { - fn from(access: AstAssigneeAccess<'ast>) -> Self { +impl<'ast> From> for AssigneeAccess { + fn from(access: GrammarAssigneeAccess<'ast>) -> Self { match access { - AstAssigneeAccess::Array(array) => AssigneeAccess::Array(RangeOrExpression::from(array.expression)), - AstAssigneeAccess::Tuple(tuple) => AssigneeAccess::Tuple(Expression::get_count_from_ast(tuple.number)), - AstAssigneeAccess::Member(member) => AssigneeAccess::Member(Identifier::from(member.identifier)), + GrammarAssigneeAccess::Array(array) => AssigneeAccess::Array(RangeOrExpression::from(array.expression)), + GrammarAssigneeAccess::Tuple(tuple) => { + AssigneeAccess::Tuple(PositiveNumber::from(tuple.number), Span::from(tuple.span)) + } + GrammarAssigneeAccess::Member(member) => AssigneeAccess::Member(Identifier::from(member.identifier)), } } } @@ -52,8 +54,8 @@ impl Assignee { } } -impl<'ast> From> for Assignee { - fn from(assignee: AstAssignee<'ast>) -> Self { +impl<'ast> From> for Assignee { + fn from(assignee: GrammarAssignee<'ast>) -> Self { Assignee { identifier: Identifier::from(assignee.name), accesses: assignee @@ -73,7 +75,7 @@ impl fmt::Display for Assignee { for access in &self.accesses { match access { AssigneeAccess::Array(expression) => write!(f, "[{}]", expression)?, - AssigneeAccess::Tuple(index) => write!(f, ".{}", index)?, + AssigneeAccess::Tuple(index, _span) => write!(f, ".{}", index)?, AssigneeAccess::Member(member) => write!(f, ".{}", member)?, } } diff --git a/ast/src/common/mod.rs b/ast/src/common/mod.rs index 9187f2e653..382d82142c 100644 --- a/ast/src/common/mod.rs +++ b/ast/src/common/mod.rs @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +pub mod array_dimensions; +pub use array_dimensions::*; + pub mod assignee; pub use assignee::*; @@ -23,6 +26,9 @@ pub use declare::*; pub mod identifier; pub use identifier::*; +pub mod positive_number; +pub use positive_number::*; + pub mod range_or_expression; pub use range_or_expression::*; diff --git a/ast/src/common/positive_number.rs b/ast/src/common/positive_number.rs new file mode 100644 index 0000000000..714e99ba6f --- /dev/null +++ b/ast/src/common/positive_number.rs @@ -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 . + +use crate::Span; +use leo_grammar::values::PositiveNumber as GrammarPositiveNumber; +use leo_input::values::PositiveNumber as InputPositiveNumber; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// A number string guaranteed to be positive by the pest grammar. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct PositiveNumber { + pub value: String, + pub span: Span, +} + +/// Create a new [`PositiveNumber`] from a [`GrammarPositiveNumber`] in a Leo program file. +impl<'ast> From> for PositiveNumber { + fn from(array: GrammarPositiveNumber<'ast>) -> Self { + Self { + value: array.value, + span: Span::from(array.span), + } + } +} + +/// Create a new [`PositiveNumber`] from an [`InputPositiveNumber`] in a Leo input file. +impl<'ast> From> for PositiveNumber { + fn from(array: InputPositiveNumber<'ast>) -> Self { + Self { + value: array.value, + span: Span::from(array.span), + } + } +} + +impl fmt::Display for PositiveNumber { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.value) + } +} diff --git a/ast/src/expression.rs b/ast/src/expression.rs index 7ab2018004..63be1ec6b2 100644 --- a/ast/src/expression.rs +++ b/ast/src/expression.rs @@ -15,10 +15,12 @@ // along with the Leo library. If not, see . use crate::{ + ArrayDimensions, CircuitVariableDefinition, GroupValue, Identifier, IntegerType, + PositiveNumber, RangeOrExpression, Span, SpreadOrExpression, @@ -44,13 +46,11 @@ use leo_grammar::{ GroupValue as AstGroupValue, IntegerValue, NumberValue as AstNumber, - PositiveNumber as AstPositiveNumber, Value, }, }; -use leo_input::{types::ArrayDimensions as InputArrayDimensions, values::PositiveNumber as InputAstPositiveNumber}; -use leo_grammar::{expressions::TupleExpression, types::ArrayDimensions}; +use leo_grammar::{access::TupleAccess, expressions::TupleExpression}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -92,15 +92,17 @@ pub enum Expression { // Arrays // (array_elements, span) - Array(Vec, Span), - // (array_name, range, span) + ArrayInline(Vec, Span), + // ((array element, dimensions), span) + ArrayInitializer(Box<(Expression, ArrayDimensions)>, Span), + // ((array_name, range), span) ArrayAccess(Box<(Expression, RangeOrExpression)>, Span), // Tuples // (tuple_elements, span) Tuple(Vec, Span), - // (tuple_name, index, span) - TupleAccess(Box, usize, Span), + // ((tuple_name, index), span) + TupleAccess(Box<(Expression, PositiveNumber)>, Span), // Circuits // (defined_circuit_name, circuit_members, span) @@ -139,11 +141,12 @@ impl Expression { Expression::Lt(_, old_span) => *old_span = new_span, Expression::IfElse(_, old_span) => *old_span = new_span, - Expression::Array(_, old_span) => *old_span = new_span, + Expression::ArrayInline(_, old_span) => *old_span = new_span, + Expression::ArrayInitializer(_, old_span) => *old_span = new_span, Expression::ArrayAccess(_, old_span) => *old_span = new_span, Expression::Tuple(_, old_span) => *old_span = new_span, - Expression::TupleAccess(_, _, old_span) => *old_span = new_span, + Expression::TupleAccess(_, old_span) => *old_span = new_span, Expression::Circuit(_, _, old_span) => *old_span = new_span, Expression::CircuitMemberAccess(_, _, old_span) => *old_span = new_span, @@ -156,40 +159,6 @@ impl Expression { } } -impl<'ast> Expression { - pub(crate) fn get_count_from_input_ast(number: InputAstPositiveNumber<'ast>) -> usize { - number - .value - .parse::() - .expect("Array size should be a positive number") - } - - pub(crate) fn get_input_array_dimensions(dimensions: InputArrayDimensions<'ast>) -> Vec { - match dimensions { - InputArrayDimensions::Single(single) => vec![Self::get_count_from_input_ast(single.number)], - InputArrayDimensions::Multiple(multiple) => multiple - .numbers - .into_iter() - .map(Self::get_count_from_input_ast) - .collect(), - } - } - - pub(crate) fn get_count_from_ast(number: AstPositiveNumber<'ast>) -> usize { - number - .value - .parse::() - .expect("Array size should be a positive number") - } - - pub(crate) fn get_array_dimensions(dimensions: ArrayDimensions<'ast>) -> Vec { - match dimensions { - ArrayDimensions::Single(single) => vec![Self::get_count_from_ast(single.number)], - ArrayDimensions::Multiple(multiple) => multiple.numbers.into_iter().map(Self::get_count_from_ast).collect(), - } - } -} - impl<'ast> fmt::Display for Expression { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -228,7 +197,7 @@ impl<'ast> fmt::Display for Expression { } // Arrays - Expression::Array(ref array, ref _span) => { + Expression::ArrayInline(ref array, ref _span) => { write!(f, "[")?; for (i, e) in array.iter().enumerate() { write!(f, "{}", e)?; @@ -238,6 +207,7 @@ impl<'ast> fmt::Display for Expression { } write!(f, "]") } + Expression::ArrayInitializer(ref array, ref _span) => write!(f, "[{}; {}]", array.0, array.1), Expression::ArrayAccess(ref array_w_index, ref _span) => { write!(f, "{}[{}]", array_w_index.0, array_w_index.1) } @@ -248,7 +218,9 @@ impl<'ast> fmt::Display for Expression { write!(f, "({})", values) } - Expression::TupleAccess(ref tuple, ref index, ref _span) => write!(f, "{}.{}", tuple, index), + Expression::TupleAccess(ref tuple_w_index, ref _span) => { + write!(f, "{}.{}", tuple_w_index.0, tuple_w_index.1) + } // Circuits Expression::Circuit(ref var, ref members, ref _span) => { @@ -326,8 +298,7 @@ impl<'ast> From> for Expression { // Handle tuple access Access::Tuple(tuple) => Expression::TupleAccess( - Box::new(acc), - Expression::get_count_from_ast(tuple.number), + Box::new((acc, PositiveNumber::from(tuple.number))), Span::from(tuple.span), ), @@ -393,9 +364,8 @@ impl<'ast> From> for Expression { Span::from(array.span), ), AssigneeAccess::Tuple(tuple) => Expression::TupleAccess( - Box::new(acc), - Expression::get_count_from_ast(tuple.number), - Span::from(tuple.span), + Box::new((acc, PositiveNumber::from(tuple.number))), + Span::from(tuple.span.clone()), ), }) } @@ -482,7 +452,7 @@ impl<'ast> From> for Expression { impl<'ast> From> for Expression { fn from(array: ArrayInlineExpression<'ast>) -> Self { - Expression::Array( + Expression::ArrayInline( array.expressions.into_iter().map(SpreadOrExpression::from).collect(), Span::from(array.span), ) @@ -491,26 +461,13 @@ impl<'ast> From> for Expression { impl<'ast> From> for Expression { fn from(array: ArrayInitializerExpression<'ast>) -> Self { - let dimensions = Expression::get_array_dimensions(array.dimensions); - let expression = SpreadOrExpression::from(array.expression); - - let mut elements = vec![]; - - // Initializes an arrays elements using the rust `vec!` macro. - // If there are multiple array dimensions, then `elements` is used as the first expression in a `vec!` macro. - // This creates a multi-dimensional array by chaining `vec!` macros. - for (i, dimension) in dimensions.into_iter().rev().enumerate() { - if i == 0 { - elements = vec![expression.clone(); dimension]; - } else { - let element = - SpreadOrExpression::Expression(Expression::Array(elements, Span::from(array.span.clone()))); - - elements = vec![element; dimension]; - } - } - - Expression::Array(elements, Span::from(array.span)) + Expression::ArrayInitializer( + Box::new(( + Expression::from(array.expression), + ArrayDimensions::from(array.dimensions), + )), + Span::from(array.span), + ) } } @@ -611,6 +568,12 @@ impl<'ast> From> for Expression { } } +impl<'ast> From> for Expression { + fn from(tuple: TupleAccess<'ast>) -> Self { + Expression::Implicit(tuple.number.to_string(), Span::from(tuple.span)) + } +} + impl<'ast> From> for Expression { fn from(identifier: AstIdentifier<'ast>) -> Self { Expression::Identifier(Identifier::from(identifier)) diff --git a/ast/src/input/input_value.rs b/ast/src/input/input_value.rs index befc9c50d6..1f6124e518 100644 --- a/ast/src/input/input_value.rs +++ b/ast/src/input/input_value.rs @@ -14,13 +14,14 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression as TypedExpression, GroupValue}; +use crate::{ArrayDimensions, GroupValue}; use leo_input::{ errors::InputParserError, expressions::{ArrayInitializerExpression, ArrayInlineExpression, Expression, TupleExpression}, types::{ArrayType, DataType, IntegerType, TupleType, Type}, values::{Address, AddressValue, BooleanValue, FieldValue, GroupValue as InputGroupValue, NumberValue, Value}, }; +use pest::Span; use std::fmt; @@ -102,11 +103,18 @@ impl InputValue { } } + /// + /// Returns a new `InputValue` from the given `ArrayType` and `ArrayInlineExpression`. + /// pub(crate) fn from_array_inline( mut array_type: ArrayType, inline: ArrayInlineExpression, ) -> Result { - let array_dimensions = TypedExpression::get_input_array_dimensions(array_type.dimensions.clone()); + // Create a new `ArrayDimensions` type from the input array_type dimensions. + let array_dimensions_type = ArrayDimensions::from(array_type.dimensions.clone()); + + // Convert the array dimensions to usize. + let array_dimensions = parse_array_dimensions(array_dimensions_type, array_type.span.clone())?; // Return an error if the outer array dimension does not equal the number of array elements. if array_dimensions[0] != inline.expressions.len() { @@ -137,14 +145,15 @@ impl InputValue { array_type: ArrayType, initializer: ArrayInitializerExpression, ) -> Result { - let initializer_dimensions = TypedExpression::get_input_array_dimensions(initializer.dimensions.clone()); + let array_dimensions_type = ArrayDimensions::from(initializer.dimensions.clone()); + let array_dimensions = parse_array_dimensions(array_dimensions_type, array_type.span.clone())?; - if initializer_dimensions.len() > 1 { + if array_dimensions.len() > 1 { // The expression is an array initializer with tuple syntax - Self::from_array_initializer_tuple(array_type, initializer, initializer_dimensions) + Self::from_array_initializer_tuple(array_type, initializer, array_dimensions) } else { // The expression is an array initializer with nested syntax - Self::from_array_initializer_nested(array_type, initializer, initializer_dimensions) + Self::from_array_initializer_nested(array_type, initializer, array_dimensions) } } @@ -153,7 +162,7 @@ impl InputValue { initializer: ArrayInitializerExpression, initializer_dimensions: Vec, ) -> Result { - let (array_dimensions, array_element_type) = fetch_nested_array_type_dimensions(array_type.clone(), vec![]); + let (array_dimensions, array_element_type) = fetch_nested_array_type_dimensions(array_type.clone(), vec![])?; // Return an error if the dimensions of the array are incorrect. if array_dimensions.ne(&initializer_dimensions) { @@ -186,7 +195,11 @@ impl InputValue { initializer: ArrayInitializerExpression, initializer_dimensions: Vec, ) -> Result { - let array_dimensions = TypedExpression::get_input_array_dimensions(array_type.dimensions.clone()); + // Create a new `ArrayDimensions` type from the input array_type dimensions. + let array_dimensions_type = ArrayDimensions::from(array_type.dimensions.clone()); + + // Convert the array dimensions to usize. + let array_dimensions = parse_array_dimensions(array_dimensions_type, array_type.span.clone())?; let current_array_dimension = array_dimensions[0]; let current_initializer_dimension = initializer_dimensions[0]; @@ -240,14 +253,52 @@ impl InputValue { } } -// Recursively fetch all dimensions from the array type -fn fetch_nested_array_type_dimensions(array_type: ArrayType, mut array_dimensions: Vec) -> (Vec, Type) { - let mut current_dimension = TypedExpression::get_input_array_dimensions(array_type.dimensions); +/// +/// Returns a new vector of usize values from an [`ArrayDimensions`] type. +/// +/// Attempts to parse each dimension in the array from a `String` to a `usize` value. If parsing +/// is successful, the `usize` value is appended to the return vector. If parsing fails, an error +/// is returned. +/// +fn parse_array_dimensions(array_dimensions_type: ArrayDimensions, span: Span) -> Result, InputParserError> { + // Convert the array dimensions to usize. + let mut array_dimensions = Vec::with_capacity(array_dimensions_type.0.len()); + + for dimension in array_dimensions_type.0 { + // Convert the dimension to a string. + let dimension_string = dimension.to_string(); + + // Convert the string to usize. + let dimension_usize = match dimension_string.parse::() { + Ok(dimension_usize) => dimension_usize, + Err(_) => return Err(InputParserError::array_index(dimension_string, span.clone())), + }; + + // Collect dimension usize values. + array_dimensions.push(dimension_usize); + } + + Ok(array_dimensions) +} + +/// +/// Recursively fetch all dimensions from the array type. +/// +fn fetch_nested_array_type_dimensions( + array_type: ArrayType, + mut array_dimensions: Vec, +) -> Result<(Vec, Type), InputParserError> { + // Create a new `ArrayDimensions` type from the input array_type dimensions. + let array_dimensions_type = ArrayDimensions::from(array_type.dimensions.clone()); + + // Convert the array dimensions to usize. + let mut current_dimension = parse_array_dimensions(array_dimensions_type, array_type.span.clone())?; + array_dimensions.append(&mut current_dimension); match *array_type.type_ { Type::Array(next_array_type) => fetch_nested_array_type_dimensions(next_array_type, array_dimensions), - type_ => (array_dimensions, type_), + type_ => Ok((array_dimensions, type_)), } } diff --git a/ast/src/types/type_.rs b/ast/src/types/type_.rs index aced7b5045..8c13c23e04 100644 --- a/ast/src/types/type_.rs +++ b/ast/src/types/type_.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, Identifier, IntegerType}; +use crate::{ArrayDimensions, Identifier, IntegerType}; use leo_grammar::types::{ArrayType, CircuitType, DataType, TupleType, Type as AstType}; use leo_input::types::{ ArrayType as InputArrayType, @@ -37,7 +37,7 @@ pub enum Type { IntegerType(IntegerType), // Data type wrappers - Array(Box, Vec), + Array(Box, ArrayDimensions), Tuple(Vec), Circuit(Identifier), SelfType, @@ -52,62 +52,66 @@ impl Type { matches!(self, Type::Circuit(_)) } - pub fn match_array_types(&self, other: &Type) -> bool { - // Check that both `self` and `other` are of type array - let (type_1, dimensions_1) = match self { - Type::Array(type_, dimensions) => (type_, dimensions), - _ => return false, - }; - - let (type_2, dimensions_2) = match other { - Type::Array(type_, dimensions) => (type_, dimensions), - _ => return false, - }; - - // Expand multidimensional array syntax - let (type_1_expanded, dimensions_1_expanded) = expand_array_type(type_1, dimensions_1); - let (type_2_expanded, dimensions_2_expanded) = expand_array_type(type_2, dimensions_2); - - // Return true if expanded array types and dimensions match - type_1_expanded.eq(&type_2_expanded) && dimensions_1_expanded.eq(&dimensions_2_expanded) + pub fn match_array_types(&self, _other: &Type) -> bool { + unimplemented!("deprecated") + // // Check that both `self` and `other` are of type array + // let (type_1, dimensions_1) = match self { + // Type::Array(type_, dimensions) => (type_, dimensions), + // _ => return false, + // }; + // + // let (type_2, dimensions_2) = match other { + // Type::Array(type_, dimensions) => (type_, dimensions), + // _ => return false, + // }; + // + // // Expand multidimensional array syntax + // let (type_1_expanded, dimensions_1_expanded) = expand_array_type(type_1, dimensions_1); + // let (type_2_expanded, dimensions_2_expanded) = expand_array_type(type_2, dimensions_2); + // + // // Return true if expanded array types and dimensions match + // type_1_expanded.eq(&type_2_expanded) && dimensions_1_expanded.eq(&dimensions_2_expanded) } - pub fn outer_dimension(&self, dimensions: &[usize]) -> Self { - let type_ = self.clone(); - - if dimensions.len() > 1 { - let next = dimensions[1..].to_vec(); - - return Type::Array(Box::new(type_), next); - } - - type_ + pub fn outer_dimension(&self, _dimensions: &[usize]) -> Self { + unimplemented!("deprecated") + // let type_ = self.clone(); + // + // if dimensions.len() > 1 { + // let next = dimensions[1..].to_vec(); + // + // return Type::Array(Box::new(type_), next); + // } + // + // type_ } - pub fn inner_dimension(&self, dimensions: &[usize]) -> Self { - let type_ = self.clone(); - - if dimensions.len() > 1 { - let next = dimensions[..dimensions.len() - 1].to_vec(); - - return Type::Array(Box::new(type_), next); - } - - type_ + pub fn inner_dimension(&self, _dimensions: &[usize]) -> Self { + unimplemented!("deprecated") + // let type_ = self.clone(); + // + // if dimensions.len() > 1 { + // let next = dimensions[..dimensions.len() - 1].to_vec(); + // + // return Type::Array(Box::new(type_), next); + // } + // + // type_ } } -fn expand_array_type(type_: &Type, dimensions: &[usize]) -> (Type, Vec) { - if let Type::Array(nested_type, nested_dimensions) = type_ { - // Expand nested array type - let mut expanded_dimensions = dimensions.to_vec(); - expanded_dimensions.append(&mut nested_dimensions.clone()); - - expand_array_type(nested_type, &expanded_dimensions) - } else { - // Array type is fully expanded - (type_.clone(), dimensions.to_vec()) - } +fn expand_array_type(_type: &Type, _dimensions: &[usize]) -> (Type, Vec) { + unimplemented!("deprecated") + // if let Type::Array(nested_type, nested_dimensions) = type_ { + // // Expand nested array type + // let mut expanded_dimensions = dimensions.to_vec(); + // expanded_dimensions.append(&mut nested_dimensions.clone()); + // + // expand_array_type(nested_type, &expanded_dimensions) + // } else { + // // Array type is fully expanded + // (type_.clone(), dimensions.to_vec()) + // } } /// pest ast -> Explicit Type for defining circuit members and function params @@ -127,7 +131,7 @@ impl From for Type { impl<'ast> From> for Type { fn from(array_type: ArrayType<'ast>) -> Self { let element_type = Box::new(Type::from(*array_type.type_)); - let dimensions = Expression::get_array_dimensions(array_type.dimensions); + let dimensions = ArrayDimensions::from(array_type.dimensions); Type::Array(element_type, dimensions) } @@ -176,7 +180,7 @@ impl From for Type { impl<'ast> From> for Type { fn from(array_type: InputArrayType<'ast>) -> Self { let element_type = Box::new(Type::from(*array_type.type_)); - let dimensions = Expression::get_input_array_dimensions(array_type.dimensions); + let dimensions = ArrayDimensions::from(array_type.dimensions); Type::Array(element_type, dimensions) } @@ -210,10 +214,7 @@ impl fmt::Display for Type { Type::IntegerType(ref integer_type) => write!(f, "{}", integer_type), Type::Circuit(ref variable) => write!(f, "circuit {}", variable), Type::SelfType => write!(f, "SelfType"), - Type::Array(ref array, ref dimensions) => { - let dimensions = dimensions.iter().map(|x| x.to_string()).collect::>().join(", "); - write!(f, "[{}; ({})]", *array, dimensions) - } + Type::Array(ref array, ref dimensions) => write!(f, "[{}; {}]", *array, dimensions), Type::Tuple(ref tuple) => { let types = tuple.iter().map(|x| x.to_string()).collect::>().join(", "); From 0868ef52d3003f69a8355646dd3e70584d9b6528 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 2 Nov 2020 12:55:55 -0800 Subject: [PATCH 122/139] Refactor blake2s array type initialization --- core/src/packages/unstable/blake2s.rs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/core/src/packages/unstable/blake2s.rs b/core/src/packages/unstable/blake2s.rs index a9371cd070..c4c37c4c91 100644 --- a/core/src/packages/unstable/blake2s.rs +++ b/core/src/packages/unstable/blake2s.rs @@ -17,6 +17,7 @@ use crate::{CoreCircuit, CoreCircuitError, Value}; use leo_ast::{ + ArrayDimensions, Circuit, CircuitMember, Expression, @@ -25,6 +26,7 @@ use leo_ast::{ FunctionInputVariable, Identifier, IntegerType, + PositiveNumber, Span, Statement, Type, @@ -73,7 +75,13 @@ impl CoreCircuit for Blake2sCircuit { span: span.clone(), }, mutable: false, - type_: Type::Array(Box::new(Type::IntegerType(IntegerType::U8)), vec![32usize]), + type_: Type::Array( + Box::new(Type::IntegerType(IntegerType::U8)), + ArrayDimensions(vec![PositiveNumber { + value: 32usize.to_string(), + span: span.clone(), + }]), + ), span: span.clone(), }), FunctionInput::Variable(FunctionInputVariable { @@ -82,11 +90,23 @@ impl CoreCircuit for Blake2sCircuit { span: span.clone(), }, mutable: false, - type_: Type::Array(Box::new(Type::IntegerType(IntegerType::U8)), vec![32usize]), + type_: Type::Array( + Box::new(Type::IntegerType(IntegerType::U8)), + ArrayDimensions(vec![PositiveNumber { + value: 32usize.to_string(), + span: span.clone(), + }]), + ), span: span.clone(), }), ], - output: Some(Type::Array(Box::new(Type::IntegerType(IntegerType::U8)), vec![32usize])), + output: Some(Type::Array( + Box::new(Type::IntegerType(IntegerType::U8)), + ArrayDimensions(vec![PositiveNumber { + value: 32usize.to_string(), + span: span.clone(), + }]), + )), statements: vec![Statement::Return( Expression::CoreFunctionCall( Self::name(), From 6f3a235c765aefd5c367bac62d2aac37f9b4e482 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 2 Nov 2020 13:28:03 -0800 Subject: [PATCH 123/139] Refactor symbol table array type comparison --- ast/src/types/type_.rs | 14 ------ compiler/src/expression/expression.rs | 2 +- input/src/errors/parser.rs | 6 +++ symbol-table/src/types/type_.rs | 43 ++++++++----------- .../src/assertions/type_variable_pair.rs | 32 ++++---------- type-inference/src/objects/frame.rs | 2 +- 6 files changed, 33 insertions(+), 66 deletions(-) diff --git a/ast/src/types/type_.rs b/ast/src/types/type_.rs index 8c13c23e04..51f37ef9a0 100644 --- a/ast/src/types/type_.rs +++ b/ast/src/types/type_.rs @@ -100,20 +100,6 @@ impl Type { } } -fn expand_array_type(_type: &Type, _dimensions: &[usize]) -> (Type, Vec) { - unimplemented!("deprecated") - // if let Type::Array(nested_type, nested_dimensions) = type_ { - // // Expand nested array type - // let mut expanded_dimensions = dimensions.to_vec(); - // expanded_dimensions.append(&mut nested_dimensions.clone()); - // - // expand_array_type(nested_type, &expanded_dimensions) - // } else { - // // Array type is fully expanded - // (type_.clone(), dimensions.to_vec()) - // } -} - /// pest ast -> Explicit Type for defining circuit members and function params impl From for Type { diff --git a/compiler/src/expression/expression.rs b/compiler/src/expression/expression.rs index 859175f8af..9af7ab7c1c 100644 --- a/compiler/src/expression/expression.rs +++ b/compiler/src/expression/expression.rs @@ -243,7 +243,7 @@ impl> ConstrainedProgram { ), // Arrays - Expression::Array(array, span) => { + Expression::ArrayInline(array, span) => { self.enforce_array(cs, file_scope, function_scope, expected_type, array, span) } Expression::ArrayAccess(array_w_index, span) => self.enforce_array_access( diff --git a/input/src/errors/parser.rs b/input/src/errors/parser.rs index 24bfaa5e52..a3f3684a04 100644 --- a/input/src/errors/parser.rs +++ b/input/src/errors/parser.rs @@ -77,6 +77,12 @@ impl InputParserError { InputParserError::SyntaxError(InputSyntaxError::from(error)) } + pub fn array_index(actual: String, span: Span) -> Self { + let message = format!("Expected constant number for array index, found `{}`", actual); + + Self::new_from_span(message, span) + } + pub fn implicit_type(data_type: DataType, implicit: NumberValue) -> Self { let message = format!("expected `{}`, found `{}`", data_type, implicit); diff --git a/symbol-table/src/types/type_.rs b/symbol-table/src/types/type_.rs index ba819be1e7..693904db3c 100644 --- a/symbol-table/src/types/type_.rs +++ b/symbol-table/src/types/type_.rs @@ -14,11 +14,10 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{SymbolTable, TypeError, TypeVariable}; -use leo_ast::{Identifier, IntegerType, Span, Type as UnresolvedType}; +use leo_ast::{ArrayDimensions, Identifier, IntegerType, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; use std::{ - borrow::Cow, cmp::{Eq, PartialEq}, fmt, }; @@ -34,7 +33,7 @@ pub enum Type { IntegerType(IntegerType), // Data type wrappers - Array(Box, Vec), + Array(Box, ArrayDimensions), Tuple(Vec), // User defined types @@ -145,7 +144,7 @@ impl Type { /// /// Returns array element type and dimensions if self is an expected array type `Type::Array`. /// - pub fn get_type_array(&self, span: Span) -> Result<(&Type, &Vec), TypeError> { + pub fn get_type_array(&self, span: Span) -> Result<(&Type, &ArrayDimensions), TypeError> { match self { Type::Array(element_type, dimensions) => Ok((element_type, dimensions)), // Throw mismatched type error @@ -275,15 +274,7 @@ impl fmt::Display for Type { Type::Group => write!(f, "group"), Type::IntegerType(integer_type) => write!(f, "{}", integer_type), - Type::Array(type_, dimensions) => { - let dimensions_string = dimensions - .iter() - .map(|dimension| dimension.to_string()) - .collect::>() - .join(", "); - - write!(f, "[{}; ({})]", *type_, dimensions_string) - } + Type::Array(type_, dimensions) => write!(f, "[{}; {}]", *type_, dimensions), Type::Tuple(tuple) => { let tuple_string = tuple.iter().map(|x| x.to_string()).collect::>().join(", "); @@ -306,13 +297,13 @@ impl PartialEq for Type { (Type::Group, Type::Group) => true, (Type::IntegerType(integer_type1), Type::IntegerType(integer_type2)) => integer_type1.eq(integer_type2), - (Type::Array(type1, dimensions1), Type::Array(type2, dimensions2)) => { - // Flatten both array types before comparison. - let (type1_flat, dimensions1_flat) = flatten_array_type(type1, Cow::from(dimensions1)); - let (type2_flat, dimensions2_flat) = flatten_array_type(type2, Cow::from(dimensions2)); + (Type::Array(array1, _), Type::Array(array2, _)) => { + // Get both array element types before comparison. + let array1_element = get_array_element_type(array1); + let array2_element = get_array_element_type(array2); - // Element types and dimensions must match - type1_flat.eq(type2_flat) && dimensions1_flat.eq(&dimensions2_flat) + // Check that both arrays have the same element type. + array1_element.eq(array2_element) } (Type::Tuple(types1), Type::Tuple(types2)) => types1.eq(types2), @@ -327,15 +318,15 @@ impl PartialEq for Type { impl Eq for Type {} /// -/// Returns the data type of the array element and vector of dimensions. +/// Returns the data type of the array element. /// -/// Will flatten an array type `[[[u8; 1]; 2]; 3]` into `[u8; (3, 2, 1)]`. +/// If the given `type_` is an array, call `get_array_element_type()` on the array element type. +/// If the given `type_` is any other type, return the `type_`. /// -pub fn flatten_array_type<'a>(type_: &'a Type, mut dimensions: Cow<'a, [usize]>) -> (&'a Type, Cow<'a, [usize]>) { - if let Type::Array(element_type, element_dimensions) = type_ { - dimensions.to_mut().extend(element_dimensions); - flatten_array_type(element_type, dimensions) +pub fn get_array_element_type(type_: &Type) -> &Type { + if let Type::Array(element_type, _) = type_ { + get_array_element_type(element_type) } else { - (type_, dimensions) + type_ } } diff --git a/type-inference/src/assertions/type_variable_pair.rs b/type-inference/src/assertions/type_variable_pair.rs index b7e7f09552..2673cb365a 100644 --- a/type-inference/src/assertions/type_variable_pair.rs +++ b/type-inference/src/assertions/type_variable_pair.rs @@ -16,7 +16,7 @@ use crate::TypeAssertionError; use leo_ast::Span; -use leo_symbol_table::{flatten_array_type, Type, TypeVariable}; +use leo_symbol_table::{get_array_element_type, Type, TypeVariable}; use std::borrow::Cow; /// A type variable -> type pair. @@ -88,8 +88,8 @@ impl TypeVariablePairs { match (left, right) { (Type::TypeVariable(variable), type_) => Ok(self.push(variable, type_)), (type_, Type::TypeVariable(variable)) => Ok(self.push(variable, type_)), - (Type::Array(left_type, left_dimensions), Type::Array(right_type, right_dimensions)) => { - self.push_pairs_array(*left_type, left_dimensions, *right_type, right_dimensions, span) + (Type::Array(left_type, _), Type::Array(right_type, _)) => { + self.push_pairs_array(*left_type, *right_type, span) } (Type::Tuple(left_types), Type::Tuple(right_types)) => { self.push_pairs_tuple(left_types.into_iter(), right_types.into_iter(), span) @@ -103,29 +103,13 @@ impl TypeVariablePairs { /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left /// and right type. /// - fn push_pairs_array( - &mut self, - left_type: Type, - left_dimensions: Vec, - right_type: Type, - right_dimensions: Vec, - span: &Span, - ) -> Result<(), TypeAssertionError> { - // Flatten the array types to get the element types. - let (left_type_flat, left_dimensions_flat) = flatten_array_type(&left_type, Cow::from(&left_dimensions)); - let (right_type_flat, right_dimensions_flat) = flatten_array_type(&right_type, Cow::from(&right_dimensions)); - - // If the dimensions do not match, then throw an error. - if left_dimensions_flat.ne(&right_dimensions_flat) { - return Err(TypeAssertionError::array_dimensions( - &left_dimensions_flat, - &right_dimensions_flat, - span, - )); - } + fn push_pairs_array(&mut self, left_type: Type, right_type: Type, span: &Span) -> Result<(), TypeAssertionError> { + // Get both array element types before comparison. + let array1_element = get_array_element_type(&left_type); + let array2_element = get_array_element_type(&right_type); // Compare the array element types. - self.push_pairs(left_type_flat.to_owned(), right_type_flat.to_owned(), span) + self.push_pairs(array1_element.to_owned(), array2_element.to_owned(), span) } /// diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index 9fd37814d6..fcbab70b33 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -548,7 +548,7 @@ impl Frame { } // Arrays - Expression::Array(expressions, span) => self.parse_array(expressions, span), + Expression::ArrayInline(expressions, span) => self.parse_array(expressions, span), Expression::ArrayAccess(array_w_index, span) => { self.parse_expression_array_access(&array_w_index.0, &array_w_index.1, span) } From 1daf6c983136e7089adfec95f2fb7add69ffd40c Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 6 Nov 2020 13:26:47 -0800 Subject: [PATCH 124/139] do not compare array dimensions in type inference --- symbol-table/src/errors/type_.rs | 55 ------------ symbol-table/src/types/type_.rs | 87 +++---------------- .../src/assertions/type_variable_pair.rs | 5 +- type-inference/src/errors/frame.rs | 9 ++ type-inference/src/objects/frame.rs | 78 +++++++++-------- 5 files changed, 60 insertions(+), 174 deletions(-) diff --git a/symbol-table/src/errors/type_.rs b/symbol-table/src/errors/type_.rs index 5e3bed8102..030fce9c0f 100644 --- a/symbol-table/src/errors/type_.rs +++ b/symbol-table/src/errors/type_.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::Type; use leo_ast::{Error as FormattedError, Identifier, Span}; use std::path::Path; @@ -43,60 +42,6 @@ impl TypeError { TypeError::Error(FormattedError::new_from_span(message, span)) } - /// - /// Expected an array type from the given expression. - /// - pub fn invalid_array(actual: &Type, span: Span) -> Self { - let message = format!("Expected array type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// Expected a circuit type from the given expression. - /// - pub fn invalid_circuit(actual: &Type, span: Span) -> Self { - let message = format!("Expected circuit type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// Expected a function type from the given expression. - /// - pub fn invalid_function(actual: &Type, span: Span) -> Self { - let message = format!("Expected function type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// Expected an integer type from the given expression. - /// - pub fn invalid_integer(actual: &Type, span: Span) -> Self { - let message = format!("Expected integer type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// Expected a tuple type from the given expression. - /// - pub fn invalid_tuple(actual: &Type, span: Span) -> Self { - let message = format!("Expected tuple type, found type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// The value of the expression does not match the given explicit type. - /// - pub fn mismatched_types(expected: &Type, actual: &Type, span: Span) -> Self { - let message = format!("Expected type `{}`, found type `{}`.", expected, actual); - - Self::new_from_span(message, span) - } - /// /// The `Self` keyword was used outside of a circuit. /// diff --git a/symbol-table/src/types/type_.rs b/symbol-table/src/types/type_.rs index 693904db3c..4f1721e9ea 100644 --- a/symbol-table/src/types/type_.rs +++ b/symbol-table/src/types/type_.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . use crate::{SymbolTable, TypeError, TypeVariable}; -use leo_ast::{ArrayDimensions, Identifier, IntegerType, Span, Type as UnresolvedType}; +use leo_ast::{Identifier, IntegerType, Span, Type as UnresolvedType}; use serde::{Deserialize, Serialize}; use std::{ @@ -33,7 +33,7 @@ pub enum Type { IntegerType(IntegerType), // Data type wrappers - Array(Box, ArrayDimensions), + Array(Box), Tuple(Vec), // User defined types @@ -58,10 +58,10 @@ impl Type { UnresolvedType::Group => Type::Group, UnresolvedType::IntegerType(integer) => Type::IntegerType(integer), - UnresolvedType::Array(type_, dimensions) => { + UnresolvedType::Array(type_, _) => { let array_type = Type::new(table, *type_, span)?; - Type::Array(Box::new(array_type), dimensions) + Type::Array(Box::new(array_type)) } UnresolvedType::Tuple(types) => { let tuple_types = types @@ -100,9 +100,9 @@ impl Type { span: Span, ) -> Result { Ok(match type_ { - UnresolvedType::Array(type_, dimensions) => { + UnresolvedType::Array(type_, _) => { let array_type = Type::new_from_circuit(table, *type_, circuit_name, span)?; - Type::Array(Box::new(array_type), dimensions) + Type::Array(Box::new(array_type)) } UnresolvedType::Tuple(types) => { let tuple_types = types @@ -118,73 +118,6 @@ impl Type { }) } - /// - /// Returns `Ok` if the given expected type is `Some` and expected type == actual type. - /// - pub fn check_type(expected_option: &Option, actual: &Type, span: Span) -> Result<(), TypeError> { - if let Some(expected) = expected_option { - if expected.ne(actual) { - return Err(TypeError::mismatched_types(expected, actual, span)); - } - } - Ok(()) - } - - /// - /// Returns `Ok` if self is an expected integer type `Type::IntegerType`. - /// - pub fn check_type_integer(&self, span: Span) -> Result<(), TypeError> { - match self { - Type::IntegerType(_) => Ok(()), - // Throw mismatched type error - type_ => Err(TypeError::invalid_integer(type_, span)), - } - } - - /// - /// Returns array element type and dimensions if self is an expected array type `Type::Array`. - /// - pub fn get_type_array(&self, span: Span) -> Result<(&Type, &ArrayDimensions), TypeError> { - match self { - Type::Array(element_type, dimensions) => Ok((element_type, dimensions)), - // Throw mismatched type error - type_ => Err(TypeError::invalid_array(type_, span)), - } - } - - /// - /// Returns tuple element types if self is an expected tuple type `Type::Tuple`. - /// - pub fn get_type_tuple(&self, span: Span) -> Result<&Vec, TypeError> { - match self { - Type::Tuple(types) => Ok(types), - // Throw mismatched type error - type_ => Err(TypeError::invalid_tuple(type_, span)), - } - } - - /// - /// Returns circuit identifier if self is an expected circuit type `Type::Circuit`. - /// - pub fn get_type_circuit(&self, span: Span) -> Result<&Identifier, TypeError> { - match self { - Type::Circuit(identifier) => Ok(identifier), - // Throw mismatched type error - type_ => Err(TypeError::invalid_circuit(type_, span)), - } - } - - /// - /// Returns function identifier if self is an expected function type `Type::Function`. - /// - pub fn get_type_function(&self, span: Span) -> Result<&Identifier, TypeError> { - match self { - Type::Function(identifier) => Ok(identifier), - // Throw mismatched type error - type_ => Err(TypeError::invalid_function(type_, span)), - } - } - /// Returns a list of signed integer types. pub const fn signed_integer_types() -> [Type; 5] { [ @@ -254,7 +187,7 @@ impl Type { *self = type_.to_owned() } } - Type::Array(self_type, _) => { + Type::Array(self_type) => { self_type.substitute(variable, type_); } Type::Tuple(types) => types @@ -274,7 +207,7 @@ impl fmt::Display for Type { Type::Group => write!(f, "group"), Type::IntegerType(integer_type) => write!(f, "{}", integer_type), - Type::Array(type_, dimensions) => write!(f, "[{}; {}]", *type_, dimensions), + Type::Array(type_) => write!(f, "[{}]", *type_), Type::Tuple(tuple) => { let tuple_string = tuple.iter().map(|x| x.to_string()).collect::>().join(", "); @@ -297,7 +230,7 @@ impl PartialEq for Type { (Type::Group, Type::Group) => true, (Type::IntegerType(integer_type1), Type::IntegerType(integer_type2)) => integer_type1.eq(integer_type2), - (Type::Array(array1, _), Type::Array(array2, _)) => { + (Type::Array(array1), Type::Array(array2)) => { // Get both array element types before comparison. let array1_element = get_array_element_type(array1); let array2_element = get_array_element_type(array2); @@ -324,7 +257,7 @@ impl Eq for Type {} /// If the given `type_` is any other type, return the `type_`. /// pub fn get_array_element_type(type_: &Type) -> &Type { - if let Type::Array(element_type, _) = type_ { + if let Type::Array(element_type) = type_ { get_array_element_type(element_type) } else { type_ diff --git a/type-inference/src/assertions/type_variable_pair.rs b/type-inference/src/assertions/type_variable_pair.rs index 2673cb365a..6bfc25397e 100644 --- a/type-inference/src/assertions/type_variable_pair.rs +++ b/type-inference/src/assertions/type_variable_pair.rs @@ -17,7 +17,6 @@ use crate::TypeAssertionError; use leo_ast::Span; use leo_symbol_table::{get_array_element_type, Type, TypeVariable}; -use std::borrow::Cow; /// A type variable -> type pair. pub struct TypeVariablePair(TypeVariable, Type); @@ -88,9 +87,7 @@ impl TypeVariablePairs { match (left, right) { (Type::TypeVariable(variable), type_) => Ok(self.push(variable, type_)), (type_, Type::TypeVariable(variable)) => Ok(self.push(variable, type_)), - (Type::Array(left_type, _), Type::Array(right_type, _)) => { - self.push_pairs_array(*left_type, *right_type, span) - } + (Type::Array(left_type), Type::Array(right_type)) => self.push_pairs_array(*left_type, *right_type, span), (Type::Tuple(left_types), Type::Tuple(right_types)) => { self.push_pairs_tuple(left_types.into_iter(), right_types.into_iter(), span) } diff --git a/type-inference/src/errors/frame.rs b/type-inference/src/errors/frame.rs index 1d671fc40b..36e8576832 100644 --- a/type-inference/src/errors/frame.rs +++ b/type-inference/src/errors/frame.rs @@ -112,6 +112,15 @@ impl FrameError { Self::new_from_span(message, span) } + /// + /// Expected a usize number for the index. + /// + pub fn invalid_index(actual: String, span: &Span) -> Self { + let message = format!("Expected constant number for index, found `{}`", actual); + + Self::new_from_span(message, span) + } + /// /// Attempted to call non-static member using `::`. /// diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index fcbab70b33..7df352a404 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -26,6 +26,7 @@ use leo_ast::{ Function, Identifier, IntegerType, + PositiveNumber, RangeOrExpression, Span, SpreadOrExpression, @@ -372,7 +373,7 @@ impl Frame { for access in &assignee.accesses { let access_type = match access { AssigneeAccess::Array(r_or_e) => self.parse_array_access(type_, r_or_e, span), - AssigneeAccess::Tuple(index) => self.parse_tuple_access(type_, *index, span), + AssigneeAccess::Tuple(index, _) => self.parse_tuple_access(type_, &index, span), AssigneeAccess::Member(identifier) => self.parse_circuit_member_access(type_, identifier, span), }?; @@ -549,13 +550,18 @@ impl Frame { // Arrays Expression::ArrayInline(expressions, span) => self.parse_array(expressions, span), + Expression::ArrayInitializer(array_w_dimensions, _span) => { + self.parse_array_initializer(&array_w_dimensions.0) + } Expression::ArrayAccess(array_w_index, span) => { self.parse_expression_array_access(&array_w_index.0, &array_w_index.1, span) } // Tuples Expression::Tuple(expressions, span) => self.parse_tuple(expressions, span), - Expression::TupleAccess(tuple, index, span) => self.parse_expression_tuple_access(tuple, *index, span), + Expression::TupleAccess(tuple_w_index, span) => { + self.parse_expression_tuple_access(&tuple_w_index.0, &tuple_w_index.1, span) + } // Circuits Expression::Circuit(identifier, members, span) => self.parse_circuit(identifier, members, span), @@ -737,7 +743,7 @@ impl Frame { fn parse_expression_tuple_access( &mut self, expression: &Expression, - index: usize, + index: &PositiveNumber, span: &Span, ) -> Result { // Parse the tuple expression which could be a variable with type tuple. @@ -750,14 +756,20 @@ impl Frame { /// /// Returns the type of the accessed tuple element. /// - fn parse_tuple_access(&mut self, type_: Type, index: usize, span: &Span) -> Result { + fn parse_tuple_access(&mut self, type_: Type, index: &PositiveNumber, span: &Span) -> Result { // Check the type is a tuple. let mut elements = match type_ { Type::Tuple(elements) => elements, type_ => return Err(FrameError::tuple_access(&type_, span)), }; - let element_type = elements.swap_remove(index); + // Parse index `String` to `usize`. + let index_usize = match index.to_string().parse::() { + Ok(index_usize) => index_usize, + Err(_) => return Err(FrameError::invalid_index(index.to_string(), span)), + }; + + let element_type = elements.swap_remove(index_usize); Ok(element_type) } @@ -768,12 +780,11 @@ impl Frame { fn parse_array(&mut self, expressions: &[SpreadOrExpression], span: &Span) -> Result { // Store array element type. let mut element_type = None; - let mut count = 0usize; // Parse all array elements. for expression in expressions { // Get the type and count of elements in each spread or expression. - let (type_, element_count) = self.parse_spread_or_expression(expression, span)?; + let type_ = self.parse_spread_or_expression(expression, span)?; // Assert that array element types are the same. if let Some(prev_type) = element_type { @@ -782,9 +793,6 @@ impl Frame { // Update array element type. element_type = Some(type_); - - // Update number of array elements. - count += element_count; } // Return an error for empty arrays. @@ -793,43 +801,37 @@ impl Frame { None => return Err(FrameError::empty_array(span)), }; - Ok(Type::Array(Box::new(type_), vec![count])) + Ok(Type::Array(Box::new(type_))) + } + + /// + /// Returns the type of the array initializer expression. + /// + fn parse_array_initializer(&mut self, array: &Expression) -> Result { + // Get element type. + let element_type = self.parse_expression(array)?; + + // Return array type. + Ok(Type::Array(Box::new(element_type))) } /// /// Returns the type and count of elements in a spread or expression. /// - fn parse_spread_or_expression( - &mut self, - s_or_e: &SpreadOrExpression, - span: &Span, - ) -> Result<(Type, usize), FrameError> { - Ok(match s_or_e { + fn parse_spread_or_expression(&mut self, s_or_e: &SpreadOrExpression, span: &Span) -> Result { + match s_or_e { SpreadOrExpression::Spread(expression) => { // Parse the type of the spread array expression. let array_type = self.parse_expression(expression)?; // Check that the type is an array. - let (element_type, mut dimensions) = match array_type { - Type::Array(element_type, dimensions) => (element_type, dimensions), - type_ => return Err(FrameError::invalid_spread(type_, span)), - }; - - // A spread copies the elements of an array. - // If the array has elements of type array, we must return a new array type with proper dimensions. - // If the array has elements of any other type, we can return the type and count directly. - let count = dimensions.pop().unwrap(); - - let type_ = if dimensions.is_empty() { - *element_type - } else { - Type::Array(element_type, dimensions) - }; - - (type_, count) + match array_type { + Type::Array(element_type) => Ok(Type::Array(element_type)), + type_ => Err(FrameError::invalid_spread(type_, span)), + } } - SpreadOrExpression::Expression(expression) => (self.parse_expression(expression)?, 1), - }) + SpreadOrExpression::Expression(expression) => self.parse_expression(expression), + } } /// @@ -853,8 +855,8 @@ impl Frame { /// fn parse_array_access(&mut self, type_: Type, r_or_e: &RangeOrExpression, span: &Span) -> Result { // Check the type is an array. - let (element_type, _dimensions) = match type_ { - Type::Array(type_, dimensions) => (type_, dimensions), + let element_type = match type_ { + Type::Array(type_) => type_, type_ => return Err(FrameError::array_access(&type_, span)), }; From d7ff80866065bc3de9110b3bc26145dd6c616317 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 6 Nov 2020 16:24:38 -0800 Subject: [PATCH 125/139] add support for refactored array type in compiler --- ast/src/common/array_dimensions.rs | 59 +++++++++++++++++++++- compiler/src/errors/expression.rs | 10 +++- compiler/src/expression/array/array.rs | 65 +++++++++++++++++++------ compiler/src/expression/array/index.rs | 2 +- compiler/src/expression/expression.rs | 12 +++-- compiler/src/expression/tuple/access.rs | 17 ++++--- compiler/src/function/input/array.rs | 37 +++++++++++--- compiler/src/statement/assign/assign.rs | 4 +- compiler/src/statement/assign/tuple.rs | 18 ++++--- compiler/src/value/value.rs | 5 +- 10 files changed, 183 insertions(+), 46 deletions(-) diff --git a/ast/src/common/array_dimensions.rs b/ast/src/common/array_dimensions.rs index ced54792c1..baa503b1b5 100644 --- a/ast/src/common/array_dimensions.rs +++ b/ast/src/common/array_dimensions.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::PositiveNumber; +use crate::{PositiveNumber, Span}; use leo_grammar::types::ArrayDimensions as GrammarArrayDimensions; use leo_input::types::ArrayDimensions as InputArrayDimensions; @@ -23,16 +23,71 @@ use std::fmt; /// A vector of positive numbers that represent array dimensions. /// Can be used in an array [`Type`] or an array initializer [`Expression`]. -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct ArrayDimensions(pub Vec); impl ArrayDimensions { + /// + /// Creates a new `PositiveNumber` from the given `usize` and `Span`. + /// Appends the new `PositiveNumber` to the array dimensions. + /// + pub fn push_usize(&mut self, number: usize, span: Span) { + let positive_number = PositiveNumber { + value: number.to_string(), + span, + }; + + self.0.push(positive_number) + } + + /// + /// Appends a vector of array dimensions to the self array dimensions. + /// + pub fn append(&mut self, other: &mut ArrayDimensions) { + self.0.append(&mut other.0) + } + /// /// Returns the array dimensions as strings. /// pub fn to_strings(&self) -> Vec { self.0.iter().map(|number| number.to_string()).collect() } + + /// + /// Returns `true` if the all array dimensions have been removed. + /// + /// This method is called after repeated calls to `remove_first`. + /// + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// + /// Returns the first dimension of the array. + /// + pub fn first(&self) -> Option<&PositiveNumber> { + self.0.first() + } + + /// + /// Attempts to remove the first dimension from the array. + /// + /// If the first dimension exists, then remove and return `Some(PositiveNumber)`. + /// If the first dimension does not exist, then return `None`. + /// + pub fn remove_first(&mut self) -> Option { + // If there are no dimensions in the array, then return None. + if self.0.get(0).is_none() { + return None; + } + + // Remove the first dimension. + let removed = self.0.remove(0); + + // Return the first dimension. + Some(removed) + } } /// Create a new [`ArrayDimensions`] from a [`GrammarArrayDimensions`] in a Leo program file. diff --git a/compiler/src/errors/expression.rs b/compiler/src/errors/expression.rs index bde8d04f4d..64648035b4 100644 --- a/compiler/src/errors/expression.rs +++ b/compiler/src/errors/expression.rs @@ -109,10 +109,10 @@ impl ExpressionError { Self::new_from_span(message, span) } - pub fn invalid_index(actual: String, span: Span) -> Self { + pub fn invalid_index(actual: String, span: &Span) -> Self { let message = format!("index must resolve to an integer, found `{}`", actual); - Self::new_from_span(message, span) + Self::new_from_span(message, span.to_owned()) } pub fn invalid_length(expected: usize, actual: usize, span: Span) -> Self { @@ -157,6 +157,12 @@ impl ExpressionError { Self::new_from_span(message, span) } + pub fn undefined_tuple(actual: String, span: Span) -> Self { + let message = format!("tuple `{}` must be declared before it is used in an expression", actual); + + Self::new_from_span(message, span) + } + pub fn undefined_circuit(actual: String, span: Span) -> Self { let message = format!( "circuit `{}` must be declared before it is used in an expression", diff --git a/compiler/src/expression/array/array.rs b/compiler/src/expression/array/array.rs index 7a0494fb9d..c87d6f2a40 100644 --- a/compiler/src/expression/array/array.rs +++ b/compiler/src/expression/array/array.rs @@ -22,7 +22,7 @@ use crate::{ value::ConstrainedValue, GroupType, }; -use leo_ast::{Expression, Span, SpreadOrExpression, Type}; +use leo_ast::{ArrayDimensions, Expression, PositiveNumber, Span, SpreadOrExpression, Type}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -41,20 +41,28 @@ impl> ConstrainedProgram { span: Span, ) -> Result, ExpressionError> { // Check explicit array type dimension if given - let mut expected_dimensions = vec![]; + let mut expected_dimension = None; if let Some(type_) = expected_type { match type_ { - Type::Array(ref type_, ref dimensions) => { - let number = match dimensions.first() { - Some(number) => *number, + Type::Array(type_, mut dimensions) => { + // Remove the first dimension of the array. + let first = match dimensions.remove_first() { + Some(number) => { + // Parse the array dimension into a `usize`. + parse_index(&number, &span)? + } None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)), }; - expected_dimensions.push(number); - expected_type = Some(type_.outer_dimension(dimensions)); + // Update the expected dimension to the first dimension. + expected_dimension = Some(first); + + // Update the expected type to a new array type with the first dimension removed. + expected_type = Some(inner_array_type(*type_, dimensions)); } ref type_ => { + // Return an error if the expected type is not an array. return Err(ExpressionError::unexpected_array(type_.to_string(), span)); } } @@ -88,15 +96,44 @@ impl> ConstrainedProgram { } } - // Check expected_dimensions if given - if !expected_dimensions.is_empty() && expected_dimensions[expected_dimensions.len() - 1] != result.len() { - return Err(ExpressionError::invalid_length( - expected_dimensions[expected_dimensions.len() - 1], - result.len(), - span, - )); + // Check expected_dimension if given. + if let Some(dimension) = expected_dimension { + // Return an error if the expected dimension != the actual dimension. + if dimension != result.len() { + return Err(ExpressionError::invalid_length(dimension, result.len(), span)); + } } Ok(ConstrainedValue::Array(result)) } } + +/// +/// Returns the index as a usize. +/// +pub fn parse_index(number: &PositiveNumber, span: &Span) -> Result { + number + .value + .parse::() + .map_err(|_| ExpressionError::invalid_index(number.value.to_owned(), span)) +} + +/// +/// Returns the type of the inner array given an array element and array dimensions. +/// +/// If the array has no dimensions, then an inner array does not exist. Simply return the given +/// element type. +/// +/// If the array has dimensions, then an inner array exists. Create a new type for the +/// inner array. The element type of the new array should be the same as the old array. The +/// dimensions of the new array should be the old array dimensions with the first dimension removed. +/// +pub fn inner_array_type(element_type: Type, dimensions: ArrayDimensions) -> Type { + if dimensions.is_empty() { + // The array has one dimension. + element_type + } else { + // The array has multiple dimensions. + Type::Array(Box::new(element_type), dimensions) + } +} diff --git a/compiler/src/expression/array/index.rs b/compiler/src/expression/array/index.rs index 52d2e863c8..02d361bae5 100644 --- a/compiler/src/expression/array/index.rs +++ b/compiler/src/expression/array/index.rs @@ -36,7 +36,7 @@ impl> ConstrainedProgram { let expected_type = Some(Type::IntegerType(IntegerType::U32)); match self.enforce_operand(cs, file_scope, function_scope, expected_type, index, &span)? { ConstrainedValue::Integer(number) => Ok(number.to_usize(span)?), - value => Err(ExpressionError::invalid_index(value.to_string(), span.to_owned())), + value => Err(ExpressionError::invalid_index(value.to_string(), span)), } } } diff --git a/compiler/src/expression/expression.rs b/compiler/src/expression/expression.rs index 9af7ab7c1c..5b842eeb95 100644 --- a/compiler/src/expression/expression.rs +++ b/compiler/src/expression/expression.rs @@ -260,9 +260,15 @@ impl> ConstrainedProgram { Expression::Tuple(tuple, span) => { self.enforce_tuple(cs, file_scope, function_scope, expected_type, tuple, span) } - Expression::TupleAccess(tuple, index, span) => { - self.enforce_tuple_access(cs, file_scope, function_scope, expected_type, *tuple, index, &span) - } + Expression::TupleAccess(tuple_w_index, span) => self.enforce_tuple_access( + cs, + file_scope, + function_scope, + expected_type, + tuple_w_index.0, + tuple_w_index.1, + &span, + ), // Circuits Expression::Circuit(circuit_name, members, span) => { diff --git a/compiler/src/expression/tuple/access.rs b/compiler/src/expression/tuple/access.rs index 33cc551c98..03cc03ebce 100644 --- a/compiler/src/expression/tuple/access.rs +++ b/compiler/src/expression/tuple/access.rs @@ -16,8 +16,8 @@ //! Enforces array access in a compiled Leo program. -use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_ast::{Expression, Span, Type}; +use crate::{errors::ExpressionError, parse_index, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; +use leo_ast::{Expression, PositiveNumber, Span, Type}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -33,18 +33,23 @@ impl> ConstrainedProgram { function_scope: &str, expected_type: Option, tuple: Expression, - index: usize, + index: PositiveNumber, span: &Span, ) -> Result, ExpressionError> { + // Get the tuple values. let tuple = match self.enforce_operand(cs, file_scope, function_scope, expected_type, tuple, &span)? { ConstrainedValue::Tuple(tuple) => tuple, value => return Err(ExpressionError::undefined_array(value.to_string(), span.to_owned())), }; - if index > tuple.len() - 1 { - return Err(ExpressionError::index_out_of_bounds(index, span.to_owned())); + // Parse the tuple index. + let index_usize = parse_index(&index, &span)?; + + // Check for out of bounds access. + if index_usize > tuple.len() - 1 { + return Err(ExpressionError::index_out_of_bounds(index_usize, span.to_owned())); } - Ok(tuple[index].to_owned()) + Ok(tuple[index_usize].to_owned()) } } diff --git a/compiler/src/function/input/array.rs b/compiler/src/function/input/array.rs index 8c3cf3a9e7..5158947d0c 100644 --- a/compiler/src/function/input/array.rs +++ b/compiler/src/function/input/array.rs @@ -18,13 +18,16 @@ use crate::{ errors::FunctionError, + inner_array_type, + parse_index, program::{new_scope, ConstrainedProgram}, value::ConstrainedValue, GroupType, }; -use leo_ast::{InputValue, Span, Type}; +use leo_ast::{ArrayDimensions, InputValue, Span, Type}; +use crate::errors::ExpressionError; use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::ConstraintSystem, @@ -36,11 +39,27 @@ impl> ConstrainedProgram { cs: &mut CS, name: &str, array_type: Type, - array_dimensions: Vec, + mut array_dimensions: ArrayDimensions, input_value: Option, span: &Span, ) -> Result, FunctionError> { - let expected_length = array_dimensions[0]; + let expected_length = match array_dimensions.remove_first() { + Some(number) => { + // Parse the array dimension into a `usize`. + parse_index(&number, &span)? + } + None => { + return Err(FunctionError::ExpressionError(ExpressionError::unexpected_array( + array_type.to_string(), + span.to_owned(), + ))); + } + }; + + // Get the expected type for each array element. + let inner_array_type = inner_array_type(array_type, array_dimensions); + + // Build the array value using the expected types. let mut array_value = vec![]; match input_value { @@ -48,11 +67,10 @@ impl> ConstrainedProgram { // Allocate each value in the current row for (i, value) in arr.into_iter().enumerate() { let value_name = new_scope(&name, &i.to_string()); - let value_type = array_type.outer_dimension(&array_dimensions); array_value.push(self.allocate_main_function_input( cs, - value_type, + inner_array_type.clone(), &value_name, Some(value), span, @@ -63,9 +81,14 @@ impl> ConstrainedProgram { // Allocate all row values as none for i in 0..expected_length { let value_name = new_scope(&name, &i.to_string()); - let value_type = array_type.outer_dimension(&array_dimensions); - array_value.push(self.allocate_main_function_input(cs, value_type, &value_name, None, span)?); + array_value.push(self.allocate_main_function_input( + cs, + inner_array_type.clone(), + &value_name, + None, + span, + )?); } } _ => { diff --git a/compiler/src/statement/assign/assign.rs b/compiler/src/statement/assign/assign.rs index 2dad3ea1f8..c33bd43f79 100644 --- a/compiler/src/statement/assign/assign.rs +++ b/compiler/src/statement/assign/assign.rs @@ -83,8 +83,8 @@ impl> ConstrainedProgram { new_value, span, ), - AssigneeAccess::Tuple(index) => { - self.assign_tuple(cs, indicator, &variable_name, index, new_value, span) + AssigneeAccess::Tuple(index, span) => { + self.assign_tuple(cs, indicator, &variable_name, index, new_value, &span) } AssigneeAccess::Member(identifier) => { // Mutate a circuit variable using the self keyword. diff --git a/compiler/src/statement/assign/tuple.rs b/compiler/src/statement/assign/tuple.rs index 6fb7885255..5ecb0dd767 100644 --- a/compiler/src/statement/assign/tuple.rs +++ b/compiler/src/statement/assign/tuple.rs @@ -16,8 +16,8 @@ //! Enforces a tuple assignment statement in a compiled Leo program. -use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; -use leo_ast::Span; +use crate::{errors::StatementError, parse_index, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; +use leo_ast::{PositiveNumber, Span}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -33,28 +33,32 @@ impl> ConstrainedProgram { cs: &mut CS, indicator: Option, name: &str, - index: usize, + index: PositiveNumber, mut new_value: ConstrainedValue, span: &Span, ) -> Result<(), StatementError> { + // Get the indicator value. let condition = indicator.unwrap_or(Boolean::Constant(true)); + // Parse the index. + let index_usize = parse_index(&index, &span)?; + // Modify the single value of the tuple in place match self.get_mutable_assignee(name, &span)? { ConstrainedValue::Tuple(old) => { - new_value.resolve_type(Some(old[index].to_type(&span)?), &span)?; + new_value.resolve_type(Some(old[index_usize].to_type(&span)?), &span)?; let selected_value = ConstrainedValue::conditionally_select( cs.ns(|| format!("select {} {}:{}", new_value, span.line, span.start)), &condition, &new_value, - &old[index], + &old[index_usize], ) .map_err(|_| { - StatementError::select_fail(new_value.to_string(), old[index].to_string(), span.to_owned()) + StatementError::select_fail(new_value.to_string(), old[index_usize].to_string(), span.to_owned()) })?; - old[index] = selected_value; + old[index_usize] = selected_value; } _ => return Err(StatementError::tuple_assign_index(span.to_owned())), } diff --git a/compiler/src/value/value.rs b/compiler/src/value/value.rs index b83cb79b71..0de94a7e65 100644 --- a/compiler/src/value/value.rs +++ b/compiler/src/value/value.rs @@ -26,7 +26,7 @@ use crate::{ GroupType, Integer, }; -use leo_ast::{Circuit, Function, GroupValue, Identifier, Span, Type}; +use leo_ast::{ArrayDimensions, Circuit, Function, GroupValue, Identifier, Span, Type}; use leo_core::Value; use snarkos_errors::gadgets::SynthesisError; @@ -114,7 +114,8 @@ impl> ConstrainedValue { // Data type wrappers ConstrainedValue::Array(array) => { let array_type = array[0].to_type(span)?; - let mut dimensions = vec![array.len()]; + let mut dimensions = ArrayDimensions::default(); + dimensions.push_usize(array.len(), span.to_owned()); // Nested array type if let Type::Array(inner_type, inner_dimensions) = &array_type { From 1ae66d9908a2748253c7c510536d1cf910dfc602 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 6 Nov 2020 19:42:07 -0800 Subject: [PATCH 126/139] add support for refactored array initializer in compiler --- ast/src/common/array_dimensions.rs | 31 ++++++++++++- compiler/src/errors/expression.rs | 11 ++++- compiler/src/expression/array/array.rs | 61 +++++++++++++++++++++++++- compiler/src/expression/expression.rs | 9 ++++ 4 files changed, 108 insertions(+), 4 deletions(-) diff --git a/ast/src/common/array_dimensions.rs b/ast/src/common/array_dimensions.rs index baa503b1b5..33fd2dcbc7 100644 --- a/ast/src/common/array_dimensions.rs +++ b/ast/src/common/array_dimensions.rs @@ -19,11 +19,14 @@ use leo_grammar::types::ArrayDimensions as GrammarArrayDimensions; use leo_input::types::ArrayDimensions as InputArrayDimensions; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::{ + fmt, + hash::{Hash, Hasher}, +}; /// A vector of positive numbers that represent array dimensions. /// Can be used in an array [`Type`] or an array initializer [`Expression`]. -#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct ArrayDimensions(pub Vec); impl ArrayDimensions { @@ -127,3 +130,27 @@ impl fmt::Display for ArrayDimensions { } } } + +/// Compares two array dimensions and ignores `Span`s. +impl PartialEq for ArrayDimensions { + fn eq(&self, other: &Self) -> bool { + // If the number of dimensions differs return false + if self.0.len() != other.0.len() { + return false; + } + + // Iteratively compare each dimension. + self.0 + .iter() + .zip(&other.0) + .all(|(first, second)| first.value.eq(&second.value)) + } +} + +impl Eq for ArrayDimensions {} + +impl Hash for ArrayDimensions { + fn hash(&self, state: &mut H) { + self.0.hash(state) + } +} diff --git a/compiler/src/errors/expression.rs b/compiler/src/errors/expression.rs index 64648035b4..33427f1e50 100644 --- a/compiler/src/errors/expression.rs +++ b/compiler/src/errors/expression.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::{AddressError, BooleanError, FieldError, FunctionError, GroupError, IntegerError, ValueError}; -use leo_ast::{Error as FormattedError, Identifier, Span}; +use leo_ast::{ArrayDimensions, Error as FormattedError, Identifier, Span}; use leo_core::LeoCorePackageError; use snarkos_errors::gadgets::SynthesisError; @@ -109,6 +109,15 @@ impl ExpressionError { Self::new_from_span(message, span) } + pub fn invalid_dimensions(expected: &ArrayDimensions, actual: &ArrayDimensions, span: Span) -> Self { + let message = format!( + "expected array dimensions {}, found array dimensions {}", + expected, actual + ); + + Self::new_from_span(message, span) + } + pub fn invalid_index(actual: String, span: &Span) -> Self { let message = format!("index must resolve to an integer, found `{}`", actual); diff --git a/compiler/src/expression/array/array.rs b/compiler/src/expression/array/array.rs index c87d6f2a40..a7984cd5bd 100644 --- a/compiler/src/expression/array/array.rs +++ b/compiler/src/expression/array/array.rs @@ -40,9 +40,9 @@ impl> ConstrainedProgram { array: Vec, span: Span, ) -> Result, ExpressionError> { - // Check explicit array type dimension if given let mut expected_dimension = None; + // Check explicit array type dimension if given if let Some(type_) = expected_type { match type_ { Type::Array(type_, mut dimensions) => { @@ -106,6 +106,65 @@ impl> ConstrainedProgram { Ok(ConstrainedValue::Array(result)) } + + /// Enforce array expressions + pub fn enforce_array_initializer>( + &mut self, + cs: &mut CS, + file_scope: &str, + function_scope: &str, + mut expected_type: Option, + element_expression: Expression, + mut actual_dimensions: ArrayDimensions, + span: Span, + ) -> Result, ExpressionError> { + let mut expected_dimensions = None; + + // Check explicit array type dimension if given + if let Some(type_) = expected_type { + match type_ { + Type::Array(element_type, dimensions) => { + // Update the expected type to the element type. + expected_type = Some(*element_type); + + // Update the expected dimensions to the first dimension. + expected_dimensions = Some(dimensions); + } + ref type_ => { + // Return an error if the expected type is not an array. + return Err(ExpressionError::unexpected_array(type_.to_string(), span)); + } + } + } + + // Evaluate array element expression. + let mut value = self.enforce_expression(cs, file_scope, function_scope, expected_type, element_expression)?; + + // Check array dimensions. + if let Some(dimensions) = expected_dimensions { + if dimensions.ne(&actual_dimensions) { + return Err(ExpressionError::invalid_dimensions( + &dimensions, + &actual_dimensions, + span, + )); + } + } + + // Allocate the array. + while let Some(dimension) = actual_dimensions.remove_first() { + // Parse the dimension into a `usize`. + let dimension_usize = parse_index(&dimension, &span)?; + + // Allocate the array dimension. + let array = vec![value; dimension_usize]; + + // Set the array value. + value = ConstrainedValue::Array(array); + } + + Ok(value) + } } /// diff --git a/compiler/src/expression/expression.rs b/compiler/src/expression/expression.rs index 5b842eeb95..c36980e346 100644 --- a/compiler/src/expression/expression.rs +++ b/compiler/src/expression/expression.rs @@ -246,6 +246,15 @@ impl> ConstrainedProgram { Expression::ArrayInline(array, span) => { self.enforce_array(cs, file_scope, function_scope, expected_type, array, span) } + Expression::ArrayInitializer(array_w_dimensions, span) => self.enforce_array_initializer( + cs, + file_scope, + function_scope, + expected_type, + array_w_dimensions.0, + array_w_dimensions.1, + span, + ), Expression::ArrayAccess(array_w_index, span) => self.enforce_array_access( cs, file_scope, From aa17355a72f074ea8d950ece72a54a6664cfc9a8 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 9 Nov 2020 14:27:59 -0800 Subject: [PATCH 127/139] fix refactored array initializer tests wip 1 --- ast/src/common/array_dimensions.rs | 9 +- ast/src/common/positive_number.rs | 22 +++- compiler/src/errors/expression.rs | 23 +++- compiler/src/errors/value/integer.rs | 14 ++- compiler/src/expression/array/array.rs | 114 ++++++++++++------ compiler/src/expression/expression.rs | 8 +- compiler/src/value/integer/integer.rs | 40 +++++- compiler/tests/array/mod.rs | 12 +- .../tests/array/output/registers_ones.out | 2 +- .../tests/array/output/registers_zeros.out | 2 +- 10 files changed, 184 insertions(+), 62 deletions(-) diff --git a/ast/src/common/array_dimensions.rs b/ast/src/common/array_dimensions.rs index 33fd2dcbc7..ea8dde1f0b 100644 --- a/ast/src/common/array_dimensions.rs +++ b/ast/src/common/array_dimensions.rs @@ -134,16 +134,13 @@ impl fmt::Display for ArrayDimensions { /// Compares two array dimensions and ignores `Span`s. impl PartialEq for ArrayDimensions { fn eq(&self, other: &Self) -> bool { - // If the number of dimensions differs return false + // If the number of dimensions differs return false. if self.0.len() != other.0.len() { return false; } - // Iteratively compare each dimension. - self.0 - .iter() - .zip(&other.0) - .all(|(first, second)| first.value.eq(&second.value)) + // Compare all dimensions and ignore `Span`s. + self.0.eq(&other.0) } } diff --git a/ast/src/common/positive_number.rs b/ast/src/common/positive_number.rs index 714e99ba6f..c0e9fb004f 100644 --- a/ast/src/common/positive_number.rs +++ b/ast/src/common/positive_number.rs @@ -19,10 +19,13 @@ use leo_grammar::values::PositiveNumber as GrammarPositiveNumber; use leo_input::values::PositiveNumber as InputPositiveNumber; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::{ + fmt, + hash::{Hash, Hasher}, +}; /// A number string guaranteed to be positive by the pest grammar. -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct PositiveNumber { pub value: String, pub span: Span, @@ -53,3 +56,18 @@ impl fmt::Display for PositiveNumber { write!(f, "{}", self.value) } } + +/// Compares two positive numbers and ignores `Span`s. +impl PartialEq for PositiveNumber { + fn eq(&self, other: &Self) -> bool { + self.value.eq(&other.value) + } +} + +impl Eq for PositiveNumber {} + +impl Hash for PositiveNumber { + fn hash(&self, state: &mut H) { + self.value.hash(state) + } +} diff --git a/compiler/src/errors/expression.rs b/compiler/src/errors/expression.rs index 33427f1e50..41a83cd6f2 100644 --- a/compiler/src/errors/expression.rs +++ b/compiler/src/errors/expression.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::{AddressError, BooleanError, FieldError, FunctionError, GroupError, IntegerError, ValueError}; -use leo_ast::{ArrayDimensions, Error as FormattedError, Identifier, Span}; +use leo_ast::{ArrayDimensions, Error as FormattedError, Identifier, PositiveNumber, Span}; use leo_core::LeoCorePackageError; use snarkos_errors::gadgets::SynthesisError; @@ -118,6 +118,15 @@ impl ExpressionError { Self::new_from_span(message, span) } + pub fn invalid_first_dimension(expected: &PositiveNumber, actual: &PositiveNumber) -> Self { + let message = format!( + "expected array dimension {}, found array dimension {}", + expected, actual + ); + + Self::new_from_span(message, actual.span.to_owned()) + } + pub fn invalid_index(actual: String, span: &Span) -> Self { let message = format!("index must resolve to an integer, found `{}`", actual); @@ -181,10 +190,10 @@ impl ExpressionError { Self::new_from_span(message, span) } - pub fn undefined_identifier(identifier: Identifier) -> Self { - let message = format!("cannot find value `{}` in this scope", identifier.name); + pub fn undefined_first_dimension(span: Span) -> Self { + let message = "the first dimension of the array must be a number".to_string(); - Self::new_from_span(message, identifier.span) + Self::new_from_span(message, span) } pub fn undefined_function(function: String, span: Span) -> Self { @@ -196,6 +205,12 @@ impl ExpressionError { Self::new_from_span(message, span) } + pub fn undefined_identifier(identifier: Identifier) -> Self { + let message = format!("cannot find value `{}` in this scope", identifier.name); + + Self::new_from_span(message, identifier.span) + } + pub fn undefined_member_access(circuit: String, member: String, span: Span) -> Self { let message = format!("Circuit `{}` has no member `{}`", circuit, member); diff --git a/compiler/src/errors/value/integer.rs b/compiler/src/errors/value/integer.rs index 23d9d847d9..5ff19eb492 100644 --- a/compiler/src/errors/value/integer.rs +++ b/compiler/src/errors/value/integer.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::{error::Error as FormattedError, Span}; +use leo_ast::{error::Error as FormattedError, IntegerType, Span, Type}; use leo_gadgets::errors::SignedIntegerError; use snarkos_errors::gadgets::SynthesisError; @@ -96,6 +96,18 @@ impl IntegerError { Self::new_from_span(message, span) } + pub fn invalid_integer_type(expected: &IntegerType, actual: &IntegerType, span: Span) -> Self { + let message = format!("expected integer type {} found integer type {}", expected, actual); + + Self::new_from_span(message, span) + } + + pub fn invalid_type(actual: &Type, span: Span) -> Self { + let message = format!("expected type {}, found type IntegerType", actual); + + Self::new_from_span(message, span) + } + pub fn missing_integer(expected: String, span: Span) -> Self { let message = format!("expected integer input `{}` not found", expected); diff --git a/compiler/src/expression/array/array.rs b/compiler/src/expression/array/array.rs index a7984cd5bd..aedb834e3c 100644 --- a/compiler/src/expression/array/array.rs +++ b/compiler/src/expression/array/array.rs @@ -113,57 +113,95 @@ impl> ConstrainedProgram { cs: &mut CS, file_scope: &str, function_scope: &str, - mut expected_type: Option, + expected_type: Option, element_expression: Expression, mut actual_dimensions: ArrayDimensions, span: Span, ) -> Result, ExpressionError> { - let mut expected_dimensions = None; + // Compare dimensions + // Case 1: expected == actual => enforce expression with array element type + // Case 2: expected first dimension == actual first dimension => enforce expression with updated array type + // Case 3: expected first dimension != actual first dimension => return mismatched dimensions error - // Check explicit array type dimension if given - if let Some(type_) = expected_type { - match type_ { - Type::Array(element_type, dimensions) => { - // Update the expected type to the element type. - expected_type = Some(*element_type); + if let Some(Type::Array(type_, mut expected_dimensions)) = expected_type { + if expected_dimensions.eq(&actual_dimensions) { + // Case 1 - enforce expression with array element type + let mut value = + self.enforce_expression(cs, file_scope, function_scope, Some(*type_), element_expression)?; - // Update the expected dimensions to the first dimension. - expected_dimensions = Some(dimensions); + // Allocate the array. + while let Some(dimension) = actual_dimensions.remove_first() { + // Parse the dimension into a `usize`. + let dimension_usize = parse_index(&dimension, &span)?; + + // Allocate the array dimension. + let array = vec![value; dimension_usize]; + + // Set the array value. + value = ConstrainedValue::Array(array); } - ref type_ => { - // Return an error if the expected type is not an array. - return Err(ExpressionError::unexpected_array(type_.to_string(), span)); + + Ok(value) + } else { + if expected_dimensions.first().eq(&actual_dimensions.first()) { + // Case 2 - enforce expression with updated array type. + let dimension = match expected_dimensions.remove_first() { + Some(number) => { + // Parse the array dimension into a `usize`. + parse_index(&number, &span)? + } + None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)), + }; + + // Update the expected type to a new array type with the first dimension removed. + let expected_expression_type = Some(inner_array_type(*type_, expected_dimensions)); + println!("expected type {:?}", expected_expression_type); + + // Get the value of the array element. + let element_value = self.enforce_expression( + cs, + file_scope, + function_scope, + expected_expression_type, + element_expression, + )?; + + // Allocate the array of values. + let array_values = vec![element_value; dimension]; + + // Create a new value with the expected dimension. + Ok(ConstrainedValue::Array(array_values)) + } else { + // Case 3 - return mismatched dimensions error. + Err(ExpressionError::invalid_first_dimension( + expected_dimensions + .first() + .ok_or(ExpressionError::undefined_first_dimension(span.clone()))?, + actual_dimensions + .first() + .ok_or(ExpressionError::undefined_first_dimension(span.clone()))?, + )) } } - } + } else { + // No explicit type given - evaluate array element expression. + let mut value = + self.enforce_expression(cs, file_scope, function_scope, expected_type, element_expression)?; - // Evaluate array element expression. - let mut value = self.enforce_expression(cs, file_scope, function_scope, expected_type, element_expression)?; + // Allocate the array. + while let Some(dimension) = actual_dimensions.remove_first() { + // Parse the dimension into a `usize`. + let dimension_usize = parse_index(&dimension, &span)?; - // Check array dimensions. - if let Some(dimensions) = expected_dimensions { - if dimensions.ne(&actual_dimensions) { - return Err(ExpressionError::invalid_dimensions( - &dimensions, - &actual_dimensions, - span, - )); + // Allocate the array dimension. + let array = vec![value; dimension_usize]; + + // Set the array value. + value = ConstrainedValue::Array(array); } + + Ok(value) } - - // Allocate the array. - while let Some(dimension) = actual_dimensions.remove_first() { - // Parse the dimension into a `usize`. - let dimension_usize = parse_index(&dimension, &span)?; - - // Allocate the array dimension. - let array = vec![value; dimension_usize]; - - // Set the array value. - value = ConstrainedValue::Array(array); - } - - Ok(value) } } diff --git a/compiler/src/expression/expression.rs b/compiler/src/expression/expression.rs index c36980e346..884194b0c0 100644 --- a/compiler/src/expression/expression.rs +++ b/compiler/src/expression/expression.rs @@ -44,6 +44,7 @@ impl> ConstrainedProgram { expected_type: Option, expression: Expression, ) -> Result, ExpressionError> { + println!("expr {}", expression); match expression { // Variables Expression::Identifier(unresolved_variable) => { @@ -56,8 +57,11 @@ impl> ConstrainedProgram { Expression::Field(field, span) => Ok(ConstrainedValue::Field(FieldType::constant(field, &span)?)), Expression::Group(group_element) => Ok(ConstrainedValue::Group(G::constant(*group_element)?)), Expression::Implicit(value, span) => Ok(enforce_number_implicit(expected_type, value, &span)?), - Expression::Integer(type_, integer, span) => Ok(ConstrainedValue::Integer(Integer::new_constant( - &type_, integer, &span, + Expression::Integer(type_, integer, span) => Ok(ConstrainedValue::Integer(Integer::new( + expected_type, + &type_, + integer, + &span, )?)), // Binary operations diff --git a/compiler/src/value/integer/integer.rs b/compiler/src/value/integer/integer.rs index 1476f3a3bc..13f8170a04 100644 --- a/compiler/src/value/integer/integer.rs +++ b/compiler/src/value/integer/integer.rs @@ -16,7 +16,7 @@ //! Conversion of integer declarations to constraints in Leo. use crate::{errors::IntegerError, IntegerTrait}; -use leo_ast::{InputValue, IntegerType, Span}; +use leo_ast::{InputValue, IntegerType, Span, Type}; use leo_gadgets::{ arithmetic::*, bits::comparator::{ComparatorGadget, EvaluateLtGadget}, @@ -67,6 +67,44 @@ impl fmt::Display for Integer { } impl Integer { + /// + /// Returns a new integer from an expression. + /// + /// Checks that the expression is equal to the expected type if given. + /// + pub fn new( + expected_type: Option, + actual_integer_type: &IntegerType, + string: String, + span: &Span, + ) -> Result { + // Check expected type if given. + if let Some(type_) = expected_type { + // Check expected type is an integer. + match type_ { + Type::IntegerType(expected_integer_type) => { + // Check expected integer type == actual integer type + if expected_integer_type.ne(actual_integer_type) { + return Err(IntegerError::invalid_integer_type( + &expected_integer_type, + actual_integer_type, + span.to_owned(), + )); + } + } + type_ => return Err(IntegerError::invalid_type(&type_, span.to_owned())), + } + } + + // Return a new constant integer. + Self::new_constant(actual_integer_type, string, span) + } + + /// + /// Returns a new integer value from an expression. + /// + /// The returned integer value is "constant" and is not allocated in the constraint system. + /// pub fn new_constant(integer_type: &IntegerType, string: String, span: &Span) -> Result { match integer_type { IntegerType::U8 => { diff --git a/compiler/tests/array/mod.rs b/compiler/tests/array/mod.rs index 6c8aa8988c..097ec73b8f 100644 --- a/compiler/tests/array/mod.rs +++ b/compiler/tests/array/mod.rs @@ -151,17 +151,17 @@ fn test_input_tuple_3x2_fail() { #[test] fn test_multi_fail_initializer() { let program_bytes = include_bytes!("multi_fail_initializer.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] fn test_multi_inline_fail() { let program_bytes = include_bytes!("multi_fail_inline.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -175,9 +175,9 @@ fn test_multi_initializer() { #[test] fn test_multi_initializer_fail() { let program_bytes = include_bytes!("multi_initializer_fail.leo"); - let err = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(err); + let _err = expect_compiler_error(program); } #[test] diff --git a/compiler/tests/array/output/registers_ones.out b/compiler/tests/array/output/registers_ones.out index c6a97c7fd7..05a8842ec3 100644 --- a/compiler/tests/array/output/registers_ones.out +++ b/compiler/tests/array/output/registers_ones.out @@ -1,2 +1,2 @@ [registers] -r: [u8; (3)] = [1, 1, 1]; +r: [u8; 3] = [1, 1, 1]; diff --git a/compiler/tests/array/output/registers_zeros.out b/compiler/tests/array/output/registers_zeros.out index e8c21bb46a..4fdb9f3359 100644 --- a/compiler/tests/array/output/registers_zeros.out +++ b/compiler/tests/array/output/registers_zeros.out @@ -1,2 +1,2 @@ [registers] -r: [u8; (3)] = [0, 0, 0]; +r: [u8; 3] = [0, 0, 0]; From 34b425ffe5a7b95a5093de0d66c84f3d776df195 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 9 Nov 2020 15:03:12 -0800 Subject: [PATCH 128/139] fix refactored array initializer tests wip 2 --- compiler/src/expression/array/array.rs | 37 +++++++++++++++++------ compiler/src/expression/expression.rs | 1 - compiler/tests/array/mod.rs | 41 +++++++++++++------------- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/compiler/src/expression/array/array.rs b/compiler/src/expression/array/array.rs index aedb834e3c..4c70279854 100644 --- a/compiler/src/expression/array/array.rs +++ b/compiler/src/expression/array/array.rs @@ -153,18 +153,37 @@ impl> ConstrainedProgram { None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)), }; + // Update the actual array dimensions. + let _first_dimension = actual_dimensions.remove_first(); + // Update the expected type to a new array type with the first dimension removed. let expected_expression_type = Some(inner_array_type(*type_, expected_dimensions)); - println!("expected type {:?}", expected_expression_type); - // Get the value of the array element. - let element_value = self.enforce_expression( - cs, - file_scope, - function_scope, - expected_expression_type, - element_expression, - )?; + // If the expression has more dimensions. + let element_value = match actual_dimensions.first() { + Some(_dimension) => { + // Get the value of the array element as an initializer. + self.enforce_array_initializer( + cs, + file_scope, + function_scope, + expected_expression_type, + element_expression, + actual_dimensions.clone(), + span.clone(), + )? + } + None => { + // Get the value of the array element as an expression. + self.enforce_expression( + cs, + file_scope, + function_scope, + expected_expression_type, + element_expression, + )? + } + }; // Allocate the array of values. let array_values = vec![element_value; dimension]; diff --git a/compiler/src/expression/expression.rs b/compiler/src/expression/expression.rs index 884194b0c0..186fb0e0b8 100644 --- a/compiler/src/expression/expression.rs +++ b/compiler/src/expression/expression.rs @@ -44,7 +44,6 @@ impl> ConstrainedProgram { expected_type: Option, expression: Expression, ) -> Result, ExpressionError> { - println!("expr {}", expression); match expression { // Variables Expression::Identifier(unresolved_variable) => { diff --git a/compiler/tests/array/mod.rs b/compiler/tests/array/mod.rs index 097ec73b8f..59610476e5 100644 --- a/compiler/tests/array/mod.rs +++ b/compiler/tests/array/mod.rs @@ -17,7 +17,6 @@ use crate::{ assert_satisfied, expect_compiler_error, - expect_type_inference_error, get_output, parse_program, parse_program_with_input, @@ -191,9 +190,9 @@ fn test_nested_3x2_value() { #[test] fn test_nested_3x2_value_fail() { let program_bytes = include_bytes!("nested_3x2_value_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -207,9 +206,9 @@ fn test_tuple_3x2_value() { #[test] fn test_tuple_3x2_value_fail() { let program_bytes = include_bytes!("tuple_3x2_value_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -251,9 +250,9 @@ fn test_type_nested_value_nested_3x2() { #[test] fn test_type_nested_value_nested_3x2_fail() { let program_bytes = include_bytes!("type_nested_value_nested_3x2_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -267,9 +266,9 @@ fn test_type_nested_value_nested_4x3x2() { #[test] fn test_type_nested_value_nested_4x3x2_fail() { let program_bytes = include_bytes!("type_nested_value_nested_4x3x2_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -283,9 +282,9 @@ fn test_type_nested_value_tuple_3x2() { #[test] fn test_type_nested_value_tuple_3x2_fail() { let program_bytes = include_bytes!("type_nested_value_tuple_3x2_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -299,9 +298,9 @@ fn test_type_nested_value_tuple_4x3x2() { #[test] fn test_type_nested_value_tuple_4x3x2_fail() { let program_bytes = include_bytes!("type_nested_value_tuple_4x3x2_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -315,9 +314,9 @@ fn test_type_tuple_value_nested_3x2() { #[test] fn test_type_tuple_value_nested_3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_nested_3x2_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -331,9 +330,9 @@ fn test_type_tuple_value_nested_4x3x2() { #[test] fn test_type_tuple_value_nested_4x3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_nested_4x3x2_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -347,9 +346,9 @@ fn test_type_tuple_value_tuple_3x2() { #[test] fn test_type_tuple_value_tuple_3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_tuple_3x2_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -363,9 +362,9 @@ fn test_type_tuple_value_tuple_4x3x2() { #[test] fn test_type_tuple_value_tuple_4x3x2_fail() { let program_bytes = include_bytes!("type_tuple_value_tuple_4x3x2_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); + let program = parse_program(program_bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } // Tests for nested multi-dimensional arrays as input to the program From d6686005a37e3ab6f08c68cce6c144ec09ca0600 Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 9 Nov 2020 19:26:34 -0800 Subject: [PATCH 129/139] fix refactored array initializer tests wip 3 --- ast/src/types/type_.rs | 123 +++++++++++++--------- compiler/src/statement/return_/return_.rs | 2 +- compiler/tests/function/mod.rs | 8 +- 3 files changed, 79 insertions(+), 54 deletions(-) diff --git a/ast/src/types/type_.rs b/ast/src/types/type_.rs index 51f37ef9a0..8525c6ba85 100644 --- a/ast/src/types/type_.rs +++ b/ast/src/types/type_.rs @@ -24,10 +24,13 @@ use leo_input::types::{ }; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::{ + fmt, + hash::{Hash, Hasher}, +}; /// Explicit type used for defining a variable or expression type -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub enum Type { // Data types Address, @@ -51,53 +54,6 @@ impl Type { pub fn is_circuit(&self) -> bool { matches!(self, Type::Circuit(_)) } - - pub fn match_array_types(&self, _other: &Type) -> bool { - unimplemented!("deprecated") - // // Check that both `self` and `other` are of type array - // let (type_1, dimensions_1) = match self { - // Type::Array(type_, dimensions) => (type_, dimensions), - // _ => return false, - // }; - // - // let (type_2, dimensions_2) = match other { - // Type::Array(type_, dimensions) => (type_, dimensions), - // _ => return false, - // }; - // - // // Expand multidimensional array syntax - // let (type_1_expanded, dimensions_1_expanded) = expand_array_type(type_1, dimensions_1); - // let (type_2_expanded, dimensions_2_expanded) = expand_array_type(type_2, dimensions_2); - // - // // Return true if expanded array types and dimensions match - // type_1_expanded.eq(&type_2_expanded) && dimensions_1_expanded.eq(&dimensions_2_expanded) - } - - pub fn outer_dimension(&self, _dimensions: &[usize]) -> Self { - unimplemented!("deprecated") - // let type_ = self.clone(); - // - // if dimensions.len() > 1 { - // let next = dimensions[1..].to_vec(); - // - // return Type::Array(Box::new(type_), next); - // } - // - // type_ - } - - pub fn inner_dimension(&self, _dimensions: &[usize]) -> Self { - unimplemented!("deprecated") - // let type_ = self.clone(); - // - // if dimensions.len() > 1 { - // let next = dimensions[..dimensions.len() - 1].to_vec(); - // - // return Type::Array(Box::new(type_), next); - // } - // - // type_ - } } /// pest ast -> Explicit Type for defining circuit members and function params @@ -209,3 +165,72 @@ impl fmt::Display for Type { } } } + +/// Compares two types while flattening array types. +impl PartialEq for Type { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Type::Address, Type::Address) => true, + (Type::Boolean, Type::Boolean) => true, + (Type::Field, Type::Field) => true, + (Type::Group, Type::Group) => true, + (Type::IntegerType(left), Type::IntegerType(right)) => left.eq(&right), + (Type::Circuit(left), Type::Circuit(right)) => left.eq(&right), + (Type::SelfType, Type::SelfType) => true, + (Type::Array(left_type, left_dim), Type::Array(right_type, right_dim)) => { + let mut left_dim_owned = left_dim.to_owned(); + let mut right_dim_owned = right_dim.to_owned(); + + println!("left_owned {}", left_dim_owned); + println!("right_owned {}", right_dim_owned); + + let left_first = left_dim_owned.remove_first(); + let right_first = right_dim_owned.remove_first(); + + if left_first.ne(&right_first) { + return false; + } + + let left_new_type = inner_array_type(*left_type.to_owned(), left_dim_owned); + let right_new_type = inner_array_type(*right_type.to_owned(), right_dim_owned); + println!("left_new {}", left_new_type); + println!("right_new {}", right_new_type); + + return left_new_type.eq(&right_new_type); + } + (Type::Tuple(left), Type::Tuple(right)) => left + .iter() + .zip(right) + .all(|(left_type, right_type)| left_type.eq(right_type)), + _ => false, + } + } +} + +impl Eq for Type {} + +impl Hash for Type { + fn hash(&self, state: &mut H) { + self.hash(state) + } +} + +/// +/// Returns the type of the inner array given an array element and array dimensions. +/// +/// If the array has no dimensions, then an inner array does not exist. Simply return the given +/// element type. +/// +/// If the array has dimensions, then an inner array exists. Create a new type for the +/// inner array. The element type of the new array should be the same as the old array. The +/// dimensions of the new array should be the old array dimensions with the first dimension removed. +/// +pub fn inner_array_type(element_type: Type, dimensions: ArrayDimensions) -> Type { + if dimensions.is_empty() { + // The array has one dimension. + element_type + } else { + // The array has multiple dimensions. + Type::Array(Box::new(element_type), dimensions) + } +} diff --git a/compiler/src/statement/return_/return_.rs b/compiler/src/statement/return_/return_.rs index ad8e6568c0..23a8542867 100644 --- a/compiler/src/statement/return_/return_.rs +++ b/compiler/src/statement/return_/return_.rs @@ -28,7 +28,7 @@ fn check_return_type(expected: Option, actual: Type, span: &Span) -> Resul match expected { Some(expected) => { if expected.ne(&actual) { - if (expected.is_self() && actual.is_circuit()) || expected.match_array_types(&actual) { + if (expected.is_self() && actual.is_circuit()) || expected.eq(&actual) { return Ok(()); } else { return Err(StatementError::arguments_type(&expected, &actual, span.to_owned())); diff --git a/compiler/tests/function/mod.rs b/compiler/tests/function/mod.rs index ccbb6be68d..0c62b34e76 100644 --- a/compiler/tests/function/mod.rs +++ b/compiler/tests/function/mod.rs @@ -146,9 +146,9 @@ fn test_array_input() { #[test] fn test_return_array_nested_fail() { let bytes = include_bytes!("return_array_nested_fail.leo"); - let error = parse_program(bytes).err().unwrap(); + let program = parse_program(bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] @@ -162,9 +162,9 @@ fn test_return_array_nested_pass() { #[test] fn test_return_array_tuple_fail() { let bytes = include_bytes!("return_array_tuple_fail.leo"); - let error = parse_program(bytes).err().unwrap(); + let program = parse_program(bytes).unwrap(); - expect_type_inference_error(error); + let _err = expect_compiler_error(program); } #[test] From 04f4e685edbf44a1ae820a2a90d8a9e20e6015ee Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 10 Nov 2020 13:22:18 -0800 Subject: [PATCH 130/139] array type refactor finished. all tests pass --- ast/src/common/array_dimensions.rs | 12 +- ast/src/types/type_.rs | 105 +++++++++--------- compiler/src/expression/array/array.rs | 4 +- compiler/src/statement/return_/return_.rs | 5 +- .../unstable/blake2s/outputs/valid_output.out | 2 +- 5 files changed, 67 insertions(+), 61 deletions(-) diff --git a/ast/src/common/array_dimensions.rs b/ast/src/common/array_dimensions.rs index ea8dde1f0b..1a3236f01b 100644 --- a/ast/src/common/array_dimensions.rs +++ b/ast/src/common/array_dimensions.rs @@ -81,7 +81,7 @@ impl ArrayDimensions { /// pub fn remove_first(&mut self) -> Option { // If there are no dimensions in the array, then return None. - if self.0.get(0).is_none() { + if self.0.first().is_none() { return None; } @@ -91,6 +91,16 @@ impl ArrayDimensions { // Return the first dimension. Some(removed) } + + /// + /// Attempts to remove the last dimension from the array. + /// + /// If the last dimension exists, then remove and return `Some(PositiveNumber)`. + /// If the last dimension does not exist, then return `None`. + /// + pub fn remove_last(&mut self) -> Option { + self.0.pop() + } } /// Create a new [`ArrayDimensions`] from a [`GrammarArrayDimensions`] in a Leo program file. diff --git a/ast/src/types/type_.rs b/ast/src/types/type_.rs index 8525c6ba85..b32b8534ad 100644 --- a/ast/src/types/type_.rs +++ b/ast/src/types/type_.rs @@ -24,13 +24,10 @@ use leo_input::types::{ }; use serde::{Deserialize, Serialize}; -use std::{ - fmt, - hash::{Hash, Hasher}, -}; +use std::fmt; /// Explicit type used for defining a variable or expression type -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Type { // Data types Address, @@ -47,13 +44,62 @@ pub enum Type { } impl Type { + /// + /// Returns `true` if the self `Type` is the `SelfType`. + /// pub fn is_self(&self) -> bool { matches!(self, Type::SelfType) } + /// + /// Returns `true` if the self `Type` is a `Circuit`. + /// pub fn is_circuit(&self) -> bool { matches!(self, Type::Circuit(_)) } + + /// + /// Returns `true` if the self `Type` is equal to the other `Type`. + /// + /// Flattens array syntax: `[[u8; 1]; 2] == [u8; (2, 1)] == true` + /// + pub fn eq_flat(&self, other: &Self) -> bool { + match (self, other) { + (Type::Address, Type::Address) => true, + (Type::Boolean, Type::Boolean) => true, + (Type::Field, Type::Field) => true, + (Type::Group, Type::Group) => true, + (Type::IntegerType(left), Type::IntegerType(right)) => left.eq(&right), + (Type::Circuit(left), Type::Circuit(right)) => left.eq(&right), + (Type::SelfType, Type::SelfType) => true, + (Type::Array(left_type, left_dim), Type::Array(right_type, right_dim)) => { + // Convert array dimensions to owned. + let mut left_dim_owned = left_dim.to_owned(); + let mut right_dim_owned = right_dim.to_owned(); + + // Remove the first element from both dimensions. + let left_first = left_dim_owned.remove_first(); + let right_first = right_dim_owned.remove_first(); + + // Compare the first dimensions. + if left_first.ne(&right_first) { + return false; + } + + // Create a new array type from the remaining array dimensions. + let left_new_type = inner_array_type(*left_type.to_owned(), left_dim_owned); + let right_new_type = inner_array_type(*right_type.to_owned(), right_dim_owned); + + // Call eq_flat() on the new left and right types. + return left_new_type.eq_flat(&right_new_type); + } + (Type::Tuple(left), Type::Tuple(right)) => left + .iter() + .zip(right) + .all(|(left_type, right_type)| left_type.eq_flat(right_type)), + _ => false, + } + } } /// pest ast -> Explicit Type for defining circuit members and function params @@ -166,55 +212,6 @@ impl fmt::Display for Type { } } -/// Compares two types while flattening array types. -impl PartialEq for Type { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (Type::Address, Type::Address) => true, - (Type::Boolean, Type::Boolean) => true, - (Type::Field, Type::Field) => true, - (Type::Group, Type::Group) => true, - (Type::IntegerType(left), Type::IntegerType(right)) => left.eq(&right), - (Type::Circuit(left), Type::Circuit(right)) => left.eq(&right), - (Type::SelfType, Type::SelfType) => true, - (Type::Array(left_type, left_dim), Type::Array(right_type, right_dim)) => { - let mut left_dim_owned = left_dim.to_owned(); - let mut right_dim_owned = right_dim.to_owned(); - - println!("left_owned {}", left_dim_owned); - println!("right_owned {}", right_dim_owned); - - let left_first = left_dim_owned.remove_first(); - let right_first = right_dim_owned.remove_first(); - - if left_first.ne(&right_first) { - return false; - } - - let left_new_type = inner_array_type(*left_type.to_owned(), left_dim_owned); - let right_new_type = inner_array_type(*right_type.to_owned(), right_dim_owned); - println!("left_new {}", left_new_type); - println!("right_new {}", right_new_type); - - return left_new_type.eq(&right_new_type); - } - (Type::Tuple(left), Type::Tuple(right)) => left - .iter() - .zip(right) - .all(|(left_type, right_type)| left_type.eq(right_type)), - _ => false, - } - } -} - -impl Eq for Type {} - -impl Hash for Type { - fn hash(&self, state: &mut H) { - self.hash(state) - } -} - /// /// Returns the type of the inner array given an array element and array dimensions. /// diff --git a/compiler/src/expression/array/array.rs b/compiler/src/expression/array/array.rs index 4c70279854..ed36684c88 100644 --- a/compiler/src/expression/array/array.rs +++ b/compiler/src/expression/array/array.rs @@ -130,7 +130,7 @@ impl> ConstrainedProgram { self.enforce_expression(cs, file_scope, function_scope, Some(*type_), element_expression)?; // Allocate the array. - while let Some(dimension) = actual_dimensions.remove_first() { + while let Some(dimension) = actual_dimensions.remove_last() { // Parse the dimension into a `usize`. let dimension_usize = parse_index(&dimension, &span)?; @@ -208,7 +208,7 @@ impl> ConstrainedProgram { self.enforce_expression(cs, file_scope, function_scope, expected_type, element_expression)?; // Allocate the array. - while let Some(dimension) = actual_dimensions.remove_first() { + while let Some(dimension) = actual_dimensions.remove_last() { // Parse the dimension into a `usize`. let dimension_usize = parse_index(&dimension, &span)?; diff --git a/compiler/src/statement/return_/return_.rs b/compiler/src/statement/return_/return_.rs index 23a8542867..f70b69ca79 100644 --- a/compiler/src/statement/return_/return_.rs +++ b/compiler/src/statement/return_/return_.rs @@ -28,7 +28,7 @@ fn check_return_type(expected: Option, actual: Type, span: &Span) -> Resul match expected { Some(expected) => { if expected.ne(&actual) { - if (expected.is_self() && actual.is_circuit()) || expected.eq(&actual) { + if (expected.is_self() && actual.is_circuit()) || expected.eq_flat(&actual) { return Ok(()); } else { return Err(StatementError::arguments_type(&expected, &actual, span.to_owned())); @@ -50,10 +50,9 @@ impl> ConstrainedProgram { return_type: Option, span: &Span, ) -> Result, StatementError> { - // Make sure we return the correct number of values - let result = self.enforce_operand(cs, file_scope, function_scope, return_type.clone(), expression, span)?; + // Make sure we return the correct type. check_return_type(return_type, result.to_type(&span)?, span)?; Ok(result) diff --git a/compiler/tests/core/packages/unstable/blake2s/outputs/valid_output.out b/compiler/tests/core/packages/unstable/blake2s/outputs/valid_output.out index 8a8a447558..f8f60f3e4e 100644 --- a/compiler/tests/core/packages/unstable/blake2s/outputs/valid_output.out +++ b/compiler/tests/core/packages/unstable/blake2s/outputs/valid_output.out @@ -1,2 +1,2 @@ [registers] -r0: [u8; (32)] = [174, 9, 219, 124, 213, 79, 66, 180, 144, 239, 9, 182, 188, 84, 26, 246, 136, 228, 149, 155, 184, 197, 63, 53, 154, 111, 86, 227, 138, 180, 84, 163]; +r0: [u8; 32] = [174, 9, 219, 124, 213, 79, 66, 180, 144, 239, 9, 182, 188, 84, 26, 246, 136, 228, 149, 155, 184, 197, 63, 53, 154, 111, 86, 227, 138, 180, 84, 163]; From 9c9f29c4969d5a55c436262c9a29c1efaaac70f8 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 10 Nov 2020 13:27:43 -0800 Subject: [PATCH 131/139] rename struct alias Ast -> Grammar in ast module 1 --- ast/src/circuits/circuit.rs | 6 +++--- ast/src/circuits/circuit_member.rs | 22 +++++++++++----------- ast/src/common/declare.rs | 10 +++++----- ast/src/common/identifier.rs | 18 +++++++++--------- ast/src/common/range_or_expression.rs | 12 +++++++----- ast/src/common/span.rs | 6 +++--- ast/src/common/spread_or_expression.rs | 6 +++--- ast/src/common/variable_name.rs | 6 +++--- ast/src/common/variables.rs | 6 +++--- ast/src/imports/import_symbol.rs | 6 +++--- 10 files changed, 50 insertions(+), 48 deletions(-) diff --git a/ast/src/circuits/circuit.rs b/ast/src/circuits/circuit.rs index c6c27c846a..010f408c78 100644 --- a/ast/src/circuits/circuit.rs +++ b/ast/src/circuits/circuit.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{CircuitMember, Identifier}; -use leo_grammar::circuits::Circuit as AstCircuit; +use leo_grammar::circuits::Circuit as GrammarCircuit; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,8 +26,8 @@ pub struct Circuit { pub members: Vec, } -impl<'ast> From> for Circuit { - fn from(circuit: AstCircuit<'ast>) -> Self { +impl<'ast> From> for Circuit { + fn from(circuit: GrammarCircuit<'ast>) -> Self { let circuit_name = Identifier::from(circuit.identifier); let members = circuit.members.into_iter().map(CircuitMember::from).collect(); diff --git a/ast/src/circuits/circuit_member.rs b/ast/src/circuits/circuit_member.rs index b738901ad3..f8e885dd9d 100644 --- a/ast/src/circuits/circuit_member.rs +++ b/ast/src/circuits/circuit_member.rs @@ -16,9 +16,9 @@ use crate::{Function, Identifier, Type}; use leo_grammar::circuits::{ - CircuitFunction as AstCircuitFunction, - CircuitMember as AstCircuitMember, - CircuitVariableDefinition as AstCircuitVariableDefinition, + CircuitFunction as GrammarCircuitFunction, + CircuitMember as GrammarCircuitMember, + CircuitVariableDefinition as GrammarCircuitVariableDefinition, }; use serde::{Deserialize, Serialize}; @@ -32,8 +32,8 @@ pub enum CircuitMember { CircuitFunction(bool, Function), } -impl<'ast> From> for CircuitMember { - fn from(circuit_value: AstCircuitVariableDefinition<'ast>) -> Self { +impl<'ast> From> for CircuitMember { + fn from(circuit_value: GrammarCircuitVariableDefinition<'ast>) -> Self { CircuitMember::CircuitVariable( circuit_value.mutable.is_some(), Identifier::from(circuit_value.identifier), @@ -42,8 +42,8 @@ impl<'ast> From> for CircuitMember { } } -impl<'ast> From> for CircuitMember { - fn from(circuit_function: AstCircuitFunction<'ast>) -> Self { +impl<'ast> From> for CircuitMember { + fn from(circuit_function: GrammarCircuitFunction<'ast>) -> Self { CircuitMember::CircuitFunction( circuit_function._static.is_some(), Function::from(circuit_function.function), @@ -51,11 +51,11 @@ impl<'ast> From> for CircuitMember { } } -impl<'ast> From> for CircuitMember { - fn from(object: AstCircuitMember<'ast>) -> Self { +impl<'ast> From> for CircuitMember { + fn from(object: GrammarCircuitMember<'ast>) -> Self { match object { - AstCircuitMember::CircuitVariableDefinition(circuit_value) => CircuitMember::from(circuit_value), - AstCircuitMember::CircuitFunction(circuit_function) => CircuitMember::from(circuit_function), + GrammarCircuitMember::CircuitVariableDefinition(circuit_value) => CircuitMember::from(circuit_value), + GrammarCircuitMember::CircuitFunction(circuit_function) => CircuitMember::from(circuit_function), } } } diff --git a/ast/src/common/declare.rs b/ast/src/common/declare.rs index 12ceceeebc..399604831a 100644 --- a/ast/src/common/declare.rs +++ b/ast/src/common/declare.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_grammar::common::Declare as AstDeclare; +use leo_grammar::common::Declare as GrammarDeclare; use serde::{Deserialize, Serialize}; use std::fmt; @@ -25,11 +25,11 @@ pub enum Declare { Let, } -impl<'ast> From for Declare { - fn from(declare: AstDeclare) -> Self { +impl<'ast> From for Declare { + fn from(declare: GrammarDeclare) -> Self { match declare { - AstDeclare::Const(_) => Declare::Const, - AstDeclare::Let(_) => Declare::Let, + GrammarDeclare::Const(_) => Declare::Const, + GrammarDeclare::Let(_) => Declare::Let, } } } diff --git a/ast/src/common/identifier.rs b/ast/src/common/identifier.rs index 97ce361644..e4d20dc48d 100644 --- a/ast/src/common/identifier.rs +++ b/ast/src/common/identifier.rs @@ -17,13 +17,13 @@ use crate::Span; use leo_grammar::{ annotations::AnnotationArgument, - common::{Identifier as AstIdentifier, KeywordOrIdentifier, SelfKeyword, SelfKeywordOrIdentifier}, + common::{Identifier as GrammarIdentifier, KeywordOrIdentifier, SelfKeyword, SelfKeywordOrIdentifier}, expressions::CircuitName, functions::InputKeyword, - imports::PackageName as AstPackageName, + imports::PackageName as GrammarPackageName, types::SelfType, }; -use leo_input::common::Identifier as InputAstIdentifier; +use leo_input::common::Identifier as InputIdentifier; use serde::{ de::{self, Visitor}, @@ -73,8 +73,8 @@ impl Identifier { } } -impl<'ast> From> for Identifier { - fn from(identifier: AstIdentifier<'ast>) -> Self { +impl<'ast> From> for Identifier { + fn from(identifier: GrammarIdentifier<'ast>) -> Self { Self { name: identifier.value, span: Span::from(identifier.span), @@ -82,8 +82,8 @@ impl<'ast> From> for Identifier { } } -impl<'ast> From> for Identifier { - fn from(name: AstPackageName<'ast>) -> Self { +impl<'ast> From> for Identifier { + fn from(name: GrammarPackageName<'ast>) -> Self { Self { name: name.value, span: Span::from(name.span), @@ -91,8 +91,8 @@ impl<'ast> From> for Identifier { } } -impl<'ast> From> for Identifier { - fn from(identifier: InputAstIdentifier<'ast>) -> Self { +impl<'ast> From> for Identifier { + fn from(identifier: InputIdentifier<'ast>) -> Self { Self { name: identifier.value, span: Span::from(identifier.span), diff --git a/ast/src/common/range_or_expression.rs b/ast/src/common/range_or_expression.rs index 0406497ff6..23f04e0422 100644 --- a/ast/src/common/range_or_expression.rs +++ b/ast/src/common/range_or_expression.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Expression; -use leo_grammar::common::RangeOrExpression as AstRangeOrExpression; +use leo_grammar::common::RangeOrExpression as GrammarRangeOrExpression; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,13 +27,15 @@ pub enum RangeOrExpression { Expression(Expression), } -impl<'ast> From> for RangeOrExpression { - fn from(range_or_expression: AstRangeOrExpression<'ast>) -> Self { +impl<'ast> From> for RangeOrExpression { + fn from(range_or_expression: GrammarRangeOrExpression<'ast>) -> Self { match range_or_expression { - AstRangeOrExpression::Range(range) => { + GrammarRangeOrExpression::Range(range) => { RangeOrExpression::Range(range.from.map(Expression::from), range.to.map(Expression::from)) } - AstRangeOrExpression::Expression(expression) => RangeOrExpression::Expression(Expression::from(expression)), + GrammarRangeOrExpression::Expression(expression) => { + RangeOrExpression::Expression(Expression::from(expression)) + } } } } diff --git a/ast/src/common/span.rs b/ast/src/common/span.rs index 4b68a98ce1..db4bc3f436 100644 --- a/ast/src/common/span.rs +++ b/ast/src/common/span.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use pest::Span as AstSpan; +use pest::Span as GrammarSpan; use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; @@ -46,8 +46,8 @@ impl Hash for Span { } } -impl<'ast> From> for Span { - fn from(span: AstSpan<'ast>) -> Self { +impl<'ast> From> for Span { + fn from(span: GrammarSpan<'ast>) -> Self { let mut text = " ".to_string(); let line_col = span.start_pos().line_col(); let end = span.end_pos().line_col().1; diff --git a/ast/src/common/spread_or_expression.rs b/ast/src/common/spread_or_expression.rs index d6e41861c9..ccac55ce3d 100644 --- a/ast/src/common/spread_or_expression.rs +++ b/ast/src/common/spread_or_expression.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Expression; -use leo_grammar::{common::SpreadOrExpression as AstSpreadOrExpression, expressions::Expression as AstExpression}; +use leo_grammar::{common::SpreadOrExpression as AstSpreadOrExpression, expressions::Expression as GrammarExpression}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -38,8 +38,8 @@ impl<'ast> From> for SpreadOrExpression { } } -impl<'ast> From> for SpreadOrExpression { - fn from(expression: AstExpression<'ast>) -> Self { +impl<'ast> From> for SpreadOrExpression { + fn from(expression: GrammarExpression<'ast>) -> Self { SpreadOrExpression::Expression(Expression::from(expression)) } } diff --git a/ast/src/common/variable_name.rs b/ast/src/common/variable_name.rs index 2141207d0f..134c4748d1 100644 --- a/ast/src/common/variable_name.rs +++ b/ast/src/common/variable_name.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::common::{Identifier, Span}; -use leo_grammar::common::VariableName as AstVariableName; +use leo_grammar::common::VariableName as GrammarVariableName; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,8 +27,8 @@ pub struct VariableName { pub span: Span, } -impl<'ast> From> for VariableName { - fn from(name: AstVariableName<'ast>) -> Self { +impl<'ast> From> for VariableName { + fn from(name: GrammarVariableName<'ast>) -> Self { Self { mutable: name.mutable.is_some(), identifier: Identifier::from(name.identifier), diff --git a/ast/src/common/variables.rs b/ast/src/common/variables.rs index 75c43c8a97..49999efee2 100644 --- a/ast/src/common/variables.rs +++ b/ast/src/common/variables.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Type, VariableName}; -use leo_grammar::common::Variables as AstVariables; +use leo_grammar::common::Variables as GrammarVariables; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,8 +27,8 @@ pub struct Variables { pub type_: Option, } -impl<'ast> From> for Variables { - fn from(variables: AstVariables<'ast>) -> Self { +impl<'ast> From> for Variables { + fn from(variables: GrammarVariables<'ast>) -> Self { let names = variables.names.into_iter().map(VariableName::from).collect::>(); let type_ = variables.type_.map(Type::from); diff --git a/ast/src/imports/import_symbol.rs b/ast/src/imports/import_symbol.rs index bdd67843fc..5ba0636c21 100644 --- a/ast/src/imports/import_symbol.rs +++ b/ast/src/imports/import_symbol.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Identifier, Span}; -use leo_grammar::imports::ImportSymbol as AstImportSymbol; +use leo_grammar::imports::ImportSymbol as GrammarImportSymbol; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,8 +27,8 @@ pub struct ImportSymbol { pub span: Span, } -impl<'ast> From> for ImportSymbol { - fn from(symbol: AstImportSymbol<'ast>) -> Self { +impl<'ast> From> for ImportSymbol { + fn from(symbol: GrammarImportSymbol<'ast>) -> Self { ImportSymbol { symbol: Identifier::from(symbol.value), alias: symbol.alias.map(Identifier::from), From cc8337853c94a548a92ce8073d93cc6eaf2e070d Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 10 Nov 2020 13:32:25 -0800 Subject: [PATCH 132/139] rename struct alias Ast -> Grammar in ast module 2 --- ast/src/common/spread_or_expression.rs | 15 ++++-- ast/src/console/console_function.rs | 38 +++++++------- ast/src/console/console_function_call.rs | 6 +-- ast/src/console/formatted_container.rs | 6 +-- ast/src/console/formatted_parameter.rs | 6 +-- ast/src/console/formatted_string.rs | 6 +-- ast/src/expression.rs | 52 +++++++++---------- ast/src/functions/function.rs | 6 +-- ast/src/functions/input/function_input.rs | 6 +-- ast/src/functions/input/input_variable.rs | 10 ++-- ast/src/functions/test_function.rs | 6 +-- ast/src/groups/group_coordinate.rs | 38 +++++++------- ast/src/groups/group_value.rs | 18 +++---- ast/src/imports/import.rs | 6 +-- ast/src/imports/package.rs | 6 +-- ast/src/imports/package_access.rs | 14 ++--- ast/src/input/parameters/parameter.rs | 6 +-- .../conditional_nested_or_end_statement.rs | 10 ++-- ast/src/statements/conditional_statement.rs | 6 +-- ast/src/statements/statement.rs | 6 +-- 20 files changed, 136 insertions(+), 131 deletions(-) diff --git a/ast/src/common/spread_or_expression.rs b/ast/src/common/spread_or_expression.rs index ccac55ce3d..1353be71bb 100644 --- a/ast/src/common/spread_or_expression.rs +++ b/ast/src/common/spread_or_expression.rs @@ -15,7 +15,10 @@ // along with the Leo library. If not, see . use crate::Expression; -use leo_grammar::{common::SpreadOrExpression as AstSpreadOrExpression, expressions::Expression as GrammarExpression}; +use leo_grammar::{ + common::SpreadOrExpression as GrammarSpreadOrExpression, + expressions::Expression as GrammarExpression, +}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,11 +30,13 @@ pub enum SpreadOrExpression { Expression(Expression), } -impl<'ast> From> for SpreadOrExpression { - fn from(s_or_e: AstSpreadOrExpression<'ast>) -> Self { +impl<'ast> From> for SpreadOrExpression { + fn from(s_or_e: GrammarSpreadOrExpression<'ast>) -> Self { match s_or_e { - AstSpreadOrExpression::Spread(spread) => SpreadOrExpression::Spread(Expression::from(spread.expression)), - AstSpreadOrExpression::Expression(expression) => { + GrammarSpreadOrExpression::Spread(spread) => { + SpreadOrExpression::Spread(Expression::from(spread.expression)) + } + GrammarSpreadOrExpression::Expression(expression) => { SpreadOrExpression::Expression(Expression::from(expression)) } } diff --git a/ast/src/console/console_function.rs b/ast/src/console/console_function.rs index 781acefecd..c9e3356c31 100644 --- a/ast/src/console/console_function.rs +++ b/ast/src/console/console_function.rs @@ -16,11 +16,11 @@ use crate::{Expression, FormattedString}; use leo_grammar::console::{ - ConsoleAssert as AstConsoleAssert, - ConsoleDebug as AstConsoleDebug, - ConsoleError as AstConsoleError, - ConsoleFunction as AstConsoleFunction, - ConsoleLog as AstConsoleLog, + ConsoleAssert as GrammarConsoleAssert, + ConsoleDebug as GrammarConsoleDebug, + ConsoleError as GrammarConsoleError, + ConsoleFunction as GrammarConsoleFunction, + ConsoleLog as GrammarConsoleLog, }; use serde::{Deserialize, Serialize}; @@ -34,37 +34,37 @@ pub enum ConsoleFunction { Log(FormattedString), } -impl<'ast> From> for ConsoleFunction { - fn from(console_function: AstConsoleFunction<'ast>) -> Self { +impl<'ast> From> for ConsoleFunction { + fn from(console_function: GrammarConsoleFunction<'ast>) -> Self { match console_function { - AstConsoleFunction::Assert(assert) => ConsoleFunction::from(assert), - AstConsoleFunction::Debug(debug) => ConsoleFunction::from(debug), - AstConsoleFunction::Error(error) => ConsoleFunction::from(error), - AstConsoleFunction::Log(log) => ConsoleFunction::from(log), + GrammarConsoleFunction::Assert(assert) => ConsoleFunction::from(assert), + GrammarConsoleFunction::Debug(debug) => ConsoleFunction::from(debug), + GrammarConsoleFunction::Error(error) => ConsoleFunction::from(error), + GrammarConsoleFunction::Log(log) => ConsoleFunction::from(log), } } } -impl<'ast> From> for ConsoleFunction { - fn from(assert: AstConsoleAssert<'ast>) -> Self { +impl<'ast> From> for ConsoleFunction { + fn from(assert: GrammarConsoleAssert<'ast>) -> Self { ConsoleFunction::Assert(Expression::from(assert.expression)) } } -impl<'ast> From> for ConsoleFunction { - fn from(debug: AstConsoleDebug<'ast>) -> Self { +impl<'ast> From> for ConsoleFunction { + fn from(debug: GrammarConsoleDebug<'ast>) -> Self { ConsoleFunction::Debug(FormattedString::from(debug.string)) } } -impl<'ast> From> for ConsoleFunction { - fn from(error: AstConsoleError<'ast>) -> Self { +impl<'ast> From> for ConsoleFunction { + fn from(error: GrammarConsoleError<'ast>) -> Self { ConsoleFunction::Error(FormattedString::from(error.string)) } } -impl<'ast> From> for ConsoleFunction { - fn from(log: AstConsoleLog<'ast>) -> Self { +impl<'ast> From> for ConsoleFunction { + fn from(log: GrammarConsoleLog<'ast>) -> Self { ConsoleFunction::Log(FormattedString::from(log.string)) } } diff --git a/ast/src/console/console_function_call.rs b/ast/src/console/console_function_call.rs index e2fa9293f2..7ec71b9ba6 100644 --- a/ast/src/console/console_function_call.rs +++ b/ast/src/console/console_function_call.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ConsoleFunction, Span}; -use leo_grammar::console::ConsoleFunctionCall as AstConsoleFunctionCall; +use leo_grammar::console::ConsoleFunctionCall as GrammarConsoleFunctionCall; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,8 +26,8 @@ pub struct ConsoleFunctionCall { pub span: Span, } -impl<'ast> From> for ConsoleFunctionCall { - fn from(console: AstConsoleFunctionCall<'ast>) -> Self { +impl<'ast> From> for ConsoleFunctionCall { + fn from(console: GrammarConsoleFunctionCall<'ast>) -> Self { ConsoleFunctionCall { function: ConsoleFunction::from(console.function), span: Span::from(console.span), diff --git a/ast/src/console/formatted_container.rs b/ast/src/console/formatted_container.rs index 0647c5af56..0781bf3280 100644 --- a/ast/src/console/formatted_container.rs +++ b/ast/src/console/formatted_container.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Span; -use leo_grammar::console::FormattedContainer as AstFormattedContainer; +use leo_grammar::console::FormattedContainer as GrammarFormattedContainer; use serde::{Deserialize, Serialize}; use std::fmt; @@ -25,8 +25,8 @@ pub struct FormattedContainer { pub span: Span, } -impl<'ast> From> for FormattedContainer { - fn from(container: AstFormattedContainer<'ast>) -> Self { +impl<'ast> From> for FormattedContainer { + fn from(container: GrammarFormattedContainer<'ast>) -> Self { Self { span: Span::from(container.span), } diff --git a/ast/src/console/formatted_parameter.rs b/ast/src/console/formatted_parameter.rs index c61c0122e2..c95f0e9bd6 100644 --- a/ast/src/console/formatted_parameter.rs +++ b/ast/src/console/formatted_parameter.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Expression, Span}; -use leo_grammar::console::FormattedParameter as AstFormattedParameter; +use leo_grammar::console::FormattedParameter as GrammarFormattedParameter; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,8 +26,8 @@ pub struct FormattedParameter { pub span: Span, } -impl<'ast> From> for FormattedParameter { - fn from(parameter: AstFormattedParameter<'ast>) -> Self { +impl<'ast> From> for FormattedParameter { + fn from(parameter: GrammarFormattedParameter<'ast>) -> Self { Self { expression: Expression::from(parameter.expression), span: Span::from(parameter.span), diff --git a/ast/src/console/formatted_string.rs b/ast/src/console/formatted_string.rs index a880220465..2ef547219f 100644 --- a/ast/src/console/formatted_string.rs +++ b/ast/src/console/formatted_string.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{FormattedContainer, FormattedParameter, Span}; -use leo_grammar::console::FormattedString as AstFormattedString; +use leo_grammar::console::FormattedString as GrammarFormattedString; use serde::{Deserialize, Serialize}; use std::fmt; @@ -28,8 +28,8 @@ pub struct FormattedString { pub span: Span, } -impl<'ast> From> for FormattedString { - fn from(formatted: AstFormattedString<'ast>) -> Self { +impl<'ast> From> for FormattedString { + fn from(formatted: GrammarFormattedString<'ast>) -> Self { let string = formatted.string; let span = Span::from(formatted.span); let containers = formatted.containers.into_iter().map(FormattedContainer::from).collect(); diff --git a/ast/src/expression.rs b/ast/src/expression.rs index 63be1ec6b2..7fedd4b1d2 100644 --- a/ast/src/expression.rs +++ b/ast/src/expression.rs @@ -27,13 +27,13 @@ use crate::{ }; use leo_grammar::{ access::{Access, AssigneeAccess}, - common::{Assignee, Identifier as AstIdentifier}, + common::{Assignee, Identifier as GrammarIdentifier}, expressions::{ ArrayInitializerExpression, ArrayInlineExpression, BinaryExpression, CircuitInlineExpression, - Expression as AstExpression, + Expression as GrammarExpression, PostfixExpression, TernaryExpression, UnaryExpression, @@ -43,9 +43,9 @@ use leo_grammar::{ AddressValue, BooleanValue, FieldValue, - GroupValue as AstGroupValue, + GroupValue as GrammarGroupValue, IntegerValue, - NumberValue as AstNumber, + NumberValue as GrammarNumber, Value, }, }; @@ -327,19 +327,19 @@ impl<'ast> From> for Expression { } } -impl<'ast> From> for Expression { - fn from(expression: AstExpression<'ast>) -> Self { +impl<'ast> From> for Expression { + fn from(expression: GrammarExpression<'ast>) -> Self { match expression { - AstExpression::Value(value) => Expression::from(value), - AstExpression::Identifier(variable) => Expression::from(variable), - AstExpression::Unary(expression) => Expression::from(*expression), - AstExpression::Binary(expression) => Expression::from(*expression), - AstExpression::Ternary(expression) => Expression::from(*expression), - AstExpression::ArrayInline(expression) => Expression::from(expression), - AstExpression::ArrayInitializer(expression) => Expression::from(*expression), - AstExpression::Tuple(expression) => Expression::from(expression), - AstExpression::CircuitInline(expression) => Expression::from(expression), - AstExpression::Postfix(expression) => Expression::from(expression), + GrammarExpression::Value(value) => Expression::from(value), + GrammarExpression::Identifier(variable) => Expression::from(variable), + GrammarExpression::Unary(expression) => Expression::from(*expression), + GrammarExpression::Binary(expression) => Expression::from(*expression), + GrammarExpression::Ternary(expression) => Expression::from(*expression), + GrammarExpression::ArrayInline(expression) => Expression::from(expression), + GrammarExpression::ArrayInitializer(expression) => Expression::from(*expression), + GrammarExpression::Tuple(expression) => Expression::from(expression), + GrammarExpression::CircuitInline(expression) => Expression::from(expression), + GrammarExpression::Postfix(expression) => Expression::from(expression), } } } @@ -526,17 +526,17 @@ impl<'ast> From> for Expression { } } -impl<'ast> From> for Expression { - fn from(ast_group: AstGroupValue<'ast>) -> Self { +impl<'ast> From> for Expression { + fn from(ast_group: GrammarGroupValue<'ast>) -> Self { Expression::Group(Box::new(GroupValue::from(ast_group))) } } -impl<'ast> From> for Expression { - fn from(number: AstNumber<'ast>) -> Self { +impl<'ast> From> for Expression { + fn from(number: GrammarNumber<'ast>) -> Self { let (value, span) = match number { - AstNumber::Positive(number) => (number.value, number.span), - AstNumber::Negative(number) => (number.value, number.span), + GrammarNumber::Positive(number) => (number.value, number.span), + GrammarNumber::Negative(number) => (number.value, number.span), }; Expression::Implicit(value, Span::from(span)) @@ -550,8 +550,8 @@ impl<'ast> From> for Expression { IntegerValue::Signed(integer) => { let type_ = IntegerType::from(integer.type_); let number = match integer.number { - AstNumber::Negative(number) => number.value, - AstNumber::Positive(number) => number.value, + GrammarNumber::Negative(number) => number.value, + GrammarNumber::Positive(number) => number.value, }; (type_, number) @@ -574,8 +574,8 @@ impl<'ast> From> for Expression { } } -impl<'ast> From> for Expression { - fn from(identifier: AstIdentifier<'ast>) -> Self { +impl<'ast> From> for Expression { + fn from(identifier: GrammarIdentifier<'ast>) -> Self { Expression::Identifier(Identifier::from(identifier)) } } diff --git a/ast/src/functions/function.rs b/ast/src/functions/function.rs index 15cfcba9fc..be15d5131e 100644 --- a/ast/src/functions/function.rs +++ b/ast/src/functions/function.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{FunctionInput, Identifier, Span, Statement, Type}; -use leo_grammar::functions::Function as AstFunction; +use leo_grammar::functions::Function as GrammarFunction; use serde::{Deserialize, Serialize}; use std::fmt; @@ -37,8 +37,8 @@ impl PartialEq for Function { impl Eq for Function {} -impl<'ast> From> for Function { - fn from(function: AstFunction<'ast>) -> Self { +impl<'ast> From> for Function { + fn from(function: GrammarFunction<'ast>) -> Self { let function_name = Identifier::from(function.identifier); let parameters = function.parameters.into_iter().map(FunctionInput::from).collect(); diff --git a/ast/src/functions/input/function_input.rs b/ast/src/functions/input/function_input.rs index 03d8587d97..07dbafdf27 100644 --- a/ast/src/functions/input/function_input.rs +++ b/ast/src/functions/input/function_input.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Identifier, Span, Type}; -use leo_grammar::functions::FunctionInput as AstFunctionInput; +use leo_grammar::functions::FunctionInput as GrammarFunctionInput; use serde::{Deserialize, Serialize}; use std::fmt; @@ -28,8 +28,8 @@ pub struct FunctionInputVariable { pub span: Span, } -impl<'ast> From> for FunctionInputVariable { - fn from(parameter: AstFunctionInput<'ast>) -> Self { +impl<'ast> From> for FunctionInputVariable { + fn from(parameter: GrammarFunctionInput<'ast>) -> Self { FunctionInputVariable { identifier: Identifier::from(parameter.identifier), mutable: parameter.mutable.is_some(), diff --git a/ast/src/functions/input/input_variable.rs b/ast/src/functions/input/input_variable.rs index 46b8d8b315..cc7c75231c 100644 --- a/ast/src/functions/input/input_variable.rs +++ b/ast/src/functions/input/input_variable.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{FunctionInputVariable, Identifier, Span}; -use leo_grammar::functions::input::Input as AstInput; +use leo_grammar::functions::input::Input as GrammarInput; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,10 +26,10 @@ pub enum FunctionInput { Variable(FunctionInputVariable), } -impl<'ast> From> for FunctionInput { - fn from(input: AstInput<'ast>) -> Self { +impl<'ast> From> for FunctionInput { + fn from(input: GrammarInput<'ast>) -> Self { match input { - AstInput::InputKeyword(input_keyword) => { + GrammarInput::InputKeyword(input_keyword) => { let id = Identifier { name: input_keyword.keyword, span: Span::from(input_keyword.span), @@ -37,7 +37,7 @@ impl<'ast> From> for FunctionInput { FunctionInput::InputKeyword(id) } - AstInput::FunctionInput(function_input) => { + GrammarInput::FunctionInput(function_input) => { FunctionInput::Variable(FunctionInputVariable::from(function_input)) } } diff --git a/ast/src/functions/test_function.rs b/ast/src/functions/test_function.rs index b567a48307..6996b2da20 100644 --- a/ast/src/functions/test_function.rs +++ b/ast/src/functions/test_function.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Function, Identifier}; -use leo_grammar::functions::TestFunction as AstTestFunction; +use leo_grammar::functions::TestFunction as GrammarTestFunction; use serde::{Deserialize, Serialize}; @@ -25,8 +25,8 @@ pub struct TestFunction { pub input_file: Option, } -impl<'ast> From> for TestFunction { - fn from(test: AstTestFunction) -> Self { +impl<'ast> From> for TestFunction { + fn from(test: GrammarTestFunction) -> Self { TestFunction { function: Function::from(test.function), input_file: None, // pass custom input file with `@context` annotation diff --git a/ast/src/groups/group_coordinate.rs b/ast/src/groups/group_coordinate.rs index 5b653b041d..e3dea687ac 100644 --- a/ast/src/groups/group_coordinate.rs +++ b/ast/src/groups/group_coordinate.rs @@ -16,11 +16,11 @@ use crate::common::span::Span; use leo_grammar::values::{ - GroupCoordinate as AstGroupCoordinate, - Inferred as AstInferred, - NumberValue as AstNumberValue, - SignHigh as AstSignHigh, - SignLow as AstSignLow, + GroupCoordinate as GrammarGroupCoordinate, + Inferred as GrammarInferred, + NumberValue as GrammarNumberValue, + SignHigh as GrammarSignHigh, + SignLow as GrammarSignLow, }; use leo_input::values::{ GroupCoordinate as InputGroupCoordinate, @@ -41,13 +41,13 @@ pub enum GroupCoordinate { Inferred, } -impl<'ast> From> for GroupCoordinate { - fn from(coordinate: AstGroupCoordinate<'ast>) -> Self { +impl<'ast> From> for GroupCoordinate { + fn from(coordinate: GrammarGroupCoordinate<'ast>) -> Self { match coordinate { - AstGroupCoordinate::Number(number) => GroupCoordinate::from(number), - AstGroupCoordinate::SignHigh(sign_high) => GroupCoordinate::from(sign_high), - AstGroupCoordinate::SignLow(sign_low) => GroupCoordinate::from(sign_low), - AstGroupCoordinate::Inferred(inferred) => GroupCoordinate::from(inferred), + GrammarGroupCoordinate::Number(number) => GroupCoordinate::from(number), + GrammarGroupCoordinate::SignHigh(sign_high) => GroupCoordinate::from(sign_high), + GrammarGroupCoordinate::SignLow(sign_low) => GroupCoordinate::from(sign_low), + GrammarGroupCoordinate::Inferred(inferred) => GroupCoordinate::from(inferred), } } } @@ -74,8 +74,8 @@ impl fmt::Display for GroupCoordinate { } } -impl<'ast> From> for GroupCoordinate { - fn from(number: AstNumberValue<'ast>) -> Self { +impl<'ast> From> for GroupCoordinate { + fn from(number: GrammarNumberValue<'ast>) -> Self { let value = number.to_string(); let span = Span::from(number.span().clone()); @@ -83,20 +83,20 @@ impl<'ast> From> for GroupCoordinate { } } -impl<'ast> From> for GroupCoordinate { - fn from(_sign: AstSignHigh<'ast>) -> Self { +impl<'ast> From> for GroupCoordinate { + fn from(_sign: GrammarSignHigh<'ast>) -> Self { GroupCoordinate::SignHigh } } -impl<'ast> From> for GroupCoordinate { - fn from(_sign: AstSignLow<'ast>) -> Self { +impl<'ast> From> for GroupCoordinate { + fn from(_sign: GrammarSignLow<'ast>) -> Self { GroupCoordinate::SignLow } } -impl<'ast> From> for GroupCoordinate { - fn from(_sign: AstInferred<'ast>) -> Self { +impl<'ast> From> for GroupCoordinate { + fn from(_sign: GrammarInferred<'ast>) -> Self { GroupCoordinate::Inferred } } diff --git a/ast/src/groups/group_value.rs b/ast/src/groups/group_value.rs index 83fdc35a57..0385e2896f 100644 --- a/ast/src/groups/group_value.rs +++ b/ast/src/groups/group_value.rs @@ -16,9 +16,9 @@ use crate::{common::span::Span, groups::GroupCoordinate}; use leo_grammar::values::{ - GroupRepresentation as AstGroupRepresentation, - GroupTuple as AstGroupTuple, - GroupValue as AstGroupValue, + GroupRepresentation as GrammarGroupRepresentation, + GroupTuple as GrammarGroupTuple, + GroupValue as GrammarGroupValue, }; use leo_input::values::{ GroupRepresentation as InputGroupRepresentation, @@ -51,13 +51,13 @@ impl GroupValue { } } -impl<'ast> From> for GroupValue { - fn from(ast_group: AstGroupValue) -> Self { +impl<'ast> From> for GroupValue { + fn from(ast_group: GrammarGroupValue) -> Self { let span = Span::from(ast_group.span); match ast_group.value { - AstGroupRepresentation::Single(number) => GroupValue::Single(number.to_string(), span), - AstGroupRepresentation::Tuple(tuple) => GroupValue::Tuple(GroupTuple::from(tuple)), + GrammarGroupRepresentation::Single(number) => GroupValue::Single(number.to_string(), span), + GrammarGroupRepresentation::Tuple(tuple) => GroupValue::Tuple(GroupTuple::from(tuple)), } } } @@ -89,8 +89,8 @@ pub struct GroupTuple { pub span: Span, } -impl<'ast> From> for GroupTuple { - fn from(ast_group: AstGroupTuple<'ast>) -> Self { +impl<'ast> From> for GroupTuple { + fn from(ast_group: GrammarGroupTuple<'ast>) -> Self { let ast_x = ast_group.x; let ast_y = ast_group.y; diff --git a/ast/src/imports/import.rs b/ast/src/imports/import.rs index 54135eba43..72bca9e33e 100644 --- a/ast/src/imports/import.rs +++ b/ast/src/imports/import.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Package, Span}; -use leo_grammar::imports::Import as AstImport; +use leo_grammar::imports::Import as GrammarImport; use serde::{Deserialize, Serialize}; use std::fmt; @@ -36,8 +36,8 @@ impl ImportStatement { } } -impl<'ast> From> for ImportStatement { - fn from(import: AstImport<'ast>) -> Self { +impl<'ast> From> for ImportStatement { + fn from(import: GrammarImport<'ast>) -> Self { ImportStatement { package: Package::from(import.package), span: Span::from(import.span), diff --git a/ast/src/imports/package.rs b/ast/src/imports/package.rs index de4e4b2a35..071393fe54 100644 --- a/ast/src/imports/package.rs +++ b/ast/src/imports/package.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{common::Identifier, PackageAccess, Span}; -use leo_grammar::imports::Package as AstPackage; +use leo_grammar::imports::Package as GrammarPackage; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,8 +27,8 @@ pub struct Package { pub span: Span, } -impl<'ast> From> for Package { - fn from(package: AstPackage<'ast>) -> Self { +impl<'ast> From> for Package { + fn from(package: GrammarPackage<'ast>) -> Self { Package { name: Identifier::from(package.name), access: PackageAccess::from(package.access), diff --git a/ast/src/imports/package_access.rs b/ast/src/imports/package_access.rs index a9c6817256..f7f0c92605 100644 --- a/ast/src/imports/package_access.rs +++ b/ast/src/imports/package_access.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ImportSymbol, Package, Span}; -use leo_grammar::imports::PackageAccess as AstPackageAccess; +use leo_grammar::imports::PackageAccess as GrammarPackageAccess; use serde::{Deserialize, Serialize}; use std::fmt; @@ -28,13 +28,13 @@ pub enum PackageAccess { Multiple(Vec), } -impl<'ast> From> for PackageAccess { - fn from(access: AstPackageAccess<'ast>) -> Self { +impl<'ast> From> for PackageAccess { + fn from(access: GrammarPackageAccess<'ast>) -> Self { match access { - AstPackageAccess::Star(star) => PackageAccess::Star(Span::from(star.span)), - AstPackageAccess::SubPackage(package) => PackageAccess::SubPackage(Box::new(Package::from(*package))), - AstPackageAccess::Symbol(symbol) => PackageAccess::Symbol(ImportSymbol::from(symbol)), - AstPackageAccess::Multiple(accesses) => { + 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()) } } diff --git a/ast/src/input/parameters/parameter.rs b/ast/src/input/parameters/parameter.rs index 709cd38daa..964538dc88 100644 --- a/ast/src/input/parameters/parameter.rs +++ b/ast/src/input/parameters/parameter.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{Identifier, Span, Type}; -use leo_input::parameters::Parameter as AstParameter; +use leo_input::parameters::Parameter as GrammarParameter; #[derive(Clone, PartialEq, Eq, Hash)] pub struct Parameter { @@ -24,8 +24,8 @@ pub struct Parameter { pub span: Span, } -impl<'ast> From> for Parameter { - fn from(parameter: AstParameter<'ast>) -> Self { +impl<'ast> From> for Parameter { + fn from(parameter: GrammarParameter<'ast>) -> Self { Self { variable: Identifier::from(parameter.variable), type_: Type::from(parameter.type_), diff --git a/ast/src/statements/conditional_nested_or_end_statement.rs b/ast/src/statements/conditional_nested_or_end_statement.rs index 2ee01c045c..ddb1f75dc1 100644 --- a/ast/src/statements/conditional_nested_or_end_statement.rs +++ b/ast/src/statements/conditional_nested_or_end_statement.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ConditionalStatement, Statement}; -use leo_grammar::statements::ConditionalNestedOrEndStatement as AstConditionalNestedOrEndStatement; +use leo_grammar::statements::ConditionalNestedOrEndStatement as GrammarConditionalNestedOrEndStatement; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,13 +26,13 @@ pub enum ConditionalNestedOrEndStatement { End(Vec), } -impl<'ast> From> for ConditionalNestedOrEndStatement { - fn from(statement: AstConditionalNestedOrEndStatement<'ast>) -> Self { +impl<'ast> From> for ConditionalNestedOrEndStatement { + fn from(statement: GrammarConditionalNestedOrEndStatement<'ast>) -> Self { match statement { - AstConditionalNestedOrEndStatement::Nested(nested) => { + GrammarConditionalNestedOrEndStatement::Nested(nested) => { ConditionalNestedOrEndStatement::Nested(Box::new(ConditionalStatement::from(*nested))) } - AstConditionalNestedOrEndStatement::End(statements) => { + GrammarConditionalNestedOrEndStatement::End(statements) => { ConditionalNestedOrEndStatement::End(statements.into_iter().map(Statement::from).collect()) } } diff --git a/ast/src/statements/conditional_statement.rs b/ast/src/statements/conditional_statement.rs index 299fbbb1ae..628b0f9dc4 100644 --- a/ast/src/statements/conditional_statement.rs +++ b/ast/src/statements/conditional_statement.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{ConditionalNestedOrEndStatement, Expression, Statement}; -use leo_grammar::statements::ConditionalStatement as AstConditionalStatement; +use leo_grammar::statements::ConditionalStatement as GrammarConditionalStatement; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,8 +27,8 @@ pub struct ConditionalStatement { pub next: Option, } -impl<'ast> From> for ConditionalStatement { - fn from(statement: AstConditionalStatement<'ast>) -> Self { +impl<'ast> From> for ConditionalStatement { + fn from(statement: GrammarConditionalStatement<'ast>) -> Self { ConditionalStatement { condition: Expression::from(statement.condition), statements: statement.statements.into_iter().map(Statement::from).collect(), diff --git a/ast/src/statements/statement.rs b/ast/src/statements/statement.rs index adf0eee4a1..2ad5113ea3 100644 --- a/ast/src/statements/statement.rs +++ b/ast/src/statements/statement.rs @@ -16,7 +16,7 @@ use crate::{Assignee, ConditionalStatement, ConsoleFunctionCall, Declare, Expression, Identifier, Span, Variables}; use leo_grammar::{ - console::ConsoleFunctionCall as AstConsoleFunctionCall, + console::ConsoleFunctionCall as GrammarConsoleFunctionCall, operations::AssignOperation, statements::{ AssignStatement, @@ -133,8 +133,8 @@ impl<'ast> From> for Statement { } } -impl<'ast> From> for Statement { - fn from(function_call: AstConsoleFunctionCall<'ast>) -> Self { +impl<'ast> From> for Statement { + fn from(function_call: GrammarConsoleFunctionCall<'ast>) -> Self { Statement::Console(ConsoleFunctionCall::from(function_call)) } } From 2bb17b496b1110dff4a1cc2278f0056f0f053745 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 10 Nov 2020 13:34:55 -0800 Subject: [PATCH 133/139] rename struct alias Ast -> Grammar in ast module 3 --- ast/src/statements/statement.rs | 20 ++++---- ast/src/types/integer_type.rs | 84 ++++++++++++++++----------------- ast/src/types/type_.rs | 28 +++++------ 3 files changed, 66 insertions(+), 66 deletions(-) diff --git a/ast/src/statements/statement.rs b/ast/src/statements/statement.rs index 2ad5113ea3..680ddf7dbd 100644 --- a/ast/src/statements/statement.rs +++ b/ast/src/statements/statement.rs @@ -24,7 +24,7 @@ use leo_grammar::{ ExpressionStatement, ForStatement, ReturnStatement, - Statement as AstStatement, + Statement as GrammarStatement, }, }; @@ -150,19 +150,19 @@ impl<'ast> From> for Statement { } } -impl<'ast> From> for Statement { - fn from(statement: AstStatement<'ast>) -> Self { +impl<'ast> From> for Statement { + fn from(statement: GrammarStatement<'ast>) -> Self { match statement { - AstStatement::Return(statement) => Statement::from(statement), - AstStatement::Definition(statement) => Statement::from(statement), - AstStatement::Assign(statement) => Statement::from(statement), - AstStatement::Conditional(statement) => { + GrammarStatement::Return(statement) => Statement::from(statement), + GrammarStatement::Definition(statement) => Statement::from(statement), + GrammarStatement::Assign(statement) => Statement::from(statement), + GrammarStatement::Conditional(statement) => { let span = Span::from(statement.span.clone()); Statement::Conditional(ConditionalStatement::from(statement), span) } - AstStatement::Iteration(statement) => Statement::from(statement), - AstStatement::Console(console) => Statement::from(console), - AstStatement::Expression(statement) => Statement::from(statement), + GrammarStatement::Iteration(statement) => Statement::from(statement), + GrammarStatement::Console(console) => Statement::from(console), + GrammarStatement::Expression(statement) => Statement::from(statement), } } } diff --git a/ast/src/types/integer_type.rs b/ast/src/types/integer_type.rs index cdf75e0f8a..a65e6595f0 100644 --- a/ast/src/types/integer_type.rs +++ b/ast/src/types/integer_type.rs @@ -15,14 +15,14 @@ // along with the Leo library. If not, see . use leo_grammar::types::{ - IntegerType as AstIntegerType, - SignedIntegerType as AstSignedIntegerType, - UnsignedIntegerType as AstUnsignedIntegerType, + IntegerType as GrammarIntegerType, + SignedIntegerType as GrammarSignedIntegerType, + UnsignedIntegerType as GrammarUnsignedIntegerType, }; use leo_input::types::{ - IntegerType as InputAstIntegerType, - SignedIntegerType as InputAstSignedIntegerType, - UnsignedIntegerType as InputAstUnsignedIntegerType, + IntegerType as InputIntegerType, + SignedIntegerType as InputSignedIntegerType, + UnsignedIntegerType as InputUnsignedIntegerType, }; use serde::{Deserialize, Serialize}; @@ -44,68 +44,68 @@ pub enum IntegerType { I128, } -impl From for IntegerType { - fn from(integer_type: AstIntegerType) -> Self { +impl From for IntegerType { + fn from(integer_type: GrammarIntegerType) -> Self { match integer_type { - AstIntegerType::Signed(signed) => Self::from(signed), - AstIntegerType::Unsigned(unsigned) => Self::from(unsigned), + GrammarIntegerType::Signed(signed) => Self::from(signed), + GrammarIntegerType::Unsigned(unsigned) => Self::from(unsigned), } } } -impl From for IntegerType { - fn from(integer_type: AstUnsignedIntegerType) -> Self { +impl From for IntegerType { + fn from(integer_type: GrammarUnsignedIntegerType) -> Self { match integer_type { - AstUnsignedIntegerType::U8Type(_type) => IntegerType::U8, - AstUnsignedIntegerType::U16Type(_type) => IntegerType::U16, - AstUnsignedIntegerType::U32Type(_type) => IntegerType::U32, - AstUnsignedIntegerType::U64Type(_type) => IntegerType::U64, - AstUnsignedIntegerType::U128Type(_type) => IntegerType::U128, + GrammarUnsignedIntegerType::U8Type(_type) => IntegerType::U8, + GrammarUnsignedIntegerType::U16Type(_type) => IntegerType::U16, + GrammarUnsignedIntegerType::U32Type(_type) => IntegerType::U32, + GrammarUnsignedIntegerType::U64Type(_type) => IntegerType::U64, + GrammarUnsignedIntegerType::U128Type(_type) => IntegerType::U128, } } } -impl From for IntegerType { - fn from(integer_type: AstSignedIntegerType) -> Self { +impl From for IntegerType { + fn from(integer_type: GrammarSignedIntegerType) -> Self { match integer_type { - AstSignedIntegerType::I8Type(_type) => IntegerType::I8, - AstSignedIntegerType::I16Type(_type) => IntegerType::I16, - AstSignedIntegerType::I32Type(_type) => IntegerType::I32, - AstSignedIntegerType::I64Type(_type) => IntegerType::I64, - AstSignedIntegerType::I128Type(_type) => IntegerType::I128, + GrammarSignedIntegerType::I8Type(_type) => IntegerType::I8, + GrammarSignedIntegerType::I16Type(_type) => IntegerType::I16, + GrammarSignedIntegerType::I32Type(_type) => IntegerType::I32, + GrammarSignedIntegerType::I64Type(_type) => IntegerType::I64, + GrammarSignedIntegerType::I128Type(_type) => IntegerType::I128, } } } -impl From for IntegerType { - fn from(integer_type: InputAstIntegerType) -> Self { +impl From for IntegerType { + fn from(integer_type: InputIntegerType) -> Self { match integer_type { - InputAstIntegerType::Signed(signed) => Self::from(signed), - InputAstIntegerType::Unsigned(unsigned) => Self::from(unsigned), + InputIntegerType::Signed(signed) => Self::from(signed), + InputIntegerType::Unsigned(unsigned) => Self::from(unsigned), } } } -impl From for IntegerType { - fn from(integer_type: InputAstUnsignedIntegerType) -> Self { +impl From for IntegerType { + fn from(integer_type: InputUnsignedIntegerType) -> Self { match integer_type { - InputAstUnsignedIntegerType::U8Type(_type) => IntegerType::U8, - InputAstUnsignedIntegerType::U16Type(_type) => IntegerType::U16, - InputAstUnsignedIntegerType::U32Type(_type) => IntegerType::U32, - InputAstUnsignedIntegerType::U64Type(_type) => IntegerType::U64, - InputAstUnsignedIntegerType::U128Type(_type) => IntegerType::U128, + InputUnsignedIntegerType::U8Type(_type) => IntegerType::U8, + InputUnsignedIntegerType::U16Type(_type) => IntegerType::U16, + InputUnsignedIntegerType::U32Type(_type) => IntegerType::U32, + InputUnsignedIntegerType::U64Type(_type) => IntegerType::U64, + InputUnsignedIntegerType::U128Type(_type) => IntegerType::U128, } } } -impl From for IntegerType { - fn from(integer_type: InputAstSignedIntegerType) -> Self { +impl From for IntegerType { + fn from(integer_type: InputSignedIntegerType) -> Self { match integer_type { - InputAstSignedIntegerType::I8Type(_type) => IntegerType::I8, - InputAstSignedIntegerType::I16Type(_type) => IntegerType::I16, - InputAstSignedIntegerType::I32Type(_type) => IntegerType::I32, - InputAstSignedIntegerType::I64Type(_type) => IntegerType::I64, - InputAstSignedIntegerType::I128Type(_type) => IntegerType::I128, + InputSignedIntegerType::I8Type(_type) => IntegerType::I8, + InputSignedIntegerType::I16Type(_type) => IntegerType::I16, + InputSignedIntegerType::I32Type(_type) => IntegerType::I32, + InputSignedIntegerType::I64Type(_type) => IntegerType::I64, + InputSignedIntegerType::I128Type(_type) => IntegerType::I128, } } } diff --git a/ast/src/types/type_.rs b/ast/src/types/type_.rs index b32b8534ad..32d462d11e 100644 --- a/ast/src/types/type_.rs +++ b/ast/src/types/type_.rs @@ -15,12 +15,12 @@ // along with the Leo library. If not, see . use crate::{ArrayDimensions, Identifier, IntegerType}; -use leo_grammar::types::{ArrayType, CircuitType, DataType, TupleType, Type as AstType}; +use leo_grammar::types::{ArrayType, CircuitType, DataType, TupleType, Type as GrammarType}; use leo_input::types::{ ArrayType as InputArrayType, DataType as InputDataType, TupleType as InputTupleType, - Type as InputAstType, + Type as InputType, }; use serde::{Deserialize, Serialize}; @@ -139,14 +139,14 @@ impl<'ast> From> for Type { } } -impl<'ast> From> for Type { - fn from(type_: AstType<'ast>) -> Self { +impl<'ast> From> for Type { + fn from(type_: GrammarType<'ast>) -> Self { match type_ { - AstType::Basic(type_) => Type::from(type_), - AstType::Array(type_) => Type::from(type_), - AstType::Tuple(type_) => Type::from(type_), - AstType::Circuit(type_) => Type::from(type_), - AstType::SelfType(_type) => Type::SelfType, + GrammarType::Basic(type_) => Type::from(type_), + GrammarType::Array(type_) => Type::from(type_), + GrammarType::Tuple(type_) => Type::from(type_), + GrammarType::Circuit(type_) => Type::from(type_), + GrammarType::SelfType(_type) => Type::SelfType, } } } @@ -182,12 +182,12 @@ impl<'ast> From> for Type { } } -impl<'ast> From> for Type { - fn from(type_: InputAstType<'ast>) -> Self { +impl<'ast> From> for Type { + fn from(type_: InputType<'ast>) -> Self { match type_ { - InputAstType::Basic(type_) => Type::from(type_), - InputAstType::Array(type_) => Type::from(type_), - InputAstType::Tuple(type_) => Type::from(type_), + InputType::Basic(type_) => Type::from(type_), + InputType::Array(type_) => Type::from(type_), + InputType::Tuple(type_) => Type::from(type_), } } } From 33fae17b35285dd6e25f078dd7b28a68b5cb69b9 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 10 Nov 2020 16:23:55 -0800 Subject: [PATCH 134/139] clippy lints 1 --- ast/src/common/array_dimensions.rs | 4 +- ast/src/types/type_.rs | 2 +- compiler/src/compiler.rs | 6 +- compiler/src/constraints/constraints.rs | 4 +- compiler/src/expression/array/array.rs | 119 +++++++++--------- compiler/src/statement/assign/assign.rs | 2 +- compiler/src/statement/statement.rs | 2 + imports/src/errors/import_parser.rs | 2 +- imports/src/parser/import_parser.rs | 16 +-- symbol-table/src/errors/type_.rs | 2 +- symbol-table/src/symbol_table.rs | 2 +- symbol-table/src/types/functions/function.rs | 2 +- symbol-table/src/types/type_.rs | 2 +- symbol-table/tests/mod.rs | 6 +- .../src/assertions/type_variable_pair.rs | 10 +- type-inference/src/objects/frame.rs | 4 +- type-inference/src/type_inference.rs | 2 +- type-inference/tests/mod.rs | 6 +- 18 files changed, 94 insertions(+), 99 deletions(-) diff --git a/ast/src/common/array_dimensions.rs b/ast/src/common/array_dimensions.rs index 1a3236f01b..4e2b06f9f5 100644 --- a/ast/src/common/array_dimensions.rs +++ b/ast/src/common/array_dimensions.rs @@ -81,9 +81,7 @@ impl ArrayDimensions { /// pub fn remove_first(&mut self) -> Option { // If there are no dimensions in the array, then return None. - if self.0.first().is_none() { - return None; - } + self.0.first()?; // Remove the first dimension. let removed = self.0.remove(0); diff --git a/ast/src/types/type_.rs b/ast/src/types/type_.rs index 32d462d11e..554e524898 100644 --- a/ast/src/types/type_.rs +++ b/ast/src/types/type_.rs @@ -91,7 +91,7 @@ impl Type { let right_new_type = inner_array_type(*right_type.to_owned(), right_dim_owned); // Call eq_flat() on the new left and right types. - return left_new_type.eq_flat(&right_new_type); + left_new_type.eq_flat(&right_new_type) } (Type::Tuple(left), Type::Tuple(right)) => left .iter() diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 61a36acfa2..b0dd22fc77 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -70,7 +70,7 @@ impl> Compiler { output_directory, program: Program::new(package_name), program_input: Input::new(), - imported_programs: ImportParser::new(), + imported_programs: ImportParser::default(), _engine: PhantomData, _group: PhantomData, } @@ -214,7 +214,7 @@ impl> Compiler { })?; // Run type inference check on program. - TypeInference::new(&self.program, symbol_table).map_err(|mut e| { + TypeInference::run(&self.program, symbol_table).map_err(|mut e| { e.set_path(&self.main_file_path); e @@ -256,7 +256,7 @@ impl> Compiler { let symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; // Run type inference check on program. - TypeInference::new(&self.program, symbol_table)?; + TypeInference::run(&self.program, symbol_table)?; tracing::debug!("Program parsing complete\n{:#?}", self.program); diff --git a/compiler/src/constraints/constraints.rs b/compiler/src/constraints/constraints.rs index d8b067c9bd..0027f0762e 100644 --- a/compiler/src/constraints/constraints.rs +++ b/compiler/src/constraints/constraints.rs @@ -48,9 +48,7 @@ pub fn generate_constraints, CS: Constrai resolved_program.store_definitions(program, imported_programs)?; - let main = resolved_program - .get(&main_function_name) - .ok_or_else(|| CompilerError::NoMain)?; + let main = resolved_program.get(&main_function_name).ok_or(CompilerError::NoMain)?; match main.clone() { ConstrainedValue::Function(_circuit_identifier, function) => { diff --git a/compiler/src/expression/array/array.rs b/compiler/src/expression/array/array.rs index ed36684c88..fe740cc069 100644 --- a/compiler/src/expression/array/array.rs +++ b/compiler/src/expression/array/array.rs @@ -107,7 +107,10 @@ impl> ConstrainedProgram { Ok(ConstrainedValue::Array(result)) } - /// Enforce array expressions + /// + /// Returns an array value from an array initializer expression. + /// + #[allow(clippy::too_many_arguments)] pub fn enforce_array_initializer>( &mut self, cs: &mut CS, @@ -142,65 +145,63 @@ impl> ConstrainedProgram { } Ok(value) + } else if expected_dimensions.first().eq(&actual_dimensions.first()) { + // Case 2 - enforce expression with updated array type. + let dimension = match expected_dimensions.remove_first() { + Some(number) => { + // Parse the array dimension into a `usize`. + parse_index(&number, &span)? + } + None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)), + }; + + // Update the actual array dimensions. + let _first_dimension = actual_dimensions.remove_first(); + + // Update the expected type to a new array type with the first dimension removed. + let expected_expression_type = Some(inner_array_type(*type_, expected_dimensions)); + + // If the expression has more dimensions. + let element_value = match actual_dimensions.first() { + Some(_dimension) => { + // Get the value of the array element as an initializer. + self.enforce_array_initializer( + cs, + file_scope, + function_scope, + expected_expression_type, + element_expression, + actual_dimensions.clone(), + span, + )? + } + None => { + // Get the value of the array element as an expression. + self.enforce_expression( + cs, + file_scope, + function_scope, + expected_expression_type, + element_expression, + )? + } + }; + + // Allocate the array of values. + let array_values = vec![element_value; dimension]; + + // Create a new value with the expected dimension. + Ok(ConstrainedValue::Array(array_values)) } else { - if expected_dimensions.first().eq(&actual_dimensions.first()) { - // Case 2 - enforce expression with updated array type. - let dimension = match expected_dimensions.remove_first() { - Some(number) => { - // Parse the array dimension into a `usize`. - parse_index(&number, &span)? - } - None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)), - }; - - // Update the actual array dimensions. - let _first_dimension = actual_dimensions.remove_first(); - - // Update the expected type to a new array type with the first dimension removed. - let expected_expression_type = Some(inner_array_type(*type_, expected_dimensions)); - - // If the expression has more dimensions. - let element_value = match actual_dimensions.first() { - Some(_dimension) => { - // Get the value of the array element as an initializer. - self.enforce_array_initializer( - cs, - file_scope, - function_scope, - expected_expression_type, - element_expression, - actual_dimensions.clone(), - span.clone(), - )? - } - None => { - // Get the value of the array element as an expression. - self.enforce_expression( - cs, - file_scope, - function_scope, - expected_expression_type, - element_expression, - )? - } - }; - - // Allocate the array of values. - let array_values = vec![element_value; dimension]; - - // Create a new value with the expected dimension. - Ok(ConstrainedValue::Array(array_values)) - } else { - // Case 3 - return mismatched dimensions error. - Err(ExpressionError::invalid_first_dimension( - expected_dimensions - .first() - .ok_or(ExpressionError::undefined_first_dimension(span.clone()))?, - actual_dimensions - .first() - .ok_or(ExpressionError::undefined_first_dimension(span.clone()))?, - )) - } + // Case 3 - return mismatched dimensions error. + Err(ExpressionError::invalid_first_dimension( + expected_dimensions + .first() + .ok_or_else(|| ExpressionError::undefined_first_dimension(span.clone()))?, + actual_dimensions + .first() + .ok_or_else(|| ExpressionError::undefined_first_dimension(span))?, + )) } } else { // No explicit type given - evaluate array element expression. diff --git a/compiler/src/statement/assign/assign.rs b/compiler/src/statement/assign/assign.rs index c33bd43f79..8899c9b286 100644 --- a/compiler/src/statement/assign/assign.rs +++ b/compiler/src/statement/assign/assign.rs @@ -70,7 +70,7 @@ impl> ConstrainedProgram { *old_value = selected_value; - return Ok(()); + Ok(()) } else { match assignee.accesses[0].clone() { AssigneeAccess::Array(range_or_expression) => self.assign_array( diff --git a/compiler/src/statement/statement.rs b/compiler/src/statement/statement.rs index 6b3472c9b6..763ea328a7 100644 --- a/compiler/src/statement/statement.rs +++ b/compiler/src/statement/statement.rs @@ -28,11 +28,13 @@ pub type StatementResult = Result; pub type IndicatorAndConstrainedValue = (Option, ConstrainedValue); impl> ConstrainedProgram { + /// /// Enforce a program statement. /// Returns a Vector of (indicator, value) tuples. /// Each evaluated statement may execute of one or more statements that may return early. /// To indicate which of these return values to take we conditionally select the value according /// to the `indicator` bit that evaluates to true. + /// #[allow(clippy::too_many_arguments)] pub fn enforce_statement>( &mut self, diff --git a/imports/src/errors/import_parser.rs b/imports/src/errors/import_parser.rs index 5638e867cd..647a37a259 100644 --- a/imports/src/errors/import_parser.rs +++ b/imports/src/errors/import_parser.rs @@ -58,7 +58,7 @@ impl ImportParserError { /// Failed to convert a file path into an os string. /// pub fn convert_os_string(span: Span) -> Self { - let message = format!("Failed to convert file string name, maybe an illegal character?"); + let message = "Failed to convert file string name, maybe an illegal character?".to_string(); Self::new_from_span(message, span) } diff --git a/imports/src/parser/import_parser.rs b/imports/src/parser/import_parser.rs index 58a2ca8f19..49b41f7533 100644 --- a/imports/src/parser/import_parser.rs +++ b/imports/src/parser/import_parser.rs @@ -26,23 +26,13 @@ use std::{ /// /// A program can import one or more packages. A package can be found locally in the source /// directory, foreign in the imports directory, or part of the core package list. -#[derive(Clone)] +#[derive(Clone, Default)] pub struct ImportParser { imports: HashMap, core_packages: HashSet, } impl ImportParser { - /// - /// Creates a new empty `ImportParser`. - /// - pub fn new() -> Self { - Self { - imports: HashMap::new(), - core_packages: HashSet::new(), - } - } - /// /// Inserts a (file name -> program) pair into the `ImportParser`. /// @@ -96,10 +86,10 @@ impl ImportParser { /// 3. Insert the typed syntax tree into the `ImportParser` /// pub fn parse(program: &Program) -> Result { - let mut imports = Self::new(); + let mut imports = Self::default(); // Find all imports relative to current directory. - let path = current_dir().map_err(|error| ImportParserError::current_directory_error(error))?; + let path = current_dir().map_err(ImportParserError::current_directory_error)?; // Parse each import statement. for import in &program.imports { diff --git a/symbol-table/src/errors/type_.rs b/symbol-table/src/errors/type_.rs index 030fce9c0f..c040fcc10a 100644 --- a/symbol-table/src/errors/type_.rs +++ b/symbol-table/src/errors/type_.rs @@ -46,7 +46,7 @@ impl TypeError { /// The `Self` keyword was used outside of a circuit. /// pub fn self_not_available(span: Span) -> Self { - let message = format!("Type `Self` is only available in circuit definitions and circuit functions."); + let message = "Type `Self` is only available in circuit definitions and circuit functions.".to_string(); Self::new_from_span(message, span) } diff --git a/symbol-table/src/symbol_table.rs b/symbol-table/src/symbol_table.rs index 2214e66b36..0e5a56b121 100644 --- a/symbol-table/src/symbol_table.rs +++ b/symbol-table/src/symbol_table.rs @@ -367,7 +367,7 @@ impl SymbolTable { self.check_function_names(&program.functions) } else { // Check for a symbol alias. - let identifier = symbol.alias.to_owned().unwrap_or(symbol.symbol.to_owned()); + let identifier = symbol.alias.to_owned().unwrap_or_else(|| symbol.symbol.to_owned()); // Check if the imported symbol is a circuit match program.circuits.get(&symbol.symbol) { diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs index ca96be17e7..0abdc87aa9 100644 --- a/symbol-table/src/types/functions/function.rs +++ b/symbol-table/src/types/functions/function.rs @@ -92,7 +92,7 @@ impl FunctionType { // Type check function output. let output = FunctionOutputType::new_from_circuit( table, - circuit_name.clone(), + circuit_name, unresolved_function.output, unresolved_function.span, )?; diff --git a/symbol-table/src/types/type_.rs b/symbol-table/src/types/type_.rs index 4f1721e9ea..304ffa083d 100644 --- a/symbol-table/src/types/type_.rs +++ b/symbol-table/src/types/type_.rs @@ -76,7 +76,7 @@ impl Type { // Lookup the circuit type in the symbol table let circuit_type = table .get_circuit_type(&identifier.name) - .ok_or(TypeError::undefined_circuit(identifier))?; + .ok_or_else(|| TypeError::undefined_circuit(identifier))?; Type::Circuit(circuit_type.identifier.clone()) } diff --git a/symbol-table/tests/mod.rs b/symbol-table/tests/mod.rs index 5e7646b25e..a0db2ba170 100644 --- a/symbol-table/tests/mod.rs +++ b/symbol-table/tests/mod.rs @@ -60,7 +60,7 @@ impl TestSymbolTable { let program = self.typed.into_repr(); // Create empty import parser. - let import_parser = ImportParser::new(); + let import_parser = ImportParser::default(); // Create empty input. let input = Input::new(); @@ -82,7 +82,7 @@ impl TestSymbolTable { let static_check = &mut SymbolTable::default(); // Create empty import parser. - let import_parser = ImportParser::new(); + let import_parser = ImportParser::default(); // Run pass one and expect an error. let error = static_check.check_names(&program, &import_parser).unwrap_err(); @@ -106,7 +106,7 @@ impl TestSymbolTable { let static_check = &mut SymbolTable::default(); // Create empty import parser. - let import_parser = ImportParser::new(); + let import_parser = ImportParser::default(); // Run the pass one and expect no errors. static_check.check_names(&program, &import_parser).unwrap(); diff --git a/type-inference/src/assertions/type_variable_pair.rs b/type-inference/src/assertions/type_variable_pair.rs index 6bfc25397e..e7cca2b2e6 100644 --- a/type-inference/src/assertions/type_variable_pair.rs +++ b/type-inference/src/assertions/type_variable_pair.rs @@ -85,8 +85,14 @@ impl TypeVariablePairs { /// pub fn push_pairs(&mut self, left: Type, right: Type, span: &Span) -> Result<(), TypeAssertionError> { match (left, right) { - (Type::TypeVariable(variable), type_) => Ok(self.push(variable, type_)), - (type_, Type::TypeVariable(variable)) => Ok(self.push(variable, type_)), + (Type::TypeVariable(variable), type_) => { + self.push(variable, type_); + Ok(()) + } + (type_, Type::TypeVariable(variable)) => { + self.push(variable, type_); + Ok(()) + } (Type::Array(left_type), Type::Array(right_type)) => self.push_pairs_array(*left_type, *right_type, span), (Type::Tuple(left_types), Type::Tuple(right_types)) => { self.push_pairs_tuple(left_types.into_iter(), right_types.into_iter(), span) diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index 7df352a404..7244cc3a19 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -302,7 +302,7 @@ impl Frame { }; // Assert that the expected type is equal to the actual type. - self.assert_equal(expected_type.clone(), actual_type.clone(), span) + self.assert_equal(expected_type, actual_type.clone(), span) } // Check for multiple defined variables. @@ -1128,7 +1128,7 @@ impl Frame { } // Return the function output type. - Ok(function_type.output.type_.clone()) + Ok(function_type.output.type_) } /// diff --git a/type-inference/src/type_inference.rs b/type-inference/src/type_inference.rs index ee485d1d47..087b82c82b 100644 --- a/type-inference/src/type_inference.rs +++ b/type-inference/src/type_inference.rs @@ -34,7 +34,7 @@ impl TypeInference { /// /// Evaluates all `TypeAssertion` predicates. /// - pub fn new(program: &Program, symbol_table: SymbolTable) -> Result<(), TypeInferenceError> { + pub fn run(program: &Program, symbol_table: SymbolTable) -> Result<(), TypeInferenceError> { let mut type_inference = Self { table: symbol_table, frames: Vec::new(), diff --git a/type-inference/tests/mod.rs b/type-inference/tests/mod.rs index 0753812059..f03a083711 100644 --- a/type-inference/tests/mod.rs +++ b/type-inference/tests/mod.rs @@ -53,7 +53,7 @@ impl TestTypeInference { let program = typed.into_repr(); // Create empty import parser. - let import_parser = ImportParser::new(); + let import_parser = ImportParser::default(); // Create empty input. let input = Input::new(); @@ -66,11 +66,11 @@ impl TestTypeInference { } pub fn check(self) { - TypeInference::new(&self.program, self.symbol_table).unwrap(); + TypeInference::run(&self.program, self.symbol_table).unwrap(); } pub fn expect_error(self) { - assert!(TypeInference::new(&self.program, self.symbol_table).is_err()); + assert!(TypeInference::run(&self.program, self.symbol_table).is_err()); } } From f28eb8c20a7f6223c610b41a668bd659d90b8f7f Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 10 Nov 2020 16:34:44 -0800 Subject: [PATCH 135/139] clippy lints 2 --- compiler/src/compiler.rs | 4 +-- .../src/statement/definition/definition.rs | 9 ++--- compiler/src/value/value.rs | 36 +++++++------------ leo/cli.rs | 1 + type-inference/src/type_inference.rs | 3 +- type-inference/tests/mod.rs | 4 +-- 6 files changed, 21 insertions(+), 36 deletions(-) diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index b0dd22fc77..00ec57fe90 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -214,7 +214,7 @@ impl> Compiler { })?; // Run type inference check on program. - TypeInference::run(&self.program, symbol_table).map_err(|mut e| { + TypeInference::new(&self.program, symbol_table).map_err(|mut e| { e.set_path(&self.main_file_path); e @@ -256,7 +256,7 @@ impl> Compiler { let symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; // Run type inference check on program. - TypeInference::run(&self.program, symbol_table)?; + TypeInference::new(&self.program, symbol_table)?; tracing::debug!("Program parsing complete\n{:#?}", self.program); diff --git a/compiler/src/statement/definition/definition.rs b/compiler/src/statement/definition/definition.rs index aae6d4f79a..feb839135a 100644 --- a/compiler/src/statement/definition/definition.rs +++ b/compiler/src/statement/definition/definition.rs @@ -88,13 +88,8 @@ impl> ConstrainedProgram { Declare::Let => false, Declare::Const => true, }; - let expression = self.enforce_expression( - cs, - file_scope.clone(), - function_scope.clone(), - variables.type_.clone(), - expression, - )?; + let expression = + self.enforce_expression(cs, file_scope, function_scope, variables.type_.clone(), expression)?; if num_variables == 1 { // Define a single variable with a single value diff --git a/compiler/src/value/value.rs b/compiler/src/value/value.rs index 0de94a7e65..94f47d7295 100644 --- a/compiler/src/value/value.rs +++ b/compiler/src/value/value.rs @@ -273,37 +273,25 @@ impl> ConstrainedValue { // Data type wrappers ConstrainedValue::Array(array) => { - array - .iter_mut() - .enumerate() - .map(|(i, value)| { - let unique_name = format!("allocate array member {} {}:{}", i, span.line, span.start); + array.iter_mut().enumerate().try_for_each(|(i, value)| { + let unique_name = format!("allocate array member {} {}:{}", i, span.line, span.start); - value.allocate_value(cs.ns(|| unique_name), span) - }) - .collect::>()?; + value.allocate_value(cs.ns(|| unique_name), span) + })?; } ConstrainedValue::Tuple(tuple) => { - tuple - .iter_mut() - .enumerate() - .map(|(i, value)| { - let unique_name = format!("allocate tuple member {} {}:{}", i, span.line, span.start); + tuple.iter_mut().enumerate().try_for_each(|(i, value)| { + let unique_name = format!("allocate tuple member {} {}:{}", i, span.line, span.start); - value.allocate_value(cs.ns(|| unique_name), span) - }) - .collect::>()?; + value.allocate_value(cs.ns(|| unique_name), span) + })?; } ConstrainedValue::CircuitExpression(_id, members) => { - members - .iter_mut() - .enumerate() - .map(|(i, member)| { - let unique_name = format!("allocate circuit member {} {}:{}", i, span.line, span.start); + members.iter_mut().enumerate().try_for_each(|(i, member)| { + let unique_name = format!("allocate circuit member {} {}:{}", i, span.line, span.start); - member.1.allocate_value(cs.ns(|| unique_name), span) - }) - .collect::>()?; + member.1.allocate_value(cs.ns(|| unique_name), span) + })?; } ConstrainedValue::Mutable(value) => { value.allocate_value(cs, span)?; diff --git a/leo/cli.rs b/leo/cli.rs index 80dd05eecd..caff530283 100644 --- a/leo/cli.rs +++ b/leo/cli.rs @@ -29,6 +29,7 @@ pub trait CLI { const OPTIONS: &'static [OptionType]; const SUBCOMMANDS: &'static [SubCommandType]; + #[allow(clippy::new_ret_no_self)] #[cfg_attr(tarpaulin, skip)] fn new<'a, 'b>() -> App<'a, 'b> { let arguments = &Self::ARGUMENTS diff --git a/type-inference/src/type_inference.rs b/type-inference/src/type_inference.rs index 087b82c82b..fee87bb035 100644 --- a/type-inference/src/type_inference.rs +++ b/type-inference/src/type_inference.rs @@ -34,7 +34,8 @@ impl TypeInference { /// /// Evaluates all `TypeAssertion` predicates. /// - pub fn run(program: &Program, symbol_table: SymbolTable) -> Result<(), TypeInferenceError> { + #[allow(clippy::new_ret_no_self)] + pub fn new(program: &Program, symbol_table: SymbolTable) -> Result<(), TypeInferenceError> { let mut type_inference = Self { table: symbol_table, frames: Vec::new(), diff --git a/type-inference/tests/mod.rs b/type-inference/tests/mod.rs index f03a083711..58362fc972 100644 --- a/type-inference/tests/mod.rs +++ b/type-inference/tests/mod.rs @@ -66,11 +66,11 @@ impl TestTypeInference { } pub fn check(self) { - TypeInference::run(&self.program, self.symbol_table).unwrap(); + TypeInference::new(&self.program, self.symbol_table).unwrap(); } pub fn expect_error(self) { - assert!(TypeInference::run(&self.program, self.symbol_table).is_err()); + assert!(TypeInference::new(&self.program, self.symbol_table).is_err()); } } From a29bdbdef2b98d3b52ada5120b0620bae09326b0 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 10 Nov 2020 17:04:55 -0800 Subject: [PATCH 136/139] add check for empty arrays in array initializers --- ast/src/common/array_dimensions.rs | 7 +++++++ ast/src/common/positive_number.rs | 9 +++++++++ type-inference/src/objects/frame.rs | 17 ++++++++++++++--- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/ast/src/common/array_dimensions.rs b/ast/src/common/array_dimensions.rs index 4e2b06f9f5..b2bd90e124 100644 --- a/ast/src/common/array_dimensions.rs +++ b/ast/src/common/array_dimensions.rs @@ -66,6 +66,13 @@ impl ArrayDimensions { self.0.is_empty() } + /// + /// Returns `true` if there is an array dimension equal to zero. + /// + pub fn is_zero(&self) -> bool { + self.0.iter().find(|number| number.is_zero()).is_some() + } + /// /// Returns the first dimension of the array. /// diff --git a/ast/src/common/positive_number.rs b/ast/src/common/positive_number.rs index c0e9fb004f..d53e8d013f 100644 --- a/ast/src/common/positive_number.rs +++ b/ast/src/common/positive_number.rs @@ -31,6 +31,15 @@ pub struct PositiveNumber { pub span: Span, } +impl PositiveNumber { + /// + /// Returns `true` if this number is zero. + /// + pub fn is_zero(&self) -> bool { + self.value.eq("0") + } +} + /// Create a new [`PositiveNumber`] from a [`GrammarPositiveNumber`] in a Leo program file. impl<'ast> From> for PositiveNumber { fn from(array: GrammarPositiveNumber<'ast>) -> Self { diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index 7244cc3a19..0daeba20dd 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -16,6 +16,7 @@ use crate::{FrameError, Scope, TypeAssertion}; use leo_ast::{ + ArrayDimensions, Assignee, AssigneeAccess, CircuitVariableDefinition, @@ -550,8 +551,8 @@ impl Frame { // Arrays Expression::ArrayInline(expressions, span) => self.parse_array(expressions, span), - Expression::ArrayInitializer(array_w_dimensions, _span) => { - self.parse_array_initializer(&array_w_dimensions.0) + Expression::ArrayInitializer(array_w_dimensions, span) => { + self.parse_array_initializer(&array_w_dimensions.0, &array_w_dimensions.1, span) } Expression::ArrayAccess(array_w_index, span) => { self.parse_expression_array_access(&array_w_index.0, &array_w_index.1, span) @@ -807,10 +808,20 @@ impl Frame { /// /// Returns the type of the array initializer expression. /// - fn parse_array_initializer(&mut self, array: &Expression) -> Result { + fn parse_array_initializer( + &mut self, + array: &Expression, + dimensions: &ArrayDimensions, + span: &Span, + ) -> Result { // Get element type. let element_type = self.parse_expression(array)?; + // Return an error for array initializers of length 0. + if dimensions.is_zero() { + return Err(FrameError::empty_array(span)); + } + // Return array type. Ok(Type::Array(Box::new(element_type))) } From 74b346f3e6b02918bd9cbcfe6a2beb8afc151bb7 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 11 Nov 2020 12:47:54 -0800 Subject: [PATCH 137/139] remove deprecated names from comments and variables --- ast/benches/leo_ast.rs | 2 +- ast/src/common/identifier.rs | 2 +- ast/src/lib.rs | 14 ++--- ast/src/main.rs | 22 +++---- ast/src/program.rs | 2 +- ...ed_core_ast.json => expected_leo_ast.json} | 2 +- ast/tests/serialization/json.rs | 60 +++++++++---------- imports/src/parser/import_parser.rs | 4 +- imports/src/parser/parse_package.rs | 4 +- imports/src/parser/parse_symbol.rs | 12 ++-- .../local_data_commitment.rs | 10 ++-- .../state_leaf_values.rs | 6 +- .../src/local_data_commitment/state_values.rs | 6 +- .../record_commitment/dpc_record_values.rs | 6 +- .../record_commitment/record_commitment.rs | 6 +- symbol-table/tests/mod.rs | 24 ++++---- 16 files changed, 91 insertions(+), 91 deletions(-) rename ast/tests/serialization/{expected_core_ast.json => expected_leo_ast.json} (98%) diff --git a/ast/benches/leo_ast.rs b/ast/benches/leo_ast.rs index e510b4d7c8..a6f1e8dba8 100644 --- a/ast/benches/leo_ast.rs +++ b/ast/benches/leo_ast.rs @@ -21,7 +21,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use std::{path::Path, time::Duration}; fn leo_ast<'ast>(ast: &Grammar<'ast>) -> LeoAst { - LeoAst::new("leo_core_tree", &ast) + LeoAst::new("leo_tree", &ast) } fn bench_big_if_else(c: &mut Criterion) { diff --git a/ast/src/common/identifier.rs b/ast/src/common/identifier.rs index e4d20dc48d..e6f3f4baf2 100644 --- a/ast/src/common/identifier.rs +++ b/ast/src/common/identifier.rs @@ -215,7 +215,7 @@ impl<'de> Deserialize<'de> for Identifier { type Value = Identifier; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a string encoding the typed Identifier struct") + formatter.write_str("a string encoding the ast Identifier struct") } /// Implementation for recovering a string that serializes Identifier. diff --git a/ast/src/lib.rs b/ast/src/lib.rs index 7d08ba7a15..787370078f 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -//! The core abstract syntax tree (ast) for a Leo program. +//! The abstract syntax tree (ast) for a Leo program. //! //! This module contains the [`LeoAst`] type, a wrapper around the [`Program`] type. //! The [`LeoAst`] type is intended to be parsed and modified by different passes @@ -61,7 +61,7 @@ pub use self::types::*; use leo_grammar::Grammar; -/// The core abstract syntax tree (ast) for a Leo program. +/// The abstract syntax tree (ast) for a Leo program. /// /// The [`LeoAst`] type represents a Leo program as a series of recursive data types. /// These data types form a tree that begins from a [`Program`] type root. @@ -73,7 +73,7 @@ pub struct LeoAst { } impl LeoAst { - /// Creates a new core syntax tree from a given program name and abstract syntax tree. + /// Creates a new syntax tree from a given program name and abstract syntax tree. pub fn new<'ast>(program_name: &str, ast: &Grammar<'ast>) -> Self { Self { ast: Program::from(program_name, ast.as_repr()), @@ -85,14 +85,14 @@ impl LeoAst { self.ast } - /// Serializes the core syntax tree into a JSON string. + /// Serializes the syntax tree into a JSON string. pub fn to_json_string(&self) -> Result { Ok(serde_json::to_string_pretty(&self.ast)?) } - /// Deserializes the JSON string into a core syntax tree. + /// Deserializes the JSON string into a syntax tree. pub fn from_json_string(json: &str) -> Result { - let typed_ast: Program = serde_json::from_str(json)?; - Ok(Self { ast: typed_ast }) + let ast: Program = serde_json::from_str(json)?; + Ok(Self { ast }) } } diff --git a/ast/src/main.rs b/ast/src/main.rs index c231cc677b..35db61ec00 100644 --- a/ast/src/main.rs +++ b/ast/src/main.rs @@ -18,7 +18,7 @@ use leo_ast::LeoAst; use leo_grammar::{Grammar, ParserError}; use std::{env, fs, path::Path}; -fn to_leo_core_tree(filepath: &Path) -> Result { +fn to_leo_tree(filepath: &Path) -> Result { // Loads the Leo code as a string from the given file path. let program_filepath = filepath.to_path_buf(); let program_string = Grammar::load_file(&program_filepath)?; @@ -26,13 +26,13 @@ fn to_leo_core_tree(filepath: &Path) -> Result { // Parses the Leo file and constructs a pest ast. let ast = Grammar::new(&program_filepath, &program_string)?; - // Parse the pest ast and constructs a core ast. - let core_ast = LeoAst::new("leo_core_tree", &ast); + // Parse the pest ast and constructs a ast. + let leo_ast = LeoAst::new("leo_tree", &ast); - // Serializes the core tree into JSON format. - let serialized_core_ast = LeoAst::to_json_string(&core_ast)?; + // Serializes the tree into JSON format. + let serialized_leo_ast = LeoAst::to_json_string(&leo_ast)?; - Ok(serialized_core_ast) + Ok(serialized_leo_ast) } fn main() -> Result<(), ParserError> { @@ -51,9 +51,9 @@ fn main() -> Result<(), ParserError> { // Construct the input filepath. let input_filepath = Path::new(&cli_arguments[1]); - // Construct the serialized core syntax tree. - let serialized_core_tree = to_leo_core_tree(&input_filepath)?; - println!("{}", serialized_core_tree); + // Construct the serialized syntax tree. + let serialized_leo_tree = to_leo_tree(&input_filepath)?; + println!("{}", serialized_leo_tree); // Determine the output directory. let output_directory = match cli_arguments.len() == 3 { @@ -65,8 +65,8 @@ fn main() -> Result<(), ParserError> { false => format!("./{}.json", input_filepath.file_stem().unwrap().to_str().unwrap()), }; - // Write the serialized core syntax tree to the output directory. - fs::write(Path::new(&output_directory), serialized_core_tree)?; + // Write the serialized syntax tree to the output directory. + fs::write(Path::new(&output_directory), serialized_leo_tree)?; Ok(()) } diff --git a/ast/src/program.rs b/ast/src/program.rs index 5b21a165ab..ac016363e5 100644 --- a/ast/src/program.rs +++ b/ast/src/program.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . //! A Leo program consists of import, circuit, and function definitions. -//! Each defined type consists of typed statements and expressions. +//! Each defined type consists of ast statements and expressions. use crate::{load_annotation, Circuit, Function, FunctionInput, Identifier, ImportStatement, TestFunction}; use leo_grammar::{definitions::Definition, files::File}; diff --git a/ast/tests/serialization/expected_core_ast.json b/ast/tests/serialization/expected_leo_ast.json similarity index 98% rename from ast/tests/serialization/expected_core_ast.json rename to ast/tests/serialization/expected_leo_ast.json index 8d3060e20f..f542246816 100644 --- a/ast/tests/serialization/expected_core_ast.json +++ b/ast/tests/serialization/expected_leo_ast.json @@ -1,5 +1,5 @@ { - "name": "leo_core_tree", + "name": "leo_tree", "expected_input": [], "imports": [], "circuits": {}, diff --git a/ast/tests/serialization/json.rs b/ast/tests/serialization/json.rs index 8e9c2edf09..35edba92ae 100644 --- a/ast/tests/serialization/json.rs +++ b/ast/tests/serialization/json.rs @@ -21,74 +21,74 @@ use leo_grammar::Grammar; use std::path::{Path, PathBuf}; -fn to_core_ast(program_filepath: &Path) -> LeoAst { +fn to_ast(program_filepath: &Path) -> LeoAst { // Loads the Leo code as a string from the given file path. let program_string = Grammar::load_file(program_filepath).unwrap(); - // Parses the Leo file and constructs a pest ast. + // Parses the Leo file and constructs a grammar ast. let ast = Grammar::new(&program_filepath, &program_string).unwrap(); - // Parses the pest ast and constructs a core ast. - LeoAst::new("leo_core_tree", &ast) + // Parses the pest ast and constructs a Leo ast. + LeoAst::new("leo_tree", &ast) } #[test] #[cfg(not(feature = "ci_skip"))] fn test_serialize() { - // Construct a core ast from the given test file. - let core_ast = { + // Construct a ast from the given test file. + let leo_ast = { let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR")); program_filepath.push("tests/serialization/main.leo"); - to_core_ast(&program_filepath) + to_ast(&program_filepath) }; - // Serializes the core ast into JSON format. - let serialized_core_ast: Program = - serde_json::from_value(serde_json::to_value(core_ast.into_repr()).unwrap()).unwrap(); + // Serializes the ast into JSON format. + let serialized_leo_ast: Program = + serde_json::from_value(serde_json::to_value(leo_ast.into_repr()).unwrap()).unwrap(); - // Load the expected core ast. - let expected: Program = serde_json::from_str(include_str!("expected_core_ast.json")).unwrap(); + // Load the expected ast. + let expected: Program = serde_json::from_str(include_str!("expected_leo_ast.json")).unwrap(); - assert_eq!(expected, serialized_core_ast); + assert_eq!(expected, serialized_leo_ast); } #[test] #[cfg(not(feature = "ci_skip"))] fn test_deserialize() { - // Load the expected core ast. - let expected_core_ast = { + // Load the expected ast. + let expected_leo_ast = { let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR")); program_filepath.push("tests/serialization/main.leo"); - to_core_ast(&program_filepath) + to_ast(&program_filepath) }; - // Construct a core ast by deserializing a core ast JSON file. - let serialized_typed_ast = include_str!("expected_core_ast.json"); - let core_ast = LeoAst::from_json_string(serialized_typed_ast).unwrap(); + // Construct an ast by deserializing a ast JSON file. + let serialized_ast = include_str!("expected_leo_ast.json"); + let leo_ast = LeoAst::from_json_string(serialized_ast).unwrap(); - assert_eq!(expected_core_ast, core_ast); + assert_eq!(expected_leo_ast, leo_ast); } #[test] fn test_serialize_deserialize_serialize() { - // Construct a core ast from the given test file. - let core_ast = { + // Construct a ast from the given test file. + let leo_ast = { let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR")); program_filepath.push("tests/serialization/main.leo"); - to_core_ast(&program_filepath) + to_ast(&program_filepath) }; - // Serializes the core ast into JSON format. - let serialized_core_ast = core_ast.to_json_string().unwrap(); + // Serializes the ast into JSON format. + let serialized_leo_ast = leo_ast.to_json_string().unwrap(); - // Deserializes the serialized core ast into a LeoAst. - let core_ast = LeoAst::from_json_string(&serialized_core_ast).unwrap(); + // Deserializes the serialized ast into a LeoAst. + let leo_ast = LeoAst::from_json_string(&serialized_leo_ast).unwrap(); - // Reserializes the core ast into JSON format. - let reserialized_core_ast = core_ast.to_json_string().unwrap(); + // Reserializes the ast into JSON format. + let reserialized_leo_ast = leo_ast.to_json_string().unwrap(); - assert_eq!(serialized_core_ast, reserialized_core_ast); + assert_eq!(serialized_leo_ast, reserialized_leo_ast); } diff --git a/imports/src/parser/import_parser.rs b/imports/src/parser/import_parser.rs index 49b41f7533..2466448ec9 100644 --- a/imports/src/parser/import_parser.rs +++ b/imports/src/parser/import_parser.rs @@ -82,8 +82,8 @@ impl ImportParser { /// /// For every import statement in the program: /// 1. Check if the imported package exists. - /// 2. Create the typed syntax tree for the imported package. - /// 3. Insert the typed syntax tree into the `ImportParser` + /// 2. Create the Leo syntax tree for the imported package. + /// 3. Insert the Leo syntax tree into the `ImportParser` /// pub fn parse(program: &Program) -> Result { let mut imports = Self::default(); diff --git a/imports/src/parser/parse_package.rs b/imports/src/parser/parse_package.rs index 0ab54a84ca..78118acd53 100644 --- a/imports/src/parser/parse_package.rs +++ b/imports/src/parser/parse_package.rs @@ -51,9 +51,9 @@ impl ImportParser { } /// - /// Create the typed syntax tree for an imported package. + /// Create the Leo syntax tree for an imported package. /// - /// Inserts the typed syntax tree into the `ImportParser`. + /// Inserts the Leo syntax tree into the `ImportParser`. /// pub fn parse_package(&mut self, mut path: PathBuf, package: &Package) -> Result<(), ImportParserError> { let error_path = path.clone(); diff --git a/imports/src/parser/parse_symbol.rs b/imports/src/parser/parse_symbol.rs index 4856862aad..3061a7ff8a 100644 --- a/imports/src/parser/parse_symbol.rs +++ b/imports/src/parser/parse_symbol.rs @@ -24,9 +24,9 @@ static LIBRARY_FILE: &str = "src/lib.leo"; static FILE_EXTENSION: &str = "leo"; /// -/// Returns a typed syntax tree from a given package. +/// Returns a Leo syntax tree from a given package. /// -/// Builds an abstract syntax tree from the given file and then builds the typed syntax tree. +/// Builds an abstract syntax tree from the given file and then builds the Leo syntax tree. /// fn parse_import_file(package: &DirEntry, span: &Span) -> Result { // Get the package file type. @@ -54,7 +54,7 @@ fn parse_import_file(package: &DirEntry, span: &Span) -> Result Result<(), ImportParserError> { - // Get the package typed syntax tree. + // Get the package Leo syntax tree. self.parse_import_package(package, &symbol.span) } @@ -101,7 +101,7 @@ impl ImportParser { /// Import a symbol from a given package. /// pub fn parse_import_package(&mut self, package: &DirEntry, span: &Span) -> Result<(), ImportParserError> { - // Get the package typed syntax tree. + // Get the package Leo syntax tree. let program = parse_import_file(package, span)?; // Insert the package's imports into the import parser. @@ -118,7 +118,7 @@ impl ImportParser { .into_string() .unwrap(); // the file exists so these will not fail - // Attempt to insert the typed syntax tree for the imported package. + // Attempt to insert the Leo syntax tree for the imported package. self.insert_import(file_name, program); Ok(()) diff --git a/state/src/local_data_commitment/local_data_commitment.rs b/state/src/local_data_commitment/local_data_commitment.rs index fd6fc3cd64..2f795353f3 100644 --- a/state/src/local_data_commitment/local_data_commitment.rs +++ b/state/src/local_data_commitment/local_data_commitment.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{verify_record_commitment, LocalDataVerificationError, StateLeafValues, StateValues}; -use leo_ast::Input as TypedInput; +use leo_ast::Input as InputAst; use snarkos_algorithms::commitment_tree::CommitmentMerklePath; use snarkos_dpc::base_dpc::{ @@ -32,22 +32,22 @@ use std::convert::TryFrom; pub fn verify_local_data_commitment( system_parameters: &SystemParameters, - typed_input: &TypedInput, + input_ast: &InputAst, ) -> Result { // verify record commitment - let typed_record = typed_input.get_record(); + let typed_record = input_ast.get_record(); let dpc_record_values = verify_record_commitment(system_parameters, typed_record)?; let record_commitment: Vec = dpc_record_values.commitment; let record_serial_number: Vec = dpc_record_values.serial_number; // parse typed state values - let typed_state = typed_input.get_state(); + let typed_state = input_ast.get_state(); let state_values = StateValues::try_from(typed_state)?; let leaf_index: u32 = state_values.leaf_index; let root: Vec = state_values.root; // parse typed state leaf values - let typed_state_leaf = typed_input.get_state_leaf(); + let typed_state_leaf = input_ast.get_state_leaf(); let state_leaf_values = StateLeafValues::try_from(typed_state_leaf)?; let path: Vec = state_leaf_values.path; let memo: Vec = state_leaf_values.memo; diff --git a/state/src/local_data_commitment/state_leaf_values.rs b/state/src/local_data_commitment/state_leaf_values.rs index 4c7b743f7f..3265c68310 100644 --- a/state/src/local_data_commitment/state_leaf_values.rs +++ b/state/src/local_data_commitment/state_leaf_values.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{find_input, input_to_integer_string, input_to_u8_vec, StateLeafValuesError}; -use leo_ast::StateLeaf as TypedStateLeaf; +use leo_ast::StateLeaf as StateLeafAst; use std::convert::TryFrom; @@ -31,10 +31,10 @@ pub struct StateLeafValues { pub leaf_randomness: Vec, } -impl TryFrom<&TypedStateLeaf> for StateLeafValues { +impl TryFrom<&StateLeafAst> for StateLeafValues { type Error = StateLeafValuesError; - fn try_from(state_leaf: &TypedStateLeaf) -> Result { + fn try_from(state_leaf: &StateLeafAst) -> Result { let parameters = state_leaf.values(); // Lookup path diff --git a/state/src/local_data_commitment/state_values.rs b/state/src/local_data_commitment/state_values.rs index eafc9d4f2f..6b67ba7ea7 100644 --- a/state/src/local_data_commitment/state_values.rs +++ b/state/src/local_data_commitment/state_values.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{find_input, input_to_integer_string, input_to_u8_vec, StateValuesError}; -use leo_ast::State as TypedState; +use leo_ast::State as StateAst; use std::convert::TryFrom; @@ -27,10 +27,10 @@ pub struct StateValues { pub root: Vec, } -impl TryFrom<&TypedState> for StateValues { +impl TryFrom<&StateAst> for StateValues { type Error = StateValuesError; - fn try_from(state: &TypedState) -> Result { + fn try_from(state: &StateAst) -> Result { let parameters = state.values(); // Lookup leaf index diff --git a/state/src/record_commitment/dpc_record_values.rs b/state/src/record_commitment/dpc_record_values.rs index 5d0e9a271b..16f4963ba6 100644 --- a/state/src/record_commitment/dpc_record_values.rs +++ b/state/src/record_commitment/dpc_record_values.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{utilities::*, DPCRecordValuesError}; -use leo_ast::Record as TypedRecord; +use leo_ast::Record as RecordAst; use snarkos_dpc::base_dpc::instantiated::Components; use snarkos_objects::AccountAddress; @@ -46,10 +46,10 @@ pub struct DPCRecordValues { pub commitment_randomness: Vec, } -impl TryFrom<&TypedRecord> for DPCRecordValues { +impl TryFrom<&RecordAst> for DPCRecordValues { type Error = DPCRecordValuesError; - fn try_from(record: &TypedRecord) -> Result { + fn try_from(record: &RecordAst) -> Result { let parameters = record.values(); // Lookup serial number diff --git a/state/src/record_commitment/record_commitment.rs b/state/src/record_commitment/record_commitment.rs index 5b9ebc38b7..89b633acf2 100644 --- a/state/src/record_commitment/record_commitment.rs +++ b/state/src/record_commitment/record_commitment.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::{DPCRecordValues, RecordVerificationError}; -use leo_ast::Record as TypedRecord; +use leo_ast::Record as RecordAst; use snarkos_dpc::base_dpc::{ instantiated::{Components, RecordCommitment}, @@ -28,10 +28,10 @@ use std::convert::TryFrom; pub fn verify_record_commitment( system_parameters: &SystemParameters, - typed_record: &TypedRecord, + record_ast: &RecordAst, ) -> Result { // generate a dpc record from the typed record - let record = DPCRecordValues::try_from(typed_record)?; + let record = DPCRecordValues::try_from(record_ast)?; // verify record commitment let record_commitment_input = to_bytes![ diff --git a/symbol-table/tests/mod.rs b/symbol-table/tests/mod.rs index a0db2ba170..ccb84e1170 100644 --- a/symbol-table/tests/mod.rs +++ b/symbol-table/tests/mod.rs @@ -27,12 +27,12 @@ const TEST_PROGRAM_PATH: &str = ""; /// A helper struct to test a `SymbolTable`. pub struct TestSymbolTable { - typed: LeoAst, + ast: LeoAst, } impl TestSymbolTable { /// - /// Returns a typed syntax tree given a Leo program. + /// Returns a Leo syntax tree given a Leo program. /// pub fn new(bytes: &[u8]) -> Self { // Get file string from bytes. @@ -42,22 +42,22 @@ impl TestSymbolTable { let file_path = PathBuf::from(TEST_PROGRAM_PATH); // Get parser syntax tree - let ast = Grammar::new(&file_path, &*file_string).unwrap(); + let grammar = Grammar::new(&file_path, &*file_string).unwrap(); - // Get typed syntax tree - let typed = LeoAst::new(TEST_PROGRAM_PATH, &ast); + // Get Leo syntax tree + let ast = LeoAst::new(TEST_PROGRAM_PATH, &grammar); - Self { typed } + Self { ast } } /// - /// Parse the typed syntax tree into a symbol table. + /// Parse the Leo syntax tree into a symbol table. /// /// Expect no errors during parsing. /// pub fn expect_success(self) { // Get program. - let program = self.typed.into_repr(); + let program = self.ast.into_repr(); // Create empty import parser. let import_parser = ImportParser::default(); @@ -70,13 +70,13 @@ impl TestSymbolTable { } /// - /// Parse the typed syntax tree into a symbol table. + /// Parse the Leo syntax tree into a symbol table. /// /// Expect an error involving entries in the symbol table. /// pub fn expect_pass_one_error(self) { // Get program. - let program = self.typed.into_repr(); + let program = self.ast.into_repr(); // Create new symbol table. let static_check = &mut SymbolTable::default(); @@ -94,13 +94,13 @@ impl TestSymbolTable { } /// - /// Parse the typed syntax tree into a symbol table. + /// Parse the Leo syntax tree into a symbol table. /// /// Expect an error involving types in the symbol table. /// pub fn expect_pass_two_error(self) { // Get program. - let program = self.typed.into_repr(); + let program = self.ast.into_repr(); // Create a new symbol table. let static_check = &mut SymbolTable::default(); From eb301d310bd66378e5a8ca056c31a10e5527a93d Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 11 Nov 2020 14:32:46 -0800 Subject: [PATCH 138/139] separate type-inference module --- Cargo.lock | 14 - Cargo.toml | 1 - compiler/Cargo.toml | 6 +- compiler/src/compiler.rs | 22 +- compiler/src/errors/compiler.rs | 9 +- compiler/tests/boolean/mod.rs | 29 +- compiler/tests/circuits/mod.rs | 170 +-- .../core/packages/unstable/blake2s/mod.rs | 39 +- compiler/tests/function/mod.rs | 37 +- compiler/tests/mod.rs | 8 +- compiler/tests/mutability/mod.rs | 32 +- compiler/tests/statements/mod.rs | 16 +- compiler/tests/syntax/mod.rs | 28 +- type-inference/Cargo.toml | 43 - type-inference/src/assertions/mod.rs | 27 - .../src/assertions/type_assertion.rs | 74 - .../src/assertions/type_equality.rs | 68 - .../src/assertions/type_membership.rs | 71 - .../src/assertions/type_variable_pair.rs | 137 -- type-inference/src/errors/frame.rs | 240 ---- type-inference/src/errors/mod.rs | 30 - type-inference/src/errors/scope.rs | 42 - type-inference/src/errors/type_assertion.rs | 89 -- type-inference/src/errors/type_inference.rs | 42 - type-inference/src/errors/variable_table.rs | 53 - type-inference/src/lib.rs | 37 - type-inference/src/objects/frame.rs | 1210 ----------------- type-inference/src/objects/mod.rs | 24 - type-inference/src/objects/scope.rs | 81 -- type-inference/src/objects/variable_table.rs | 67 - type-inference/src/type_inference.rs | 138 -- type-inference/tests/arrays/empty_array.leo | 3 - .../tests/arrays/invalid_array_access.leo | 5 - .../tests/arrays/invalid_spread.leo | 5 - type-inference/tests/arrays/mod.rs | 44 - .../tests/circuits/invalid_circuit.leo | 4 - type-inference/tests/circuits/mod.rs | 25 - type-inference/tests/empty.leo | 0 .../tests/functions/invalid_function.leo | 4 - type-inference/tests/functions/mod.rs | 25 - type-inference/tests/mod.rs | 84 -- .../tests/tuples/invalid_tuple_access.leo | 5 - type-inference/tests/tuples/mod.rs | 25 - .../tests/variables/duplicate_variable.leo | 4 - .../variables/duplicate_variable_multi.leo | 3 - type-inference/tests/variables/mod.rs | 49 - .../tests/variables/not_enough_values.leo | 3 - .../tests/variables/too_many_values.leo | 3 - 48 files changed, 190 insertions(+), 2985 deletions(-) delete mode 100644 type-inference/Cargo.toml delete mode 100644 type-inference/src/assertions/mod.rs delete mode 100644 type-inference/src/assertions/type_assertion.rs delete mode 100644 type-inference/src/assertions/type_equality.rs delete mode 100644 type-inference/src/assertions/type_membership.rs delete mode 100644 type-inference/src/assertions/type_variable_pair.rs delete mode 100644 type-inference/src/errors/frame.rs delete mode 100644 type-inference/src/errors/mod.rs delete mode 100644 type-inference/src/errors/scope.rs delete mode 100644 type-inference/src/errors/type_assertion.rs delete mode 100644 type-inference/src/errors/type_inference.rs delete mode 100644 type-inference/src/errors/variable_table.rs delete mode 100644 type-inference/src/lib.rs delete mode 100644 type-inference/src/objects/frame.rs delete mode 100644 type-inference/src/objects/mod.rs delete mode 100644 type-inference/src/objects/scope.rs delete mode 100644 type-inference/src/objects/variable_table.rs delete mode 100644 type-inference/src/type_inference.rs delete mode 100644 type-inference/tests/arrays/empty_array.leo delete mode 100644 type-inference/tests/arrays/invalid_array_access.leo delete mode 100644 type-inference/tests/arrays/invalid_spread.leo delete mode 100644 type-inference/tests/arrays/mod.rs delete mode 100644 type-inference/tests/circuits/invalid_circuit.leo delete mode 100644 type-inference/tests/circuits/mod.rs delete mode 100644 type-inference/tests/empty.leo delete mode 100644 type-inference/tests/functions/invalid_function.leo delete mode 100644 type-inference/tests/functions/mod.rs delete mode 100644 type-inference/tests/mod.rs delete mode 100644 type-inference/tests/tuples/invalid_tuple_access.leo delete mode 100644 type-inference/tests/tuples/mod.rs delete mode 100644 type-inference/tests/variables/duplicate_variable.leo delete mode 100644 type-inference/tests/variables/duplicate_variable_multi.leo delete mode 100644 type-inference/tests/variables/mod.rs delete mode 100644 type-inference/tests/variables/not_enough_values.leo delete mode 100644 type-inference/tests/variables/too_many_values.leo diff --git a/Cargo.lock b/Cargo.lock index 5189b77b29..b615fa8454 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1313,7 +1313,6 @@ dependencies = [ "leo-package", "leo-state", "leo-symbol-table", - "leo-type-inference", "num-bigint", "pest", "rand", @@ -1496,19 +1495,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "leo-type-inference" -version = "1.0.4" -dependencies = [ - "leo-ast", - "leo-grammar", - "leo-imports", - "leo-symbol-table", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "libc" version = "0.2.80" diff --git a/Cargo.toml b/Cargo.toml index 25bac29d5d..419353f1a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,6 @@ members = [ "package", "state", "symbol-table", - "type-inference", ] [dependencies.leo-ast] diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 7cb81be57c..e9e94ea3b5 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -53,9 +53,9 @@ version = "1.0.4" path = "../symbol-table" version = "1.0.4" -[dependencies.leo-type-inference] -path = "../type-inference" -version = "1.0.4" +#[dependencies.leo-type-inference] +#path = "../type-inference" +#version = "1.0.4" [dependencies.snarkos-curves] version = "1.1.3" diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 00ec57fe90..ea2cc9ef09 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -30,7 +30,7 @@ use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; use leo_state::verify_local_data_commitment; use leo_symbol_table::SymbolTable; -use leo_type_inference::TypeInference; +// use leo_type_inference::TypeInference; use snarkos_dpc::{base_dpc::instantiated::Components, SystemParameters}; use snarkos_errors::gadgets::SynthesisError; @@ -206,19 +206,19 @@ impl> Compiler { /// pub(crate) fn check_program(&self) -> Result<(), CompilerError> { // Create a new symbol table from the program, imported_programs, and program_input. - let symbol_table = + let _symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input).map_err(|mut e| { e.set_path(&self.main_file_path); e })?; - // Run type inference check on program. - TypeInference::new(&self.program, symbol_table).map_err(|mut e| { - e.set_path(&self.main_file_path); - - e - })?; + // // Run type inference check on program. + // TypeInference::new(&self.program, symbol_table).map_err(|mut e| { + // e.set_path(&self.main_file_path); + // + // e + // })?; tracing::debug!("Program checks complete"); @@ -253,10 +253,10 @@ impl> Compiler { self.imported_programs = ImportParser::parse(&self.program)?; // Create a new symbol table from the program, imported programs, and program input. - let symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; + let _symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; - // Run type inference check on program. - TypeInference::new(&self.program, symbol_table)?; + // // Run type inference check on program. + // TypeInference::new(&self.program, symbol_table)?; tracing::debug!("Program parsing complete\n{:#?}", self.program); diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index f5820ba127..cffd128308 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -20,16 +20,15 @@ use leo_imports::ImportParserError; use leo_input::InputParserError; use leo_state::LocalDataVerificationError; use leo_symbol_table::SymbolTableError; -use leo_type_inference::TypeInferenceError; +// use leo_type_inference::TypeInferenceError; use bincode::Error as SerdeError; use std::path::{Path, PathBuf}; #[derive(Debug, Error)] pub enum CompilerError { - #[error("{}", _0)] - TypeInferenceError(#[from] TypeInferenceError), - + // #[error("{}", _0)] + // TypeInferenceError(#[from] TypeInferenceError), #[error("{}", _0)] ImportError(#[from] ImportError), @@ -79,7 +78,7 @@ pub enum CompilerError { impl CompilerError { pub fn set_path(&mut self, path: &Path) { match self { - CompilerError::TypeInferenceError(error) => error.set_path(path), + // CompilerError::TypeInferenceError(error) => error.set_path(path), CompilerError::InputParserError(error) => error.set_path(path), CompilerError::FunctionError(error) => error.set_path(path), CompilerError::OutputStringError(error) => error.set_path(path), diff --git a/compiler/tests/boolean/mod.rs b/compiler/tests/boolean/mod.rs index 8015cfd335..ac221986d0 100644 --- a/compiler/tests/boolean/mod.rs +++ b/compiler/tests/boolean/mod.rs @@ -17,7 +17,6 @@ use crate::{ assert_satisfied, expect_compiler_error, - expect_type_inference_error, get_output, parse_program, parse_program_with_input, @@ -127,13 +126,13 @@ fn test_false_or_false() { assert_satisfied(program); } -#[test] -fn test_true_or_u32() { - let bytes = include_bytes!("true_or_u32.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_true_or_u32() { +// let bytes = include_bytes!("true_or_u32.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } // Boolean and && @@ -161,13 +160,13 @@ fn test_false_and_false() { assert_satisfied(program); } -#[test] -fn test_true_and_u32() { - let bytes = include_bytes!("true_and_u32.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_true_and_u32() { +// let bytes = include_bytes!("true_and_u32.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } // All diff --git a/compiler/tests/circuits/mod.rs b/compiler/tests/circuits/mod.rs index 33d0d41ea9..df63410d1e 100644 --- a/compiler/tests/circuits/mod.rs +++ b/compiler/tests/circuits/mod.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_compiler_error, expect_type_inference_error, parse_program}; +use crate::{assert_satisfied, expect_compiler_error, parse_program}; // Expressions @@ -34,13 +34,13 @@ fn test_inline_fail() { expect_compiler_error(program); } -#[test] -fn test_inline_undefined() { - let bytes = include_bytes!("inline_undefined.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_inline_undefined() { +// let bytes = include_bytes!("inline_undefined.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } // Members @@ -52,13 +52,13 @@ fn test_member_variable() { assert_satisfied(program); } -#[test] -fn test_member_variable_fail() { - let bytes = include_bytes!("member_variable_fail.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_member_variable_fail() { +// let bytes = include_bytes!("member_variable_fail.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } #[test] fn test_member_variable_and_function() { @@ -76,21 +76,21 @@ fn test_member_function() { assert_satisfied(program); } -#[test] -fn test_member_function_fail() { - let bytes = include_bytes!("member_function_fail.leo"); - let error = parse_program(bytes).err().unwrap(); +// #[test] +// fn test_member_function_fail() { +// let bytes = include_bytes!("member_function_fail.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } - expect_type_inference_error(error); -} - -#[test] -fn test_member_function_invalid() { - let bytes = include_bytes!("member_function_invalid.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_member_function_invalid() { +// let bytes = include_bytes!("member_function_invalid.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } #[test] fn test_member_function_nested() { @@ -116,31 +116,31 @@ fn test_member_static_function_nested() { assert_satisfied(program); } -#[test] -fn test_member_static_function_invalid() { - let bytes = include_bytes!("member_static_function_invalid.leo"); - let error = parse_program(bytes).err().unwrap(); +// #[test] +// fn test_member_static_function_invalid() { +// let bytes = include_bytes!("member_static_function_invalid.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error) +// } - expect_type_inference_error(error) -} - -#[test] -fn test_member_static_function_undefined() { - let bytes = include_bytes!("member_static_function_undefined.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error) -} +// #[test] +// fn test_member_static_function_undefined() { +// let bytes = include_bytes!("member_static_function_undefined.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error) +// } // Mutability -#[test] -fn test_mutate_function_fail() { - let bytes = include_bytes!("mut_function_fail.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_mutate_function_fail() { +// let bytes = include_bytes!("mut_function_fail.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } #[test] fn test_mutate_self_variable() { @@ -158,29 +158,29 @@ fn test_mutate_self_variable_fail() { expect_compiler_error(program); } -#[test] -fn test_mutate_self_function_fail() { - let bytes = include_bytes!("mut_self_function_fail.leo"); - let error = parse_program(bytes).err().unwrap(); +// #[test] +// fn test_mutate_self_function_fail() { +// let bytes = include_bytes!("mut_self_function_fail.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } - expect_type_inference_error(error); -} +// #[test] +// fn test_mutate_self_static_function_fail() { +// let bytes = include_bytes!("mut_self_static_function_fail.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } -#[test] -fn test_mutate_self_static_function_fail() { - let bytes = include_bytes!("mut_self_static_function_fail.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} - -#[test] -fn test_mutate_static_function_fail() { - let bytes = include_bytes!("mut_static_function_fail.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_mutate_static_function_fail() { +// let bytes = include_bytes!("mut_static_function_fail.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } #[test] fn test_mutate_variable() { @@ -200,13 +200,13 @@ fn test_mutate_variable_fail() { // Self -#[test] -fn test_self_fail() { - let bytes = include_bytes!("self_fail.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_self_fail() { +// let bytes = include_bytes!("self_fail.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } #[test] fn test_self_member_pass() { @@ -224,13 +224,13 @@ fn test_self_member_invalid() { let _err = expect_compiler_error(program); } -#[test] -fn test_self_member_undefined() { - let bytes = include_bytes!("self_member_undefined.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_self_member_undefined() { +// let bytes = include_bytes!("self_member_undefined.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } // All diff --git a/compiler/tests/core/packages/unstable/blake2s/mod.rs b/compiler/tests/core/packages/unstable/blake2s/mod.rs index 2b308db42e..1c1476c495 100644 --- a/compiler/tests/core/packages/unstable/blake2s/mod.rs +++ b/compiler/tests/core/packages/unstable/blake2s/mod.rs @@ -14,14 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ - assert_satisfied, - expect_type_inference_error, - generate_main_input, - get_output, - parse_program, - parse_program_with_input, -}; +use crate::{assert_satisfied, generate_main_input, get_output, parse_program, parse_program_with_input}; use leo_ast::InputValue; use leo_input::types::{IntegerType, U8Type, UnsignedIntegerType}; @@ -29,22 +22,22 @@ use rand::{Rng, SeedableRng}; use rand_xorshift::XorShiftRng; use snarkos_algorithms::prf::blake2s::Blake2s as B2SPRF; use snarkos_models::algorithms::PRF; +// +// #[test] +// fn test_arguments_length_fail() { +// let program_bytes = include_bytes!("arguments_length_fail.leo"); +// let error = parse_program(program_bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } -#[test] -fn test_arguments_length_fail() { - let program_bytes = include_bytes!("arguments_length_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); - - expect_type_inference_error(error); -} - -#[test] -fn test_arguments_type_fail() { - let program_bytes = include_bytes!("arguments_type_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_arguments_type_fail() { +// let program_bytes = include_bytes!("arguments_type_fail.leo"); +// let error = parse_program(program_bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } #[test] fn test_blake2s_input() { diff --git a/compiler/tests/function/mod.rs b/compiler/tests/function/mod.rs index 0c62b34e76..a5a4e2c9db 100644 --- a/compiler/tests/function/mod.rs +++ b/compiler/tests/function/mod.rs @@ -14,14 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ - assert_satisfied, - expect_compiler_error, - expect_type_inference_error, - get_output, - parse_program, - parse_program_with_input, -}; +use crate::{assert_satisfied, expect_compiler_error, get_output, parse_program, parse_program_with_input}; use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError}; #[test] @@ -117,13 +110,13 @@ fn test_scope_fail() { } } -#[test] -fn test_undefined() { - let bytes = include_bytes!("undefined.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_undefined() { +// let bytes = include_bytes!("undefined.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } #[test] fn test_value_unchanged() { @@ -133,13 +126,13 @@ fn test_value_unchanged() { assert_satisfied(program); } -#[test] -fn test_array_input() { - let bytes = include_bytes!("array_input.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error) -} +// #[test] +// fn test_array_input() { +// let bytes = include_bytes!("array_input.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error) +// } // Test return multidimensional arrays diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index a18efa9428..57cb8f3d2c 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -180,10 +180,10 @@ pub(crate) fn expect_compiler_error(program: EdwardsTestCompiler) -> CompilerErr let mut cs = TestConstraintSystem::::new(); program.generate_constraints_helper(&mut cs).unwrap_err() } - -pub(crate) fn expect_type_inference_error(error: CompilerError) { - assert!(matches!(error, CompilerError::TypeInferenceError(_))) -} +// +// pub(crate) fn expect_type_inference_error(error: CompilerError) { +// assert!(matches!(error, CompilerError::TypeInferenceError(_))) +// } pub(crate) fn expect_symbol_table_error(error: CompilerError) { assert!(matches!(error, CompilerError::SymbolTableError(_))) diff --git a/compiler/tests/mutability/mod.rs b/compiler/tests/mutability/mod.rs index 8442357044..861ffd6a64 100644 --- a/compiler/tests/mutability/mod.rs +++ b/compiler/tests/mutability/mod.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_compiler_error, expect_type_inference_error, generate_main_input, parse_program}; +use crate::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program}; use leo_ast::InputValue; #[test] @@ -89,21 +89,21 @@ fn test_circuit_variable_mut() { assert_satisfied(program); } -#[test] -fn test_circuit_function_mut() { - let bytes = include_bytes!("circuit_function_mut.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} - -#[test] -fn test_circuit_static_function_mut() { - let bytes = include_bytes!("circuit_static_function_mut.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_circuit_function_mut() { +// let bytes = include_bytes!("circuit_function_mut.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } +// +// #[test] +// fn test_circuit_static_function_mut() { +// let bytes = include_bytes!("circuit_static_function_mut.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } #[test] fn test_function_input() { diff --git a/compiler/tests/statements/mod.rs b/compiler/tests/statements/mod.rs index 4680bee86d..b5599d2dd5 100644 --- a/compiler/tests/statements/mod.rs +++ b/compiler/tests/statements/mod.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{assert_satisfied, expect_type_inference_error, generate_main_input, parse_program}; +use crate::{assert_satisfied, generate_main_input, parse_program}; use leo_ast::InputValue; pub mod conditional; @@ -57,10 +57,10 @@ fn test_iteration_basic() { assert_satisfied(program); } -#[test] -fn test_num_returns_fail() { - let bytes = include_bytes!("num_returns_fail.leo"); - let error = parse_program(bytes).err().unwrap(); - - expect_type_inference_error(error); -} +// #[test] +// fn test_num_returns_fail() { +// let bytes = include_bytes!("num_returns_fail.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// expect_type_inference_error(error); +// } diff --git a/compiler/tests/syntax/mod.rs b/compiler/tests/syntax/mod.rs index 55b7292d2a..9cd6aaf3f5 100644 --- a/compiler/tests/syntax/mod.rs +++ b/compiler/tests/syntax/mod.rs @@ -18,7 +18,7 @@ use crate::{expect_compiler_error, parse_input, parse_program}; use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError}; use leo_grammar::ParserError; use leo_input::InputParserError; -use leo_type_inference::errors::{FrameError, TypeAssertionError, TypeInferenceError}; +// use leo_type_inference::errors::{FrameError, TypeAssertionError, TypeInferenceError}; pub mod identifiers; @@ -75,16 +75,16 @@ fn input_syntax_error() { } } -#[test] -fn test_compare_mismatched_types() { - let bytes = include_bytes!("compare_mismatched_types.leo"); - let error = parse_program(bytes).err().unwrap(); - - // Expect a type inference error. - match error { - CompilerError::TypeInferenceError(TypeInferenceError::FrameError(FrameError::TypeAssertionError( - TypeAssertionError::Error(_), - ))) => {} - error => panic!("Expected type inference error, found {}", error), - } -} +// #[test] +// fn test_compare_mismatched_types() { +// let bytes = include_bytes!("compare_mismatched_types.leo"); +// let error = parse_program(bytes).err().unwrap(); +// +// // Expect a type inference error. +// match error { +// CompilerError::TypeInferenceError(TypeInferenceError::FrameError(FrameError::TypeAssertionError( +// TypeAssertionError::Error(_), +// ))) => {} +// error => panic!("Expected type inference error, found {}", error), +// } +// } diff --git a/type-inference/Cargo.toml b/type-inference/Cargo.toml deleted file mode 100644 index a0f38f7418..0000000000 --- a/type-inference/Cargo.toml +++ /dev/null @@ -1,43 +0,0 @@ -[package] -name = "leo-type-inference" -version = "1.0.4" -authors = [ "The Aleo Team " ] -description = "Checks that a program is correct using type inference" -homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/leo" -keywords = [ - "aleo", - "cryptography", - "leo", - "programming-language", - "zero-knowledge" -] -categories = [ "cryptography::croptocurrencies", "web-programming" ] -include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] -license = "GPL-3.0" -edition = "2018" - -[dependencies.leo-ast] -path = "../ast" -version = "1.0.4" - -[dependencies.leo-imports] -path = "../imports" -version = "1.0.4" - -[dependencies.leo-grammar] -path = "../grammar" -version = "1.0.4" - -[dependencies.leo-symbol-table] -path = "../symbol-table" -version = "1.0.4" - -[dependencies.serde_json] -version = "1.0" - -[dependencies.serde] -version = "1.0" - -[dependencies.thiserror] -version = "1.0" \ No newline at end of file diff --git a/type-inference/src/assertions/mod.rs b/type-inference/src/assertions/mod.rs deleted file mode 100644 index d98b3aad82..0000000000 --- a/type-inference/src/assertions/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -pub mod type_assertion; -pub use self::type_assertion::*; - -pub mod type_equality; -pub use self::type_equality::*; - -pub mod type_membership; -pub use self::type_membership::*; - -pub mod type_variable_pair; -pub use self::type_variable_pair::*; diff --git a/type-inference/src/assertions/type_assertion.rs b/type-inference/src/assertions/type_assertion.rs deleted file mode 100644 index 8baf98f5b0..0000000000 --- a/type-inference/src/assertions/type_assertion.rs +++ /dev/null @@ -1,74 +0,0 @@ -// 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 . - -use crate::{TypeAssertionError, TypeEquality, TypeMembership, TypeVariablePairs}; -use leo_ast::Span; -use leo_symbol_table::{Type, TypeVariable}; - -use serde::{Deserialize, Serialize}; - -/// A predicate that evaluates equality between two `Types`s. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub enum TypeAssertion { - Equality(TypeEquality), - Membership(TypeMembership), -} - -impl TypeAssertion { - /// - /// Returns a `TypeAssertion::Equality` predicate from given left and right `Types`s. - /// - pub fn new_equality(left: Type, right: Type, span: &Span) -> Self { - Self::Equality(TypeEquality::new(left, right, span)) - } - - /// - /// Returns a `TypeAssertion::Membership` predicate from given and set `Type`s. - /// - pub fn new_membership(given: Type, set: Vec, span: &Span) -> Self { - Self::Membership(TypeMembership::new(given, set, span)) - } - - /// - /// Returns one or more `TypeVariablePairs` generated by the given `TypeAssertion`. - /// - pub fn pairs(&self) -> Result { - match self { - TypeAssertion::Equality(equality) => equality.pairs(), - TypeAssertion::Membership(membership) => Err(TypeAssertionError::membership_pairs(membership)), - } - } - - /// - /// Substitutes the given type for self if self is equal to the type variable. - /// - pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { - match self { - TypeAssertion::Equality(equality) => equality.substitute(variable, type_), - TypeAssertion::Membership(membership) => membership.substitute(variable, type_), - } - } - - /// - /// Checks if the `TypeAssertion` is satisfied. - /// - pub fn evaluate(&self) -> Result<(), TypeAssertionError> { - match self { - TypeAssertion::Equality(equality) => equality.evaluate(), - TypeAssertion::Membership(membership) => membership.evaluate(), - } - } -} diff --git a/type-inference/src/assertions/type_equality.rs b/type-inference/src/assertions/type_equality.rs deleted file mode 100644 index f20fd696ce..0000000000 --- a/type-inference/src/assertions/type_equality.rs +++ /dev/null @@ -1,68 +0,0 @@ -// 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 . - -use crate::{TypeAssertionError, TypeVariablePairs}; -use leo_ast::Span; -use leo_symbol_table::{Type, TypeVariable}; - -use serde::{Deserialize, Serialize}; - -/// A predicate that evaluates equality between two `Type`s. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct TypeEquality { - left: Type, - right: Type, - span: Span, -} - -impl TypeEquality { - /// - /// Returns a `TypeEquality` predicate from given left and right `Types`s - /// - pub fn new(left: Type, right: Type, span: &Span) -> Self { - Self { - left, - right, - span: span.to_owned(), - } - } - - /// - /// Substitutes the given `TypeVariable` for each `Types` in the `TypeEquality`. - /// - pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { - self.left.substitute(variable, type_); - self.right.substitute(variable, type_); - } - - /// - /// Checks if the `self.left` == `self.right`. - /// - pub fn evaluate(&self) -> Result<(), TypeAssertionError> { - if self.left.eq(&self.right) { - Ok(()) - } else { - Err(TypeAssertionError::equality_failed(&self.left, &self.right, &self.span)) - } - } - - /// - /// Returns the (type variable, type) pair from this assertion. - /// - pub fn pairs(&self) -> Result { - TypeVariablePairs::new(self.left.to_owned(), self.right.to_owned(), &self.span) - } -} diff --git a/type-inference/src/assertions/type_membership.rs b/type-inference/src/assertions/type_membership.rs deleted file mode 100644 index 5df0edb0c7..0000000000 --- a/type-inference/src/assertions/type_membership.rs +++ /dev/null @@ -1,71 +0,0 @@ -// 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 . - -use crate::TypeAssertionError; -use leo_ast::Span; -use leo_symbol_table::{Type, TypeVariable}; - -use serde::{Deserialize, Serialize}; - -/// A predicate that evaluates to true if the given type is equal to a member in the set vector of types. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct TypeMembership { - given: Type, - set: Vec, - span: Span, -} - -impl TypeMembership { - /// - /// Returns a `TypeMembership` predicate from given and set `Type`s. - /// - pub fn new(given: Type, set: Vec, span: &Span) -> Self { - Self { - given, - set, - span: span.to_owned(), - } - } - - /// - /// Substitutes the given `TypeVariable` for each `Type` in the `TypeMembership`. - /// - pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { - self.given.substitute(variable, type_) - } - - /// - /// Returns true if the given type is equal to a member of the set. - /// - pub fn evaluate(&self) -> Result<(), TypeAssertionError> { - if self.set.contains(&self.given) { - Ok(()) - } else { - Err(TypeAssertionError::membership_failed( - &self.given, - &self.set, - &self.span, - )) - } - } - - /// - /// Returns the self.span. - /// - pub fn span(&self) -> &Span { - &self.span - } -} diff --git a/type-inference/src/assertions/type_variable_pair.rs b/type-inference/src/assertions/type_variable_pair.rs deleted file mode 100644 index e7cca2b2e6..0000000000 --- a/type-inference/src/assertions/type_variable_pair.rs +++ /dev/null @@ -1,137 +0,0 @@ -// 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 . - -use crate::TypeAssertionError; -use leo_ast::Span; -use leo_symbol_table::{get_array_element_type, Type, TypeVariable}; - -/// A type variable -> type pair. -pub struct TypeVariablePair(TypeVariable, Type); - -impl TypeVariablePair { - pub fn first(&self) -> &TypeVariable { - &self.0 - } - - pub fn second(&self) -> &Type { - &self.1 - } -} - -/// A vector of `TypeVariablePair`s. -pub struct TypeVariablePairs(Vec); - -impl Default for TypeVariablePairs { - fn default() -> Self { - Self(Vec::new()) - } -} - -impl TypeVariablePairs { - /// - /// Returns a new `TypeVariablePairs` struct from the given left and right types. - /// - pub fn new(left: Type, right: Type, span: &Span) -> Result { - let mut pairs = Self::default(); - - // Push all `TypeVariablePair`s. - pairs.push_pairs(left, right, span)?; - - Ok(pairs) - } - - /// - /// Returns true if the self vector has no pairs. - /// - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - /// - /// Returns the self vector of pairs. - /// - pub fn get_pairs(&self) -> &[TypeVariablePair] { - &self.0 - } - - /// - /// Pushes a new `TypeVariablePair` struct to self. - /// - pub fn push(&mut self, variable: TypeVariable, type_: Type) { - // Create a new type variable -> type pair. - let pair = TypeVariablePair(variable, type_); - - // Push the pair to the self vector. - self.0.push(pair); - } - - /// - /// Checks if the given left or right type contains a `TypeVariable`. - /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left - /// and right type. - /// - pub fn push_pairs(&mut self, left: Type, right: Type, span: &Span) -> Result<(), TypeAssertionError> { - match (left, right) { - (Type::TypeVariable(variable), type_) => { - self.push(variable, type_); - Ok(()) - } - (type_, Type::TypeVariable(variable)) => { - self.push(variable, type_); - Ok(()) - } - (Type::Array(left_type), Type::Array(right_type)) => self.push_pairs_array(*left_type, *right_type, span), - (Type::Tuple(left_types), Type::Tuple(right_types)) => { - self.push_pairs_tuple(left_types.into_iter(), right_types.into_iter(), span) - } - (_, _) => Ok(()), // No `TypeVariable` found so we do not push any pairs. - } - } - - /// - /// Checks if the given left or right array type contains a `TypeVariable`. - /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left - /// and right type. - /// - fn push_pairs_array(&mut self, left_type: Type, right_type: Type, span: &Span) -> Result<(), TypeAssertionError> { - // Get both array element types before comparison. - let array1_element = get_array_element_type(&left_type); - let array2_element = get_array_element_type(&right_type); - - // Compare the array element types. - self.push_pairs(array1_element.to_owned(), array2_element.to_owned(), span) - } - - /// - /// Checks if any given left or right tuple type contains a `TypeVariable`. - /// If a `TypeVariable` is found, create a new `TypeVariablePair` between the given left - /// and right type. - /// - fn push_pairs_tuple( - &mut self, - left_types: impl Iterator, - right_types: impl Iterator, - span: &Span, - ) -> Result<(), TypeAssertionError> { - // Iterate over each left == right pair of types. - for (left, right) in left_types.into_iter().zip(right_types) { - // Check for `TypeVariablePair`s. - self.push_pairs(left, right, span)?; - } - - Ok(()) - } -} diff --git a/type-inference/src/errors/frame.rs b/type-inference/src/errors/frame.rs deleted file mode 100644 index 36e8576832..0000000000 --- a/type-inference/src/errors/frame.rs +++ /dev/null @@ -1,240 +0,0 @@ -// 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 . - -use crate::{ScopeError, TypeAssertionError}; -use leo_ast::{Error as FormattedError, Expression, Identifier, Span}; -use leo_symbol_table::{Type, TypeError}; - -use std::path::Path; - -/// Errors encountered when tracking variable names in a program. -#[derive(Debug, Error)] -pub enum FrameError { - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - ScopeError(#[from] ScopeError), - - #[error("{}", _0)] - TypeAssertionError(#[from] TypeAssertionError), - - #[error("{}", _0)] - TypeError(#[from] TypeError), -} - -impl FrameError { - /// - /// Set the filepath for the error stacktrace - /// - pub fn set_path(&mut self, path: &Path) { - match self { - FrameError::Error(error) => error.set_path(path), - FrameError::ScopeError(error) => error.set_path(path), - FrameError::TypeAssertionError(error) => error.set_path(path), - FrameError::TypeError(error) => error.set_path(path), - } - } - - /// - /// Return a new formatted error with a given message and span information - /// - fn new_from_span(message: String, span: &Span) -> Self { - FrameError::Error(FormattedError::new_from_span(message, span.to_owned())) - } - - /// - /// Attempted to access the index of a non-array type. - /// - pub fn array_access(actual: &Type, span: &Span) -> Self { - let message = format!("Cannot access the index of non-array type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to access the `Self` type outside of a circuit context. - /// - pub fn circuit_self(span: &Span) -> Self { - let message = "The `Self` keyword is only valid inside a circuit context.".to_string(); - - Self::new_from_span(message, span) - } - - /// - /// Two variables have been defined with the same name. - /// - pub fn duplicate_variable(name: &str, span: &Span) -> Self { - let message = format!("Duplicate variable definition found for `{}`", name); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to create an empty array in a Leo program. - /// - /// Arrays in Leo are not resizeable so defining empty arrays are effectively dead code. - /// - pub fn empty_array(span: &Span) -> Self { - let message = "Cannot create an empty array in a Leo program.".to_string(); - - Self::new_from_span(message, span) - } - - /// - /// Expected a circuit name but found a different type. - /// - pub fn invalid_circuit(type_: Type, span: &Span) -> Self { - let message = format!("Expected a circuit type. Found type `{}`.", type_); - - Self::new_from_span(message, span) - } - - /// - /// Expected a function name but found a different expression. - /// - pub fn invalid_function(expression: &Expression, span: &Span) -> Self { - let message = format!("Expected a function name. Found expression `{}`.", expression); - - Self::new_from_span(message, span) - } - - /// - /// Expected a usize number for the index. - /// - pub fn invalid_index(actual: String, span: &Span) -> Self { - let message = format!("Expected constant number for index, found `{}`", actual); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to call non-static member using `::`. - /// - pub fn invalid_member_access(identifier: &Identifier) -> Self { - let message = format!("non-static member `{}` must be accessed using `.` syntax.", identifier); - - Self::new_from_span(message, &identifier.span) - } - - /// - /// Attempted to use the spread operator on a non-array type. - /// - pub fn invalid_spread(actual: Type, span: &Span) -> Self { - let message = format!( - "The spread operator `...` can only be applied to array types. Found type `{}`.", - actual - ); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to call static member using `.`. - /// - pub fn invalid_static_access(identifier: &Identifier) -> Self { - let message = format!("Static member `{}` must be accessed using `::` syntax.", identifier); - - Self::new_from_span(message, &identifier.span) - } - - /// - /// Attempted to create a circuit with the incorrect number of member variables. - /// - pub fn num_circuit_variables(expected: usize, actual: usize, span: &Span) -> Self { - let message = format!("Circuit expected {} variables, found {} variables.", expected, actual); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to call a function with the incorrect number of inputs. - /// - pub fn num_inputs(expected: usize, actual: usize, span: &Span) -> Self { - let message = format!( - "Function expected {} input variables, found {} inputs.", - expected, actual - ); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to access the index of a non-tuple type. - /// - pub fn tuple_access(actual: &Type, span: &Span) -> Self { - let message = format!("Cannot access the index of non-tuple type `{}`.", actual); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to call a circuit type that is not defined in the current context. - /// - pub fn undefined_circuit(identifier: &Identifier) -> Self { - let message = format!("The circuit `{}` is not defined.", identifier); - - Self::new_from_span(message, &identifier.span) - } - - /// - /// Attempted to call a circuit function that is not defined in the current context. - /// - pub fn undefined_circuit_function(identifier: &Identifier) -> Self { - let message = format!("The circuit function `{}` is not defined.", identifier); - - Self::new_from_span(message, &identifier.span) - } - - /// - /// Attempted to call a function that is not defined in the current context. - /// - pub fn undefined_function(identifier: &Identifier) -> Self { - let message = format!("The function `{}` is not defined.", identifier); - - Self::new_from_span(message, &identifier.span) - } - - /// - /// Attempted to call a variable that is not defined in the current context. - /// - pub fn undefined_variable(identifier: &Identifier) -> Self { - let message = format!("The variable `{}` is not defined.", identifier); - - Self::new_from_span(message, &identifier.span) - } - - /// - /// Attempted to assign a tuple of variables to a single value. - /// - pub fn not_enough_values(span: &Span) -> Self { - let message = "Expected a tuple type for multiple defined variables".to_string(); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to assign a tuple with a different number of variables than values. - /// - pub fn invalid_number_of_values(expected: usize, actual: usize, span: &Span) -> Self { - let message = format!( - "Incorrect number of defined variables. Expected `{}`, found `{}`.", - expected, actual - ); - - Self::new_from_span(message, span) - } -} diff --git a/type-inference/src/errors/mod.rs b/type-inference/src/errors/mod.rs deleted file mode 100644 index 629a558e2f..0000000000 --- a/type-inference/src/errors/mod.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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 . - -pub mod frame; -pub use self::frame::*; - -pub mod scope; -pub use self::scope::*; - -pub mod type_assertion; -pub use self::type_assertion::*; - -pub mod type_inference; -pub use self::type_inference::*; - -pub mod variable_table; -pub use self::variable_table::*; diff --git a/type-inference/src/errors/scope.rs b/type-inference/src/errors/scope.rs deleted file mode 100644 index e31c3aaea4..0000000000 --- a/type-inference/src/errors/scope.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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 . - -use crate::VariableTableError; -use leo_ast::Error as FormattedError; - -use std::path::Path; - -/// Errors encountered when evaluating variables in a scope. -#[derive(Debug, Error)] -pub enum ScopeError { - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - VariableTableError(#[from] VariableTableError), -} - -impl ScopeError { - /// - /// Set the filepath for the error stacktrace. - /// - pub fn set_path(&mut self, path: &Path) { - match self { - ScopeError::Error(error) => error.set_path(path), - ScopeError::VariableTableError(error) => error.set_path(path), - } - } -} diff --git a/type-inference/src/errors/type_assertion.rs b/type-inference/src/errors/type_assertion.rs deleted file mode 100644 index a2da4a6c08..0000000000 --- a/type-inference/src/errors/type_assertion.rs +++ /dev/null @@ -1,89 +0,0 @@ -// 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 . - -use crate::TypeMembership; - -use leo_ast::{Error as FormattedError, Span}; -use leo_symbol_table::Type; - -use std::path::Path; - -/// Errors encountered when attempting to solve a type assertion. -#[derive(Debug, Error)] -pub enum TypeAssertionError { - #[error("{}", _0)] - Error(#[from] FormattedError), -} - -impl TypeAssertionError { - /// - /// Set the filepath for the error stacktrace. - /// - pub fn set_path(&mut self, path: &Path) { - match self { - TypeAssertionError::Error(error) => error.set_path(path), - } - } - - /// - /// Returns a new formatted error with a given message and span information. - /// - fn new_from_span(message: String, span: &Span) -> Self { - TypeAssertionError::Error(FormattedError::new_from_span(message, span.to_owned())) - } - - /// - /// Found mismatched types during program parsing. - /// - pub fn equality_failed(left: &Type, right: &Type, span: &Span) -> Self { - let message = format!("Mismatched types. Expected type `{}`, found type `{}`.", left, right); - - Self::new_from_span(message, span) - } - - /// - /// Given type is not a member of the set of expected types. - /// - pub fn membership_failed(given: &Type, set: &[Type], span: &Span) -> Self { - let message = format!( - "Mismatched types. Given type `{}` is not in the expected type set `{:?}`.", - given, set - ); - - Self::new_from_span(message, span) - } - - /// - /// Attempted to generate pairs from a membership assertion. - /// - pub fn membership_pairs(membership: &TypeMembership) -> Self { - let message = "Cannot generate a type variable -> type pair for the given type membership".to_string(); - - Self::new_from_span(message, membership.span()) - } - - /// - /// Mismatched array type dimensions. - /// - pub fn array_dimensions(dimensions1: &[usize], dimensions2: &[usize], span: &Span) -> Self { - let message = format!( - "Expected array with dimensions `{:?}`, found array with dimensions `{:?}`.", - dimensions1, dimensions2 - ); - - Self::new_from_span(message, span) - } -} diff --git a/type-inference/src/errors/type_inference.rs b/type-inference/src/errors/type_inference.rs deleted file mode 100644 index dac08fc59b..0000000000 --- a/type-inference/src/errors/type_inference.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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 . - -use crate::FrameError; -use leo_ast::Error as FormattedError; - -use std::path::Path; - -/// Errors encountered when running type inference checks. -#[derive(Debug, Error)] -pub enum TypeInferenceError { - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - FrameError(#[from] FrameError), -} - -impl TypeInferenceError { - /// - /// Set the filepath for the error stacktrace. - /// - pub fn set_path(&mut self, path: &Path) { - match self { - TypeInferenceError::Error(error) => error.set_path(path), - TypeInferenceError::FrameError(error) => error.set_path(path), - } - } -} diff --git a/type-inference/src/errors/variable_table.rs b/type-inference/src/errors/variable_table.rs deleted file mode 100644 index bb26dfb7e6..0000000000 --- a/type-inference/src/errors/variable_table.rs +++ /dev/null @@ -1,53 +0,0 @@ -// 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 . - -use leo_ast::{Error as FormattedError, Span}; - -use std::path::Path; - -/// Errors encountered when tracking variable names in a program. -#[derive(Debug, Error)] -pub enum VariableTableError { - #[error("{}", _0)] - Error(#[from] FormattedError), -} - -impl VariableTableError { - /// - /// Set the filepath for the error stacktrace - /// - pub fn set_path(&mut self, path: &Path) { - match self { - VariableTableError::Error(error) => error.set_path(path), - } - } - - /// - /// Return a new formatted error with a given message and span information - /// - fn new_from_span(message: String, span: Span) -> Self { - VariableTableError::Error(FormattedError::new_from_span(message, span)) - } - - /// - /// Attempted to lookup a variable name that does not exist in the table. - /// - pub fn undefined_variable_name(name: &str, span: &Span) -> Self { - let message = format!("Cannot find variable `{}` in this scope.", name); - - Self::new_from_span(message, span.clone()) - } -} diff --git a/type-inference/src/lib.rs b/type-inference/src/lib.rs deleted file mode 100644 index ab20d42409..0000000000 --- a/type-inference/src/lib.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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 . - -//! A type inference check for a Leo program. -//! -//! This module contains the [`TypeInference`] type, which stores information needed to run a type -//! inference check over a program. -//! -//! A new [`TypeInference`] type can be created from a [`LeoAst`] type and a [`Symbol Table`]. - -#[macro_use] -extern crate thiserror; - -pub mod assertions; -pub use self::assertions::*; - -pub mod type_inference; -pub use self::type_inference::*; - -pub mod errors; -pub use self::errors::*; - -pub mod objects; -pub use self::objects::*; diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs deleted file mode 100644 index 0daeba20dd..0000000000 --- a/type-inference/src/objects/frame.rs +++ /dev/null @@ -1,1210 +0,0 @@ -// 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 . - -use crate::{FrameError, Scope, TypeAssertion}; -use leo_ast::{ - ArrayDimensions, - Assignee, - AssigneeAccess, - CircuitVariableDefinition, - ConditionalNestedOrEndStatement, - ConditionalStatement, - Declare, - Expression, - Function, - Identifier, - IntegerType, - PositiveNumber, - RangeOrExpression, - Span, - SpreadOrExpression, - Statement, - Variables, -}; -use leo_symbol_table::{Attribute, CircuitFunctionType, CircuitType, FunctionType, SymbolTable, Type, TypeVariable}; - -/// A vector of `TypeAssertion` predicates created from a function body. -#[derive(Clone)] -pub struct Frame { - pub function_type: FunctionType, - pub self_type: Option, - pub scopes: Vec, - pub statements: Vec, - pub type_assertions: Vec, - pub user_defined_types: SymbolTable, -} - -impl Frame { - /// - /// Collects a vector of `TypeAssertion` predicates from a function. - /// - pub fn new_function( - function: Function, - self_type: Option, - parent_scope: Option, - user_defined_types: SymbolTable, - ) -> Result { - let name = &function.identifier.name; - - // Get function type from symbol table. - let function_type = user_defined_types.get_function_type(name).unwrap().clone(); - - // Create a new scope for the function variables. - let mut scope = Scope::new(parent_scope); - - // Initialize function inputs as variables. - scope.insert_function_inputs(&function_type.inputs)?; - - // Create new list of scopes for frame. - let scopes = vec![scope]; - - // Create new frame struct. - // Update variables when encountering let/const variable definitions. - let mut frame = Self { - function_type, - self_type, - scopes, - statements: function.statements, - type_assertions: vec![], - user_defined_types, - }; - - // Create type assertions for function statements - frame.parse_statements()?; - - Ok(frame) - } - - /// - /// Collects vector of `TypeAssertion` predicates from a circuit function. - /// - pub fn new_circuit_function( - function: Function, - self_type: CircuitType, - parent_scope: Scope, - user_defined_types: SymbolTable, - ) -> Result { - let identifier = &function.identifier; - - // Find function name in circuit members. - let circuit_function_type = self_type.member_function_type(identifier).unwrap().to_owned(); - - // Create a new scope for the function variables. - let mut scope = Scope::new(Some(parent_scope)); - - // Initialize function inputs as variables. - scope.insert_function_inputs(&circuit_function_type.function.inputs)?; - - // Create new list of scopes for frame. - let scopes = vec![scope]; - - // Create new frame struct. - // Update variables when encountering let/const variable definitions. - let mut frame = Self { - function_type: circuit_function_type.function, - self_type: Some(self_type), - scopes, - statements: function.statements, - type_assertions: Vec::new(), - user_defined_types, - }; - - // Create type assertions for function statements - frame.parse_statements()?; - - Ok(frame) - } - - /// - /// Pushes a new variable `Scope` to the list of scopes in the current `Frame`. - /// - fn push_scope(&mut self, scope: Scope) { - self.scopes.push(scope) - } - - /// - /// Removes and returns the most recent `Scope` from the list of scopes in the current `Frame`. - /// - fn pop_scope(&mut self) -> Option { - self.scopes.pop() - } - - /// - /// Insert a variable into the symbol table in the current scope. - /// - fn insert_variable(&mut self, name: String, type_: Type, span: &Span) -> Result<(), FrameError> { - // Modify the current scope. - let scope = self.scopes.last_mut().unwrap(); - - // Insert the variable name -> type. - match scope.variables.insert(name.clone(), type_) { - Some(_type) => Err(FrameError::duplicate_variable(&name, span)), - None => Ok(()), - } - } - - /// - /// Get a variable's type from the symbol table in the current scope. - /// - fn get_variable(&self, name: &str) -> Option<&Type> { - // Lookup in the current scope. - let scope = self.scopes.last().unwrap(); - - // Get the variable by name. - scope.get_variable(name) - } - - /// - /// Get a function's type from the user defined types in the current scope. - /// - fn get_function(&self, name: &str) -> Option<&FunctionType> { - self.user_defined_types.get_function_type(name) - } - - /// - /// Get a circuit's type from the user defined types in the current scope. - /// - fn get_circuit(&self, name: &str) -> Option<&CircuitType> { - self.user_defined_types.get_circuit_type(name) - } - - /// - /// Creates a new equality type assertion between the given types. - /// - fn assert_equal(&mut self, left: Type, right: Type, span: &Span) { - let type_assertion = TypeAssertion::new_equality(left, right, span); - - self.type_assertions.push(type_assertion); - } - - /// - /// Creates a new membership type assertion between a given and set of types. - /// - fn assert_membership(&mut self, given: Type, set: Vec, span: &Span) { - let type_assertion = TypeAssertion::new_membership(given, set, span); - - self.type_assertions.push(type_assertion); - } - - /// - /// Creates a new membership type assertion between a given and the set of negative integer types. - /// - fn assert_negative_integer(&mut self, given: &Type, span: &Span) { - let negative_integer_types = Type::negative_integer_types(); - - self.assert_membership(given.clone(), negative_integer_types, span) - } - - /// - /// Creates a new membership type assertion between a given and the set of all integer types. - /// - fn assert_integer(&mut self, given: &Type, span: &Span) { - let integer_types = Type::integer_types(); - - self.assert_membership(given.clone(), integer_types, span) - } - - /// - /// Creates a new membership type assertion between a given and the set of index types. - /// - fn assert_index(&mut self, given: &Type, span: &Span) { - let index_types = Type::index_types(); - - self.assert_membership(given.clone(), index_types, span) - } - - /// - /// Collects a vector of `TypeAssertion` predicates from a vector of statements. - /// - fn parse_statements(&mut self) -> Result<(), FrameError> { - for statement in self.statements.clone() { - self.parse_statement(&statement)?; - } - - Ok(()) - } - - /// - /// Collects a vector of `TypeAssertion` predicates from a statement. - /// - fn parse_statement(&mut self, statement: &Statement) -> Result<(), FrameError> { - match statement { - Statement::Return(expression, span) => self.parse_return(expression, span), - Statement::Definition(declare, variables, expression, span) => { - self.parse_definition(declare, variables, expression, span) - } - Statement::Assign(assignee, expression, span) => self.parse_assign(assignee, expression, span), - Statement::Conditional(conditional, span) => self.parse_statement_conditional(conditional, span), - Statement::Iteration(identifier, from_to, statements, span) => { - self.parse_iteration(identifier, from_to, statements, span) - } - Statement::Expression(expression, span) => self.parse_statement_expression(expression, span), - Statement::Console(_console_call) => Ok(()), // Console function calls do not generate type assertions. - } - } - - /// - /// Collects `TypeAssertion` predicates from a return statement. - /// - fn parse_return(&mut self, expression: &Expression, span: &Span) -> Result<(), FrameError> { - // Get the function output type. - let output_type = &self.function_type.output.type_; - - // Create the left hand side of a type assertion. - let left = output_type.clone(); - - // Create the right hand side from the statement return expression. - let right = self.parse_expression(expression)?; - - // Create a new type assertion for the statement return. - self.assert_equal(left, right, span); - - Ok(()) - } - - /// - /// Collects `Type Assertion` predicates from a definition statement. - /// - fn parse_definition( - &mut self, - _declare: &Declare, - variables: &Variables, - expression: &Expression, - span: &Span, - ) -> Result<(), FrameError> { - // Parse the definition expression. - let actual_type = self.parse_expression(expression)?; - - // Check if an explicit type is given. - if let Some(type_) = variables.type_.clone() { - // Check the expected type. - let expected_type = match self.self_type { - Some(ref circuit_type) => Type::new_from_circuit( - &self.user_defined_types, - type_, - circuit_type.identifier.clone(), - span.clone(), - ) - .unwrap(), - None => Type::new(&self.user_defined_types, type_, span.clone()).unwrap(), - }; - - // Assert that the expected type is equal to the actual type. - self.assert_equal(expected_type, actual_type.clone(), span) - } - - // Check for multiple defined variables. - if variables.names.len() == 1 { - // Insert variable into symbol table - let variable = variables.names[0].clone(); - - self.insert_variable(variable.identifier.name, actual_type, span)?; - } else { - // Expect a tuple type. - let types = match actual_type { - Type::Tuple(types) => types, - _ => return Err(FrameError::not_enough_values(span)), - }; - - // Check number of variables == number of types. - if types.len() != variables.names.len() { - return Err(FrameError::invalid_number_of_values( - types.len(), - variables.names.len(), - span, - )); - } - - // Insert variables into symbol table - for (variable, type_) in variables.names.iter().zip(types) { - self.insert_variable(variable.identifier.name.clone(), type_, span)?; - } - } - - Ok(()) - } - - /// - /// Asserts that the assignee's type is equal to the `Expression` type. - /// - fn parse_assign(&mut self, assignee: &Assignee, expression: &Expression, span: &Span) -> Result<(), FrameError> { - // Parse assignee type. - let assignee_type = self.parse_assignee(assignee, span)?; - - // Parse expression type. - let expression_type = self.parse_expression(expression)?; - - // Assert that the assignee_type == expression_type. - self.assert_equal(assignee_type, expression_type, span); - - Ok(()) - } - - /// - /// Returns the type of the assignee. - /// - fn parse_assignee(&mut self, assignee: &Assignee, span: &Span) -> Result { - // Get the type of the assignee variable. - let mut type_ = if assignee.identifier.is_self() { - // If the variable is the self keyword, then return the self.circuit_type - let self_type = self.self_type_or_error(span)?; - - Type::Circuit(self_type.identifier) - } else { - // Otherwise, lookup the variable by name in the symbol table. - self.get_variable(&assignee.identifier.name) - .map(|type_| type_.to_owned()) - .ok_or_else(|| FrameError::undefined_variable(&assignee.identifier))? - }; - - // Iteratively evaluate assignee access types. - for access in &assignee.accesses { - let access_type = match access { - AssigneeAccess::Array(r_or_e) => self.parse_array_access(type_, r_or_e, span), - AssigneeAccess::Tuple(index, _) => self.parse_tuple_access(type_, &index, span), - AssigneeAccess::Member(identifier) => self.parse_circuit_member_access(type_, identifier, span), - }?; - - type_ = access_type; - } - - Ok(type_) - } - - /// - /// Collects `TypeAssertion` predicates from a block of statements. - /// - fn parse_block(&mut self, statements: &[Statement], _span: &Span) -> Result<(), FrameError> { - // Push new scope. - let scope = Scope::new(self.scopes.last().cloned()); - self.push_scope(scope); - - // Parse all statements. - for statement in statements { - self.parse_statement(&statement)?; - } - - // Pop out of scope. - let _scope = self.pop_scope(); - - Ok(()) - } - - /// - /// Collects `TypeAssertion` predicates from a conditional statement. - /// - /// Creates a new scope for each code block in the conditional. - /// - fn parse_statement_conditional( - &mut self, - conditional: &ConditionalStatement, - span: &Span, - ) -> Result<(), FrameError> { - // Parse the condition expression. - let condition = self.parse_expression(&conditional.condition)?; - - // Assert that the condition is a boolean type. - let boolean_type = Type::Boolean; - self.assert_equal(boolean_type, condition, span); - - // Parse conditional statements. - self.parse_block(&conditional.statements, span)?; - - // Parse conditional or end. - if let Some(cond_or_end) = &conditional.next { - self.parse_conditional_nested_or_end(cond_or_end, span)?; - } - - Ok(()) - } - - /// - /// Collects `TypeAssertion` predicates from a conditional statement. - /// - fn parse_conditional_nested_or_end( - &mut self, - cond_or_end: &ConditionalNestedOrEndStatement, - span: &Span, - ) -> Result<(), FrameError> { - match cond_or_end { - ConditionalNestedOrEndStatement::Nested(nested) => self.parse_statement_conditional(nested, span), - ConditionalNestedOrEndStatement::End(statements) => self.parse_block(statements, span), - } - } - - /// - /// Collects `TypeAssertion` predicates from an iteration statement. - /// - fn parse_iteration( - &mut self, - identifier: &Identifier, - from_to: &(Expression, Expression), - statements: &[Statement], - span: &Span, - ) -> Result<(), FrameError> { - // Insert variable into symbol table with u32 type. - let u32_type = Type::IntegerType(IntegerType::U32); - let _expect_none = self.insert_variable(identifier.name.to_owned(), u32_type.clone(), span); - - // Parse `from` and `to` expressions. - let from_type = self.parse_expression(&from_to.0)?; - let to_type = self.parse_expression(&from_to.1)?; - - // Assert `from` and `to` types are a u32 or implicit. - self.assert_equal(u32_type.clone(), from_type, span); - self.assert_equal(u32_type, to_type, span); - - // Parse block of statements. - self.parse_block(statements, span) - } - - /// - /// Asserts that the statement `UnresolvedExpression` returns an empty tuple. - /// - fn parse_statement_expression(&mut self, expression: &Expression, span: &Span) -> Result<(), FrameError> { - // Create empty tuple type. - let expected_type = Type::Tuple(Vec::new()); - - // Parse the actual type of the expression. - let actual_type = self.parse_expression(expression)?; - - self.assert_equal(expected_type, actual_type, span); - - Ok(()) - } - - /// - /// Returns the type of an expression. - /// - fn parse_expression(&mut self, expression: &Expression) -> Result { - match expression { - // Type variables - Expression::Identifier(identifier) => self.parse_identifier(identifier), - - // Explicit types - Expression::Boolean(_, _) => Ok(Type::Boolean), - Expression::Address(_, _) => Ok(Type::Address), - Expression::Field(_, _) => Ok(Type::Field), - Expression::Group(_) => Ok(Type::Group), - Expression::Implicit(name, span) => Ok(Self::parse_implicit(Identifier::new_with_span(name, span))), - Expression::Integer(integer_type, _, _) => Ok(Type::IntegerType(integer_type.clone())), - - // Number operations - Expression::Add(left_right, span) => { - self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Sub(left_right, span) => { - self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Mul(left_right, span) => { - self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Div(left_right, span) => { - self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Pow(left_right, span) => { - self.parse_integer_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Negate(expression, span) => self.parse_negate_expression(expression, span), - - // Boolean operations - Expression::Not(expression, span) => self.parse_boolean_expression(expression, span), - Expression::Or(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::And(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Eq(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Ge(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Gt(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Le(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - Expression::Lt(left_right, span) => { - self.parse_boolean_binary_expression(&left_right.0, &left_right.1, span) - } - - // Conditionals - Expression::IfElse(triplet, span) => { - self.parse_conditional_expression(&triplet.0, &triplet.1, &triplet.2, span) - } - - // Arrays - Expression::ArrayInline(expressions, span) => self.parse_array(expressions, span), - Expression::ArrayInitializer(array_w_dimensions, span) => { - self.parse_array_initializer(&array_w_dimensions.0, &array_w_dimensions.1, span) - } - Expression::ArrayAccess(array_w_index, span) => { - self.parse_expression_array_access(&array_w_index.0, &array_w_index.1, span) - } - - // Tuples - Expression::Tuple(expressions, span) => self.parse_tuple(expressions, span), - Expression::TupleAccess(tuple_w_index, span) => { - self.parse_expression_tuple_access(&tuple_w_index.0, &tuple_w_index.1, span) - } - - // Circuits - Expression::Circuit(identifier, members, span) => self.parse_circuit(identifier, members, span), - Expression::CircuitMemberAccess(expression, identifier, span) => { - self.parse_expression_circuit_member_access(expression, identifier, span) - } - Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { - self.parse_static_circuit_function_access(expression, identifier, span) - } - - // Functions - Expression::FunctionCall(name, arguments, span) => self.parse_function_call(name, arguments, span), - Expression::CoreFunctionCall(name, arguments, span) => self.parse_core_function_call(name, arguments, span), - } - } - - /// - /// Returns the type of the identifier in the symbol table. - /// - fn parse_identifier(&self, identifier: &Identifier) -> Result { - // Check Self type. - if identifier.is_self() { - // Check for frame circuit self type. - let circuit_type = self.self_type_or_error(&identifier.span)?; - - // Return new type with circuit identifier. - return Ok(Type::Circuit(circuit_type.identifier)); - } - - // Check variable symbol table. - if let Some(type_) = self.get_variable(&identifier.name) { - return Ok(type_.to_owned()); - }; - - // Check function symbol table. - if let Some(function_type) = self.get_function(&identifier.name) { - return Ok(Type::Function(function_type.identifier.to_owned())); - }; - - // Check circuit symbol table. - if let Some(circuit_type) = self.get_circuit(&identifier.name) { - return Ok(Type::Circuit(circuit_type.identifier.to_owned())); - } - - Ok(Self::parse_implicit(identifier.to_owned())) - } - - /// - /// Returns a new type variable from a given identifier - /// - fn parse_implicit(identifier: Identifier) -> Type { - Type::TypeVariable(TypeVariable::from(identifier)) - } - - /// - /// Returns the type of a binary expression. - /// - fn parse_binary_expression( - &mut self, - left: &Expression, - right: &Expression, - span: &Span, - ) -> Result { - // Get the left expression type. - let left_type = self.parse_expression(left)?; - - // Get the right expression type. - let right_type = self.parse_expression(right)?; - - // Create a type assertion left_type == right_type. - self.assert_equal(left_type.clone(), right_type, span); - - Ok(left_type) - } - - /// - /// Returns the `Type` of the expression after the binary operation. - /// - /// Asserts that the `Type` is an integer. - /// - fn parse_integer_binary_expression( - &mut self, - left: &Expression, - right: &Expression, - span: &Span, - ) -> Result { - let type_ = self.parse_binary_expression(left, right, span)?; - - // Assert that the type is an integer. - self.assert_integer(&type_, span); - - Ok(type_) - } - - /// - /// Returns the `Boolean` type if the expression is a `Boolean` type. - /// - fn parse_boolean_expression(&mut self, expression: &Expression, span: &Span) -> Result { - // Return the `Boolean` type - let boolean_type = Type::Boolean; - - // Get the type of the expression - let expression_type = self.parse_expression(expression)?; - - // Assert that the type is a boolean. - self.assert_equal(boolean_type.clone(), expression_type, span); - - Ok(boolean_type) - } - - /// - /// Returns the `Type` of the expression being negated. Must be a negative integer type. - /// - fn parse_negate_expression(&mut self, expression: &Expression, span: &Span) -> Result { - // Parse the expression type. - let type_ = self.parse_expression(expression)?; - - // Assert that this integer can be negated. - self.assert_negative_integer(&type_, span); - - Ok(type_) - } - - /// - /// Returns the `Boolean` type if the binary expression is a `Boolean` type. - /// - fn parse_boolean_binary_expression( - &mut self, - left: &Expression, - right: &Expression, - span: &Span, - ) -> Result { - // Create the `Boolean` type. - let boolean_type = Type::Boolean; - - // Create a new type assertion for the binary expression - let _binary_expression_type = self.parse_binary_expression(left, right, span)?; - - // Return the `Boolean` type. - Ok(boolean_type) - } - - /// - /// Returns the type of the conditional expression. - /// - fn parse_conditional_expression( - &mut self, - condition: &Expression, - first: &Expression, - second: &Expression, - span: &Span, - ) -> Result { - // Check that the type of the condition expression is a boolean. - let _condition_type = self.parse_boolean_expression(condition, span)?; - - // Check that the types of the first and second expression are equal. - self.parse_binary_expression(first, second, span) - } - - /// - /// Returns the type of the tuple expression. - /// - fn parse_tuple(&mut self, expressions: &[Expression], _span: &Span) -> Result { - let mut types = Vec::with_capacity(expressions.len()); - - // Parse all tuple expressions. - for expression in expressions { - let type_ = self.parse_expression(expression)?; - - types.push(type_) - } - - Ok(Type::Tuple(types)) - } - - /// - /// Returns the type of the accessed tuple element when called as an expression. - /// - fn parse_expression_tuple_access( - &mut self, - expression: &Expression, - index: &PositiveNumber, - span: &Span, - ) -> Result { - // Parse the tuple expression which could be a variable with type tuple. - let type_ = self.parse_expression(expression)?; - - // Parse the tuple access. - self.parse_tuple_access(type_, index, span) - } - - /// - /// Returns the type of the accessed tuple element. - /// - fn parse_tuple_access(&mut self, type_: Type, index: &PositiveNumber, span: &Span) -> Result { - // Check the type is a tuple. - let mut elements = match type_ { - Type::Tuple(elements) => elements, - type_ => return Err(FrameError::tuple_access(&type_, span)), - }; - - // Parse index `String` to `usize`. - let index_usize = match index.to_string().parse::() { - Ok(index_usize) => index_usize, - Err(_) => return Err(FrameError::invalid_index(index.to_string(), span)), - }; - - let element_type = elements.swap_remove(index_usize); - - Ok(element_type) - } - - /// - /// Returns the type of the array expression. - /// - fn parse_array(&mut self, expressions: &[SpreadOrExpression], span: &Span) -> Result { - // Store array element type. - let mut element_type = None; - - // Parse all array elements. - for expression in expressions { - // Get the type and count of elements in each spread or expression. - let type_ = self.parse_spread_or_expression(expression, span)?; - - // Assert that array element types are the same. - if let Some(prev_type) = element_type { - self.assert_equal(prev_type, type_.clone(), span); - } - - // Update array element type. - element_type = Some(type_); - } - - // Return an error for empty arrays. - let type_ = match element_type { - Some(type_) => type_, - None => return Err(FrameError::empty_array(span)), - }; - - Ok(Type::Array(Box::new(type_))) - } - - /// - /// Returns the type of the array initializer expression. - /// - fn parse_array_initializer( - &mut self, - array: &Expression, - dimensions: &ArrayDimensions, - span: &Span, - ) -> Result { - // Get element type. - let element_type = self.parse_expression(array)?; - - // Return an error for array initializers of length 0. - if dimensions.is_zero() { - return Err(FrameError::empty_array(span)); - } - - // Return array type. - Ok(Type::Array(Box::new(element_type))) - } - - /// - /// Returns the type and count of elements in a spread or expression. - /// - fn parse_spread_or_expression(&mut self, s_or_e: &SpreadOrExpression, span: &Span) -> Result { - match s_or_e { - SpreadOrExpression::Spread(expression) => { - // Parse the type of the spread array expression. - let array_type = self.parse_expression(expression)?; - - // Check that the type is an array. - match array_type { - Type::Array(element_type) => Ok(Type::Array(element_type)), - type_ => Err(FrameError::invalid_spread(type_, span)), - } - } - SpreadOrExpression::Expression(expression) => self.parse_expression(expression), - } - } - - /// - /// Returns the type of the accessed array element when called as an expression. - /// - fn parse_expression_array_access( - &mut self, - expression: &Expression, - r_or_e: &RangeOrExpression, - span: &Span, - ) -> Result { - // Parse the array expression which could be a variable with type array. - let type_ = self.parse_expression(expression)?; - - // Parse the array access. - self.parse_array_access(type_, r_or_e, span) - } - - /// - /// Returns the type of the accessed array element. - /// - fn parse_array_access(&mut self, type_: Type, r_or_e: &RangeOrExpression, span: &Span) -> Result { - // Check the type is an array. - let element_type = match type_ { - Type::Array(type_) => type_, - type_ => return Err(FrameError::array_access(&type_, span)), - }; - - // Get the length of the array. - // let length = *dimensions.last().unwrap(); - - // Evaluate the range as an array type or the expression as the element type. - match r_or_e { - RangeOrExpression::Range(from, to) => { - if let Some(expression) = from { - // Parse the expression type. - let type_ = self.parse_expression(expression)?; - - self.assert_index(&type_, span); - } - - if let Some(expression) = to { - // Parse the expression type. - let type_ = self.parse_expression(expression)?; - - self.assert_index(&type_, span); - } - } - RangeOrExpression::Expression(expression) => { - // Parse the expression type. - let type_ = self.parse_expression(expression)?; - - // Assert the type is an index. - self.assert_index(&type_, span); - } - } - - Ok(*element_type) - } - - /// - /// Returns the Self type of the frame or an error if it does not exist. - /// - fn self_type_or_error(&self, span: &Span) -> Result { - self.self_type.clone().ok_or_else(|| FrameError::circuit_self(span)) - } - - /// - /// Returns the type of inline circuit expression. - /// - fn parse_circuit( - &mut self, - identifier: &Identifier, - members: &[CircuitVariableDefinition], - span: &Span, - ) -> Result { - // Check if identifier is Self circuit type. - let circuit_type = if identifier.is_self() { - // Get the Self type of the frame. - self.self_type_or_error(span)? - } else { - // Get circuit type. - self.user_defined_types - .get_circuit_type(&identifier.name) - .cloned() - .ok_or_else(|| FrameError::undefined_circuit(identifier))? - }; - - // Check the length of the circuit members. - if circuit_type.variables.len() != members.len() { - return Err(FrameError::num_circuit_variables( - circuit_type.variables.len(), - members.len(), - span, - )); - } - - // Assert members are circuit type member types. - for (expected_variable, actual_variable) in circuit_type.variables.iter().zip(members) { - // Parse actual variable expression. - let actual_type = self.parse_expression(&actual_variable.expression)?; - - // Assert expected variable type == actual variable type. - self.assert_equal(expected_variable.type_.clone(), actual_type, span) - } - - Ok(Type::Circuit(circuit_type.identifier)) - } - - /// - /// Returns the type of the accessed circuit member when called as an expression. - /// - fn parse_expression_circuit_member_access( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Parse circuit name. - let type_ = self.parse_expression(expression)?; - - // Parse the circuit member access. - self.parse_circuit_member_access(type_, identifier, span) - } - - /// - /// Returns the type of the accessed circuit member. - /// - fn parse_circuit_member_access( - &mut self, - type_: Type, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Check that type is a circuit type. - let circuit_type = self.parse_circuit_name(type_, span)?; - - // Look for member with matching name. - Ok(circuit_type.member_type(&identifier)?) - } - - /// - /// Returns the type returned by calling the static circuit function. - /// - fn parse_static_circuit_function_access( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Parse the circuit name. - let type_ = self.parse_expression(expression)?; - - self.parse_circuit_member_access(type_, identifier, span) - } - - /// - /// Returns a `CircuitType` given a circuit expression. - /// - fn parse_circuit_name(&mut self, type_: Type, span: &Span) -> Result<&CircuitType, FrameError> { - // Check that type is a circuit type. - match type_ { - Type::Circuit(identifier) => { - // Lookup circuit identifier. - self.user_defined_types - .get_circuit_type(&identifier.name) - .ok_or_else(|| FrameError::undefined_circuit(&identifier)) - } - type_ => Err(FrameError::invalid_circuit(type_, span)), - } - } - - /// - /// Returns a `FunctionType` given a function expression. - /// - fn parse_function_name(&mut self, expression: &Expression, span: &Span) -> Result { - // Case 1: Call a function defined in the program file. - // Case 2: Call a circuit function. - // Case 3: Call a static circuit function. - // Return an Error in any other case. - match expression { - Expression::Identifier(identifier) => self.parse_program_function(identifier, span), - Expression::CircuitMemberAccess(expression, identifier, span) => { - self.parse_circuit_function(expression, identifier, span) - } - Expression::CircuitStaticFunctionAccess(expression, identifier, span) => { - self.parse_static_circuit_function(expression, identifier, span) - } - expression => Err(FrameError::invalid_function(expression, span)), - } - } - - /// - /// Returns a `FunctionType` given a function identifier. - /// - fn parse_program_function(&mut self, identifier: &Identifier, _span: &Span) -> Result { - self.user_defined_types - .get_function_type(&identifier.name) - .cloned() - .ok_or_else(|| FrameError::undefined_function(identifier)) - } - - /// - /// Returns a `CircuitFunctionType` given a circuit expression and function identifier. - /// - fn parse_circuit_function_type( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result<&CircuitFunctionType, FrameError> { - // Parse circuit name. - let type_ = self.parse_expression(expression)?; - - // Get circuit type. - let circuit_type = self.parse_circuit_name(type_, span)?; - - // Find circuit function by identifier. - circuit_type - .member_function_type(identifier) - .ok_or_else(|| FrameError::undefined_circuit_function(identifier)) - } - - /// - /// Returns a `FunctionType` given a circuit expression and non-static function identifier. - /// - fn parse_circuit_function( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Find circuit function type. - let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; - - // Check that the function is non-static. - if let Some(Attribute::Static) = circuit_function_type.attribute { - return Err(FrameError::invalid_static_access(identifier)); - } - - // Return the function type. - Ok(circuit_function_type.function.to_owned()) - } - - /// - /// Returns a `FunctionType` given a circuit expression and static function identifier. - /// - fn parse_static_circuit_function( - &mut self, - expression: &Expression, - identifier: &Identifier, - span: &Span, - ) -> Result { - // Find circuit function type. - let circuit_function_type = self.parse_circuit_function_type(expression, identifier, span)?; - - // Check that the function is static. - if let Some(Attribute::Static) = circuit_function_type.attribute { - Ok(circuit_function_type.function.to_owned()) - } else { - Err(FrameError::invalid_member_access(identifier)) - } - } - - /// - /// Returns the type returned by calling the function. - /// - /// Does not attempt to evaluate the function call. We are just checking types at this step. - /// - fn parse_function_call( - &mut self, - expression: &Expression, - inputs: &[Expression], - span: &Span, - ) -> Result { - // Parse the function name. - let function_type = self.parse_function_name(expression, span)?; - - // Check the length of arguments - if function_type.inputs.len() != inputs.len() { - return Err(FrameError::num_inputs(function_type.inputs.len(), inputs.len(), span)); - } - - // Assert function inputs are correct types. - for (expected_input, actual_input) in function_type.inputs.iter().zip(inputs) { - // Parse expected input type. - let expected_type = expected_input.type_(); - - // Parse actual input type. - let actual_type = self.parse_expression(actual_input)?; - - // Assert expected input type == actual input type. - self.assert_equal(expected_type, actual_type, span); - } - - // Return the function output type. - Ok(function_type.output.type_) - } - - /// - /// Returns the type returned by calling the core function. - /// - fn parse_core_function_call( - &mut self, - _name: &str, - _arguments: &[Expression], - _span: &Span, - ) -> Result { - unimplemented!("type checks for core function calls not implemented") - } - - /// - /// Returns `Ok` if all `TypeAssertions` can be solved successfully. - /// - pub(crate) fn check(self) -> Result<(), FrameError> { - let mut unsolved = self.type_assertions; - - // Solve all type equality assertions first. - let mut unsolved_membership = Vec::new(); - - while !unsolved.is_empty() { - // Pop type assertion from list - let type_assertion = unsolved.pop().unwrap(); - - // If it is a membership assertion, then skip it for now. - if let TypeAssertion::Membership(membership) = type_assertion { - unsolved_membership.push(membership); - - continue; - } - - // Collect `TypeVariablePairs` from the `TypeAssertion`. - let pairs = type_assertion.pairs()?; - - // If no pairs are found, attempt to evaluate the `TypeAssertion`. - if pairs.is_empty() { - // Evaluate the `TypeAssertion`. - type_assertion.evaluate()? - } else { - // Iterate over each `TypeVariable` -> `Type` pair. - for pair in pairs.get_pairs() { - // Substitute the `TypeVariable` for it's paired `Type` in all `TypeAssertion`s. - for original in &mut unsolved { - original.substitute(pair.first(), pair.second()) - } - - for original in &mut unsolved_membership { - original.substitute(pair.first(), pair.second()) - } - } - } - } - - // Solve all type membership assertions. - while !unsolved_membership.is_empty() { - // Pop type assertion from list - let type_assertion = unsolved_membership.pop().unwrap(); - - // Solve the membership assertion. - type_assertion.evaluate()?; - } - - Ok(()) - } -} diff --git a/type-inference/src/objects/mod.rs b/type-inference/src/objects/mod.rs deleted file mode 100644 index 745c8eca50..0000000000 --- a/type-inference/src/objects/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 . - -pub mod frame; -pub use self::frame::*; - -pub mod scope; -pub use self::scope::*; - -pub mod variable_table; -pub use self::variable_table::*; diff --git a/type-inference/src/objects/scope.rs b/type-inference/src/objects/scope.rs deleted file mode 100644 index 34a0e20c58..0000000000 --- a/type-inference/src/objects/scope.rs +++ /dev/null @@ -1,81 +0,0 @@ -// 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 . - -use crate::{ScopeError, VariableTable}; -use leo_symbol_table::{FunctionInputType, Type}; - -/// A structure for tracking the types of defined variables in a block of code. -#[derive(Clone, Default)] -pub struct Scope { - pub loop_variables: VariableTable, - pub variables: VariableTable, -} - -impl Scope { - /// - /// Returns a new `Scope` from an optional given `Scope`. - /// - /// The new scope will contain the variables of the optional given `Scope`. - /// - pub fn new(parent: Option) -> Self { - match parent { - Some(scope) => scope, - None => Self::default(), - } - } - - /// - /// Inserts a variable name -> type mapping into the loop variable table. - /// - pub fn insert_loop_variable(&mut self, name: String, type_: Type) -> Option { - self.loop_variables.insert(name, type_) - } - - /// - /// Inserts a variable name -> type mapping into the variable table. - /// - pub fn insert_variable(&mut self, name: String, type_: Type) -> Option { - self.variables.insert(name, type_) - } - - /// - /// Returns a reference to the type corresponding to the loop variable name. - /// - pub fn get_loop_variable(&self, name: &str) -> Option<&Type> { - self.loop_variables.get(name) - } - - /// - /// Returns a reference to the type corresponding to the variable name. - /// - /// Checks loop variables first, then non-loop variables. - /// - pub fn get_variable(&self, name: &str) -> Option<&Type> { - match self.get_loop_variable(name) { - Some(loop_variable_type) => Some(loop_variable_type), - None => self.variables.get(name), - } - } - - /// - /// Inserts a vector of function input types into the `Scope` variable table. - /// - pub fn insert_function_inputs(&mut self, function_inputs: &[FunctionInputType]) -> Result<(), ScopeError> { - self.variables - .insert_function_inputs(function_inputs) - .map_err(ScopeError::VariableTableError) - } -} diff --git a/type-inference/src/objects/variable_table.rs b/type-inference/src/objects/variable_table.rs deleted file mode 100644 index f6060b33a7..0000000000 --- a/type-inference/src/objects/variable_table.rs +++ /dev/null @@ -1,67 +0,0 @@ -// 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 . - -use crate::VariableTableError; -use leo_symbol_table::{FunctionInputType, Type}; -use std::collections::HashMap; - -/// Mapping of variable names to types -#[derive(Clone)] -pub struct VariableTable(pub HashMap); - -impl VariableTable { - /// - /// Insert a name -> type pair into the variable table. - /// - /// If the variable table did not have this key present, [`None`] is returned. - /// - /// If the variable table did have this key present, the type is updated, and the old - /// type is returned. - /// - pub fn insert(&mut self, name: String, type_: Type) -> Option { - self.0.insert(name, type_) - } - - /// - /// Returns a reference to the type corresponding to the name. - /// - /// If the variable table did not have this key present, throw an undefined variable error - /// using the given span. - /// - pub fn get(&self, name: &str) -> Option<&Type> { - self.0.get(name) - } - - /// - /// Inserts a vector of function input types into the variable table. - /// - pub fn insert_function_inputs(&mut self, function_inputs: &[FunctionInputType]) -> Result<(), VariableTableError> { - for input in function_inputs { - let input_name = input.identifier().name.clone(); - let input_type = input.type_(); - - // TODO (collinc97) throw an error for duplicate function input names. - self.insert(input_name, input_type); - } - Ok(()) - } -} - -impl Default for VariableTable { - fn default() -> Self { - Self(HashMap::new()) - } -} diff --git a/type-inference/src/type_inference.rs b/type-inference/src/type_inference.rs deleted file mode 100644 index fee87bb035..0000000000 --- a/type-inference/src/type_inference.rs +++ /dev/null @@ -1,138 +0,0 @@ -// 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 . - -use crate::{Frame, Scope, TypeInferenceError}; -use leo_ast::{Circuit, CircuitMember, Function, Program}; -use leo_symbol_table::SymbolTable; - -/// A type inference check for a Leo program. -/// -/// A [`TypeInference`] type stores a stack of frames. A new frame is created for every -/// function. Frames store type assertions that assert an expression is a type. -/// Calling the `check()` method on a [`TypeInference`] checks that all type assertions are satisfied. -pub struct TypeInference { - table: SymbolTable, - frames: Vec, -} - -impl TypeInference { - /// - /// Creates and runs a new `TypeInference` check on a given program and symbol table. - /// - /// Evaluates all `TypeAssertion` predicates. - /// - #[allow(clippy::new_ret_no_self)] - pub fn new(program: &Program, symbol_table: SymbolTable) -> Result<(), TypeInferenceError> { - let mut type_inference = Self { - table: symbol_table, - frames: Vec::new(), - }; - - type_inference.parse_program(program)?; - - type_inference.check() - } - - /// - /// Collects a vector of `TypeAssertion` predicates from a program. - /// - fn parse_program(&mut self, program: &Program) -> Result<(), TypeInferenceError> { - // Parse circuit types in program context. - self.parse_circuits(program.circuits.iter().map(|(_identifier, circuit)| circuit))?; - - // Parse functions in program context. - self.parse_functions(program.functions.iter().map(|(_identifier, function)| function)) - } - - /// - /// Collects a vector of `Frames`s from a vector of circuit functions. - /// - fn parse_circuits<'a>(&mut self, circuits: impl Iterator) -> Result<(), TypeInferenceError> { - for circuit in circuits { - self.parse_circuit(circuit)?; - } - - Ok(()) - } - - /// - /// Collects a vector of `Frames`s from a circuit function. - /// - /// Each frame collects a vector of `TypeAssertion` predicates from each function. - /// - fn parse_circuit(&mut self, circuit: &Circuit) -> Result<(), TypeInferenceError> { - let name = &circuit.circuit_name.name; - - // Get circuit type from circuit symbol table. - let circuit_type = self.table.get_circuit_type(name).unwrap().clone(); - - // Create a new function for each circuit member function. - for circuit_member in &circuit.members { - // ignore circuit member variables - if let CircuitMember::CircuitFunction(_, function) = circuit_member { - // Collect `TypeAssertion` predicates from the function. - // Pass down circuit self type and circuit variable types to each function. - let frame = Frame::new_circuit_function( - function.to_owned(), - circuit_type.clone(), - Scope::default(), - self.table.clone(), - )?; - - self.frames.push(frame) - } - } - - Ok(()) - } - - /// - /// Collects a vector of `TypeAssertion` predicates from a vector of functions. - /// - fn parse_functions<'a>(&mut self, functions: impl Iterator) -> Result<(), TypeInferenceError> { - for function in functions { - self.parse_function(function)?; - } - - Ok(()) - } - - /// - /// Collects a vector of `TypeAssertion` predicates from a function. - /// - fn parse_function(&mut self, function: &Function) -> Result<(), TypeInferenceError> { - let frame = Frame::new_function(function.to_owned(), None, None, self.table.clone())?; - - self.frames.push(frame); - - Ok(()) - } - - /// - /// Returns the result of evaluating all `TypeAssertion` predicates. - /// - /// Will attempt to substitute a `Type` for all `TypeVariable`s. - /// Returns a `LeoResolvedAst` if all `TypeAssertion` predicates are true. - /// Returns ERROR if a `TypeAssertion` predicate is false or a solution does not exist. - /// - pub fn check(self) -> Result<(), TypeInferenceError> { - for frame in self.frames { - frame.check()?; - } - - Ok(()) - } -} diff --git a/type-inference/tests/arrays/empty_array.leo b/type-inference/tests/arrays/empty_array.leo deleted file mode 100644 index 7cf517014e..0000000000 --- a/type-inference/tests/arrays/empty_array.leo +++ /dev/null @@ -1,3 +0,0 @@ -function main() { - let a = [1u8; 0]; // Empty arrays are illegal in Leo programs since arrays cannot be resized. -} \ No newline at end of file diff --git a/type-inference/tests/arrays/invalid_array_access.leo b/type-inference/tests/arrays/invalid_array_access.leo deleted file mode 100644 index 0064d41ae6..0000000000 --- a/type-inference/tests/arrays/invalid_array_access.leo +++ /dev/null @@ -1,5 +0,0 @@ -function main() { - let a = (1u8, 2u8); - - let b = a[0]; // It is illegal to index into a tuple using bracket syntax. -} \ No newline at end of file diff --git a/type-inference/tests/arrays/invalid_spread.leo b/type-inference/tests/arrays/invalid_spread.leo deleted file mode 100644 index 0153b3d04b..0000000000 --- a/type-inference/tests/arrays/invalid_spread.leo +++ /dev/null @@ -1,5 +0,0 @@ -function main() { - let a: u8 = 1; - - let b = [...a]; -} \ No newline at end of file diff --git a/type-inference/tests/arrays/mod.rs b/type-inference/tests/arrays/mod.rs deleted file mode 100644 index 72ab79478e..0000000000 --- a/type-inference/tests/arrays/mod.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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 . - -use crate::TestTypeInference; - -#[test] -fn test_empty_array() { - let bytes = include_bytes!("empty_array.leo"); - - let check = TestTypeInference::new(bytes); - - check.expect_error(); -} - -#[test] -fn test_invalid_array_access() { - let bytes = include_bytes!("invalid_array_access.leo"); - - let check = TestTypeInference::new(bytes); - - check.expect_error(); -} - -#[test] -fn test_invalid_spread() { - let bytes = include_bytes!("invalid_spread.leo"); - - let check = TestTypeInference::new(bytes); - - check.expect_error(); -} diff --git a/type-inference/tests/circuits/invalid_circuit.leo b/type-inference/tests/circuits/invalid_circuit.leo deleted file mode 100644 index aff73cc8d4..0000000000 --- a/type-inference/tests/circuits/invalid_circuit.leo +++ /dev/null @@ -1,4 +0,0 @@ -function main() { - let a = 1u8; - let b = a::foo(); // Variable `a` is not a circuit type. -} \ No newline at end of file diff --git a/type-inference/tests/circuits/mod.rs b/type-inference/tests/circuits/mod.rs deleted file mode 100644 index 8b8d585bd6..0000000000 --- a/type-inference/tests/circuits/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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 . - -use crate::TestTypeInference; - -#[test] -fn test_invalid_circuit() { - let bytes = include_bytes!("invalid_circuit.leo"); - let check = TestTypeInference::new(bytes); - - check.expect_error(); -} diff --git a/type-inference/tests/empty.leo b/type-inference/tests/empty.leo deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/type-inference/tests/functions/invalid_function.leo b/type-inference/tests/functions/invalid_function.leo deleted file mode 100644 index 1e72c4e8d6..0000000000 --- a/type-inference/tests/functions/invalid_function.leo +++ /dev/null @@ -1,4 +0,0 @@ -function main() { - let a = 1u8; - let b = a(); // Variable `a` is not a function. -} \ No newline at end of file diff --git a/type-inference/tests/functions/mod.rs b/type-inference/tests/functions/mod.rs deleted file mode 100644 index 20e873cbaf..0000000000 --- a/type-inference/tests/functions/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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 . - -use crate::TestTypeInference; - -#[test] -fn test_invalid_function() { - let bytes = include_bytes!("invalid_function.leo"); - let check = TestTypeInference::new(bytes); - - check.expect_error(); -} diff --git a/type-inference/tests/mod.rs b/type-inference/tests/mod.rs deleted file mode 100644 index 58362fc972..0000000000 --- a/type-inference/tests/mod.rs +++ /dev/null @@ -1,84 +0,0 @@ -// 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 . - -pub mod arrays; -pub mod circuits; -pub mod functions; -pub mod tuples; -pub mod variables; - -use leo_grammar::Grammar; -use leo_type_inference::TypeInference; - -use leo_ast::{Input, LeoAst, Program}; -use leo_imports::ImportParser; -use leo_symbol_table::SymbolTable; -use std::path::PathBuf; - -const TEST_PROGRAM_PATH: &str = ""; -const TEST_PROGRAM_NAME: &str = "test"; - -/// A helper struct to test a `TypeInference` check. -pub struct TestTypeInference { - program: Program, - symbol_table: SymbolTable, -} - -impl TestTypeInference { - pub fn new(bytes: &[u8]) -> Self { - // Get file string from bytes. - let file_string = String::from_utf8_lossy(bytes); - - // Get test file path. - let file_path = PathBuf::from(TEST_PROGRAM_PATH); - - // Get parser syntax tree. - let ast = Grammar::new(&file_path, &*file_string).unwrap(); - - // Get typed syntax tree. - let typed = LeoAst::new(TEST_PROGRAM_NAME, &ast); - let program = typed.into_repr(); - - // Create empty import parser. - let import_parser = ImportParser::default(); - - // Create empty input. - let input = Input::new(); - - // Create symbol table. - let symbol_table = SymbolTable::new(&program, &import_parser, &input).unwrap(); - - // Store fields for new type inference check. - Self { program, symbol_table } - } - - pub fn check(self) { - TypeInference::new(&self.program, self.symbol_table).unwrap(); - } - - pub fn expect_error(self) { - assert!(TypeInference::new(&self.program, self.symbol_table).is_err()); - } -} - -#[test] -fn test_new() { - let bytes = include_bytes!("empty.leo"); - - let type_inference = TestTypeInference::new(bytes); - - type_inference.check() -} diff --git a/type-inference/tests/tuples/invalid_tuple_access.leo b/type-inference/tests/tuples/invalid_tuple_access.leo deleted file mode 100644 index 1fc14e3a6b..0000000000 --- a/type-inference/tests/tuples/invalid_tuple_access.leo +++ /dev/null @@ -1,5 +0,0 @@ -function main() { - let a = [1u8; 3]; - - let b = a.0; // It is illegal to index into an array using dot syntax. -} \ No newline at end of file diff --git a/type-inference/tests/tuples/mod.rs b/type-inference/tests/tuples/mod.rs deleted file mode 100644 index cc0549cffe..0000000000 --- a/type-inference/tests/tuples/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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 . - -use crate::TestTypeInference; - -#[test] -fn test_invalid_tuple_access() { - let bytes = include_bytes!("invalid_tuple_access.leo"); - let check = TestTypeInference::new(bytes); - - check.expect_error(); -} diff --git a/type-inference/tests/variables/duplicate_variable.leo b/type-inference/tests/variables/duplicate_variable.leo deleted file mode 100644 index a748ef4efe..0000000000 --- a/type-inference/tests/variables/duplicate_variable.leo +++ /dev/null @@ -1,4 +0,0 @@ -function main() { - let a = 1u8; - let a = 2u8; // Redefining variables with the same name is unsafe in Leo. -} \ No newline at end of file diff --git a/type-inference/tests/variables/duplicate_variable_multi.leo b/type-inference/tests/variables/duplicate_variable_multi.leo deleted file mode 100644 index d0fabdea07..0000000000 --- a/type-inference/tests/variables/duplicate_variable_multi.leo +++ /dev/null @@ -1,3 +0,0 @@ -function main() { - let (a, a) = (2u8, 2u8); // Defining multiple variables with the same name is unsafe in Leo. -} \ No newline at end of file diff --git a/type-inference/tests/variables/mod.rs b/type-inference/tests/variables/mod.rs deleted file mode 100644 index 9e7b3dd1ea..0000000000 --- a/type-inference/tests/variables/mod.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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 . - -use crate::TestTypeInference; - -#[test] -fn test_duplicate_variable() { - let bytes = include_bytes!("duplicate_variable.leo"); - let check = TestTypeInference::new(bytes); - - check.expect_error(); -} - -#[test] -fn test_duplicate_variable_multi() { - let bytes = include_bytes!("duplicate_variable_multi.leo"); - let check = TestTypeInference::new(bytes); - - check.expect_error(); -} - -#[test] -fn test_not_enough_values() { - let bytes = include_bytes!("not_enough_values.leo"); - let check = TestTypeInference::new(bytes); - - check.expect_error(); -} - -#[test] -fn test_too_many_values() { - let bytes = include_bytes!("too_many_values.leo"); - let check = TestTypeInference::new(bytes); - - check.expect_error(); -} diff --git a/type-inference/tests/variables/not_enough_values.leo b/type-inference/tests/variables/not_enough_values.leo deleted file mode 100644 index 58b1ad7244..0000000000 --- a/type-inference/tests/variables/not_enough_values.leo +++ /dev/null @@ -1,3 +0,0 @@ -function main() { - let (a, b): (u8, u8) = 1; // A tuple of values must be used when defining two variables. -} \ No newline at end of file diff --git a/type-inference/tests/variables/too_many_values.leo b/type-inference/tests/variables/too_many_values.leo deleted file mode 100644 index bd3f551231..0000000000 --- a/type-inference/tests/variables/too_many_values.leo +++ /dev/null @@ -1,3 +0,0 @@ -function main() { - let (a, b): (u8, u8) = (1, 2, 3); // Cannot assign 2 variables to 3 values. -} \ No newline at end of file From d4b6a6d1f832b34bff6a5eb95efe87f43e3eb4bd Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 11 Nov 2020 14:42:57 -0800 Subject: [PATCH 139/139] separate symbol-table module --- Cargo.lock | 14 - Cargo.toml | 7 +- compiler/Cargo.toml | 6 +- compiler/src/compiler.rs | 20 +- compiler/src/errors/compiler.rs | 14 +- compiler/src/import/store/import.rs | 32 +- compiler/tests/core/mod.rs | 64 +-- compiler/tests/mod.rs | 6 +- symbol-table/Cargo.toml | 40 -- symbol-table/src/attributes/attribute.rs | 24 - symbol-table/src/attributes/mod.rs | 18 - symbol-table/src/errors/mod.rs | 21 - symbol-table/src/errors/symbol_table.rs | 100 ---- symbol-table/src/errors/type_.rs | 86 --- symbol-table/src/imports/imported_symbols.rs | 57 -- symbol-table/src/imports/mod.rs | 18 - symbol-table/src/lib.rs | 41 -- symbol-table/src/symbol_table.rs | 502 ------------------ symbol-table/src/types/circuits/circuit.rs | 194 ------- .../src/types/circuits/circuit_function.rs | 27 - .../src/types/circuits/circuit_variable.rs | 40 -- symbol-table/src/types/circuits/mod.rs | 24 - symbol-table/src/types/functions/function.rs | 136 ----- .../src/types/functions/function_input.rs | 90 ---- .../functions/function_input_variable.rs | 119 ----- .../src/types/functions/function_output.rs | 69 --- symbol-table/src/types/functions/mod.rs | 27 - symbol-table/src/types/mod.rs | 30 -- symbol-table/src/types/type_.rs | 265 --------- symbol-table/src/types/type_variable.rs | 46 -- symbol-table/src/types/user_defined/mod.rs | 18 - .../types/user_defined/user_defined_type.rs | 86 --- symbol-table/tests/mod.rs | 122 ----- .../tests/symbol_table/duplicate_circuit.leo | 10 - .../tests/symbol_table/duplicate_function.leo | 10 - symbol-table/tests/symbol_table/mod.rs | 75 --- .../tests/symbol_table/self_not_available.leo | 8 - .../tests/symbol_table/undefined_circuit.leo | 10 - 38 files changed, 73 insertions(+), 2403 deletions(-) delete mode 100644 symbol-table/Cargo.toml delete mode 100644 symbol-table/src/attributes/attribute.rs delete mode 100644 symbol-table/src/attributes/mod.rs delete mode 100644 symbol-table/src/errors/mod.rs delete mode 100644 symbol-table/src/errors/symbol_table.rs delete mode 100644 symbol-table/src/errors/type_.rs delete mode 100644 symbol-table/src/imports/imported_symbols.rs delete mode 100644 symbol-table/src/imports/mod.rs delete mode 100644 symbol-table/src/lib.rs delete mode 100644 symbol-table/src/symbol_table.rs delete mode 100644 symbol-table/src/types/circuits/circuit.rs delete mode 100644 symbol-table/src/types/circuits/circuit_function.rs delete mode 100644 symbol-table/src/types/circuits/circuit_variable.rs delete mode 100644 symbol-table/src/types/circuits/mod.rs delete mode 100644 symbol-table/src/types/functions/function.rs delete mode 100644 symbol-table/src/types/functions/function_input.rs delete mode 100644 symbol-table/src/types/functions/function_input_variable.rs delete mode 100644 symbol-table/src/types/functions/function_output.rs delete mode 100644 symbol-table/src/types/functions/mod.rs delete mode 100644 symbol-table/src/types/mod.rs delete mode 100644 symbol-table/src/types/type_.rs delete mode 100644 symbol-table/src/types/type_variable.rs delete mode 100644 symbol-table/src/types/user_defined/mod.rs delete mode 100644 symbol-table/src/types/user_defined/user_defined_type.rs delete mode 100644 symbol-table/tests/mod.rs delete mode 100644 symbol-table/tests/symbol_table/duplicate_circuit.leo delete mode 100644 symbol-table/tests/symbol_table/duplicate_function.leo delete mode 100644 symbol-table/tests/symbol_table/mod.rs delete mode 100644 symbol-table/tests/symbol_table/self_not_available.leo delete mode 100644 symbol-table/tests/symbol_table/undefined_circuit.leo diff --git a/Cargo.lock b/Cargo.lock index b615fa8454..7fb1f04a75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1312,7 +1312,6 @@ dependencies = [ "leo-input", "leo-package", "leo-state", - "leo-symbol-table", "num-bigint", "pest", "rand", @@ -1423,7 +1422,6 @@ dependencies = [ "leo-input", "leo-package", "leo-state", - "leo-symbol-table", "notify", "num-bigint", "rand", @@ -1483,18 +1481,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "leo-symbol-table" -version = "1.0.4" -dependencies = [ - "leo-ast", - "leo-core", - "leo-grammar", - "leo-imports", - "serde", - "thiserror", -] - [[package]] name = "libc" version = "0.2.80" diff --git a/Cargo.toml b/Cargo.toml index 419353f1a1..f49322dc12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,8 @@ members = [ "linter", "package", "state", - "symbol-table", +# "symbol-table", +# "type-inference", ] [dependencies.leo-ast] @@ -67,10 +68,6 @@ version = "1.0.4" path = "./state" version = "1.0.4" -[dependencies.leo-symbol-table] -path = "./symbol-table" -version = "1.0.4" - [dependencies.snarkos-algorithms] version = "1.1.3" default-features = false diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index e9e94ea3b5..aa18805cce 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -49,9 +49,9 @@ version = "1.0.4" path = "../state" version = "1.0.4" -[dependencies.leo-symbol-table] -path = "../symbol-table" -version = "1.0.4" +#[dependencies.leo-symbol-table] +#path = "../symbol-table" +#version = "1.0.4" #[dependencies.leo-type-inference] #path = "../type-inference" diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index ea2cc9ef09..c17eb9c398 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -29,7 +29,7 @@ use leo_imports::ImportParser; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; use leo_state::verify_local_data_commitment; -use leo_symbol_table::SymbolTable; +// use leo_symbol_table::SymbolTable; // use leo_type_inference::TypeInference; use snarkos_dpc::{base_dpc::instantiated::Components, SystemParameters}; @@ -205,13 +205,13 @@ impl> Compiler { /// catching type mismatch errors. /// pub(crate) fn check_program(&self) -> Result<(), CompilerError> { - // Create a new symbol table from the program, imported_programs, and program_input. - let _symbol_table = - SymbolTable::new(&self.program, &self.imported_programs, &self.program_input).map_err(|mut e| { - e.set_path(&self.main_file_path); - - e - })?; + // // Create a new symbol table from the program, imported_programs, and program_input. + // let _symbol_table = + // SymbolTable::new(&self.program, &self.imported_programs, &self.program_input).map_err(|mut e| { + // e.set_path(&self.main_file_path); + // + // e + // })?; // // Run type inference check on program. // TypeInference::new(&self.program, symbol_table).map_err(|mut e| { @@ -252,8 +252,8 @@ impl> Compiler { // Parse and store all programs imported by the main program file. self.imported_programs = ImportParser::parse(&self.program)?; - // Create a new symbol table from the program, imported programs, and program input. - let _symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; + // // Create a new symbol table from the program, imported programs, and program input. + // let _symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; // // Run type inference check on program. // TypeInference::new(&self.program, symbol_table)?; diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index cffd128308..4239c18e7f 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -19,7 +19,7 @@ use leo_grammar::ParserError; use leo_imports::ImportParserError; use leo_input::InputParserError; use leo_state::LocalDataVerificationError; -use leo_symbol_table::SymbolTableError; +// use leo_symbol_table::SymbolTableError; // use leo_type_inference::TypeInferenceError; use bincode::Error as SerdeError; @@ -27,8 +27,6 @@ use std::path::{Path, PathBuf}; #[derive(Debug, Error)] pub enum CompilerError { - // #[error("{}", _0)] - // TypeInferenceError(#[from] TypeInferenceError), #[error("{}", _0)] ImportError(#[from] ImportError), @@ -70,19 +68,21 @@ pub enum CompilerError { #[error("{}", _0)] SerdeError(#[from] SerdeError), + // #[error("{}", _0)] + // SymbolTableError(#[from] SymbolTableError), - #[error("{}", _0)] - SymbolTableError(#[from] SymbolTableError), + // #[error("{}", _0)] + // TypeInferenceError(#[from] TypeInferenceError), } impl CompilerError { pub fn set_path(&mut self, path: &Path) { match self { - // CompilerError::TypeInferenceError(error) => error.set_path(path), CompilerError::InputParserError(error) => error.set_path(path), CompilerError::FunctionError(error) => error.set_path(path), CompilerError::OutputStringError(error) => error.set_path(path), - CompilerError::SymbolTableError(error) => error.set_path(path), + // CompilerError::SymbolTableError(error) => error.set_path(path), + // CompilerError::TypeInferenceError(error) => error.set_path(path), _ => {} } } diff --git a/compiler/src/import/store/import.rs b/compiler/src/import/store/import.rs index 9453d2ef02..8e34423557 100644 --- a/compiler/src/import/store/import.rs +++ b/compiler/src/import/store/import.rs @@ -17,7 +17,7 @@ use crate::{errors::ImportError, ConstrainedProgram, GroupType}; use leo_ast::ImportStatement; use leo_imports::ImportParser; -use leo_symbol_table::imported_symbols::ImportedSymbols; +// use leo_symbol_table::imported_symbols::ImportedSymbols; use snarkos_models::curves::{Field, PrimeField}; @@ -37,21 +37,21 @@ impl> ConstrainedProgram { return Ok(()); } - // Fetch dependencies for the current import - let imported_symbols = ImportedSymbols::new(import); - - for (name, symbol) in imported_symbols.symbols { - // Find imported program - let program = imported_programs - .get_import(&name) - .ok_or_else(|| ImportError::unknown_package(import.package.name.clone()))?; - - // Parse imported program - self.store_definitions(program.clone(), imported_programs)?; - - // Store the imported symbol - self.store_symbol(scope, &name, &symbol, program)?; - } + // // Fetch dependencies for the current import + // let imported_symbols = ImportedSymbols::new(import); + // + // for (name, symbol) in imported_symbols.symbols { + // // Find imported program + // let program = imported_programs + // .get_import(&name) + // .ok_or_else(|| ImportError::unknown_package(import.package.name.clone()))?; + // + // // Parse imported program + // self.store_definitions(program.clone(), imported_programs)?; + // + // // Store the imported symbol + // self.store_symbol(scope, &name, &symbol, program)?; + // } Ok(()) } diff --git a/compiler/tests/core/mod.rs b/compiler/tests/core/mod.rs index 20943b7c36..9e22953c05 100644 --- a/compiler/tests/core/mod.rs +++ b/compiler/tests/core/mod.rs @@ -16,39 +16,39 @@ pub mod packages; -use crate::{assert_satisfied, expect_symbol_table_error, parse_program}; +use crate::{assert_satisfied, parse_program}; -#[test] -fn test_core_circuit_invalid() { - let program_bytes = include_bytes!("core_package_invalid.leo"); - let program = parse_program(program_bytes).err().unwrap(); - - expect_symbol_table_error(program); -} - -#[test] -fn test_core_circuit_star_fail() { - let program_bytes = include_bytes!("core_circuit_star_fail.leo"); - let error = parse_program(program_bytes).err().unwrap(); - - expect_symbol_table_error(error); -} - -#[test] -fn test_core_package_invalid() { - let program_bytes = include_bytes!("core_package_invalid.leo"); - let error = parse_program(program_bytes).err().unwrap(); - - expect_symbol_table_error(error); -} - -#[test] -fn test_core_unstable_package_invalid() { - let program_bytes = include_bytes!("core_unstable_package_invalid.leo"); - let error = parse_program(program_bytes).err().unwrap(); - - expect_symbol_table_error(error); -} +// #[test] +// fn test_core_circuit_invalid() { +// let program_bytes = include_bytes!("core_package_invalid.leo"); +// let program = parse_program(program_bytes).err().unwrap(); +// +// expect_symbol_table_error(program); +// } +// +// #[test] +// fn test_core_circuit_star_fail() { +// let program_bytes = include_bytes!("core_circuit_star_fail.leo"); +// let error = parse_program(program_bytes).err().unwrap(); +// +// expect_symbol_table_error(error); +// } +// +// #[test] +// fn test_core_package_invalid() { +// let program_bytes = include_bytes!("core_package_invalid.leo"); +// let error = parse_program(program_bytes).err().unwrap(); +// +// expect_symbol_table_error(error); +// } +// +// #[test] +// fn test_core_unstable_package_invalid() { +// let program_bytes = include_bytes!("core_unstable_package_invalid.leo"); +// let error = parse_program(program_bytes).err().unwrap(); +// +// expect_symbol_table_error(error); +// } #[test] fn test_unstable_blake2s_sanity() { diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index 57cb8f3d2c..478ccc9ab0 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -185,9 +185,9 @@ pub(crate) fn expect_compiler_error(program: EdwardsTestCompiler) -> CompilerErr // assert!(matches!(error, CompilerError::TypeInferenceError(_))) // } -pub(crate) fn expect_symbol_table_error(error: CompilerError) { - assert!(matches!(error, CompilerError::SymbolTableError(_))) -} +// pub(crate) fn expect_symbol_table_error(error: CompilerError) { +// assert!(matches!(error, CompilerError::SymbolTableError(_))) +// } pub(crate) fn generate_main_input(input: Vec<(&str, Option)>) -> MainInput { let mut main_input = MainInput::new(); diff --git a/symbol-table/Cargo.toml b/symbol-table/Cargo.toml deleted file mode 100644 index 0e821fd122..0000000000 --- a/symbol-table/Cargo.toml +++ /dev/null @@ -1,40 +0,0 @@ -[package] -name = "leo-symbol-table" -version = "1.0.4" -authors = [ "The Aleo Team " ] -description = "Stores user-defined variables during type resolution" -homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/leo" -keywords = [ - "aleo", - "cryptography", - "leo", - "programming-language", - "zero-knowledge" -] -categories = [ "cryptography::croptocurrencies", "web-programming" ] -include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] -license = "GPL-3.0" -edition = "2018" - -[dependencies.leo-ast] -path = "../ast" -version = "1.0.4" - -[dependencies.leo-core] -path = "../core" -version = "1.0.4" - -[dependencies.leo-grammar] -path = "../grammar" -version = "1.0.4" - -[dependencies.leo-imports] -path = "../imports" -version = "1.0.4" - -[dependencies.serde] -version = "1.0" - -[dependencies.thiserror] -version = "1.0" \ No newline at end of file diff --git a/symbol-table/src/attributes/attribute.rs b/symbol-table/src/attributes/attribute.rs deleted file mode 100644 index 81d1dca02e..0000000000 --- a/symbol-table/src/attributes/attribute.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 . - -use serde::{Deserialize, Serialize}; - -/// Indicates that a program variable has additional functionality. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum Attribute { - Mutable, - Static, -} diff --git a/symbol-table/src/attributes/mod.rs b/symbol-table/src/attributes/mod.rs deleted file mode 100644 index f8d19f5a62..0000000000 --- a/symbol-table/src/attributes/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod attribute; -pub use self::attribute::*; diff --git a/symbol-table/src/errors/mod.rs b/symbol-table/src/errors/mod.rs deleted file mode 100644 index 107ac193f8..0000000000 --- a/symbol-table/src/errors/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 . - -pub mod symbol_table; -pub use self::symbol_table::*; - -pub mod type_; -pub use self::type_::*; diff --git a/symbol-table/src/errors/symbol_table.rs b/symbol-table/src/errors/symbol_table.rs deleted file mode 100644 index 7ec93ee2b1..0000000000 --- a/symbol-table/src/errors/symbol_table.rs +++ /dev/null @@ -1,100 +0,0 @@ -// 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 . - -use crate::{TypeError, UserDefinedType}; -use leo_ast::{Error as FormattedError, ImportSymbol, Program, Span}; -use leo_core::{CorePackageListError, LeoCorePackageError}; - -use std::path::Path; - -/// Errors encountered when tracking variable, function, and circuit names in a program. -#[derive(Debug, Error)] -pub enum SymbolTableError { - #[error("{}", _0)] - CorePackageListError(#[from] CorePackageListError), - - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - LeoCorePackageError(#[from] LeoCorePackageError), - - #[error("{}", _0)] - TypeError(#[from] TypeError), -} - -impl SymbolTableError { - /// - /// Sets the filepath for the error stacktrace. - /// - pub fn set_path(&mut self, path: &Path) { - match self { - SymbolTableError::CorePackageListError(error) => error.set_path(path), - SymbolTableError::Error(error) => error.set_path(path), - SymbolTableError::LeoCorePackageError(error) => error.set_path(path), - SymbolTableError::TypeError(error) => error.set_path(path), - } - } - - /// - /// Returns a new formatted error with a given message and span information. - /// - fn new_from_span(message: String, span: Span) -> Self { - SymbolTableError::Error(FormattedError::new_from_span(message, span)) - } - - /// - /// Two circuits have been defined with the same name. - /// - pub fn duplicate_circuit(variable: UserDefinedType) -> Self { - let message = format!("Duplicate circuit definition found for `{}`", variable.identifier); - - Self::new_from_span(message, variable.identifier.span) - } - - /// - /// Two functions have been defined with the same name. - /// - pub fn duplicate_function(variable: UserDefinedType) -> Self { - let message = format!("Duplicate function definition found for `{}`", variable.identifier); - - 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()) - } -} diff --git a/symbol-table/src/errors/type_.rs b/symbol-table/src/errors/type_.rs deleted file mode 100644 index c040fcc10a..0000000000 --- a/symbol-table/src/errors/type_.rs +++ /dev/null @@ -1,86 +0,0 @@ -// 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 . - -use leo_ast::{Error as FormattedError, Identifier, Span}; - -use std::path::Path; - -/// Errors encountered when resolving types. -#[derive(Debug, Error)] -pub enum TypeError { - #[error("{}", _0)] - Error(#[from] FormattedError), -} - -impl TypeError { - /// - /// Set the filepath for the error stacktrace. - /// - pub fn set_path(&mut self, path: &Path) { - match self { - TypeError::Error(error) => error.set_path(path), - } - } - - /// - /// Return a new formatted error with a given message and span information. - /// - fn new_from_span(message: String, span: Span) -> Self { - TypeError::Error(FormattedError::new_from_span(message, span)) - } - - /// - /// The `Self` keyword was used outside of a circuit. - /// - pub fn self_not_available(span: Span) -> Self { - let message = "Type `Self` is only available in circuit definitions and circuit functions.".to_string(); - - Self::new_from_span(message, span) - } - - /// - /// Found an unknown circuit name. - /// - pub fn undefined_circuit(identifier: Identifier) -> Self { - let message = format!( - "Type circuit `{}` must be defined before it is used in an expression.", - identifier.name - ); - - Self::new_from_span(message, identifier.span) - } - - /// - /// Found an unknown circuit member name. - /// - pub fn undefined_circuit_member(identifier: Identifier) -> Self { - let message = format!("Circuit has no member `{}`.", identifier.name); - - Self::new_from_span(message, identifier.span) - } - - /// - /// Found an unknown function name. - /// - pub fn undefined_function(identifier: Identifier) -> Self { - let message = format!( - "Type function `{}` must be defined before it is used in an expression.", - identifier.name - ); - - Self::new_from_span(message, identifier.span) - } -} diff --git a/symbol-table/src/imports/imported_symbols.rs b/symbol-table/src/imports/imported_symbols.rs deleted file mode 100644 index c344b9457b..0000000000 --- a/symbol-table/src/imports/imported_symbols.rs +++ /dev/null @@ -1,57 +0,0 @@ -// 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 . - -use leo_ast::{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 { - pub fn new(import: &ImportStatement) -> Self { - let mut imported_symbols = Self::default(); - - imported_symbols.push_package(&import.package); - - imported_symbols - } - - fn push_package(&mut self, package: &Package) { - self.push_package_access(package.name.name.clone(), &package.access); - } - - fn push_package_access(&mut self, package: String, access: &PackageAccess) { - match access { - PackageAccess::SubPackage(package) => self.push_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.push_package_access(package.clone(), access)), - } - } -} - -impl Default for ImportedSymbols { - fn default() -> Self { - Self { symbols: Vec::new() } - } -} diff --git a/symbol-table/src/imports/mod.rs b/symbol-table/src/imports/mod.rs deleted file mode 100644 index 000a0a4885..0000000000 --- a/symbol-table/src/imports/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod imported_symbols; -pub use self::imported_symbols::*; diff --git a/symbol-table/src/lib.rs b/symbol-table/src/lib.rs deleted file mode 100644 index 2156653e13..0000000000 --- a/symbol-table/src/lib.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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 . - -//! The symbol table for a Leo program. -//! -//! This module contains the [`SymbolTable`] type, an abstract data type that tracks the current -//! bindings for functions and circuits in a Leo program. -//! -//! A new [`Symbol Table`] type can be created from a reference to a [`LeoAst`]. -//! A [`Symbol Table`] type can be used to create a new [`TypeInference`] type. - -#[macro_use] -extern crate thiserror; - -pub mod attributes; -pub use self::attributes::*; - -pub mod errors; -pub use self::errors::*; - -pub mod imports; -pub use self::imports::*; - -pub mod symbol_table; -pub use self::symbol_table::*; - -pub mod types; -pub use self::types::*; diff --git a/symbol-table/src/symbol_table.rs b/symbol-table/src/symbol_table.rs deleted file mode 100644 index 0e5a56b121..0000000000 --- a/symbol-table/src/symbol_table.rs +++ /dev/null @@ -1,502 +0,0 @@ -// 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 . - -use crate::{CircuitType, CircuitVariableType, FunctionType, ImportedSymbols, SymbolTableError, UserDefinedType}; -use leo_ast::{Circuit, Function, Identifier, ImportStatement, ImportSymbol, Input, Package, Program}; -use leo_core::CorePackageList; -use leo_imports::ImportParser; - -use std::collections::{HashMap, HashSet}; - -pub const INPUT_VARIABLE_NAME: &str = "input"; -pub const RECORD_VARIABLE_NAME: &str = "record"; -pub const REGISTERS_VARIABLE_NAME: &str = "registers"; -pub const STATE_VARIABLE_NAME: &str = "state"; -pub const STATE_LEAF_VARIABLE_NAME: &str = "state_leaf"; - -/// The symbol table for a Leo program. -/// -/// A symbol table has access to all function and circuit names in its parent's symbol table. -/// A symbol table cannot access names in its child's symbol table. -/// A child symbol table cannot access names in another sibling's symbol table. -#[derive(Clone, Default)] -pub struct SymbolTable { - /// Maps name -> parameter type. - names: HashMap, - - /// Maps circuit name -> circuit type. - circuits: HashMap, - - /// Maps function name -> function type. - functions: HashMap, - - /// The parent of this symbol table. - parent: Option>, -} - -impl SymbolTable { - /// - /// Returns a new `SymbolTable` from a given, program, imported programs, and program input. - /// - /// Checks that each circuit or function name is unique. - /// Unique names are added to a table of name -> user defined type. - /// - /// Checks that each circuit or function definition contains valid types. - /// - pub fn new( - program: &Program, - import_parser: &ImportParser, - input: &Input, - ) -> Result { - // Create a new symbol table. - let mut table = Self::default(); - - // Insert input types into symbol table. - table.insert_input(input)?; - - // Check for duplicate program and import names. - table.check_names(program, import_parser)?; - - // Check for unknown or invalid types. - table.check_types(program)?; - - Ok(table) - } - - /// - /// Insert a function or circuit name into the symbol table from a given name and variable type. - /// - /// If the symbol table did not have this name present, `None` is returned. - /// If the symbol table did have this name present, the variable type is updated, and the old - /// variable type is returned. - /// - pub fn insert_name(&mut self, name: String, variable_type: UserDefinedType) -> Option { - 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: UserDefinedType, - ) -> 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: UserDefinedType, - ) -> 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. - /// - /// If the symbol table did not have this name present, `None` is returned. - /// If the symbol table did have this name present, the circuit type is updated, and the old - /// circuit type is returned. - /// - pub fn insert_circuit_type(&mut self, identifier: Identifier, circuit_type: CircuitType) -> Option { - self.circuits.insert(identifier.name, circuit_type) - } - - /// - /// Insert a function definition into the symbol table from a given identifier and - /// function type. - /// - /// If the symbol table did not have this name present, `None` is returned. - /// If the symbol table did have this name present, the function type is updated, and the old - /// function type is returned. - /// - pub fn insert_function_type( - &mut self, - identifier: Identifier, - function_type: FunctionType, - ) -> Option { - self.functions.insert(identifier.name, function_type) - } - - /// - /// Returns a reference to the circuit type corresponding to the name. - /// - /// If the symbol table did not have this name present, then the parent symbol table is checked. - /// If there is no parent symbol table, then `None` is returned. - /// - pub fn get_circuit_type(&self, name: &str) -> Option<&CircuitType> { - // Lookup name in symbol table. - match self.circuits.get(name) { - Some(circuit) => Some(circuit), - None => { - // Lookup name in parent symbol table. - match &self.parent { - Some(parent) => parent.get_circuit_type(name), - None => None, - } - } - } - } - - /// - /// Returns a reference to the function type corresponding to the name. - /// - /// If the symbol table did not have this name present, then the parent symbol table is checked. - /// If there is no parent symbol table, then `None` is returned. - /// - pub fn get_function_type(&self, name: &str) -> Option<&FunctionType> { - // Lookup name in symbol table. - match self.functions.get(name) { - Some(circuit) => Some(circuit), - None => { - // Lookup name in parent symbol table - match &self.parent { - Some(parent) => parent.get_function_type(name), - None => None, - } - } - } - } - - /// - /// 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_names(&mut self, program: &Program, import_parser: &ImportParser) -> Result<(), SymbolTableError> { - // Check unresolved program import names. - self.check_import_names(&program.imports, import_parser)?; - - // Check unresolved program circuit names. - self.check_circuit_names(&program.circuits)?; - - // Check unresolved program function names. - self.check_function_names(&program.functions)?; - - Ok(()) - } - - /// - /// Checks for duplicate circuit names given a hashmap of circuits. - /// - /// If a circuit name has no duplicates, then it is inserted into the symbol table. - /// Types defined later in the program cannot have the same name. - /// - pub fn check_circuit_names(&mut self, circuits: &HashMap) -> Result<(), SymbolTableError> { - // Iterate over circuit names and definitions. - for (identifier, circuit) in circuits.iter() { - // Attempt to insert the circuit name into the symbol table. - self.insert_circuit_name(identifier.to_string(), UserDefinedType::from(circuit.clone()))?; - } - - Ok(()) - } - - /// - /// Checks for duplicate function names given a hashmap of functions. - /// - /// If a function name has no duplicates, then it is inserted into the symbol table. - /// Types defined later in the program cannot have the same name. - /// - pub fn check_function_names(&mut self, functions: &HashMap) -> Result<(), SymbolTableError> { - // Iterate over function names and definitions. - for (identifier, function) in functions.iter() { - // Attempt to insert the function name into the symbol table. - self.insert_function_name(identifier.to_string(), UserDefinedType::from(function.clone()))?; - } - - Ok(()) - } - - /// - /// Checks that all given imported names 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_names( - &mut self, - imports: &[ImportStatement], - import_parser: &ImportParser, - ) -> Result<(), SymbolTableError> { - // Iterate over imported names. - for import in imports { - self.check_import_statement(import, import_parser)?; - } - - Ok(()) - } - - /// - /// Checks that a given import statement imports an existing package. - /// - /// 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_statement( - &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.check_core_package(package); - } - - // Attempt to insert the imported names into the symbol table. - self.check_package(import, import_parser) - } - - /// - /// Inserts imported core package circuit names and types into the symbol table. - /// - /// Checks that the core package and all circuit names exist. Checks that imported circuit types - /// only contain known types. - /// - pub fn check_core_package(&mut self, package: &Package) -> Result<(), SymbolTableError> { - // Create list of imported core packages. - let list = CorePackageList::from_package_access(package.access.to_owned())?; - - // Fetch core package symbols from `leo-core`. - let symbol_list = list.to_symbols()?; - - // Insert name and type information for each core package symbol. - for (name, circuit) in symbol_list.symbols() { - // Store name of symbol. - self.insert_circuit_name(name.to_string(), UserDefinedType::from(circuit.clone()))?; - - // Create new circuit type for symbol. - let circuit_type = CircuitType::new(&self, circuit.to_owned())?; - - // Insert circuit type of symbol. - self.insert_circuit_type(circuit_type.identifier.clone(), circuit_type); - } - - Ok(()) - } - - /// - /// Inserts one or more imported symbols for a given imported package. - /// - /// Checks that the package and all circuit and function names exist. Checks that imported circuit - /// and function types only contain known types. - /// - pub fn check_package( - &mut self, - import: &ImportStatement, - import_parser: &ImportParser, - ) -> Result<(), SymbolTableError> { - // Get imported symbols from statement. - let imported_symbols = ImportedSymbols::new(import); - - // Import all symbols from an imported file for now. - // Keep track of which import files have already been checked. - let mut checked = HashSet::new(); - - // Iterate over each imported symbol. - for (name, symbol) in imported_symbols.symbols { - // Find the imported program. - let program = import_parser - .get_import(&name) - .ok_or_else(|| SymbolTableError::unknown_package(&name, &symbol.span))?; - - // Push the imported file's name to checked import files. - if !checked.insert(name) { - // Skip the imported symbol if we have already checked the file. - continue; - }; - - // Check the imported program for duplicate types. - self.check_names(program, import_parser)?; - - // Check the imported program for undefined types. - self.check_types(program)?; - - // Store the imported symbol. - // self.insert_import_symbol(symbol, program)?; // TODO (collinc97) uncomment this line when public/private import scopes are implemented. - } - - Ok(()) - } - - /// - /// 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_circuit_names(&program.circuits)?; - - // Insert all program functions. - self.check_function_names(&program.functions) - } else { - // Check for a symbol alias. - let identifier = symbol.alias.to_owned().unwrap_or_else(|| symbol.symbol.to_owned()); - - // Check if the imported symbol is a circuit - match program.circuits.get(&symbol.symbol) { - Some(circuit) => { - // Insert imported circuit. - self.insert_circuit_name(identifier.to_string(), UserDefinedType::from(circuit.to_owned())) - } - None => { - // Check if the imported symbol is a function. - match program.functions.get(&symbol.symbol) { - Some(function) => { - // Insert the imported function. - self.insert_function_name( - identifier.to_string(), - UserDefinedType::from(function.to_owned()), - ) - } - None => Err(SymbolTableError::unknown_symbol(&symbol, program)), - } - } - } - } - } - - /// - /// Checks for unknown types in circuit and function definitions given an unresolved program. - /// - /// If a circuit or function definition only contains known types, then it is inserted into the - /// symbol table. Variables defined later in the unresolved program can lookup the definition and - /// refer to its expected types. - /// - pub fn check_types(&mut self, program: &Program) -> Result<(), SymbolTableError> { - // Check unresolved program circuit definitions. - self.check_types_circuits(&program.circuits)?; - - // Check unresolved program function definitions. - self.check_types_functions(&program.functions)?; - - Ok(()) - } - - /// - /// Checks for unknown types in a circuit given a hashmap of circuits. - /// - /// If a circuit definition only contains known types, then it is inserted into the - /// symbol table. Variables defined later in the program can lookup the definition - /// and refer to its expected types - /// - pub fn check_types_circuits(&mut self, circuits: &HashMap) -> Result<(), SymbolTableError> { - // Iterate over circuit names and definitions. - for circuit in circuits.values() { - // Get the identifier of the circuit. - let identifier = circuit.circuit_name.clone(); - - // Resolve unknown types in the circuit definition. - let circuit_type = CircuitType::new(self, circuit.clone())?; - - // Attempt to insert the circuit definition into the symbol table. - self.insert_circuit_type(identifier, circuit_type); - } - - Ok(()) - } - - /// - /// Checks for unknown types in a function given a hashmap of functions. - /// - /// If a function definition only contains known types, then it is inserted into the - /// symbol table. Variables defined later in the program can lookup the definition - /// and refer to its expected types - /// - pub fn check_types_functions(&mut self, functions: &HashMap) -> Result<(), SymbolTableError> { - // Iterate over function names and definitions. - for function in functions.values() { - // Get the identifier of the function. - let identifier = function.identifier.clone(); - - // Resolve unknown types in the function definition. - let function_type = FunctionType::new(&self, function.clone())?; - - // Attempt to insert the function definition into the symbol table. - self.insert_function_type(identifier, function_type); - } - - Ok(()) - } - - /// - /// Inserts function input types into the symbol table. - /// - /// Creates a new `CircuitType` to represent the input values. - /// 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> { - // Get values for each input section. - let registers_values = input.get_registers().values(); - let record_values = input.get_record().values(); - let state_values = input.get_state().values(); - let state_leaf_values = input.get_state_leaf().values(); - - // Create a new `CircuitType` for each input section. - let registers_type = - CircuitType::from_input_section(&self, REGISTERS_VARIABLE_NAME.to_string(), registers_values)?; - let record_type = CircuitType::from_input_section(&self, RECORD_VARIABLE_NAME.to_string(), record_values)?; - let state_type = CircuitType::from_input_section(&self, STATE_VARIABLE_NAME.to_string(), state_values)?; - let state_leaf_type = - CircuitType::from_input_section(&self, STATE_LEAF_VARIABLE_NAME.to_string(), state_leaf_values)?; - - // Create a new `CircuitVariableType` for each type. - let registers_variable = CircuitVariableType::from(®isters_type); - let record_variable = CircuitVariableType::from(&record_type); - let state_variable = CircuitVariableType::from(&state_type); - let state_leaf_variable = CircuitVariableType::from(&state_leaf_type); - - // Create new `CircuitType` for input keyword. - let input_type = CircuitType { - identifier: Identifier::new(INPUT_VARIABLE_NAME.to_string()), - variables: vec![registers_variable, record_variable, state_variable, state_leaf_variable], - functions: Vec::new(), - }; - - // Insert each circuit type into the symbol table. - self.insert_circuit_type(registers_type.identifier.clone(), registers_type); - self.insert_circuit_type(record_type.identifier.clone(), record_type); - self.insert_circuit_type(state_type.identifier.clone(), state_type); - self.insert_circuit_type(state_leaf_type.identifier.clone(), state_leaf_type); - self.insert_circuit_type(input_type.identifier.clone(), input_type); - - Ok(()) - } -} diff --git a/symbol-table/src/types/circuits/circuit.rs b/symbol-table/src/types/circuits/circuit.rs deleted file mode 100644 index 2e6ea923f0..0000000000 --- a/symbol-table/src/types/circuits/circuit.rs +++ /dev/null @@ -1,194 +0,0 @@ -// 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 . - -use crate::{ - types::circuits::{CircuitFunctionType, CircuitVariableType}, - Attribute, - FunctionType, - SymbolTable, - Type, - TypeError, -}; -use leo_ast::{Circuit, CircuitMember, Identifier, InputValue, Parameter, Span}; - -use serde::{Deserialize, Serialize}; -use std::{ - collections::HashMap, - hash::{Hash, Hasher}, -}; - -/// Stores circuit definition details. -/// -/// This type should be added to the circuit symbol table for a resolved syntax tree. -/// This is a user-defined type. -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct CircuitType { - /// The name of the circuit definition. - pub identifier: Identifier, - - /// The circuit variables. - pub variables: Vec, - - /// The circuit functions. - pub functions: Vec, -} - -impl CircuitType { - /// - /// Return a new `CircuitType` from a given `Circuit` definition. - /// - /// Performs a lookup in the given symbol table if the circuit definition contains - /// user-defined types. - /// - pub fn new(table: &SymbolTable, unresolved: Circuit) -> Result { - let circuit_identifier = unresolved.circuit_name; - let mut variables = vec![]; - let mut functions = vec![]; - - // Resolve the type of every circuit member. - for member in unresolved.members { - match member { - CircuitMember::CircuitVariable(is_mutable, variable_identifier, type_) => { - // Resolve the type of the circuit member variable. - let type_ = Type::new_from_circuit( - table, - type_, - circuit_identifier.clone(), - circuit_identifier.span.clone(), - )?; - - // Check if the circuit member variable is mutable. - let attribute = if is_mutable { Some(Attribute::Mutable) } else { None }; - - // Create a new circuit variable type. - let variable = CircuitVariableType { - identifier: variable_identifier, - type_, - attribute, - }; - - // Store the circuit variable type. - variables.push(variable); - } - CircuitMember::CircuitFunction(is_static, function) => { - // Resolve the type of the circuit member function. - let function_type = FunctionType::from_circuit(table, circuit_identifier.clone(), function)?; - - // Check if the circuit member function is static. - let attribute = if is_static { Some(Attribute::Static) } else { None }; - - // Create a new circuit function type. - let function = CircuitFunctionType { - function: function_type, - attribute, - }; - - // Store the circuit function type. - functions.push(function); - } - } - } - - // Return a new circuit type. - Ok(CircuitType { - identifier: circuit_identifier, - variables, - functions, - }) - } - - /// - /// Returns the function type of a circuit member given an identifier. - /// - pub fn member_function_type(&self, identifier: &Identifier) -> Option<&CircuitFunctionType> { - self.functions - .iter() - .find(|function| function.function.identifier.eq(identifier)) - } - - /// - /// Returns the type of a circuit member. - /// - /// If the member is a circuit variable, then the type of the variable is returned. - /// If the member is a circuit function, then the return type of the function is returned. - /// - pub fn member_type(&self, identifier: &Identifier) -> Result { - // Check if the circuit member is a circuit variable. - let matched_variable = self - .variables - .iter() - .find(|variable| variable.identifier.eq(identifier)); - - match matched_variable { - Some(variable) => Ok(variable.type_.to_owned()), - None => { - // Check if the circuit member is a circuit function. - let matched_function = self.member_function_type(identifier); - - match matched_function { - Some(function) => Ok(Type::Function(function.function.identifier.to_owned())), - None => Err(TypeError::undefined_circuit_member(identifier.clone())), - } - } - } - } - - /// - /// Returns a new `CircuitType` from a given `Input` struct. - /// - pub fn from_input_section( - table: &SymbolTable, - name: String, - section: HashMap>, - ) -> Result { - // Create a new `CircuitVariableType` for each section pair. - let mut variables = Vec::new(); - - for (parameter, _option) in section.into_iter() { - let variable = CircuitVariableType { - identifier: parameter.variable, - type_: Type::new(table, parameter.type_, Span::default())?, - attribute: None, - }; - - variables.push(variable); - } - - // Create a new `Identifier` for the input section. - let identifier = Identifier::new(name); - - // Return a new `CircuitType` with the given name. - Ok(Self { - identifier, - variables, - functions: Vec::new(), - }) - } -} - -impl PartialEq for CircuitType { - fn eq(&self, other: &Self) -> bool { - self.identifier.eq(&other.identifier) - } -} - -impl Eq for CircuitType {} - -impl Hash for CircuitType { - fn hash(&self, state: &mut H) { - self.identifier.hash(state); - } -} diff --git a/symbol-table/src/types/circuits/circuit_function.rs b/symbol-table/src/types/circuits/circuit_function.rs deleted file mode 100644 index 4c6d8686a9..0000000000 --- a/symbol-table/src/types/circuits/circuit_function.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -use crate::{types::FunctionType, Attribute}; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct CircuitFunctionType { - /// The function signature of the circuit function - pub function: FunctionType, - /// The attributes of the circuit function - pub attribute: Option, -} diff --git a/symbol-table/src/types/circuits/circuit_variable.rs b/symbol-table/src/types/circuits/circuit_variable.rs deleted file mode 100644 index dfbb4d94dc..0000000000 --- a/symbol-table/src/types/circuits/circuit_variable.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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 . - -use crate::{Attribute, CircuitType, Type}; -use leo_ast::Identifier; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct CircuitVariableType { - /// The name of the circuit variable - pub identifier: Identifier, - /// The type of the circuit variable - pub type_: Type, - /// The attribute of the circuit variable - pub attribute: Option, -} - -impl From<&CircuitType> for CircuitVariableType { - fn from(type_: &CircuitType) -> Self { - Self { - identifier: type_.identifier.clone(), - type_: Type::Circuit(type_.identifier.clone()), - attribute: None, - } - } -} diff --git a/symbol-table/src/types/circuits/mod.rs b/symbol-table/src/types/circuits/mod.rs deleted file mode 100644 index 8205016c50..0000000000 --- a/symbol-table/src/types/circuits/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 . - -pub mod circuit; -pub use self::circuit::*; - -pub mod circuit_function; -pub use self::circuit_function::*; - -pub mod circuit_variable; -pub use self::circuit_variable::*; diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs deleted file mode 100644 index 0abdc87aa9..0000000000 --- a/symbol-table/src/types/functions/function.rs +++ /dev/null @@ -1,136 +0,0 @@ -// 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 . - -use crate::{ - types::functions::{FunctionInputType, FunctionOutputType}, - SymbolTable, - TypeError, -}; -use leo_ast::{Function, Identifier}; - -use serde::{Deserialize, Serialize}; -use std::hash::{Hash, Hasher}; - -/// Stores function definition details. -/// -/// This type should be added to the function symbol table for a resolved syntax tree. -/// This is a user-defined type. -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct FunctionType { - /// The name of the function definition. - pub identifier: Identifier, - - /// The function inputs. - pub inputs: Vec, - - /// The function output. - pub output: FunctionOutputType, -} - -impl FunctionType { - /// - /// Return a new `FunctionType` from a given `Function` definition. - /// - /// Performs a lookup in the given symbol table if the function definition contains - /// user-defined types. - /// - pub fn new(table: &SymbolTable, unresolved: Function) -> Result { - let mut inputs_resolved = Vec::with_capacity(unresolved.input.len()); - - // Type check function inputs - for input in unresolved.input { - let input = FunctionInputType::new(table, input)?; - inputs_resolved.push(input); - } - - // Type check function output - let output = FunctionOutputType::new(table, unresolved.output, unresolved.span)?; - - Ok(FunctionType { - identifier: unresolved.identifier, - inputs: inputs_resolved, - output, - }) - } - - /// - /// Return a new `FunctionType` from a given `Function` definition. - /// - /// Performs a lookup in the given symbol table if the function definition contains - /// user-defined types. - /// - /// If the function definition contains the `Self` keyword, then the given circuit identifier - /// is used as the type. - /// - pub fn from_circuit( - table: &SymbolTable, - circuit_name: Identifier, - unresolved_function: Function, - ) -> Result { - let function_identifier = unresolved_function.identifier; - let mut inputs = Vec::with_capacity(unresolved_function.input.len()); - - // Type check function inputs. - for unresolved_input in unresolved_function.input { - let input = FunctionInputType::new_from_circuit(table, unresolved_input, circuit_name.clone())?; - inputs.push(input); - } - - // Type check function output. - let output = FunctionOutputType::new_from_circuit( - table, - circuit_name, - unresolved_function.output, - unresolved_function.span, - )?; - - Ok(FunctionType { - identifier: function_identifier, - inputs, - output, - }) - } - - /// - /// Resolve a function definition and insert it into the given symbol table. - /// - pub fn insert_definition(table: &mut SymbolTable, unresolved_function: Function) -> Result<(), TypeError> { - // Get the identifier of the function. - let function_identifier = unresolved_function.identifier.clone(); - - // Resolve the function definition into a function type. - let function = Self::new(table, unresolved_function)?; - - // Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table. - table.insert_function_type(function_identifier, function); - - Ok(()) - } -} - -impl PartialEq for FunctionType { - fn eq(&self, other: &Self) -> bool { - self.identifier.eq(&other.identifier) - } -} - -impl Eq for FunctionType {} - -impl Hash for FunctionType { - fn hash(&self, state: &mut H) { - self.identifier.hash(state); - } -} diff --git a/symbol-table/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs deleted file mode 100644 index 42afe2a52a..0000000000 --- a/symbol-table/src/types/functions/function_input.rs +++ /dev/null @@ -1,90 +0,0 @@ -// 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 . - -use crate::{FunctionInputVariableType, SymbolTable, Type, TypeError}; -use leo_ast::{FunctionInput, Identifier}; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub enum FunctionInputType { - InputKeyword(Identifier), - Variable(FunctionInputVariableType), -} - -impl FunctionInputType { - /// - /// Return the `Identifier` containing name and span information about the current function input. - /// - pub fn identifier(&self) -> &Identifier { - match self { - FunctionInputType::InputKeyword(identifier) => identifier, - FunctionInputType::Variable(variable) => &variable.identifier, - } - } - - /// - /// Return the `Type` of the current function input. - /// - pub fn type_(&self) -> Type { - match self { - FunctionInputType::InputKeyword(identifier) => Type::Circuit(identifier.to_owned()), - FunctionInputType::Variable(variable) => variable.type_.to_owned(), - } - } - - /// - /// Return a new `FunctionInputType` from a given `FunctionInput`. - /// - /// Performs a lookup in the given symbol table if the function input contains - /// user-defined types. - /// - pub fn new(table: &SymbolTable, unresolved: FunctionInput) -> Result { - Ok(match unresolved { - FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), - FunctionInput::Variable(variable) => { - let variable_resolved = FunctionInputVariableType::new(table, variable)?; - - FunctionInputType::Variable(variable_resolved) - } - }) - } - - /// - /// Return a new `FunctionInputType` from a given `FunctionInput`. - /// - /// Performs a lookup in the given symbol table if the function input contains - /// user-defined types. - /// - /// If the type of the function input is the `Self` keyword, then the given circuit identifier - /// is used as the type. - /// - pub fn new_from_circuit( - table: &SymbolTable, - unresolved: FunctionInput, - circuit_name: Identifier, - ) -> Result { - Ok(match unresolved { - FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier), - FunctionInput::Variable(unresolved_function_input) => { - let function_input = - FunctionInputVariableType::new_from_circuit(table, unresolved_function_input, circuit_name)?; - - FunctionInputType::Variable(function_input) - } - }) - } -} diff --git a/symbol-table/src/types/functions/function_input_variable.rs b/symbol-table/src/types/functions/function_input_variable.rs deleted file mode 100644 index 2cfd8275ec..0000000000 --- a/symbol-table/src/types/functions/function_input_variable.rs +++ /dev/null @@ -1,119 +0,0 @@ -// 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 . - -use crate::{Attribute, SymbolTable, Type, TypeError, UserDefinedType}; -use leo_ast::{FunctionInputVariable, Identifier, Span}; - -use serde::{Deserialize, Serialize}; -use std::hash::{Hash, Hasher}; - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct FunctionInputVariableType { - /// Name of function input. - pub identifier: Identifier, - - /// Type of function input. - pub type_: Type, - - /// The attributes of the function input. - pub attribute: Option, - - /// The span of the function input. - pub span: Span, -} - -impl FunctionInputVariableType { - /// - /// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`. - /// - /// Performs a lookup in the given symbol table if the type is user-defined. - /// - pub fn new(table: &SymbolTable, unresolved: FunctionInputVariable) -> Result { - let type_ = Type::new(table, unresolved.type_, unresolved.span.clone())?; - let attribute = if unresolved.mutable { - Some(Attribute::Mutable) - } else { - None - }; - - Ok(FunctionInputVariableType { - identifier: unresolved.identifier, - type_, - attribute, - span: unresolved.span, - }) - } - - /// - /// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`. - /// - /// Performs a lookup in the given symbol table if the type is user-defined. - /// - /// If the type of the function return type is the `Self` keyword, then the given circuit - /// identifier is used as the type. - /// - pub fn new_from_circuit( - table: &SymbolTable, - unresolved_function_input: FunctionInputVariable, - circuit_name: Identifier, - ) -> Result { - let type_ = Type::new_from_circuit( - table, - unresolved_function_input.type_, - circuit_name, - unresolved_function_input.span.clone(), - )?; - - let attribute = if unresolved_function_input.mutable { - Some(Attribute::Mutable) - } else { - None - }; - - Ok(FunctionInputVariableType { - identifier: unresolved_function_input.identifier, - type_, - attribute, - span: unresolved_function_input.span, - }) - } - - /// - /// Insert the current function input variable type into the given symbol table. - /// - /// If the symbol table did not have this name present, `None` is returned. - /// - pub fn insert(&self, table: &mut SymbolTable) -> Option { - let key = self.identifier.name.clone(); - let value = UserDefinedType::from(self.clone()); - - table.insert_name(key, value) - } -} - -impl PartialEq for FunctionInputVariableType { - fn eq(&self, other: &Self) -> bool { - self.identifier.eq(&other.identifier) - } -} - -impl Eq for FunctionInputVariableType {} - -impl Hash for FunctionInputVariableType { - fn hash(&self, state: &mut H) { - self.identifier.hash(state) - } -} diff --git a/symbol-table/src/types/functions/function_output.rs b/symbol-table/src/types/functions/function_output.rs deleted file mode 100644 index 2da52025cf..0000000000 --- a/symbol-table/src/types/functions/function_output.rs +++ /dev/null @@ -1,69 +0,0 @@ -// 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 . - -use crate::{SymbolTable, Type, TypeError}; - -use leo_ast::{Identifier, Span, Type as UnresolvedType}; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct FunctionOutputType { - /// Type of function output. - pub type_: Type, -} - -impl FunctionOutputType { - /// - /// Return a new `FunctionOutputType` from a given optional function return type and span. - /// - /// Performs a lookup in the given symbol table if the return type is user-defined. - /// - pub(crate) fn new( - table: &SymbolTable, - function_output: Option, - span: Span, - ) -> Result { - let type_ = match function_output { - None => Type::Tuple(vec![]), // functions with no return value return an empty tuple - Some(type_) => Type::new(table, type_, span)?, - }; - - Ok(FunctionOutputType { type_ }) - } - - /// - /// Return a new `FunctionOutputType` from a given optional function return type and span. - /// - /// Performs a lookup in the given symbol table if the return type is user-defined. - /// - /// If the type of the function return type is the `Self` keyword, then the given circuit - /// identifier is used as the type. - /// - pub fn new_from_circuit( - table: &SymbolTable, - circuit_name: Identifier, - unresolved: Option, - span: Span, - ) -> Result { - let output_type = match unresolved { - None => Type::Tuple(vec![]), - Some(type_) => Type::new_from_circuit(table, type_, circuit_name, span)?, - }; - - Ok(FunctionOutputType { type_: output_type }) - } -} diff --git a/symbol-table/src/types/functions/mod.rs b/symbol-table/src/types/functions/mod.rs deleted file mode 100644 index fe22157837..0000000000 --- a/symbol-table/src/types/functions/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -pub mod function; -pub use self::function::*; - -pub mod function_input; -pub use self::function_input::*; - -pub mod function_input_variable; -pub use self::function_input_variable::*; - -pub mod function_output; -pub use self::function_output::*; diff --git a/symbol-table/src/types/mod.rs b/symbol-table/src/types/mod.rs deleted file mode 100644 index 8c8adaad13..0000000000 --- a/symbol-table/src/types/mod.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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 . - -pub mod circuits; -pub use self::circuits::*; - -pub mod functions; -pub use self::functions::*; - -pub mod type_; -pub use self::type_::*; - -pub mod type_variable; -pub use self::type_variable::*; - -pub mod user_defined; -pub use self::user_defined::*; diff --git a/symbol-table/src/types/type_.rs b/symbol-table/src/types/type_.rs deleted file mode 100644 index 304ffa083d..0000000000 --- a/symbol-table/src/types/type_.rs +++ /dev/null @@ -1,265 +0,0 @@ -// 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 . -use crate::{SymbolTable, TypeError, TypeVariable}; -use leo_ast::{Identifier, IntegerType, Span, Type as UnresolvedType}; - -use serde::{Deserialize, Serialize}; -use std::{ - cmp::{Eq, PartialEq}, - fmt, -}; - -/// A type in a Leo program. -#[derive(Clone, Debug, Serialize, Deserialize)] -pub enum Type { - // Data types - Address, - Boolean, - Field, - Group, - IntegerType(IntegerType), - - // Data type wrappers - Array(Box), - Tuple(Vec), - - // User defined types - Circuit(Identifier), - Function(Identifier), - - // Unknown type variables - TypeVariable(TypeVariable), -} - -impl Type { - /// - /// Return a new type from the given unresolved type. - /// - /// Performs a lookup in the given symbol table if the type is user-defined. - /// - pub fn new(table: &SymbolTable, type_: UnresolvedType, span: Span) -> Result { - Ok(match type_ { - UnresolvedType::Address => Type::Address, - UnresolvedType::Boolean => Type::Boolean, - UnresolvedType::Field => Type::Field, - UnresolvedType::Group => Type::Group, - UnresolvedType::IntegerType(integer) => Type::IntegerType(integer), - - UnresolvedType::Array(type_, _) => { - let array_type = Type::new(table, *type_, span)?; - - Type::Array(Box::new(array_type)) - } - UnresolvedType::Tuple(types) => { - let tuple_types = types - .into_iter() - .map(|type_| Type::new(table, type_, span.clone())) - .collect::, _>>()?; - - Type::Tuple(tuple_types) - } - - UnresolvedType::Circuit(identifier) => { - // Lookup the circuit type in the symbol table - let circuit_type = table - .get_circuit_type(&identifier.name) - .ok_or_else(|| TypeError::undefined_circuit(identifier))?; - - Type::Circuit(circuit_type.identifier.clone()) - } - - UnresolvedType::SelfType => { - // Throw an error for using `Self` outside of a circuit - return Err(TypeError::self_not_available(span)); - } - }) - } - - /// - /// Return a new type from the given unresolved type. - /// - /// If this type is SelfType, return the circuit's type. - /// - pub fn new_from_circuit( - table: &SymbolTable, - type_: UnresolvedType, - circuit_name: Identifier, - span: Span, - ) -> Result { - Ok(match type_ { - UnresolvedType::Array(type_, _) => { - let array_type = Type::new_from_circuit(table, *type_, circuit_name, span)?; - Type::Array(Box::new(array_type)) - } - UnresolvedType::Tuple(types) => { - let tuple_types = types - .into_iter() - .map(|type_| Type::new_from_circuit(table, type_, circuit_name.clone(), span.clone())) - .collect::, _>>()?; - - Type::Tuple(tuple_types) - } - UnresolvedType::SelfType => Type::Circuit(circuit_name), - // The unresolved type does not depend on the current circuit definition - unresolved => Type::new(table, unresolved, span)?, - }) - } - - /// Returns a list of signed integer types. - pub const fn signed_integer_types() -> [Type; 5] { - [ - Type::IntegerType(IntegerType::I8), - Type::IntegerType(IntegerType::I16), - Type::IntegerType(IntegerType::I32), - Type::IntegerType(IntegerType::I64), - Type::IntegerType(IntegerType::I128), - ] - } - - /// Returns a list of unsigned integer types. - pub const fn unsigned_integer_types() -> [Type; 5] { - [ - Type::IntegerType(IntegerType::U8), - Type::IntegerType(IntegerType::U16), - Type::IntegerType(IntegerType::U32), - Type::IntegerType(IntegerType::U64), - Type::IntegerType(IntegerType::U128), - ] - } - - /// Returns a list of positive integer types. - pub fn negative_integer_types() -> Vec { - let field_group = [Type::Field, Type::Group]; - - let mut types = Vec::new(); - - types.extend_from_slice(&field_group); - types.extend_from_slice(&Self::signed_integer_types()); - - types - } - - /// Returns a list of integer types. - pub fn integer_types() -> Vec { - let mut types = Vec::new(); - - types.extend_from_slice(&Self::unsigned_integer_types()); - types.extend_from_slice(&Self::negative_integer_types()); - - types - } - - /// Returns a list of possible index types (u8, u16, u32). - pub fn index_types() -> Vec { - let index_types = [ - Type::IntegerType(IntegerType::U8), - Type::IntegerType(IntegerType::U16), - Type::IntegerType(IntegerType::U32), - ]; - - let mut types = Vec::new(); - - types.extend_from_slice(&index_types); - - types - } - - /// - /// Replaces self with the given type if self is equal to the given `TypeVariable`. - /// - pub fn substitute(&mut self, variable: &TypeVariable, type_: &Type) { - match self { - Type::TypeVariable(self_variable) => { - if self_variable == variable { - *self = type_.to_owned() - } - } - Type::Array(self_type) => { - self_type.substitute(variable, type_); - } - Type::Tuple(types) => types - .iter_mut() - .for_each(|tuple_type| tuple_type.substitute(variable, type_)), - _ => {} - } - } -} - -impl fmt::Display for Type { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match &self { - Type::Address => write!(f, "address"), - Type::Boolean => write!(f, "bool"), - Type::Field => write!(f, "field"), - Type::Group => write!(f, "group"), - Type::IntegerType(integer_type) => write!(f, "{}", integer_type), - - Type::Array(type_) => write!(f, "[{}]", *type_), - Type::Tuple(tuple) => { - let tuple_string = tuple.iter().map(|x| x.to_string()).collect::>().join(", "); - - write!(f, "({})", tuple_string) - } - - Type::Circuit(identifier) => write!(f, "circuit {}", identifier), - Type::Function(identifier) => write!(f, "function {}", identifier), - Type::TypeVariable(type_variable) => write!(f, "{}", type_variable), - } - } -} - -impl PartialEq for Type { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (Type::Address, Type::Address) => true, - (Type::Boolean, Type::Boolean) => true, - (Type::Field, Type::Field) => true, - (Type::Group, Type::Group) => true, - (Type::IntegerType(integer_type1), Type::IntegerType(integer_type2)) => integer_type1.eq(integer_type2), - - (Type::Array(array1), Type::Array(array2)) => { - // Get both array element types before comparison. - let array1_element = get_array_element_type(array1); - let array2_element = get_array_element_type(array2); - - // Check that both arrays have the same element type. - array1_element.eq(array2_element) - } - - (Type::Tuple(types1), Type::Tuple(types2)) => types1.eq(types2), - (Type::Circuit(identifier1), Type::Circuit(identifier2)) => identifier1.eq(identifier2), - (Type::Function(identifier1), Type::Function(identifier2)) => identifier1.eq(identifier2), - (Type::TypeVariable(variable1), Type::TypeVariable(variable2)) => variable1.eq(variable2), - _ => false, - } - } -} - -impl Eq for Type {} - -/// -/// Returns the data type of the array element. -/// -/// If the given `type_` is an array, call `get_array_element_type()` on the array element type. -/// If the given `type_` is any other type, return the `type_`. -/// -pub fn get_array_element_type(type_: &Type) -> &Type { - if let Type::Array(element_type) = type_ { - get_array_element_type(element_type) - } else { - type_ - } -} diff --git a/symbol-table/src/types/type_variable.rs b/symbol-table/src/types/type_variable.rs deleted file mode 100644 index 161c5f3953..0000000000 --- a/symbol-table/src/types/type_variable.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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 . -use leo_ast::Identifier; - -use serde::{Deserialize, Serialize}; -use std::fmt; - -/// An unknown type in a Leo program. -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct TypeVariable { - identifier: Identifier, -} - -impl fmt::Display for TypeVariable { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.identifier) - } -} - -impl From for TypeVariable { - fn from(identifier: Identifier) -> Self { - Self { identifier } - } -} - -/// Compare the type variable `Identifier` and `Span`. -impl PartialEq for TypeVariable { - fn eq(&self, other: &Self) -> bool { - self.identifier.name.eq(&other.identifier.name) || self.identifier.span.eq(&other.identifier.span) - } -} - -impl Eq for TypeVariable {} diff --git a/symbol-table/src/types/user_defined/mod.rs b/symbol-table/src/types/user_defined/mod.rs deleted file mode 100644 index c919d6a014..0000000000 --- a/symbol-table/src/types/user_defined/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 . - -pub mod user_defined_type; -pub use self::user_defined_type::*; diff --git a/symbol-table/src/types/user_defined/user_defined_type.rs b/symbol-table/src/types/user_defined/user_defined_type.rs deleted file mode 100644 index 80e75eedf8..0000000000 --- a/symbol-table/src/types/user_defined/user_defined_type.rs +++ /dev/null @@ -1,86 +0,0 @@ -// 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 . -use crate::{Attribute, FunctionInputVariableType, Type}; -use leo_ast::{Circuit, Function, Identifier}; - -use std::{ - fmt, - hash::{Hash, Hasher}, -}; - -/// Stores information for a user defined type. -/// -/// User defined types include circuits and functions in a Leo program. -#[derive(Clone, Debug)] -pub struct UserDefinedType { - pub identifier: Identifier, - pub type_: Type, - pub attribute: Option, -} - -impl From for UserDefinedType { - fn from(value: Circuit) -> Self { - let identifier = value.circuit_name; - - UserDefinedType { - identifier: identifier.clone(), - type_: Type::Circuit(identifier), - attribute: None, - } - } -} - -impl From for UserDefinedType { - fn from(value: Function) -> Self { - let identifier = value.identifier; - - UserDefinedType { - identifier: identifier.clone(), - type_: Type::Function(identifier), - attribute: None, - } - } -} - -impl From for UserDefinedType { - fn from(value: FunctionInputVariableType) -> Self { - UserDefinedType { - identifier: value.identifier, - type_: value.type_, - attribute: value.attribute, - } - } -} - -impl fmt::Display for UserDefinedType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.identifier) - } -} - -impl PartialEq for UserDefinedType { - fn eq(&self, other: &Self) -> bool { - self.identifier.eq(&other.identifier) - } -} - -impl Eq for UserDefinedType {} - -impl Hash for UserDefinedType { - fn hash(&self, state: &mut H) { - self.identifier.hash(state); - } -} diff --git a/symbol-table/tests/mod.rs b/symbol-table/tests/mod.rs deleted file mode 100644 index ccb84e1170..0000000000 --- a/symbol-table/tests/mod.rs +++ /dev/null @@ -1,122 +0,0 @@ -// 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 . - -pub mod symbol_table; - -use leo_ast::{Input, LeoAst}; -use leo_grammar::Grammar; -use leo_symbol_table::{SymbolTable, SymbolTableError}; - -use leo_imports::ImportParser; -use std::path::PathBuf; - -const TEST_PROGRAM_PATH: &str = ""; - -/// A helper struct to test a `SymbolTable`. -pub struct TestSymbolTable { - ast: LeoAst, -} - -impl TestSymbolTable { - /// - /// Returns a Leo syntax tree given a Leo program. - /// - pub fn new(bytes: &[u8]) -> Self { - // Get file string from bytes. - let file_string = String::from_utf8_lossy(bytes); - - // Get test file path. - let file_path = PathBuf::from(TEST_PROGRAM_PATH); - - // Get parser syntax tree - let grammar = Grammar::new(&file_path, &*file_string).unwrap(); - - // Get Leo syntax tree - let ast = LeoAst::new(TEST_PROGRAM_PATH, &grammar); - - Self { ast } - } - - /// - /// Parse the Leo syntax tree into a symbol table. - /// - /// Expect no errors during parsing. - /// - pub fn expect_success(self) { - // Get program. - let program = self.ast.into_repr(); - - // Create empty import parser. - let import_parser = ImportParser::default(); - - // Create empty input. - let input = Input::new(); - - // Create new symbol table. - let _symbol_table = SymbolTable::new(&program, &import_parser, &input).unwrap(); - } - - /// - /// Parse the Leo syntax tree into a symbol table. - /// - /// Expect an error involving entries in the symbol table. - /// - pub fn expect_pass_one_error(self) { - // Get program. - let program = self.ast.into_repr(); - - // Create new symbol table. - let static_check = &mut SymbolTable::default(); - - // Create empty import parser. - let import_parser = ImportParser::default(); - - // Run pass one and expect an error. - let error = static_check.check_names(&program, &import_parser).unwrap_err(); - - match error { - SymbolTableError::Error(_) => {} // Ok - error => panic!("Expected a symbol table error found `{}`", error), - } - } - - /// - /// Parse the Leo syntax tree into a symbol table. - /// - /// Expect an error involving types in the symbol table. - /// - pub fn expect_pass_two_error(self) { - // Get program. - let program = self.ast.into_repr(); - - // Create a new symbol table. - let static_check = &mut SymbolTable::default(); - - // Create empty import parser. - let import_parser = ImportParser::default(); - - // Run the pass one and expect no errors. - static_check.check_names(&program, &import_parser).unwrap(); - - // Run the pass two and expect and error. - let error = static_check.check_types(&program).unwrap_err(); - - match error { - SymbolTableError::TypeError(_) => {} //Ok - error => panic!("Expected a type error found `{}`", error), - } - } -} diff --git a/symbol-table/tests/symbol_table/duplicate_circuit.leo b/symbol-table/tests/symbol_table/duplicate_circuit.leo deleted file mode 100644 index de08c207ad..0000000000 --- a/symbol-table/tests/symbol_table/duplicate_circuit.leo +++ /dev/null @@ -1,10 +0,0 @@ -/// -/// Defines a circuit `Foo {}`. -/// Attempts to define a second circuit `Foo {}`. -/// -/// Expected output: SymbolTableError -/// Message: "Duplicate circuit definition found for `Foo`." -/// - -circuit Foo {} -circuit Foo {} \ No newline at end of file diff --git a/symbol-table/tests/symbol_table/duplicate_function.leo b/symbol-table/tests/symbol_table/duplicate_function.leo deleted file mode 100644 index fffbbeff5a..0000000000 --- a/symbol-table/tests/symbol_table/duplicate_function.leo +++ /dev/null @@ -1,10 +0,0 @@ -/// -/// Defines a function `main() {}`. -/// Attempts to define a second function `main() {}`. -/// -/// Expected output: SymbolTableError -/// Message: "Duplicate function definition found for `main`." -/// - -function main() {} -function main() {} \ No newline at end of file diff --git a/symbol-table/tests/symbol_table/mod.rs b/symbol-table/tests/symbol_table/mod.rs deleted file mode 100644 index 4d40891377..0000000000 --- a/symbol-table/tests/symbol_table/mod.rs +++ /dev/null @@ -1,75 +0,0 @@ -// 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 . - -use crate::TestSymbolTable; - -/// -/// Defines a circuit `Foo {}`. -/// Attempts to define a second circuit `Foo {}`. -/// -/// Expected output: SymbolTableError -/// Message: "Duplicate circuit definition found for `Foo`." -/// -#[test] -fn test_duplicate_circuit() { - let program_bytes = include_bytes!("duplicate_circuit.leo"); - let resolver = TestSymbolTable::new(program_bytes); - - resolver.expect_pass_one_error(); -} - -/// -/// Defines a function `main() {}`. -/// Attempts to define a second function `main() {}`. -/// -/// Expected output: SymbolTableError -/// Message: "Duplicate function definition found for `main`." -/// -#[test] -fn test_duplicate_function() { - let program_bytes = include_bytes!("duplicate_function.leo"); - let resolver = TestSymbolTable::new(program_bytes); - - resolver.expect_pass_one_error(); -} - -/// -/// Defines a function that returns `Self`. -/// -/// Expected output: TypeError -/// Message: "Type `Self` is only available in circuit definitions and circuit functions." -/// -#[test] -fn test_self_not_available() { - let program_bytes = include_bytes!("self_not_available.leo"); - let resolver = TestSymbolTable::new(program_bytes); - - resolver.expect_pass_two_error(); -} - -/// -/// Defines a circuit with variable whose type is `Bar`, an undefined circuit. -/// -/// Expected output: TypeError -/// Message: "Type circuit `Bar` must be defined before it is used in an expression." -/// -#[test] -fn test_undefined_circuit() { - let program_bytes = include_bytes!("undefined_circuit.leo"); - let resolver = TestSymbolTable::new(program_bytes); - - resolver.expect_pass_two_error(); -} diff --git a/symbol-table/tests/symbol_table/self_not_available.leo b/symbol-table/tests/symbol_table/self_not_available.leo deleted file mode 100644 index e34a4c5670..0000000000 --- a/symbol-table/tests/symbol_table/self_not_available.leo +++ /dev/null @@ -1,8 +0,0 @@ -/// -/// Defines a function that returns `Self`. -/// -/// Expected output: TypeError -/// Message: "Type `Self` is only available in circuit definitions and circuit functions." -/// - -function main() -> Self {} \ No newline at end of file diff --git a/symbol-table/tests/symbol_table/undefined_circuit.leo b/symbol-table/tests/symbol_table/undefined_circuit.leo deleted file mode 100644 index 396dcfd177..0000000000 --- a/symbol-table/tests/symbol_table/undefined_circuit.leo +++ /dev/null @@ -1,10 +0,0 @@ -/// -/// Defines a circuit with variable whose type is `Bar`, an undefined circuit. -/// -/// Expected output: TypeError -/// Message: "Type circuit `Bar` must be defined before it is used in an expression." -/// - -circuit Foo { - b: Bar -} \ No newline at end of file