mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-23 18:21:38 +03:00
error and error message for deprecated test syntax, fmt, clean up
This commit is contained in:
parent
87bd041620
commit
29ff3c90b6
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1331,6 +1331,7 @@ dependencies = [
|
||||
"pest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -47,6 +47,9 @@ version = "1.0"
|
||||
[dependencies.serde_json]
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.thiserror]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3"
|
||||
|
||||
|
@ -36,7 +36,6 @@ pub fn load_annotation(
|
||||
match ast_definition {
|
||||
Definition::Import(_) => unimplemented!("annotated imports are not supported yet"),
|
||||
Definition::Circuit(_) => unimplemented!("annotated circuits are not supported yet"),
|
||||
// TODO need someone to take functions annotated with @test to be moved from function to tests.
|
||||
Definition::Function(function) => match ast_annotation.name {
|
||||
AnnotationName::Test(_) => {
|
||||
let ident = Identifier::from(function.identifier.clone());
|
||||
@ -49,6 +48,7 @@ pub fn load_annotation(
|
||||
load_annotated_test(test, ast_annotation, tests);
|
||||
}
|
||||
},
|
||||
Definition::Deprecated(_) => {}
|
||||
Definition::Annotated(_) => unimplemented!("nested annotations are not supported yet"),
|
||||
}
|
||||
}
|
||||
|
50
ast/src/errors/deprecated.rs
Normal file
50
ast/src/errors/deprecated.rs
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_grammar::definitions::Deprecated;
|
||||
|
||||
use crate::{Error as FormattedError, Span};
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DeprecatedError {
|
||||
#[error("{}", _0)]
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl DeprecatedError {
|
||||
pub fn set_path(&mut self, path: &Path) {
|
||||
match self {
|
||||
DeprecatedError::Error(error) => error.set_path(path),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_from_span(message: String, span: Span) -> Self {
|
||||
DeprecatedError::Error(FormattedError::new_from_span(message, span))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<Deprecated<'ast>> for DeprecatedError {
|
||||
fn from(deprecated: Deprecated<'ast>) -> Self {
|
||||
match deprecated {
|
||||
Deprecated::TestFunction(test_function) => DeprecatedError::new_from_span(
|
||||
"\"test function...\" is deprecated. Did you mean @test decorator?".to_string(),
|
||||
Span::from(test_function.span.clone()),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
@ -14,5 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
pub mod deprecated;
|
||||
pub use deprecated::*;
|
||||
|
||||
pub mod error;
|
||||
pub use error::*;
|
||||
|
@ -19,6 +19,8 @@
|
||||
//! This module contains the [`Ast`] type, a wrapper around the [`Program`] type.
|
||||
//! The [`Ast`] 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 [`Ast`].
|
||||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
|
||||
pub mod annotation;
|
||||
pub use self::annotation::*;
|
||||
@ -74,10 +76,10 @@ pub struct Ast {
|
||||
|
||||
impl Ast {
|
||||
/// Creates a new ast from a given program name and grammar tree.
|
||||
pub fn new<'ast>(program_name: &str, ast: &Grammar<'ast>) -> Self {
|
||||
Self {
|
||||
ast: Program::from(program_name, ast.as_repr()),
|
||||
}
|
||||
pub fn new<'ast>(program_name: &str, ast: &Grammar<'ast>) -> Result<Self, DeprecatedError> {
|
||||
Ok(Self {
|
||||
ast: Program::from(program_name, ast.as_repr())?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a reference to the inner program ast representation.
|
||||
|
@ -17,7 +17,16 @@
|
||||
//! A Leo program consists of import, circuit, and function definitions.
|
||||
//! Each defined type consists of ast statements and expressions.
|
||||
|
||||
use crate::{load_annotation, Circuit, Function, FunctionInput, Identifier, ImportStatement, TestFunction};
|
||||
use crate::{
|
||||
load_annotation,
|
||||
Circuit,
|
||||
DeprecatedError,
|
||||
Function,
|
||||
FunctionInput,
|
||||
Identifier,
|
||||
ImportStatement,
|
||||
TestFunction,
|
||||
};
|
||||
use leo_grammar::{definitions::Definition, files::File};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
@ -37,7 +46,7 @@ const MAIN_FUNCTION_NAME: &str = "main";
|
||||
|
||||
impl<'ast> Program {
|
||||
//! Logic to convert from an abstract syntax tree (ast) representation to a Leo program.
|
||||
pub fn from(program_name: &str, program_ast: &File<'ast>) -> Self {
|
||||
pub fn from(program_name: &str, program_ast: &File<'ast>) -> Result<Self, DeprecatedError> {
|
||||
let mut imports = vec![];
|
||||
let mut circuits = IndexMap::new();
|
||||
let mut functions = IndexMap::new();
|
||||
@ -48,10 +57,14 @@ impl<'ast> Program {
|
||||
.definitions
|
||||
.to_owned()
|
||||
.into_iter()
|
||||
.for_each(|definition| match definition {
|
||||
Definition::Import(import) => imports.push(ImportStatement::from(import)),
|
||||
.find_map::<Result<(), _>, _>(|definition| match definition {
|
||||
Definition::Import(import) => {
|
||||
imports.push(ImportStatement::from(import));
|
||||
None
|
||||
}
|
||||
Definition::Circuit(circuit) => {
|
||||
circuits.insert(Identifier::from(circuit.identifier.clone()), Circuit::from(circuit));
|
||||
None
|
||||
}
|
||||
Definition::Function(function_def) => {
|
||||
let function = Function::from(function_def);
|
||||
@ -59,6 +72,16 @@ impl<'ast> Program {
|
||||
expected_input = function.input.clone();
|
||||
}
|
||||
functions.insert(function.identifier.clone(), function);
|
||||
None
|
||||
}
|
||||
Definition::Deprecated(deprecated) => {
|
||||
// 1. convert pest span to ast span.
|
||||
// ast source common span
|
||||
// new from span -> don't call direcrtly
|
||||
|
||||
// create separate file for error warnings
|
||||
// "\"test function\" is deprecated. Did you mean @test?"
|
||||
Some(Err(DeprecatedError::from(deprecated)))
|
||||
}
|
||||
Definition::Annotated(annotated_definition) => {
|
||||
load_annotation(
|
||||
@ -69,17 +92,20 @@ impl<'ast> Program {
|
||||
&mut tests,
|
||||
&mut expected_input,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Self {
|
||||
None
|
||||
}
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
Ok(Self {
|
||||
name: program_name.to_string(),
|
||||
expected_input,
|
||||
imports,
|
||||
circuits,
|
||||
functions,
|
||||
tests,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ fn to_ast(program_filepath: &Path) -> Ast {
|
||||
let ast = Grammar::new(&program_filepath, &program_string).unwrap();
|
||||
|
||||
// Parses the pest ast and constructs a Leo ast.
|
||||
Ast::new("leo_tree", &ast)
|
||||
Ast::new("leo_tree", &ast).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -184,7 +184,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
})?;
|
||||
|
||||
// Construct the core ast from the pest ast.
|
||||
let core_ast = Ast::new(&self.package_name, &pest_ast);
|
||||
let core_ast = Ast::new(&self.package_name, &pest_ast)?;
|
||||
|
||||
// Store the main program file.
|
||||
self.program = core_ast.into_repr();
|
||||
@ -241,7 +241,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
let package_name = &self.package_name;
|
||||
|
||||
// Construct the core ast from the pest ast.
|
||||
let core_ast = Ast::new(package_name, &ast);
|
||||
let core_ast = Ast::new(package_name, &ast)?;
|
||||
|
||||
// Store the main program file.
|
||||
self.program = core_ast.into_repr();
|
||||
|
@ -15,6 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError};
|
||||
use leo_ast::DeprecatedError;
|
||||
use leo_grammar::ParserError;
|
||||
use leo_imports::ImportParserError;
|
||||
use leo_input::InputParserError;
|
||||
@ -27,6 +28,9 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CompilerError {
|
||||
#[error("{}", _0)]
|
||||
DeprecatedError(#[from] DeprecatedError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ImportError(#[from] ImportError),
|
||||
|
||||
|
@ -14,7 +14,13 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ast::Rule, circuits::Circuit, definitions::AnnotatedDefinition, functions::Function, imports::Import};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
circuits::Circuit,
|
||||
definitions::{AnnotatedDefinition, Deprecated},
|
||||
functions::Function,
|
||||
imports::Import,
|
||||
};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use serde::Serialize;
|
||||
@ -26,4 +32,5 @@ pub enum Definition<'ast> {
|
||||
Import(Import<'ast>),
|
||||
Circuit(Circuit<'ast>),
|
||||
Function(Function<'ast>),
|
||||
Deprecated(Deprecated<'ast>),
|
||||
}
|
||||
|
26
grammar/src/definitions/deprecated.rs
Normal file
26
grammar/src/definitions/deprecated.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ast::Rule, functions::TestFunction};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||
#[pest_ast(rule(Rule::deprecated))]
|
||||
pub enum Deprecated<'ast> {
|
||||
TestFunction(TestFunction<'ast>),
|
||||
}
|
@ -19,3 +19,6 @@ pub use annotated_definition::*;
|
||||
|
||||
pub mod definition;
|
||||
pub use definition::*;
|
||||
|
||||
pub mod deprecated;
|
||||
pub use deprecated::*;
|
||||
|
@ -14,14 +14,17 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{functions::Function, SpanDef};
|
||||
use crate::{ast::Rule, functions::Function, SpanDef};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||
#[pest_ast(rule(Rule::test_function))]
|
||||
pub struct TestFunction<'ast> {
|
||||
pub function: Function<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
#[serde(with = "SpanDef")]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
@ -12,6 +12,12 @@ definition = {
|
||||
| import
|
||||
| circuit
|
||||
| function
|
||||
| deprecated
|
||||
}
|
||||
|
||||
// but then in the struct ffor this... I need to explicitly put all the types there.
|
||||
deprecated = {
|
||||
test_function
|
||||
}
|
||||
|
||||
// Declared in definitions/annotated_definition.rs
|
||||
@ -409,6 +415,9 @@ statement_definition = { declare ~ variables ~ "=" ~ expression ~ LINE_END}
|
||||
// Declared in statements/expression_statement.rs
|
||||
statement_expression = { expression ~ LINE_END }
|
||||
|
||||
// Decalred in functions/test_function.rs
|
||||
test_function = { "test" ~ function }
|
||||
|
||||
// Declared in statements/for_statement.rs
|
||||
statement_for = { "for " ~ identifier ~ "in " ~ expression ~ ".." ~ expression ~ block }
|
||||
|
||||
|
@ -13,13 +13,16 @@
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
use leo_ast::{Error as FormattedError, Identifier, Span};
|
||||
use leo_ast::{DeprecatedError, Error as FormattedError, Identifier, Span};
|
||||
use leo_grammar::ParserError;
|
||||
|
||||
use std::{io, path::Path};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ImportParserError {
|
||||
#[error("{}", _0)]
|
||||
DeprecatedError(#[from] DeprecatedError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
Error(#[from] FormattedError),
|
||||
|
||||
|
@ -55,7 +55,7 @@ fn parse_import_file(package: &DirEntry, span: &Span) -> Result<Program, ImportP
|
||||
let ast = &Grammar::new(&file_path, &program_string)?;
|
||||
|
||||
// Build the package Leo syntax tree from the package abstract syntax tree.
|
||||
Ok(Program::from(&file_name, ast.as_repr()))
|
||||
Ok(Program::from(&file_name, ast.as_repr())?)
|
||||
}
|
||||
|
||||
impl ImportParser {
|
||||
|
Loading…
Reference in New Issue
Block a user