diff --git a/Cargo.lock b/Cargo.lock index 881ab30a24..ffcc86a70f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1196,7 +1196,7 @@ dependencies = [ "criterion", "indexmap", "leo-ast", - "leo-grammar", + "leo-parser", "num-bigint", "serde", "serde_json", @@ -1210,7 +1210,6 @@ version = "1.2.3" dependencies = [ "criterion", "indexmap", - "leo-grammar", "leo-input", "pest", "serde", @@ -1228,10 +1227,10 @@ dependencies = [ "leo-asg", "leo-ast", "leo-gadgets", - "leo-grammar", "leo-imports", "leo-input", "leo-package", + "leo-parser", "leo-state", "num-bigint", "pest", @@ -1266,22 +1265,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "leo-grammar" -version = "1.2.3" -dependencies = [ - "criterion", - "from-pest", - "lazy_static", - "pest", - "pest-ast", - "pest_derive", - "serde", - "serde_json", - "thiserror", - "tracing", -] - [[package]] name = "leo-imports" version = "1.2.3" @@ -1289,7 +1272,7 @@ dependencies = [ "indexmap", "leo-asg", "leo-ast", - "leo-grammar", + "leo-parser", "thiserror", "tracing", ] @@ -1363,6 +1346,20 @@ dependencies = [ "zip", ] +[[package]] +name = "leo-parser" +version = "1.2.3" +dependencies = [ + "criterion", + "indexmap", + "lazy_static", + "leo-ast", + "serde", + "serde_json", + "thiserror", + "tracing", +] + [[package]] name = "leo-state" version = "1.2.3" diff --git a/Cargo.toml b/Cargo.toml index 6628e10f2f..4436163eab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,11 +30,11 @@ members = [ "ast", "compiler", "gadgets", - "grammar", "imports", "input", "linter", "package", + "parser", "state", "synthesizer", ] diff --git a/asg/Cargo.toml b/asg/Cargo.toml index 2bd668b36b..770c031200 100644 --- a/asg/Cargo.toml +++ b/asg/Cargo.toml @@ -33,9 +33,9 @@ version = "1.0" version = "1.2.3" path = "../ast" -[dependencies.leo-grammar] +[dependencies.leo-parser] version = "1.2.3" -path = "../grammar" +path = "../parser" [dependencies.num-bigint] version = "0.3" diff --git a/asg/src/const_value.rs b/asg/src/const_value.rs index bab4aa5b3b..f093a65559 100644 --- a/asg/src/const_value.rs +++ b/asg/src/const_value.rs @@ -188,8 +188,30 @@ impl ConstInt { const_int_map!(value_negate, x, x.checked_neg()?); + const_int_map!(value_bit_negate, x, !x); + const_int_op!(to_usize, Option, x, (*x).try_into().ok()); + const_int_op!(to_u128, u128, x, *x as u128); + + const_int_op!(to_u64, u64, x, *x as u64); + + const_int_op!(to_u32, u32, x, *x as u32); + + const_int_op!(to_u16, u16, x, *x as u16); + + const_int_op!(to_u8, u8, x, *x as u8); + + const_int_op!(to_i128, i128, x, *x as i128); + + const_int_op!(to_i64, i64, x, *x as i64); + + const_int_op!(to_i32, i32, x, *x as i32); + + const_int_op!(to_i16, i16, x, *x as i16); + + const_int_op!(to_i8, i8, x, *x as i8); + const_int_op!(to_string, String, x, (*x).to_string()); const_int_bimap!(value_add, x, y, x.checked_add(*y)?); @@ -226,6 +248,21 @@ impl ConstInt { } } + pub fn cast_to(&self, target: &IntegerType) -> ConstInt { + match target { + IntegerType::I8 => ConstInt::I8(self.to_i8()), + IntegerType::I16 => ConstInt::I16(self.to_i16()), + IntegerType::I32 => ConstInt::I32(self.to_i32()), + IntegerType::I64 => ConstInt::I64(self.to_i64()), + IntegerType::I128 => ConstInt::I128(self.to_i128()), + IntegerType::U8 => ConstInt::U8(self.to_u8()), + IntegerType::U16 => ConstInt::U16(self.to_u16()), + IntegerType::U32 => ConstInt::U32(self.to_u32()), + IntegerType::U64 => ConstInt::U64(self.to_u64()), + IntegerType::U128 => ConstInt::U128(self.to_u128()), + } + } + pub fn get_type<'a>(&self) -> Type<'a> { Type::Integer(self.get_int_type()) } diff --git a/asg/src/error/mod.rs b/asg/src/error/mod.rs index 39e60735dc..87040a58fa 100644 --- a/asg/src/error/mod.rs +++ b/asg/src/error/mod.rs @@ -17,14 +17,11 @@ //! Errors encountered when attempting to convert to an asg from an ast. use crate::Span; -use leo_ast::{AstError, Error as FormattedError}; -use leo_grammar::ParserError; +use leo_ast::{FormattedError, LeoError}; +use leo_parser::SyntaxError; #[derive(Debug, Error)] pub enum AsgConvertError { - #[error("{}", _0)] - AstError(#[from] AstError), - #[error("{}", _0)] Error(#[from] FormattedError), @@ -35,12 +32,32 @@ pub enum AsgConvertError { InternalError(String), #[error("{}", _0)] - ParserError(#[from] ParserError), + SyntaxError(#[from] SyntaxError), +} + +impl LeoError for AsgConvertError { + fn get_path(&self) -> Option<&str> { + match self { + AsgConvertError::Error(error) => error.get_path(), + AsgConvertError::SyntaxError(error) => error.get_path(), + AsgConvertError::ImportError(error) => error.get_path(), + AsgConvertError::InternalError(_) => None, + } + } + + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + AsgConvertError::Error(error) => error.set_path(path, contents), + AsgConvertError::SyntaxError(error) => error.set_path(path, contents), + AsgConvertError::ImportError(error) => error.set_path(path, contents), + AsgConvertError::InternalError(_) => {} + } + } } impl AsgConvertError { fn new_from_span(message: String, span: &Span) -> Self { - AsgConvertError::Error(FormattedError::new_from_span(message, span.clone())) + AsgConvertError::Error(FormattedError::new_from_span(message, span)) } pub fn unresolved_circuit(name: &str, span: &Span) -> Self { @@ -227,6 +244,10 @@ impl AsgConvertError { Self::new_from_span(format!("failed to parse int value '{}'", value), span) } + pub fn unsigned_negation(span: &Span) -> Self { + Self::new_from_span("cannot negate unsigned integer".to_string(), span) + } + pub fn immutable_assignment(name: &str, span: &Span) -> Self { Self::new_from_span(format!("illegal assignment to immutable variable '{}'", name), span) } @@ -256,6 +277,14 @@ impl AsgConvertError { ) } + pub fn call_test_function(span: &Span) -> Self { + Self::new_from_span("cannot call test function".to_string(), span) + } + + pub fn circuit_test_function(span: &Span) -> Self { + Self::new_from_span("cannot have test function as member of circuit".to_string(), span) + } + pub fn parse_index_error() -> Self { AsgConvertError::InternalError("failed to parse index".to_string()) } diff --git a/asg/src/expression/call.rs b/asg/src/expression/call.rs index 52572a4907..8c91f86da5 100644 --- a/asg/src/expression/call.rs +++ b/asg/src/expression/call.rs @@ -109,7 +109,7 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> { return Err(AsgConvertError::unexpected_type( "circuit", type_.map(|x| x.to_string()).as_deref(), - &span, + span, )); } }; @@ -117,26 +117,26 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> { let member = circuit.members.borrow(); let member = member .get(&name.name) - .ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, &span))?; + .ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, span))?; match member { CircuitMember::Function(body) => { if body.qualifier == FunctionQualifier::Static { return Err(AsgConvertError::circuit_static_call_invalid( &circuit_name, &name.name, - &span, + span, )); } else if body.qualifier == FunctionQualifier::MutSelfRef && !target.is_mut_ref() { return Err(AsgConvertError::circuit_member_mut_call_invalid( &circuit_name, &name.name, - &span, + span, )); } (Some(target), *body) } CircuitMember::Variable(_) => { - return Err(AsgConvertError::circuit_variable_call(&circuit_name, &name.name, &span)); + return Err(AsgConvertError::circuit_variable_call(&circuit_name, &name.name, span)); } } } @@ -150,27 +150,27 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> { .resolve_circuit(&circuit_name.name) .ok_or_else(|| AsgConvertError::unresolved_circuit(&circuit_name.name, &circuit_name.span))? } else { - return Err(AsgConvertError::unexpected_type("circuit", None, &span)); + return Err(AsgConvertError::unexpected_type("circuit", None, span)); }; let circuit_name = circuit.name.borrow().name.clone(); let member = circuit.members.borrow(); let member = member .get(&name.name) - .ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, &span))?; + .ok_or_else(|| AsgConvertError::unresolved_circuit_member(&circuit_name, &name.name, span))?; match member { CircuitMember::Function(body) => { if body.qualifier != FunctionQualifier::Static { return Err(AsgConvertError::circuit_member_call_invalid( &circuit_name, &name.name, - &span, + span, )); } (None, *body) } CircuitMember::Variable(_) => { - return Err(AsgConvertError::circuit_variable_call(&circuit_name, &name.name, &span)); + return Err(AsgConvertError::circuit_variable_call(&circuit_name, &name.name, span)); } } } @@ -206,12 +206,15 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> { let argument = argument.get().borrow(); let converted = <&Expression<'a>>::from_ast(scope, expr, Some(argument.type_.clone().partial()))?; if argument.const_ && !converted.is_consty() { - return Err(AsgConvertError::unexpected_nonconst(&expr.span())); + return Err(AsgConvertError::unexpected_nonconst(expr.span())); } Ok(Cell::new(converted)) }) .collect::, AsgConvertError>>()?; + if function.is_test() { + return Err(AsgConvertError::call_test_function(&value.span)); + } Ok(CallExpression { parent: Cell::new(None), span: Some(value.span.clone()), diff --git a/asg/src/expression/cast.rs b/asg/src/expression/cast.rs new file mode 100644 index 0000000000..e7060492d4 --- /dev/null +++ b/asg/src/expression/cast.rs @@ -0,0 +1,109 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{AsgConvertError, ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Span, Type}; +pub use leo_ast::UnaryOperation; + +use std::cell::Cell; + +#[derive(Clone)] +pub struct CastExpression<'a> { + pub parent: Cell>>, + pub span: Option, + pub inner: Cell<&'a Expression<'a>>, + pub target_type: Type<'a>, +} + +impl<'a> Node for CastExpression<'a> { + fn span(&self) -> Option<&Span> { + self.span.as_ref() + } +} + +impl<'a> ExpressionNode<'a> for CastExpression<'a> { + fn set_parent(&self, parent: &'a Expression<'a>) { + self.parent.replace(Some(parent)); + } + + fn get_parent(&self) -> Option<&'a Expression<'a>> { + self.parent.get() + } + + fn enforce_parents(&self, expr: &'a Expression<'a>) { + self.inner.get().set_parent(expr); + } + + fn get_type(&self) -> Option> { + Some(self.target_type.clone()) + } + + fn is_mut_ref(&self) -> bool { + false + } + + fn const_value(&self) -> Option { + let value = self.inner.get().const_value()?; + match value { + ConstValue::Int(int) => match &self.target_type { + Type::Integer(target) => Some(ConstValue::Int(int.cast_to(target))), + _ => None, + }, + _ => None, + } + } + + fn is_consty(&self) -> bool { + self.inner.get().is_consty() + } +} + +impl<'a> FromAst<'a, leo_ast::CastExpression> for CastExpression<'a> { + fn from_ast( + scope: &'a Scope<'a>, + value: &leo_ast::CastExpression, + expected_type: Option>, + ) -> Result, AsgConvertError> { + let target_type = scope.resolve_ast_type(&value.target_type)?; + if let Some(expected_type) = &expected_type { + if !expected_type.matches(&target_type) { + return Err(AsgConvertError::unexpected_type( + &expected_type.to_string(), + Some(&target_type.to_string()), + &value.span, + )); + } + } + + let inner = <&Expression<'a>>::from_ast(scope, &*value.inner, None)?; + + Ok(CastExpression { + parent: Cell::new(None), + span: Some(value.span.clone()), + inner: Cell::new(inner), + target_type, + }) + } +} + +impl<'a> Into for &CastExpression<'a> { + fn into(self) -> leo_ast::CastExpression { + leo_ast::CastExpression { + target_type: (&self.target_type).into(), + inner: Box::new(self.inner.get().into()), + span: self.span.clone().unwrap_or_default(), + } + } +} diff --git a/asg/src/expression/circuit_init.rs b/asg/src/expression/circuit_init.rs index b7ec7a764b..8c26379072 100644 --- a/asg/src/expression/circuit_init.rs +++ b/asg/src/expression/circuit_init.rs @@ -99,10 +99,10 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<' )); } } - let members: IndexMap<&String, (&Identifier, &leo_ast::Expression)> = value + let members: IndexMap<&String, (&Identifier, Option<&leo_ast::Expression>)> = value .members .iter() - .map(|x| (&x.identifier.name, (&x.identifier, &x.expression))) + .map(|x| (&x.identifier.name, (&x.identifier, x.expression.as_ref()))) .collect(); let mut values: Vec<(Identifier, Cell<&'a Expression<'a>>)> = vec![]; @@ -125,7 +125,15 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<' continue; }; if let Some((identifier, receiver)) = members.get(&name) { - let received = <&Expression<'a>>::from_ast(scope, *receiver, Some(type_.partial()))?; + let received = if let Some(receiver) = *receiver { + <&Expression<'a>>::from_ast(scope, receiver, Some(type_.partial()))? + } else { + <&Expression<'a>>::from_ast( + scope, + &leo_ast::Expression::Identifier((*identifier).clone()), + Some(type_.partial()), + )? + }; values.push(((*identifier).clone(), Cell::new(received))); } else { return Err(AsgConvertError::missing_circuit_member( @@ -165,7 +173,7 @@ impl<'a> Into for &CircuitInitExpression<'a> { .iter() .map(|(name, value)| leo_ast::CircuitImpliedVariableDefinition { identifier: name.clone(), - expression: value.get().into(), + expression: Some(value.get().into()), }) .collect(), span: self.span.clone().unwrap_or_default(), diff --git a/asg/src/expression/mod.rs b/asg/src/expression/mod.rs index 720bac0781..781f30f497 100644 --- a/asg/src/expression/mod.rs +++ b/asg/src/expression/mod.rs @@ -62,6 +62,9 @@ pub use unary::*; mod variable_ref; pub use variable_ref::*; +mod cast; +pub use cast::*; + use crate::{AsgConvertError, ConstValue, FromAst, Node, PartialType, Scope, Span, Type}; #[derive(Clone)] @@ -71,6 +74,7 @@ pub enum Expression<'a> { Binary(BinaryExpression<'a>), Unary(UnaryExpression<'a>), Ternary(TernaryExpression<'a>), + Cast(CastExpression<'a>), ArrayInline(ArrayInlineExpression<'a>), ArrayInit(ArrayInitExpression<'a>), @@ -95,6 +99,7 @@ impl<'a> Node for Expression<'a> { Binary(x) => x.span(), Unary(x) => x.span(), Ternary(x) => x.span(), + Cast(x) => x.span(), ArrayInline(x) => x.span(), ArrayInit(x) => x.span(), ArrayAccess(x) => x.span(), @@ -128,6 +133,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> { Binary(x) => x.set_parent(parent), Unary(x) => x.set_parent(parent), Ternary(x) => x.set_parent(parent), + Cast(x) => x.set_parent(parent), ArrayInline(x) => x.set_parent(parent), ArrayInit(x) => x.set_parent(parent), ArrayAccess(x) => x.set_parent(parent), @@ -148,6 +154,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> { Binary(x) => x.get_parent(), Unary(x) => x.get_parent(), Ternary(x) => x.get_parent(), + Cast(x) => x.get_parent(), ArrayInline(x) => x.get_parent(), ArrayInit(x) => x.get_parent(), ArrayAccess(x) => x.get_parent(), @@ -168,6 +175,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> { Binary(x) => x.enforce_parents(expr), Unary(x) => x.enforce_parents(expr), Ternary(x) => x.enforce_parents(expr), + Cast(x) => x.enforce_parents(expr), ArrayInline(x) => x.enforce_parents(expr), ArrayInit(x) => x.enforce_parents(expr), ArrayAccess(x) => x.enforce_parents(expr), @@ -188,6 +196,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> { Binary(x) => x.get_type(), Unary(x) => x.get_type(), Ternary(x) => x.get_type(), + Cast(x) => x.get_type(), ArrayInline(x) => x.get_type(), ArrayInit(x) => x.get_type(), ArrayAccess(x) => x.get_type(), @@ -208,6 +217,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> { Binary(x) => x.is_mut_ref(), Unary(x) => x.is_mut_ref(), Ternary(x) => x.is_mut_ref(), + Cast(x) => x.is_mut_ref(), ArrayInline(x) => x.is_mut_ref(), ArrayInit(x) => x.is_mut_ref(), ArrayAccess(x) => x.is_mut_ref(), @@ -228,6 +238,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> { Binary(x) => x.const_value(), Unary(x) => x.const_value(), Ternary(x) => x.const_value(), + Cast(x) => x.const_value(), ArrayInline(x) => x.const_value(), ArrayInit(x) => x.const_value(), ArrayAccess(x) => x.const_value(), @@ -248,6 +259,7 @@ impl<'a> ExpressionNode<'a> for Expression<'a> { Binary(x) => x.is_consty(), Unary(x) => x.is_consty(), Ternary(x) => x.is_consty(), + Cast(x) => x.is_consty(), ArrayInline(x) => x.is_consty(), ArrayInit(x) => x.is_consty(), ArrayAccess(x) => x.is_consty(), @@ -281,6 +293,9 @@ impl<'a> FromAst<'a, leo_ast::Expression> for &'a Expression<'a> { Ternary(conditional) => scope.alloc_expression( TernaryExpression::from_ast(scope, conditional, expected_type).map(Expression::Ternary)?, ), + Cast(cast) => { + scope.alloc_expression(CastExpression::from_ast(scope, cast, expected_type).map(Expression::Cast)?) + } ArrayInline(array_inline) => scope.alloc_expression( ArrayInlineExpression::from_ast(scope, array_inline, expected_type).map(Expression::ArrayInline)?, @@ -333,6 +348,7 @@ impl<'a> Into for &Expression<'a> { Binary(x) => leo_ast::Expression::Binary(x.into()), Unary(x) => leo_ast::Expression::Unary(x.into()), Ternary(x) => leo_ast::Expression::Ternary(x.into()), + Cast(x) => leo_ast::Expression::Cast(x.into()), ArrayInline(x) => leo_ast::Expression::ArrayInline(x.into()), ArrayInit(x) => leo_ast::Expression::ArrayInit(x.into()), ArrayAccess(x) => leo_ast::Expression::ArrayAccess(x.into()), diff --git a/asg/src/expression/unary.rs b/asg/src/expression/unary.rs index 0e5078e71c..4ccc7662a6 100644 --- a/asg/src/expression/unary.rs +++ b/asg/src/expression/unary.rs @@ -69,6 +69,10 @@ impl<'a> ExpressionNode<'a> for UnaryExpression<'a> { _ => None, } } + UnaryOperation::BitNot => match inner { + ConstValue::Int(value) => Some(ConstValue::Int(value.value_bit_negate()?)), + _ => None, + }, } } else { None @@ -110,16 +114,37 @@ impl<'a> FromAst<'a, leo_ast::UnaryExpression> for UnaryExpression<'a> { )); } }, + UnaryOperation::BitNot => match expected_type.map(|x| x.full()).flatten() { + Some(type_ @ Type::Integer(_)) => Some(type_), + None => None, + Some(type_) => { + return Err(AsgConvertError::unexpected_type( + &type_.to_string(), + Some("integer"), + &value.span, + )); + } + }, }; + let expr = <&Expression<'a>>::from_ast(scope, &*value.inner, expected_type.map(Into::into))?; + + if matches!(value.op, UnaryOperation::Negate) { + let is_expr_unsigned = expr + .get_type() + .map(|x| match x { + Type::Integer(x) => !x.is_signed(), + _ => false, + }) + .unwrap_or(false); + if is_expr_unsigned { + return Err(AsgConvertError::unsigned_negation(&value.span)); + } + } Ok(UnaryExpression { parent: Cell::new(None), span: Some(value.span.clone()), operation: value.op.clone(), - inner: Cell::new(<&Expression<'a>>::from_ast( - scope, - &*value.inner, - expected_type.map(Into::into), - )?), + inner: Cell::new(expr), }) } } diff --git a/asg/src/lib.rs b/asg/src/lib.rs index ada569edeb..098abf569a 100644 --- a/asg/src/lib.rs +++ b/asg/src/lib.rs @@ -76,8 +76,6 @@ pub use context::*; pub use leo_ast::{Ast, Identifier, Span}; -use std::path::Path; - /// The abstract semantic graph (ASG) for a Leo program. /// /// The [`Asg`] type represents a Leo program as a series of recursive data types. @@ -92,14 +90,14 @@ pub struct Asg<'a> { impl<'a> Asg<'a> { /// Creates a new ASG from a given AST and import resolver. - pub fn new>( + pub fn new, Y: AsRef>( context: AsgContext<'a>, - ast: &Ast, + ast: Y, resolver: &mut T, ) -> Result { Ok(Self { context, - asg: InternalProgram::new(context, &ast.as_repr(), resolver)?, + asg: InternalProgram::new(context, ast.as_ref(), resolver)?, }) } @@ -127,10 +125,9 @@ pub fn load_asg<'a, T: ImportResolver<'a>>( resolver: &mut T, ) -> Result, AsgConvertError> { // Parses the Leo file and constructs a grammar ast. - let ast = leo_grammar::Grammar::new(&Path::new("input.leo"), content) - .map_err(|e| AsgConvertError::InternalError(format!("ast: {:?}", e)))?; + let ast = leo_parser::parse_ast("input.leo", content)?; - InternalProgram::new(context, leo_ast::Ast::new("load_ast", &ast)?.as_repr(), resolver) + InternalProgram::new(context, ast.as_repr(), resolver) } pub fn new_alloc_context<'a>() -> Arena> { diff --git a/asg/src/pass.rs b/asg/src/pass.rs index facdf10e5f..9baa4f2a5a 100644 --- a/asg/src/pass.rs +++ b/asg/src/pass.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::Program; -pub use leo_ast::Error as FormattedError; +pub use leo_ast::FormattedError; pub trait AsgPass { fn do_pass(asg: &Program) -> Result<(), FormattedError>; diff --git a/asg/src/program/circuit.rs b/asg/src/program/circuit.rs index e44c8b8277..c2efd4f86b 100644 --- a/asg/src/program/circuit.rs +++ b/asg/src/program/circuit.rs @@ -92,6 +92,9 @@ impl<'a> Circuit<'a> { } let asg_function = Function::init(new_scope, function)?; asg_function.circuit.replace(Some(circuit)); + if asg_function.is_test() { + return Err(AsgConvertError::circuit_test_function(&function.identifier.span)); + } members.insert(function.identifier.name.clone(), CircuitMember::Function(asg_function)); } } diff --git a/asg/src/program/function.rs b/asg/src/program/function.rs index 159d3ead3b..c74e15f850 100644 --- a/asg/src/program/function.rs +++ b/asg/src/program/function.rs @@ -29,6 +29,7 @@ use crate::{ Variable, }; use indexmap::IndexMap; +pub use leo_ast::Annotation; use leo_ast::FunctionInput; use std::cell::{Cell, RefCell}; @@ -52,6 +53,7 @@ pub struct Function<'a> { pub body: Cell>>, pub scope: &'a Scope<'a>, pub qualifier: FunctionQualifier, + pub annotations: Vec, } impl<'a> PartialEq for Function<'a> { @@ -126,6 +128,7 @@ impl<'a> Function<'a> { qualifier, scope: new_scope, span: Some(value.span.clone()), + annotations: value.annotations.clone(), }); function.scope.function.replace(Some(function)); @@ -177,6 +180,10 @@ impl<'a> Function<'a> { Ok(()) } + + pub fn is_test(&self) -> bool { + self.annotations.iter().any(|x| x.name.name == "test") + } } impl<'a> Into for &Function<'a> { @@ -213,6 +220,7 @@ impl<'a> Into for &Function<'a> { block: body, output: Some((&output).into()), span, + annotations: self.annotations.clone(), } } } diff --git a/asg/src/program/mod.rs b/asg/src/program/mod.rs index cccadd08d3..3ada521eb2 100644 --- a/asg/src/program/mod.rs +++ b/asg/src/program/mod.rs @@ -45,9 +45,6 @@ pub struct InternalProgram<'a> { /// these should generally not be accessed directly, but through scoped imports pub imported_modules: IndexMap>, - /// Maps test name => test code block. - pub test_functions: IndexMap, Option)>, // identifier = test input file - /// Maps function name => function code block. pub functions: IndexMap>, @@ -248,14 +245,6 @@ impl<'a> InternalProgram<'a> { scope.circuits.borrow_mut().insert(name.name.clone(), asg_circuit); } - let mut proto_test_functions = IndexMap::new(); - for (name, test_function) in program.tests.iter() { - assert_eq!(name.name, test_function.function.identifier.name); - let function = Function::init(scope, &test_function.function)?; - - proto_test_functions.insert(name.name.clone(), function); - } - for (name, function) in program.functions.iter() { assert_eq!(name.name, function.identifier.name); let function = Function::init(scope, function)?; @@ -264,16 +253,6 @@ impl<'a> InternalProgram<'a> { } // Load concrete definitions. - let mut test_functions = IndexMap::new(); - for (name, test_function) in program.tests.iter() { - assert_eq!(name.name, test_function.function.identifier.name); - let function = proto_test_functions.get(&name.name).unwrap(); - - function.fill_from_ast(&test_function.function)?; - - test_functions.insert(name.name.clone(), (*function, test_function.input_file.clone())); - } - let mut functions = IndexMap::new(); for (name, function) in program.functions.iter() { assert_eq!(name.name, function.identifier.name); @@ -298,7 +277,6 @@ impl<'a> InternalProgram<'a> { context, id: context.get_id(), name: program.name.clone(), - test_functions, functions, circuits, imported_modules: resolved_packages @@ -350,7 +328,6 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program { let mut all_circuits: IndexMap> = IndexMap::new(); let mut all_functions: IndexMap> = IndexMap::new(); - let mut all_test_functions: IndexMap, Option)> = IndexMap::new(); let mut identifiers = InternalIdentifierGenerator { next: 0 }; for (_, program) in all_programs.into_iter() { for (name, circuit) in program.circuits.iter() { @@ -367,11 +344,6 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program { function.name.borrow_mut().name = identifier.clone(); all_functions.insert(identifier, *function); } - for (name, function) in program.test_functions.iter() { - let identifier = format!("{}{}", identifiers.next().unwrap(), name); - function.0.name.borrow_mut().name = identifier.clone(); - all_test_functions.insert(identifier, function.clone()); - } } leo_ast::Program { @@ -388,15 +360,6 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program { }) .collect(), expected_input: vec![], - tests: all_test_functions - .into_iter() - .map(|(_, (function, ident))| { - (function.name.borrow().clone(), leo_ast::TestFunction { - function: function.into(), - input_file: ident, - }) - }) - .collect(), functions: all_functions .into_iter() .map(|(_, function)| (function.name.borrow().clone(), function.into())) @@ -424,16 +387,6 @@ impl<'a> Into for &InternalProgram<'a> { .iter() .map(|(_, function)| (function.name.borrow().clone(), (*function).into())) .collect(), - tests: self - .test_functions - .iter() - .map(|(_, function)| { - (function.0.name.borrow().clone(), leo_ast::TestFunction { - function: function.0.into(), - input_file: function.1.clone(), - }) - }) - .collect(), } } } diff --git a/asg/src/reducer/monoidal_director.rs b/asg/src/reducer/monoidal_director.rs index 40a55d4a30..101cb1116d 100644 --- a/asg/src/reducer/monoidal_director.rs +++ b/asg/src/reducer/monoidal_director.rs @@ -47,6 +47,7 @@ impl<'a, T: Monoid, R: MonoidalReducerExpression<'a, T>> MonoidalDirector<'a, T, Expression::CircuitAccess(e) => self.reduce_circuit_access(e), Expression::CircuitInit(e) => self.reduce_circuit_init(e), Expression::Ternary(e) => self.reduce_ternary_expression(e), + Expression::Cast(e) => self.reduce_cast_expression(e), Expression::Constant(e) => self.reduce_constant(e), Expression::TupleAccess(e) => self.reduce_tuple_access(e), Expression::TupleInit(e) => self.reduce_tuple_init(e), @@ -131,6 +132,12 @@ impl<'a, T: Monoid, R: MonoidalReducerExpression<'a, T>> MonoidalDirector<'a, T, .reduce_ternary_expression(input, condition, if_true, if_false) } + pub fn reduce_cast_expression(&mut self, input: &CastExpression<'a>) -> T { + let inner = self.reduce_expression(input.inner.get()); + + self.reducer.reduce_cast_expression(input, inner) + } + pub fn reduce_constant(&mut self, input: &Constant<'a>) -> T { self.reducer.reduce_constant(input) } @@ -299,15 +306,10 @@ impl<'a, T: Monoid, R: MonoidalReducerProgram<'a, T>> MonoidalDirector<'a, T, R> .iter() .map(|(_, import)| self.reduce_program(import)) .collect(); - let test_functions = input - .test_functions - .iter() - .map(|(_, (f, _))| self.reduce_function(f)) - .collect(); let functions = input.functions.iter().map(|(_, f)| self.reduce_function(f)).collect(); let circuits = input.circuits.iter().map(|(_, c)| self.reduce_circuit(c)).collect(); self.reducer - .reduce_program(&input, imported_modules, test_functions, functions, circuits) + .reduce_program(&input, imported_modules, functions, circuits) } } diff --git a/asg/src/reducer/monoidal_reducer.rs b/asg/src/reducer/monoidal_reducer.rs index ba7a177f5b..678255b91b 100644 --- a/asg/src/reducer/monoidal_reducer.rs +++ b/asg/src/reducer/monoidal_reducer.rs @@ -64,6 +64,10 @@ pub trait MonoidalReducerExpression<'a, T: Monoid> { condition.append(if_true).append(if_false) } + fn reduce_cast_expression(&mut self, input: &CastExpression<'a>, inner: T) -> T { + inner + } + fn reduce_constant(&mut self, input: &Constant<'a>) -> T { T::default() } @@ -157,13 +161,11 @@ pub trait MonoidalReducerProgram<'a, T: Monoid>: MonoidalReducerStatement<'a, T> &mut self, input: &InternalProgram, imported_modules: Vec, - test_functions: Vec, functions: Vec, circuits: Vec, ) -> T { T::default() .append_all(imported_modules.into_iter()) - .append_all(test_functions.into_iter()) .append_all(functions.into_iter()) .append_all(circuits.into_iter()) } diff --git a/asg/src/reducer/visitor.rs b/asg/src/reducer/visitor.rs index 415f3ed265..b0f4d3ee6a 100644 --- a/asg/src/reducer/visitor.rs +++ b/asg/src/reducer/visitor.rs @@ -72,6 +72,10 @@ pub trait ExpressionVisitor<'a> { Default::default() } + fn visit_cast_expression(&mut self, input: &CastExpression<'a>) -> VisitResult { + Default::default() + } + fn visit_constant(&mut self, input: &Constant<'a>) -> VisitResult { Default::default() } diff --git a/asg/src/reducer/visitor_director.rs b/asg/src/reducer/visitor_director.rs index 4edc95d106..83ac86072c 100644 --- a/asg/src/reducer/visitor_director.rs +++ b/asg/src/reducer/visitor_director.rs @@ -60,6 +60,7 @@ impl<'a, R: ExpressionVisitor<'a>> VisitorDirector<'a, R> { Expression::CircuitAccess(e) => self.visit_circuit_access(e), Expression::CircuitInit(e) => self.visit_circuit_init(e), Expression::Ternary(e) => self.visit_ternary_expression(e), + Expression::Cast(e) => self.visit_cast_expression(e), Expression::Constant(e) => self.visit_constant(e), Expression::TupleAccess(e) => self.visit_tuple_access(e), Expression::TupleInit(e) => self.visit_tuple_init(e), @@ -184,6 +185,16 @@ impl<'a, R: ExpressionVisitor<'a>> VisitorDirector<'a, R> { } } + pub fn visit_cast_expression(&mut self, input: &CastExpression<'a>) -> ConcreteVisitResult { + match self.visitor.visit_cast_expression(input) { + VisitResult::VisitChildren => { + self.visit_expression(&input.inner)?; + Ok(()) + } + x => x.into(), + } + } + pub fn visit_constant(&mut self, input: &Constant<'a>) -> ConcreteVisitResult { self.visitor.visit_constant(input).into() } @@ -419,9 +430,6 @@ impl<'a, R: ProgramVisitor<'a>> VisitorDirector<'a, R> { for (_, import) in input.imported_modules.iter() { self.visit_program(import)?; } - for (_, (function, _)) in input.test_functions.iter() { - self.visit_function(function)?; - } for (_, function) in input.functions.iter() { self.visit_function(function)?; } diff --git a/asg/src/statement/assign.rs b/asg/src/statement/assign.rs index 1eda9119ba..060a836f5a 100644 --- a/asg/src/statement/assign.rs +++ b/asg/src/statement/assign.rs @@ -72,10 +72,10 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> { let variable = if name == "input" { if let Some(function) = scope.resolve_current_function() { if !function.has_input { - return Err(AsgConvertError::unresolved_reference(name, span)); + return Err(AsgConvertError::unresolved_reference(name, &span)); } } else { - return Err(AsgConvertError::unresolved_reference(name, span)); + return Err(AsgConvertError::unresolved_reference(name, &span)); } if let Some(input) = scope.resolve_input() { input.container @@ -87,7 +87,7 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> { } else { scope .resolve_variable(&name) - .ok_or_else(|| AsgConvertError::unresolved_reference(name, span))? + .ok_or_else(|| AsgConvertError::unresolved_reference(name, &span))? }; if !variable.borrow().mutable { diff --git a/asg/src/statement/console.rs b/asg/src/statement/console.rs index fdcf2858e5..5820abb579 100644 --- a/asg/src/statement/console.rs +++ b/asg/src/statement/console.rs @@ -15,15 +15,14 @@ // along with the Leo library. If not, see . use crate::{AsgConvertError, Expression, FromAst, Node, PartialType, Scope, Span, Statement, Type}; -use leo_ast::ConsoleFunction as AstConsoleFunction; +use leo_ast::{ConsoleFunction as AstConsoleFunction, FormattedStringPart}; use std::cell::Cell; // TODO (protryon): Refactor to not require/depend on span #[derive(Clone)] pub struct FormattedString<'a> { - pub string: String, - pub containers: Vec, + pub parts: Vec, pub parameters: Vec>>, pub span: Span, } @@ -55,10 +54,15 @@ impl<'a> FromAst<'a, leo_ast::FormattedString> for FormattedString<'a> { value: &leo_ast::FormattedString, _expected_type: Option>, ) -> Result { - if value.parameters.len() != value.containers.len() { + let expected_param_len = value + .parts + .iter() + .filter(|x| matches!(x, FormattedStringPart::Container)) + .count(); + if value.parameters.len() != expected_param_len { // + 1 for formatting string as to not confuse user return Err(AsgConvertError::unexpected_call_argument_count( - value.containers.len() + 1, + expected_param_len + 1, value.parameters.len() + 1, &value.span, )); @@ -68,8 +72,7 @@ impl<'a> FromAst<'a, leo_ast::FormattedString> for FormattedString<'a> { parameters.push(Cell::new(<&Expression<'a>>::from_ast(scope, parameter, None)?)); } Ok(FormattedString { - string: value.string.clone(), - containers: value.containers.iter().map(|x| x.span.clone()).collect(), + parts: value.parts.clone(), parameters, span: value.span.clone(), }) @@ -79,12 +82,7 @@ impl<'a> FromAst<'a, leo_ast::FormattedString> for FormattedString<'a> { impl<'a> Into for &FormattedString<'a> { fn into(self) -> leo_ast::FormattedString { leo_ast::FormattedString { - string: self.string.clone(), - containers: self - .containers - .iter() - .map(|span| leo_ast::FormattedContainer { span: span.clone() }) - .collect(), + parts: self.parts.clone(), parameters: self.parameters.iter().map(|e| e.get().into()).collect(), span: self.span.clone(), } diff --git a/asg/src/statement/definition.rs b/asg/src/statement/definition.rs index a779454996..a6b0378705 100644 --- a/asg/src/statement/definition.rs +++ b/asg/src/statement/definition.rs @@ -28,7 +28,6 @@ use crate::{ Type, Variable, }; -use leo_ast::{AstError, DeprecatedError}; use std::cell::{Cell, RefCell}; @@ -90,11 +89,6 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> { } for (variable, type_) in statement.variable_names.iter().zip(output_types.into_iter()) { - if statement.declaration_type == leo_ast::Declare::Const { - return Err(AsgConvertError::AstError(AstError::DeprecatedError( - DeprecatedError::const_statement(&statement.span), - ))); - } variables.push(&*scope.alloc_variable(RefCell::new(InnerVariable { id: scope.context.get_id(), name: variable.identifier.clone(), diff --git a/asg/src/type_.rs b/asg/src/type_.rs index 83c5f3d759..8421d436fc 100644 --- a/asg/src/type_.rs +++ b/asg/src/type_.rs @@ -123,6 +123,10 @@ impl<'a> Type<'a> { pub fn is_unit(&self) -> bool { matches!(self, Type::Tuple(t) if t.is_empty()) } + + pub fn can_cast_to(&self, to: &Type<'a>) -> bool { + matches!(self, Type::Integer(_)) && matches!(to, Type::Integer(_)) + } } impl<'a> fmt::Display for Type<'a> { diff --git a/asg/tests/mod.rs b/asg/tests/mod.rs index 906d215feb..01d12530cc 100644 --- a/asg/tests/mod.rs +++ b/asg/tests/mod.rs @@ -15,16 +15,12 @@ // along with the Leo library. If not, see . use leo_asg::*; -use leo_ast::Ast; -use leo_grammar::Grammar; - -use std::path::Path; +use leo_parser::parse_ast; mod fail; mod pass; const TESTING_FILEPATH: &str = "input.leo"; -const TESTING_PROGRAM_NAME: &str = "test_program"; fn load_asg(program_string: &str) -> Result, AsgConvertError> { load_asg_imports(make_test_context(), program_string, &mut NullImportResolver) @@ -35,8 +31,7 @@ fn load_asg_imports<'a, T: ImportResolver<'a>>( program_string: &str, imports: &mut T, ) -> Result, AsgConvertError> { - let grammar = Grammar::new(Path::new(&TESTING_FILEPATH), program_string)?; - let ast = Ast::new(TESTING_PROGRAM_NAME, &grammar)?; + let ast = parse_ast(&TESTING_FILEPATH, program_string)?; InternalProgram::new(context, &ast.as_repr(), imports) } diff --git a/asg/tests/pass/address/ternary.leo b/asg/tests/pass/address/ternary.leo index 29ecccb918..bdd88b9d92 100644 --- a/asg/tests/pass/address/ternary.leo +++ b/asg/tests/pass/address/ternary.leo @@ -2,7 +2,7 @@ function main(s: bool, c: address) { let a = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8); let b = address(aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r); - let r = if s? a: b; + let r = s? a: b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/circuits/pedersen_mock.leo b/asg/tests/pass/circuits/pedersen_mock.leo index 0b42c64a6e..559ebb7614 100644 --- a/asg/tests/pass/circuits/pedersen_mock.leo +++ b/asg/tests/pass/circuits/pedersen_mock.leo @@ -8,7 +8,7 @@ circuit PedersenHash { function hash(self, bits: [bool; 512]) -> u32 { let mut digest: u32 = 0; for i in 0..512 { - let base = if bits[i] ? self.parameters[i] : 0u32; + let base = bits[i] ? self.parameters[i] : 0u32; digest += base; } return digest diff --git a/asg/tests/pass/field/ternary.leo b/asg/tests/pass/field/ternary.leo index 49cd6a4e62..f193ad82a3 100644 --- a/asg/tests/pass/field/ternary.leo +++ b/asg/tests/pass/field/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: field, b: field, c: field) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/form_ast.rs b/asg/tests/pass/form_ast.rs index d49cb8b970..c59e055c1e 100644 --- a/asg/tests/pass/form_ast.rs +++ b/asg/tests/pass/form_ast.rs @@ -15,10 +15,7 @@ // along with the Leo library. If not, see . use crate::{load_asg, make_test_context}; -use leo_ast::Ast; -use leo_grammar::Grammar; - -use std::path::Path; +use leo_parser::parse_ast; #[test] fn test_basic() { @@ -56,6 +53,7 @@ fn test_function_rename() { #[test] fn test_imports() { + let import_name = "test-import".to_string(); let context = make_test_context(); let mut imports = crate::mocked_resolver(&context); let test_import = r#" @@ -70,7 +68,7 @@ fn test_imports() { "#; imports .packages - .insert("test-import".to_string(), load_asg(test_import).unwrap()); + .insert(import_name.clone(), load_asg(test_import).unwrap()); let program_string = r#" import test-import.foo; @@ -79,17 +77,11 @@ fn test_imports() { } "#; - let test_import_grammar = Grammar::new(Path::new("test-import.leo"), test_import).unwrap(); - println!( - "{}", - serde_json::to_string(Ast::new("test-import", &test_import_grammar).unwrap().as_repr()).unwrap() - ); + let test_import_ast = parse_ast(&import_name, test_import).unwrap(); + println!("{}", serde_json::to_string(test_import_ast.as_repr()).unwrap()); - let test_grammar = Grammar::new(Path::new("test.leo"), program_string).unwrap(); - println!( - "{}", - serde_json::to_string(Ast::new("test", &test_grammar).unwrap().as_repr()).unwrap() - ); + let test_ast = parse_ast("test.leo", program_string).unwrap(); + println!("{}", serde_json::to_string(test_ast.as_repr()).unwrap()); let asg = crate::load_asg_imports(&context, program_string, &mut imports).unwrap(); let reformed_ast = leo_asg::reform_ast(&asg); diff --git a/asg/tests/pass/group/ternary.leo b/asg/tests/pass/group/ternary.leo index b213bb1419..fb69b74521 100644 --- a/asg/tests/pass/group/ternary.leo +++ b/asg/tests/pass/group/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: group, b: group, c: group) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/integers/i128/ternary.leo b/asg/tests/pass/integers/i128/ternary.leo index 5c2f199499..a923c428e6 100644 --- a/asg/tests/pass/integers/i128/ternary.leo +++ b/asg/tests/pass/integers/i128/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: i128, b: i128, c: i128) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/integers/i16/ternary.leo b/asg/tests/pass/integers/i16/ternary.leo index ccf29bfd50..4586b87bb4 100644 --- a/asg/tests/pass/integers/i16/ternary.leo +++ b/asg/tests/pass/integers/i16/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: i16, b: i16, c: i16) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/integers/i32/ternary.leo b/asg/tests/pass/integers/i32/ternary.leo index 3066547ae3..7927c2998b 100644 --- a/asg/tests/pass/integers/i32/ternary.leo +++ b/asg/tests/pass/integers/i32/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: i32, b: i32, c: i32) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/integers/i64/ternary.leo b/asg/tests/pass/integers/i64/ternary.leo index 811c759bdf..1a2d03a77f 100644 --- a/asg/tests/pass/integers/i64/ternary.leo +++ b/asg/tests/pass/integers/i64/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: i64, b: i64, c: i64) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/integers/i8/ternary.leo b/asg/tests/pass/integers/i8/ternary.leo index de797c6e3b..e1ec1943c9 100644 --- a/asg/tests/pass/integers/i8/ternary.leo +++ b/asg/tests/pass/integers/i8/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: i8, b: i8, c: i8) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/integers/u128/ternary.leo b/asg/tests/pass/integers/u128/ternary.leo index 48299fac66..22e2e67058 100644 --- a/asg/tests/pass/integers/u128/ternary.leo +++ b/asg/tests/pass/integers/u128/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: u128, b: u128, c: u128) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/integers/u16/ternary.leo b/asg/tests/pass/integers/u16/ternary.leo index 2e2752a130..11d836570d 100644 --- a/asg/tests/pass/integers/u16/ternary.leo +++ b/asg/tests/pass/integers/u16/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: u16, b: u16, c: u16) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/integers/u32/ternary.leo b/asg/tests/pass/integers/u32/ternary.leo index fde04ac4b8..3c96a7236c 100644 --- a/asg/tests/pass/integers/u32/ternary.leo +++ b/asg/tests/pass/integers/u32/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: u32, b: u32, c: u32) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/integers/u64/ternary.leo b/asg/tests/pass/integers/u64/ternary.leo index 315fd7400b..4c4ddd8e0c 100644 --- a/asg/tests/pass/integers/u64/ternary.leo +++ b/asg/tests/pass/integers/u64/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: u64, b: u64, c: u64) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/integers/u8/ternary.leo b/asg/tests/pass/integers/u8/ternary.leo index ce868a5ec9..1b436aa054 100644 --- a/asg/tests/pass/integers/u8/ternary.leo +++ b/asg/tests/pass/integers/u8/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: u8, b: u8, c: u8) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/asg/tests/pass/statements/conditional/for_loop.leo b/asg/tests/pass/statements/conditional/for_loop.leo index 060d27d965..2dca076858 100644 --- a/asg/tests/pass/statements/conditional/for_loop.leo +++ b/asg/tests/pass/statements/conditional/for_loop.leo @@ -7,7 +7,7 @@ function main(a: bool) { } } - let r: u32 = if a ? 6 : 0; + let r: u32 = a ? 6 : 0; console.assert(r == b); } diff --git a/asg/tests/pass/statements/ternary_basic.leo b/asg/tests/pass/statements/ternary_basic.leo index 1f9c1f65a2..675b681fa9 100644 --- a/asg/tests/pass/statements/ternary_basic.leo +++ b/asg/tests/pass/statements/ternary_basic.leo @@ -1,5 +1,5 @@ function main(a: bool, b: bool) { - let c = if a ? true : false; + let c = a ? true : false; let d = c == b; } \ No newline at end of file diff --git a/ast/Cargo.toml b/ast/Cargo.toml index 75a84f0111..c98dd62d73 100644 --- a/ast/Cargo.toml +++ b/ast/Cargo.toml @@ -17,19 +17,6 @@ include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" -[[bin]] -name = "leo_ast" -path = "src/main.rs" - -[[bench]] -name = "leo_ast" -path = "benches/leo_ast.rs" -harness = false - -[dependencies.leo-grammar] -path = "../grammar" -version = "1.2.3" - [dependencies.leo-input] path = "../input" version = "1.2.3" @@ -43,6 +30,7 @@ version = "2.0" [dependencies.serde] version = "1.0" +features = ["derive", "rc"] [dependencies.serde_json] version = "1.0" @@ -55,4 +43,4 @@ version = "0.3" [features] default = [ ] -ci_skip = [ "leo-grammar/ci_skip" ] +ci_skip = [ ] diff --git a/ast/src/annotation.rs b/ast/src/annotation.rs index 9ccc5e833d..aebfd3b083 100644 --- a/ast/src/annotation.rs +++ b/ast/src/annotation.rs @@ -14,84 +14,13 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Circuit, DeprecatedError, Function, FunctionInput, Identifier, ImportStatement, TestFunction}; -use leo_grammar::{ - annotations::{Annotation, AnnotationArguments, AnnotationName}, - definitions::{AnnotatedDefinition, Definition}, -}; +use crate::{Identifier, Span}; -use std::convert::TryFrom; +use serde::{Deserialize, Serialize}; -use indexmap::IndexMap; - -pub fn load_annotation( - annotated_definition: AnnotatedDefinition, - _imports: &mut Vec, - _circuits: &mut IndexMap, - _functions: &mut IndexMap, - tests: &mut IndexMap, - _expected: &mut Vec, -) -> Result<(), DeprecatedError> { - let ast_annotation = annotated_definition.annotation; - let ast_definition = *annotated_definition.definition; - - match ast_definition { - Definition::Import(_) => { - unimplemented!("annotated imports are not supported yet"); - } - Definition::Circuit(_) => { - unimplemented!("annotated circuits are not supported yet"); - } - Definition::Function(function) => match ast_annotation.name { - // If it's deprecated for more than one type of syntax, - // we could just call it before the match on ast_definition. - AnnotationName::Context(_) => Err(DeprecatedError::try_from(ast_annotation.name).unwrap()), - AnnotationName::Test(_) => { - let ident = Identifier::from(function.identifier.clone()); - _functions.remove(&ident); - - let test_function = leo_grammar::functions::TestFunction::from(function); - let test = TestFunction::from(test_function); - tests.insert(ident, test.clone()); - - load_annotated_test(test, ast_annotation, tests); - Ok(()) - } - }, - Definition::Deprecated(_) => Ok(()), - Definition::Annotated(_) => { - unimplemented!("nested annotations are not supported yet"); - } - } -} - -pub fn load_annotated_test(test: TestFunction, annotation: Annotation, tests: &mut IndexMap) { - let name = annotation.name; - let ast_arguments = annotation.arguments; - - match name { - AnnotationName::Test(_) if ast_arguments.is_some() => { - load_annotated_test_context(test, ast_arguments.unwrap(), tests) - } - _ => (), - } -} - -pub fn load_annotated_test_context( - mut test: TestFunction, - ast_arguments: AnnotationArguments, - tests: &mut IndexMap, -) { - let arguments = ast_arguments.arguments; - - if arguments.len() != 1 { - panic!("text context annotation must have one argument identifier") - } - - let ast_input_file = arguments[0].to_owned(); - let input_file = Identifier::from(ast_input_file); - - test.input_file = Some(input_file); - - tests.insert(test.function.identifier.clone(), test); +#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct Annotation { + pub span: Span, + pub name: Identifier, + pub arguments: Vec, } diff --git a/ast/src/circuits/circuit.rs b/ast/src/circuits/circuit.rs index 79c2280cfc..8a6222aa2f 100644 --- a/ast/src/circuits/circuit.rs +++ b/ast/src/circuits/circuit.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{CircuitMember, Identifier}; -use leo_grammar::circuits::Circuit as GrammarCircuit; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,15 +25,6 @@ pub struct Circuit { pub members: Vec, } -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(); - - Self { circuit_name, members } - } -} - impl Circuit { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "circuit {} {{ ", self.circuit_name)?; diff --git a/ast/src/circuits/circuit_implied_variable_definition.rs b/ast/src/circuits/circuit_implied_variable_definition.rs index 963c153bec..6dd5f570fb 100644 --- a/ast/src/circuits/circuit_implied_variable_definition.rs +++ b/ast/src/circuits/circuit_implied_variable_definition.rs @@ -15,27 +15,11 @@ // along with the Leo library. If not, see . use crate::{Expression, Identifier}; -use leo_grammar::circuits::CircuitImpliedVariable; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct CircuitImpliedVariableDefinition { pub identifier: Identifier, - pub expression: Expression, -} - -impl<'ast> From> for CircuitImpliedVariableDefinition { - fn from(member: CircuitImpliedVariable<'ast>) -> Self { - match member { - CircuitImpliedVariable::CircuitVariable(circuit_variable) => Self { - identifier: Identifier::from(circuit_variable.identifier), - expression: Expression::from(circuit_variable.expression), - }, - CircuitImpliedVariable::Identifier(identifier) => Self { - identifier: Identifier::from(identifier.clone()), - expression: Expression::from(identifier), - }, - } - } + pub expression: Option, } diff --git a/ast/src/circuits/circuit_member.rs b/ast/src/circuits/circuit_member.rs index 29b5777587..b9d30a8a17 100644 --- a/ast/src/circuits/circuit_member.rs +++ b/ast/src/circuits/circuit_member.rs @@ -15,10 +15,6 @@ // along with the Leo library. If not, see . use crate::{Function, Identifier, Type}; -use leo_grammar::{ - circuits::{CircuitMember as GrammarCircuitMember, CircuitVariableDefinition as GrammarCircuitVariableDefinition}, - functions::Function as GrammarFunction, -}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -31,30 +27,6 @@ pub enum CircuitMember { CircuitFunction(Function), } -impl<'ast> From> for CircuitMember { - fn from(circuit_value: GrammarCircuitVariableDefinition<'ast>) -> Self { - CircuitMember::CircuitVariable( - Identifier::from(circuit_value.identifier), - Type::from(circuit_value.type_), - ) - } -} - -impl<'ast> From> for CircuitMember { - fn from(circuit_function: GrammarFunction<'ast>) -> Self { - CircuitMember::CircuitFunction(Function::from(circuit_function)) - } -} - -impl<'ast> From> for CircuitMember { - fn from(object: GrammarCircuitMember<'ast>) -> Self { - match object { - GrammarCircuitMember::CircuitVariableDefinition(circuit_value) => CircuitMember::from(circuit_value), - GrammarCircuitMember::CircuitFunction(circuit_function) => CircuitMember::from(circuit_function), - } - } -} - impl fmt::Display for CircuitMember { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { diff --git a/ast/src/circuits/circuit_variable_definition.rs b/ast/src/circuits/circuit_variable_definition.rs index 6cd3484f88..9d997707b1 100644 --- a/ast/src/circuits/circuit_variable_definition.rs +++ b/ast/src/circuits/circuit_variable_definition.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{Expression, Identifier}; -use leo_grammar::circuits::CircuitVariable; use serde::{Deserialize, Serialize}; @@ -24,12 +23,3 @@ pub struct CircuitVariableDefinition { pub identifier: Identifier, pub expression: Expression, } - -impl<'ast> From> for CircuitVariableDefinition { - fn from(member: CircuitVariable<'ast>) -> Self { - CircuitVariableDefinition { - identifier: Identifier::from(member.identifier), - expression: Expression::from(member.expression), - } - } -} diff --git a/ast/src/common/array_dimensions.rs b/ast/src/common/array_dimensions.rs index a401475200..bdcd6b3db9 100644 --- a/ast/src/common/array_dimensions.rs +++ b/ast/src/common/array_dimensions.rs @@ -15,7 +15,6 @@ // 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}; @@ -104,18 +103,6 @@ impl ArrayDimensions { } } -/// 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 { diff --git a/ast/src/common/identifier.rs b/ast/src/common/identifier.rs index cc9c544e99..46ab97e819 100644 --- a/ast/src/common/identifier.rs +++ b/ast/src/common/identifier.rs @@ -14,21 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{InputKeyword, MutSelfKeyword, SelfKeyword, Span}; -use leo_grammar::{ - annotations::AnnotationArgument, - common::{ - Identifier as GrammarIdentifier, - KeywordOrIdentifier, - MutSelfKeyword as GrammarMutSelfKeyword, - SelfKeyword as GrammarSelfKeyword, - SelfKeywordOrIdentifier, - }, - expressions::CircuitName, - functions::InputKeyword as GrammarInputKeyword, - imports::PackageName as GrammarPackageName, - types::SelfType, -}; +use crate::Span; use leo_input::common::Identifier as InputIdentifier; use crate::Node; @@ -77,10 +63,10 @@ impl Identifier { } } - pub fn new_with_span(name: &str, span: &Span) -> Self { + pub fn new_with_span(name: &str, span: Span) -> Self { Self { name: name.to_owned(), - span: span.to_owned(), + span, } } @@ -93,24 +79,6 @@ impl Identifier { } } -impl<'ast> From> for Identifier { - fn from(identifier: GrammarIdentifier<'ast>) -> Self { - Self { - name: identifier.value, - span: Span::from(identifier.span), - } - } -} - -impl<'ast> From> for Identifier { - fn from(name: GrammarPackageName<'ast>) -> Self { - Self { - name: name.value, - span: Span::from(name.span), - } - } -} - impl<'ast> From> for Identifier { fn from(identifier: InputIdentifier<'ast>) -> Self { Self { @@ -120,106 +88,6 @@ impl<'ast> From> for Identifier { } } -impl<'ast> From> for Identifier { - fn from(argument: AnnotationArgument<'ast>) -> Self { - Self { - name: argument.value, - span: Span::from(argument.span), - } - } -} - -impl<'ast> From> for Identifier { - fn from(name: KeywordOrIdentifier<'ast>) -> Self { - match name { - KeywordOrIdentifier::Identifier(keyword) => Identifier::from(keyword), - KeywordOrIdentifier::SelfType(self_type) => Identifier::from(self_type), - KeywordOrIdentifier::Input(keyword) => Identifier::from(keyword), - } - } -} - -impl<'ast> From> for Identifier { - fn from(name: SelfKeywordOrIdentifier<'ast>) -> Self { - match name { - SelfKeywordOrIdentifier::Identifier(identifier) => Identifier::from(identifier), - SelfKeywordOrIdentifier::SelfKeyword(keyword) => Identifier::from(keyword), - } - } -} - -impl<'ast> From> for Identifier { - fn from(grammar: GrammarSelfKeyword<'ast>) -> Self { - Self { - name: grammar.keyword, - span: Span::from(grammar.span), - } - } -} - -impl From for Identifier { - fn from(keyword: SelfKeyword) -> Self { - Self { - name: keyword.to_string(), - span: keyword.span, - } - } -} - -impl<'ast> From> for Identifier { - fn from(grammar: GrammarMutSelfKeyword<'ast>) -> Self { - Self { - name: grammar.to_string(), - span: Span::from(grammar.span), - } - } -} - -impl From for Identifier { - fn from(keyword: MutSelfKeyword) -> Self { - Self { - name: keyword.to_string(), - span: keyword.span, - } - } -} - -impl<'ast> From> for Identifier { - fn from(grammar: GrammarInputKeyword<'ast>) -> Self { - Self { - name: grammar.keyword, - span: Span::from(grammar.span), - } - } -} - -impl From for Identifier { - fn from(keyword: InputKeyword) -> Self { - Self { - name: keyword.to_string(), - span: keyword.span, - } - } -} - -impl<'ast> From> for Identifier { - fn from(name: CircuitName<'ast>) -> Self { - match name { - CircuitName::SelfType(self_type) => Identifier::from(self_type), - CircuitName::Identifier(identifier) => Identifier::from(identifier), - } - } -} - -impl<'ast> From> for Identifier { - fn from(self_type: SelfType<'ast>) -> Self { - Self { - name: self_type.keyword, - span: Span::from(self_type.span), - } - } -} - impl fmt::Display for Identifier { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.name) diff --git a/ast/src/common/input_keyword.rs b/ast/src/common/input_keyword.rs index a6dd0d5e74..cc9d167861 100644 --- a/ast/src/common/input_keyword.rs +++ b/ast/src/common/input_keyword.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{Node, Span}; -use leo_grammar::functions::InputKeyword as GrammarInputKeyword; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,14 +26,6 @@ pub struct InputKeyword { pub span: Span, } -impl<'ast> From> for InputKeyword { - fn from(grammar: GrammarInputKeyword<'ast>) -> Self { - Self { - span: Span::from(grammar.span), - } - } -} - impl fmt::Display for InputKeyword { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "input") diff --git a/ast/src/common/mut_self_keyword.rs b/ast/src/common/mut_self_keyword.rs index 0d4bf62168..34de7c9921 100644 --- a/ast/src/common/mut_self_keyword.rs +++ b/ast/src/common/mut_self_keyword.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{Node, Span}; -use leo_grammar::common::MutSelfKeyword as GrammarMutSelfKeyword; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,14 +25,6 @@ pub struct MutSelfKeyword { pub span: Span, } -impl<'ast> From> for MutSelfKeyword { - fn from(grammar: GrammarMutSelfKeyword<'ast>) -> Self { - Self { - span: Span::from(grammar.span), - } - } -} - impl fmt::Display for MutSelfKeyword { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "mut self") diff --git a/ast/src/common/positive_number.rs b/ast/src/common/positive_number.rs index 667727b1b5..80fda5d71e 100644 --- a/ast/src/common/positive_number.rs +++ b/ast/src/common/positive_number.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 leo_grammar::values::PositiveNumber as GrammarPositiveNumber; use leo_input::values::PositiveNumber as InputPositiveNumber; use serde::{Deserialize, Serialize}; @@ -35,13 +34,6 @@ impl PositiveNumber { } } -/// 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 } - } -} - /// Create a new [`PositiveNumber`] from an [`InputPositiveNumber`] in a Leo input file. impl<'ast> From> for PositiveNumber { fn from(array: InputPositiveNumber<'ast>) -> Self { diff --git a/ast/src/common/self_keyword.rs b/ast/src/common/self_keyword.rs index caa9e1b7f6..ba92db2160 100644 --- a/ast/src/common/self_keyword.rs +++ b/ast/src/common/self_keyword.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{Node, Span}; -use leo_grammar::common::SelfKeyword as GrammarSelfKeyword; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,14 +26,6 @@ pub struct SelfKeyword { pub span: Span, } -impl<'ast> From> for SelfKeyword { - fn from(grammar: GrammarSelfKeyword<'ast>) -> Self { - Self { - span: Span::from(grammar.span), - } - } -} - impl fmt::Display for SelfKeyword { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "self") diff --git a/ast/src/common/span.rs b/ast/src/common/span.rs index e6e7a70388..1f672f9889 100644 --- a/ast/src/common/span.rs +++ b/ast/src/common/span.rs @@ -14,62 +14,85 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use pest::Span as GrammarSpan; +use std::{fmt, rc::Rc}; + use serde::{Deserialize, Serialize}; -use std::hash::{Hash, Hasher}; -#[derive(Clone, Debug, Default, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct Span { - /// text of input string - pub text: String, - /// program line - pub line: usize, - /// start column - pub start: usize, - /// end column - pub end: usize, + pub line_start: usize, + pub line_stop: usize, + pub col_start: usize, + pub col_stop: usize, + pub path: Rc, } -impl PartialEq for Span { - fn eq(&self, other: &Self) -> bool { - self.line == other.line && self.start == other.start && self.end == other.end +impl fmt::Display for Span { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.line_start == self.line_stop { + write!(f, "{}:{}-{}", self.line_start, self.col_start, self.col_stop) + } else { + write!( + f, + "{}:{}-{}:{}", + self.line_start, self.col_start, self.line_stop, self.col_stop + ) + } } } -impl Eq for Span {} +impl<'ast> From> for Span { + fn from(span: pest::Span) -> Self { + let start = span.start_pos().line_col(); + let end = span.end_pos().line_col(); -impl Hash for Span { - fn hash(&self, state: &mut H) { - self.line.hash(state); - self.start.hash(state); - self.end.hash(state); - } -} - -impl Span { - pub fn from_internal_string(value: &str) -> Span { Span { - text: value.to_string(), - line: 0, - start: 0, - end: 0, + line_start: start.0, + line_stop: end.0, + col_start: start.1, + col_stop: end.1, + path: Rc::new(String::new()), } } } -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; +impl std::ops::Add for &Span { + type Output = Span; - text.push_str(span.start_pos().line_of().trim_end()); + fn add(self, other: &Span) -> Span { + self.clone() + other.clone() + } +} - Self { - text, - line: line_col.0, - start: line_col.1, - end, +impl std::ops::Add for Span { + type Output = Self; + + #[allow(clippy::comparison_chain)] + fn add(self, other: Self) -> Self { + if self.line_start == other.line_stop { + Span { + line_start: self.line_start, + line_stop: self.line_stop, + col_start: self.col_start.min(other.col_start), + col_stop: self.col_stop.max(other.col_stop), + path: self.path, + } + } else if self.line_start < other.line_stop { + Span { + line_start: self.line_start, + line_stop: other.line_stop, + col_start: self.col_start, + col_stop: other.col_stop, + path: self.path, + } + } else { + Span { + line_start: other.line_start, + line_stop: self.line_stop, + col_start: other.col_start, + col_stop: self.col_stop, + path: self.path, + } } } } diff --git a/ast/src/common/spread_or_expression.rs b/ast/src/common/spread_or_expression.rs index 78f940a5af..b758d0b0ea 100644 --- a/ast/src/common/spread_or_expression.rs +++ b/ast/src/common/spread_or_expression.rs @@ -15,10 +15,6 @@ // along with the Leo library. If not, see . use crate::{Expression, Node, Span}; -use leo_grammar::{ - common::SpreadOrExpression as GrammarSpreadOrExpression, - expressions::Expression as GrammarExpression, -}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -30,25 +26,6 @@ pub enum SpreadOrExpression { Expression(Expression), } -impl<'ast> From> for SpreadOrExpression { - fn from(s_or_e: GrammarSpreadOrExpression<'ast>) -> Self { - match s_or_e { - GrammarSpreadOrExpression::Spread(spread) => { - SpreadOrExpression::Spread(Expression::from(spread.expression)) - } - GrammarSpreadOrExpression::Expression(expression) => { - SpreadOrExpression::Expression(Expression::from(expression)) - } - } - } -} - -impl<'ast> From> for SpreadOrExpression { - fn from(expression: GrammarExpression<'ast>) -> Self { - SpreadOrExpression::Expression(Expression::from(expression)) - } -} - impl fmt::Display for SpreadOrExpression { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/ast/src/errors/error.rs b/ast/src/errors/error.rs index 103b0ea9cb..1f029866aa 100644 --- a/ast/src/errors/error.rs +++ b/ast/src/errors/error.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::Span; +use crate::{LeoError, Span}; -use std::{fmt, path::Path}; +use std::fmt; pub const INDENT: &str = " "; @@ -28,68 +28,59 @@ pub const INDENT: &str = " "; /// | /// = undefined value `x` #[derive(Clone, Debug, Eq, Hash, PartialEq)] -pub struct Error { +pub struct FormattedError { /// File path where error occurred pub path: Option, - /// Line number - pub line: usize, + /// Line start number + pub line_start: usize, + /// Line end number + pub line_stop: usize, /// Starting column pub start: usize, /// Ending column pub end: usize, - /// Text of errored line - pub text: String, + /// Text of errored lines + pub text: Option>, /// Error explanation pub message: String, } -impl Error { - pub fn new_from_span(message: String, span: Span) -> Self { +impl FormattedError { + pub fn new_from_span(message: String, span: &Span) -> Self { Self { path: None, - line: span.line, - start: span.start, - end: span.end, - text: span.text, + line_start: span.line_start, + line_stop: span.line_stop, + start: span.col_start, + end: span.col_stop, + text: None, message, } } +} - pub fn new_from_span_with_path(message: String, span: Span, path: &Path) -> Self { - Self { - path: Some(format!("{:?}", path)), - line: span.line, - start: span.start, - end: span.end, - text: span.text, - message, +impl LeoError for FormattedError { + fn set_path(&mut self, path: &str, content: &[String]) { + self.path = Some(path.to_string()); + if self.line_stop - 1 > content.len() { + self.text = Some(vec!["corrupt file".to_string()]); + return; } + assert!(self.line_stop >= self.line_start); + // if self.line_stop == self.line_start { + // self.text = Some(vec![content[self.line_start - 1][self.start - 1..self.end - 1].to_string()]); + // } else { + self.text = Some( + content[self.line_start - 1..self.line_stop] + .iter() + .map(|x| x.to_string()) + .collect(), + ); + // } } - pub fn set_path(&mut self, path: &Path) { - self.path = Some(format!("{:?}", path)); - } - - pub fn format(&self) -> String { - let path = self.path.as_ref().map(|path| format!("{}:", path)).unwrap_or_default(); - let underline = underline(self.start, self.end); - - format!( - "{indent }--> {path} {line}:{start}\n\ - {indent } |\n\ - {line:width$} | {text}\n\ - {indent } | {underline}\n\ - {indent } |\n\ - {indent } = {message}", - indent = INDENT, - width = INDENT.len(), - path = path, - line = self.line, - start = self.start, - text = self.text, - underline = underline, - message = self.message, - ) + fn get_path(&self) -> Option<&str> { + self.path.as_deref() } } @@ -112,13 +103,46 @@ fn underline(mut start: usize, mut end: usize) -> String { underline } -impl fmt::Display for Error { +impl fmt::Display for FormattedError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.format()) + let path = self.path.as_ref().map(|path| format!("{}:", path)).unwrap_or_default(); + let underline = underline(self.start - 1, self.end - 1); + + write!( + f, + "{indent }--> {path} {line_start}:{start}\n\ + {indent } |\n", + indent = INDENT, + path = path, + line_start = self.line_start, + start = self.start, + )?; + + if let Some(lines) = &self.text { + for (line_no, line) in lines.iter().enumerate() { + writeln!( + f, + "{line_no:width$} | {text}", + width = INDENT.len(), + line_no = self.line_start + line_no, + text = line, + )?; + } + } + + write!( + f, + "{indent } | {underline}\n\ + {indent } |\n\ + {indent } = {message}", + indent = INDENT, + underline = underline, + message = self.message, + ) } } -impl std::error::Error for Error { +impl std::error::Error for FormattedError { fn description(&self) -> &str { &self.message } @@ -126,12 +150,13 @@ impl std::error::Error for Error { #[test] fn test_error() { - let err = Error { + let err = FormattedError { path: Some("file.leo".to_string()), - line: 2, + line_start: 2, + line_stop: 2, start: 8, end: 9, - text: "let a = x;".to_string(), + text: Some(vec!["let a = x;".to_string()]), message: "undefined value `x`".to_string(), }; diff --git a/ast/src/errors/mod.rs b/ast/src/errors/mod.rs index d3bb4d70df..1e8b06996f 100644 --- a/ast/src/errors/mod.rs +++ b/ast/src/errors/mod.rs @@ -14,30 +14,11 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -pub mod deprecated; -pub use deprecated::*; - pub mod error; pub use error::*; -use error::Error as FormattedError; +pub trait LeoError { + fn get_path(&self) -> Option<&str>; -use leo_grammar::ParserError; - -#[derive(Debug, Error)] -pub enum AstError { - #[error("{}", _0)] - DeprecatedError(#[from] DeprecatedError), - - #[error("{}", _0)] - Error(#[from] FormattedError), - - #[error("{}", _0)] - IoError(#[from] std::io::Error), - - #[error("{}", _0)] - ParserError(#[from] ParserError), - - #[error("{}", _0)] - JsonError(#[from] serde_json::error::Error), + fn set_path(&mut self, path: &str, contents: &[String]); } diff --git a/ast/src/expression/binary.rs b/ast/src/expression/binary.rs index d9c55c4f4d..dd556441ff 100644 --- a/ast/src/expression/binary.rs +++ b/ast/src/expression/binary.rs @@ -31,6 +31,13 @@ pub enum BinaryOperation { Gt, Le, Lt, + BitOr, + BitAnd, + BitXor, + Shr, + ShrSigned, + Shl, + Mod, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -55,6 +62,13 @@ impl AsRef for BinaryOperation { BinaryOperation::Gt => ">", BinaryOperation::Le => "<=", BinaryOperation::Lt => "<", + BinaryOperation::BitOr => "|", + BinaryOperation::BitAnd => "&", + BinaryOperation::BitXor => "^", + BinaryOperation::Shr => ">>", + BinaryOperation::ShrSigned => ">>>", + BinaryOperation::Shl => "<<", + BinaryOperation::Mod => "%", } } } @@ -66,6 +80,13 @@ impl BinaryOperation { | BinaryOperation::Sub | BinaryOperation::Mul | BinaryOperation::Div + | BinaryOperation::BitOr + | BinaryOperation::BitAnd + | BinaryOperation::BitXor + | BinaryOperation::Shr + | BinaryOperation::ShrSigned + | BinaryOperation::Shl + | BinaryOperation::Mod | BinaryOperation::Pow => BinaryOperationClass::Numeric, BinaryOperation::Or | BinaryOperation::And diff --git a/grammar/src/common/spread.rs b/ast/src/expression/cast.rs similarity index 63% rename from grammar/src/common/spread.rs rename to ast/src/expression/cast.rs index c9dd266816..32dd980651 100644 --- a/grammar/src/common/spread.rs +++ b/ast/src/expression/cast.rs @@ -14,24 +14,29 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ast::Rule, expressions::Expression, SpanDef}; +use crate::Type; -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; +use super::*; -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::spread))] -pub struct Spread<'ast> { - pub expression: Expression<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct CastExpression { + pub inner: Box, + pub target_type: Type, + pub span: Span, } -impl<'ast> fmt::Display for Spread<'ast> { +impl fmt::Display for CastExpression { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "...{}", self.expression) + write!(f, "{} as {}", self.inner, self.target_type) + } +} + +impl Node for CastExpression { + fn span(&self) -> &Span { + &self.span + } + + fn set_span(&mut self, span: Span) { + self.span = span; } } diff --git a/ast/src/expression/circuit_init.rs b/ast/src/expression/circuit_init.rs index 9f79f3c9ba..8ca5a230e9 100644 --- a/ast/src/expression/circuit_init.rs +++ b/ast/src/expression/circuit_init.rs @@ -27,7 +27,11 @@ impl fmt::Display for CircuitInitExpression { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{} {{", self.name)?; for (i, member) in self.members.iter().enumerate() { - write!(f, "{}: {}", member.identifier, member.expression)?; + if let Some(expression) = &member.expression { + write!(f, "{}: {}", member.identifier, expression)?; + } else { + write!(f, "{}", member.identifier)?; + } if i < self.members.len() - 1 { write!(f, ", ")?; diff --git a/ast/src/expression/mod.rs b/ast/src/expression/mod.rs index fb4050f1f2..701efc50bc 100644 --- a/ast/src/expression/mod.rs +++ b/ast/src/expression/mod.rs @@ -24,33 +24,7 @@ use crate::{ Span, SpreadOrExpression, }; -use leo_grammar::{ - access::{Access, AssigneeAccess, SelfAccess}, - common::{Assignee, Identifier as GrammarIdentifier, RangeOrExpression as GrammarRangeOrExpression}, - expressions::{ - ArrayInitializerExpression, - ArrayInlineExpression as GrammarArrayInlineExpression, - BinaryExpression as GrammarBinaryExpression, - CircuitInlineExpression, - Expression as GrammarExpression, - PostfixExpression, - SelfPostfixExpression, - TernaryExpression as GrammarTernaryExpression, - UnaryExpression as GrammarUnaryExpression, - }, - operations::{BinaryOperation as GrammarBinaryOperation, UnaryOperation as GrammarUnaryOperation}, - values::{ - AddressValue, - BooleanValue, - FieldValue, - GroupValue as GrammarGroupValue, - IntegerValue, - NumberValue as GrammarNumber, - Value, - }, -}; -use leo_grammar::{access::TupleAccess, expressions::TupleExpression}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -84,6 +58,8 @@ mod value; pub use value::*; mod call; pub use call::*; +mod cast; +pub use cast::*; /// Expression that evaluates to a value #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -93,6 +69,7 @@ pub enum Expression { Binary(BinaryExpression), Unary(UnaryExpression), Ternary(TernaryExpression), + Cast(CastExpression), ArrayInline(ArrayInlineExpression), ArrayInit(ArrayInitExpression), @@ -128,6 +105,7 @@ impl Node for Expression { CircuitMemberAccess(n) => n.span(), CircuitStaticFunctionAccess(n) => n.span(), Call(n) => n.span(), + Cast(n) => n.span(), } } @@ -149,11 +127,12 @@ impl Node for Expression { CircuitMemberAccess(n) => n.set_span(span), CircuitStaticFunctionAccess(n) => n.set_span(span), Call(n) => n.set_span(span), + Cast(n) => n.set_span(span), } } } -impl<'ast> fmt::Display for Expression { +impl fmt::Display for Expression { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use Expression::*; match &self { @@ -172,404 +151,7 @@ impl<'ast> fmt::Display for Expression { CircuitMemberAccess(n) => n.fmt(f), CircuitStaticFunctionAccess(n) => n.fmt(f), Call(n) => n.fmt(f), + Cast(n) => n.fmt(f), } } } - -impl<'ast> From> for Expression { - fn from(expression: CircuitInlineExpression<'ast>) -> Self { - let circuit_name = Identifier::from(expression.name); - let members = expression - .members - .into_iter() - .map(CircuitImpliedVariableDefinition::from) - .collect::>(); - - Expression::CircuitInit(CircuitInitExpression { - name: circuit_name, - members, - span: Span::from(expression.span), - }) - } -} - -impl<'ast> From> for Expression { - fn from(expression: PostfixExpression<'ast>) -> Self { - let variable = Expression::Identifier(Identifier::from(expression.name)); - - // ast::PostFixExpression contains an array of "accesses": `a(34)[42]` is represented as `[a, [Call(34), Select(42)]]`, but Access call expressions - // are recursive, so it is `Select(Call(a, 34), 42)`. We apply this transformation here - - // we start with the id, and we fold the array of accesses by wrapping the current value - expression - .accesses - .into_iter() - .fold(variable, |acc, access| match access { - // Handle array accesses - Access::Array(array) => match array.expression { - GrammarRangeOrExpression::Expression(expression) => { - Expression::ArrayAccess(ArrayAccessExpression { - array: Box::new(acc), - index: Box::new(Expression::from(expression)), - span: Span::from(array.span), - }) - } - GrammarRangeOrExpression::Range(range) => { - Expression::ArrayRangeAccess(ArrayRangeAccessExpression { - array: Box::new(acc), - left: range.from.map(Expression::from).map(Box::new), - right: range.to.map(Expression::from).map(Box::new), - span: Span::from(array.span), - }) - } - }, - - // Handle tuple access - Access::Tuple(tuple) => Expression::TupleAccess(TupleAccessExpression { - tuple: Box::new(acc), - index: PositiveNumber::from(tuple.number), - span: Span::from(tuple.span), - }), - - // Handle function calls - Access::Call(function) => Expression::Call(CallExpression { - function: Box::new(acc), - arguments: function.expressions.into_iter().map(Expression::from).collect(), - span: Span::from(function.span), - }), - - // Handle circuit member accesses - Access::Object(circuit_object) => Expression::CircuitMemberAccess(CircuitMemberAccessExpression { - circuit: Box::new(acc), - name: Identifier::from(circuit_object.identifier), - span: Span::from(circuit_object.span), - }), - Access::StaticObject(circuit_object) => { - Expression::CircuitStaticFunctionAccess(CircuitStaticFunctionAccessExpression { - circuit: Box::new(acc), - name: Identifier::from(circuit_object.identifier), - span: Span::from(circuit_object.span), - }) - } - }) - } -} - -impl<'ast> From> for Expression { - fn from(expression: SelfPostfixExpression<'ast>) -> Self { - let variable = Expression::Identifier(Identifier::from(expression.name)); - - // Handle self expression access. - let self_expression = match expression.self_access { - // Handle circuit member accesses - SelfAccess::Object(circuit_object) => Expression::CircuitMemberAccess(CircuitMemberAccessExpression { - circuit: Box::new(variable), - name: Identifier::from(circuit_object.identifier), - span: Span::from(circuit_object.span), - }), - - // Handle static access - SelfAccess::StaticObject(circuit_object) => { - Expression::CircuitStaticFunctionAccess(CircuitStaticFunctionAccessExpression { - circuit: Box::new(variable), - name: Identifier::from(circuit_object.identifier), - span: Span::from(circuit_object.span), - }) - } - }; - // ast::SelfPostFixExpression contains an array of "accesses": `a(34)[42]` is represented as `[a, [Call(34), Select(42)]]`, but Access call expressions - // are recursive, so it is `Select(Call(a, 34), 42)`. We apply this transformation here - - // we start with the id, and we fold the array of accesses by wrapping the current value - expression - .accesses - .into_iter() - .fold(self_expression, |acc, access| match access { - // Handle array accesses - Access::Array(array) => match array.expression { - GrammarRangeOrExpression::Expression(expression) => { - Expression::ArrayAccess(ArrayAccessExpression { - array: Box::new(acc), - index: Box::new(Expression::from(expression)), - span: Span::from(array.span), - }) - } - GrammarRangeOrExpression::Range(range) => { - Expression::ArrayRangeAccess(ArrayRangeAccessExpression { - array: Box::new(acc), - left: range.from.map(Expression::from).map(Box::new), - right: range.to.map(Expression::from).map(Box::new), - span: Span::from(array.span), - }) - } - }, - - // Handle tuple access - Access::Tuple(tuple) => Expression::TupleAccess(TupleAccessExpression { - tuple: Box::new(acc), - index: PositiveNumber::from(tuple.number), - span: Span::from(tuple.span), - }), - - // Handle function calls - Access::Call(function) => Expression::Call(CallExpression { - function: Box::new(acc), - arguments: function.expressions.into_iter().map(Expression::from).collect(), - span: Span::from(function.span), - }), - - // Handle circuit member accesses - Access::Object(circuit_object) => Expression::CircuitMemberAccess(CircuitMemberAccessExpression { - circuit: Box::new(acc), - name: Identifier::from(circuit_object.identifier), - span: Span::from(circuit_object.span), - }), - Access::StaticObject(circuit_object) => { - Expression::CircuitStaticFunctionAccess(CircuitStaticFunctionAccessExpression { - circuit: Box::new(acc), - name: Identifier::from(circuit_object.identifier), - span: Span::from(circuit_object.span), - }) - } - }) - } -} - -impl<'ast> From> for Expression { - fn from(expression: GrammarExpression<'ast>) -> Self { - match 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), - GrammarExpression::SelfPostfix(expression) => Expression::from(expression), - } - } -} - -// Assignee -> Expression for operator assign statements -impl<'ast> From> for Expression { - fn from(assignee: Assignee<'ast>) -> Self { - let variable = Expression::Identifier(Identifier::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 { - AssigneeAccess::Member(circuit_member) => { - Expression::CircuitMemberAccess(CircuitMemberAccessExpression { - circuit: Box::new(acc), - name: Identifier::from(circuit_member.identifier), - span: Span::from(circuit_member.span), - }) - } - AssigneeAccess::Array(array) => match array.expression { - GrammarRangeOrExpression::Expression(expression) => { - Expression::ArrayAccess(ArrayAccessExpression { - array: Box::new(acc), - index: Box::new(Expression::from(expression)), - span: Span::from(array.span), - }) - } - GrammarRangeOrExpression::Range(range) => { - Expression::ArrayRangeAccess(ArrayRangeAccessExpression { - array: Box::new(acc), - left: range.from.map(Expression::from).map(Box::new), - right: range.to.map(Expression::from).map(Box::new), - span: Span::from(array.span), - }) - } - }, - AssigneeAccess::Tuple(tuple) => Expression::TupleAccess(TupleAccessExpression { - tuple: Box::new(acc), - index: PositiveNumber::from(tuple.number), - span: Span::from(tuple.span.clone()), - }), - }) - } -} - -impl<'ast> From> for Expression { - fn from(expression: GrammarBinaryExpression<'ast>) -> Self { - use GrammarBinaryOperation::*; - let operator = match expression.operation { - Or => BinaryOperation::Or, - And => BinaryOperation::And, - Eq => BinaryOperation::Eq, - Ne => BinaryOperation::Ne, - Ge => BinaryOperation::Ge, - Gt => BinaryOperation::Gt, - Le => BinaryOperation::Le, - Lt => BinaryOperation::Lt, - Add => BinaryOperation::Add, - Sub => BinaryOperation::Sub, - Mul => BinaryOperation::Mul, - Div => BinaryOperation::Div, - Pow => BinaryOperation::Pow, - }; - Expression::Binary(BinaryExpression { - left: Box::new(Expression::from(expression.left)), - right: Box::new(Expression::from(expression.right)), - op: operator, - span: Span::from(expression.span), - }) - } -} - -impl<'ast> From> for Expression { - fn from(expression: GrammarTernaryExpression<'ast>) -> Self { - Expression::Ternary(TernaryExpression { - condition: Box::new(Expression::from(expression.first)), - if_true: Box::new(Expression::from(expression.second)), - if_false: Box::new(Expression::from(expression.third)), - span: Span::from(expression.span), - }) - } -} - -impl<'ast> From> for Expression { - fn from(array: GrammarArrayInlineExpression<'ast>) -> Self { - Expression::ArrayInline(ArrayInlineExpression { - elements: array.expressions.into_iter().map(SpreadOrExpression::from).collect(), - span: Span::from(array.span), - }) - } -} - -impl<'ast> From> for Expression { - fn from(array: ArrayInitializerExpression<'ast>) -> Self { - Expression::ArrayInit(ArrayInitExpression { - element: Box::new(Expression::from(array.expression)), - dimensions: ArrayDimensions::from(array.dimensions), - span: Span::from(array.span), - }) - } -} - -impl<'ast> From> for Expression { - fn from(tuple: TupleExpression<'ast>) -> Self { - Expression::TupleInit(TupleInitExpression { - elements: tuple.expressions.into_iter().map(Expression::from).collect(), - span: Span::from(tuple.span), - }) - } -} - -impl<'ast> From> for Expression { - fn from(value: Value<'ast>) -> Self { - match value { - Value::Address(address) => Expression::from(address), - Value::Boolean(boolean) => Expression::from(boolean), - Value::Field(field) => Expression::from(field), - Value::Group(group) => Expression::from(group), - Value::Implicit(number) => Expression::from(number), - Value::Integer(integer) => Expression::from(integer), - } - } -} - -impl<'ast> From> for Expression { - fn from(expression: GrammarUnaryExpression<'ast>) -> Self { - use GrammarUnaryOperation::*; - let operator = match expression.operation { - Not(_) => UnaryOperation::Not, - Negate(_) => UnaryOperation::Negate, - }; - Expression::Unary(UnaryExpression { - inner: Box::new(Expression::from(expression.expression)), - op: operator, - span: Span::from(expression.span), - }) - } -} - -impl<'ast> From> for Expression { - fn from(address: AddressValue<'ast>) -> Self { - Expression::Value(ValueExpression::Address( - address.address.value, - Span::from(address.span), - )) - } -} - -impl<'ast> From> for Expression { - fn from(boolean: BooleanValue<'ast>) -> Self { - Expression::Value(ValueExpression::Boolean(boolean.value, Span::from(boolean.span))) - } -} - -impl<'ast> From> for Expression { - fn from(field: FieldValue<'ast>) -> Self { - Expression::Value(ValueExpression::Field(field.number.to_string(), Span::from(field.span))) - } -} - -impl<'ast> From> for Expression { - fn from(ast_group: GrammarGroupValue<'ast>) -> Self { - Expression::Value(ValueExpression::Group(Box::new(GroupValue::from(ast_group)))) - } -} - -impl<'ast> From> for Expression { - fn from(number: GrammarNumber<'ast>) -> Self { - let (value, span) = match number { - GrammarNumber::Positive(number) => (number.value, number.span), - GrammarNumber::Negative(number) => (number.value, number.span), - }; - - Expression::Value(ValueExpression::Implicit(value, Span::from(span))) - } -} - -impl<'ast> From> for Expression { - fn from(integer: IntegerValue<'ast>) -> Self { - let span = Span::from(integer.span().clone()); - let (type_, value) = match integer { - IntegerValue::Signed(integer) => { - let type_ = IntegerType::from(integer.type_); - let number = match integer.number { - GrammarNumber::Negative(number) => number.value, - GrammarNumber::Positive(number) => number.value, - }; - - (type_, number) - } - IntegerValue::Unsigned(integer) => { - let type_ = IntegerType::from(integer.type_); - let number = integer.number.value; - - (type_, number) - } - }; - - Expression::Value(ValueExpression::Integer(type_, value, span)) - } -} - -impl<'ast> From> for Expression { - fn from(tuple: TupleAccess<'ast>) -> Self { - Expression::Value(ValueExpression::Implicit( - tuple.number.to_string(), - Span::from(tuple.span), - )) - } -} - -impl<'ast> From> for Expression { - fn from(identifier: GrammarIdentifier<'ast>) -> Self { - Expression::Identifier(Identifier::from(identifier)) - } -} - -impl From for Expression { - fn from(identifier: Identifier) -> Self { - Expression::Identifier(identifier) - } -} diff --git a/ast/src/expression/unary.rs b/ast/src/expression/unary.rs index af5f2c685c..cb7eaac44e 100644 --- a/ast/src/expression/unary.rs +++ b/ast/src/expression/unary.rs @@ -20,6 +20,7 @@ use super::*; pub enum UnaryOperation { Not, Negate, + BitNot, } impl AsRef for UnaryOperation { @@ -27,6 +28,7 @@ impl AsRef for UnaryOperation { match self { UnaryOperation::Not => "!", UnaryOperation::Negate => "-", + UnaryOperation::BitNot => "~", } } } diff --git a/ast/src/functions/function.rs b/ast/src/functions/function.rs index e9cea0c8c3..d00c39a084 100644 --- a/ast/src/functions/function.rs +++ b/ast/src/functions/function.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::{Block, FunctionInput, Identifier, Node, Span, Type}; -use leo_grammar::functions::Function as GrammarFunction; +use crate::{Annotation, Block, FunctionInput, Identifier, Node, Span, Type}; use serde::{Deserialize, Serialize}; use std::fmt; #[derive(Clone, Serialize, Deserialize)] pub struct Function { + pub annotations: Vec, pub identifier: Identifier, pub input: Vec, pub output: Option, @@ -37,24 +37,6 @@ impl PartialEq for Function { impl Eq for Function {} -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(); - let returns = function.returns.map(Type::from); - let block = Block::from(function.block); - - Function { - identifier: function_name, - input: parameters, - output: returns, - block, - span: Span::from(function.span), - } - } -} - impl Function { pub fn get_name(&self) -> &str { &self.identifier.name diff --git a/ast/src/functions/input/function_input.rs b/ast/src/functions/input/function_input.rs index 8cece828ad..90f45f3d24 100644 --- a/ast/src/functions/input/function_input.rs +++ b/ast/src/functions/input/function_input.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{Identifier, Node, Span, Type}; -use leo_grammar::functions::FunctionInput as GrammarFunctionInput; use serde::{Deserialize, Serialize}; use std::fmt; @@ -29,18 +28,6 @@ pub struct FunctionInputVariable { pub span: Span, } -impl<'ast> From> for FunctionInputVariable { - fn from(parameter: GrammarFunctionInput<'ast>) -> Self { - FunctionInputVariable { - identifier: Identifier::from(parameter.identifier), - const_: parameter.const_.is_some(), - mutable: parameter.mutable.is_some(), - type_: Type::from(parameter.type_), - span: Span::from(parameter.span), - } - } -} - impl FunctionInputVariable { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { // mut var: bool diff --git a/ast/src/functions/input/input_variable.rs b/ast/src/functions/input/input_variable.rs index ecab44a959..f342cb3e1b 100644 --- a/ast/src/functions/input/input_variable.rs +++ b/ast/src/functions/input/input_variable.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{FunctionInputVariable, InputKeyword, MutSelfKeyword, Node, SelfKeyword, Span}; -use leo_grammar::functions::input::Input as GrammarInput; use serde::{Deserialize, Serialize}; use std::fmt; @@ -29,19 +28,6 @@ pub enum FunctionInput { Variable(FunctionInputVariable), } -impl<'ast> From> for FunctionInput { - fn from(input: GrammarInput<'ast>) -> Self { - match input { - GrammarInput::InputKeyword(keyword) => FunctionInput::InputKeyword(InputKeyword::from(keyword)), - GrammarInput::SelfKeyword(keyword) => FunctionInput::SelfKeyword(SelfKeyword::from(keyword)), - GrammarInput::MutSelfKeyword(keyword) => FunctionInput::MutSelfKeyword(MutSelfKeyword::from(keyword)), - GrammarInput::FunctionInput(function_input) => { - FunctionInput::Variable(FunctionInputVariable::from(function_input)) - } - } - } -} - impl FunctionInput { /// /// Returns `true` if the function input is the `self` or `mut self` keyword. diff --git a/ast/src/functions/mod.rs b/ast/src/functions/mod.rs index f16e3448d2..430fc3f77a 100644 --- a/ast/src/functions/mod.rs +++ b/ast/src/functions/mod.rs @@ -19,6 +19,3 @@ pub use function::*; pub mod input; pub use input::*; - -pub mod test_function; -pub use test_function::*; diff --git a/ast/src/functions/test_function.rs b/ast/src/functions/test_function.rs deleted file mode 100644 index eb9f09a346..0000000000 --- a/ast/src/functions/test_function.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{Function, Identifier}; -use leo_grammar::functions::TestFunction as GrammarTestFunction; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct TestFunction { - pub function: Function, - pub input_file: Option, -} - -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 fd201856dd..5f64c476dc 100644 --- a/ast/src/groups/group_coordinate.rs +++ b/ast/src/groups/group_coordinate.rs @@ -15,13 +15,6 @@ // along with the Leo library. If not, see . use crate::common::span::Span; -use leo_grammar::values::{ - GroupCoordinate as GrammarGroupCoordinate, - Inferred as GrammarInferred, - NumberValue as GrammarNumberValue, - SignHigh as GrammarSignHigh, - SignLow as GrammarSignLow, -}; use leo_input::values::{ GroupCoordinate as InputGroupCoordinate, Inferred as InputInferred, @@ -41,17 +34,6 @@ pub enum GroupCoordinate { Inferred, } -impl<'ast> From> for GroupCoordinate { - fn from(coordinate: GrammarGroupCoordinate<'ast>) -> Self { - match coordinate { - 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), - } - } -} - impl<'ast> From> for GroupCoordinate { fn from(coordinate: InputGroupCoordinate<'ast>) -> Self { match coordinate { @@ -74,33 +56,6 @@ impl fmt::Display for GroupCoordinate { } } -impl<'ast> From> for GroupCoordinate { - fn from(number: GrammarNumberValue<'ast>) -> Self { - let value = number.to_string(); - let span = Span::from(number.span().clone()); - - GroupCoordinate::Number(value, span) - } -} - -impl<'ast> From> for GroupCoordinate { - fn from(_sign: GrammarSignHigh<'ast>) -> Self { - GroupCoordinate::SignHigh - } -} - -impl<'ast> From> for GroupCoordinate { - fn from(_sign: GrammarSignLow<'ast>) -> Self { - GroupCoordinate::SignLow - } -} - -impl<'ast> From> for GroupCoordinate { - fn from(_sign: GrammarInferred<'ast>) -> Self { - GroupCoordinate::Inferred - } -} - impl<'ast> From> for GroupCoordinate { fn from(number: InputNumberValue<'ast>) -> Self { let value = number.to_string(); diff --git a/ast/src/groups/group_value.rs b/ast/src/groups/group_value.rs index 5e0c42113e..e36aba3659 100644 --- a/ast/src/groups/group_value.rs +++ b/ast/src/groups/group_value.rs @@ -15,11 +15,6 @@ // along with the Leo library. If not, see . use crate::{common::span::Span, groups::GroupCoordinate}; -use leo_grammar::values::{ - GroupRepresentation as GrammarGroupRepresentation, - GroupTuple as GrammarGroupTuple, - GroupValue as GrammarGroupValue, -}; use leo_input::values::{ GroupRepresentation as InputGroupRepresentation, GroupTuple as InputGroupTuple, @@ -51,17 +46,6 @@ impl GroupValue { } } -impl<'ast> From> for GroupValue { - fn from(ast_group: GrammarGroupValue) -> Self { - let span = Span::from(ast_group.span); - - match ast_group.value { - GrammarGroupRepresentation::Single(number) => GroupValue::Single(number.to_string(), span), - GrammarGroupRepresentation::Tuple(tuple) => GroupValue::Tuple(GroupTuple::from(tuple)), - } - } -} - impl<'ast> From> for GroupValue { fn from(ast_group: InputGroupValue) -> Self { let span = Span::from(ast_group.span); @@ -89,19 +73,6 @@ pub struct GroupTuple { pub span: Span, } -impl<'ast> From> for GroupTuple { - fn from(ast_group: GrammarGroupTuple<'ast>) -> Self { - let ast_x = ast_group.x; - let ast_y = ast_group.y; - - Self { - x: GroupCoordinate::from(ast_x), - y: GroupCoordinate::from(ast_y), - span: Span::from(ast_group.span), - } - } -} - impl<'ast> From> for GroupTuple { fn from(ast_group: InputGroupTuple<'ast>) -> Self { let ast_x = ast_group.x; diff --git a/ast/src/imports/import.rs b/ast/src/imports/import.rs index 246f61c3b1..93c4ad6f6d 100644 --- a/ast/src/imports/import.rs +++ b/ast/src/imports/import.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{PackageOrPackages, Span}; -use leo_grammar::imports::Import as GrammarImport; use serde::{Deserialize, Serialize}; use std::fmt; @@ -39,15 +38,6 @@ impl ImportStatement { } } -impl<'ast> From> for ImportStatement { - fn from(import: GrammarImport<'ast>) -> Self { - ImportStatement { - package_or_packages: PackageOrPackages::from(import.package_or_packages), - span: Span::from(import.span), - } - } -} - impl ImportStatement { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "import {};", self.package_or_packages) diff --git a/ast/src/imports/import_symbol.rs b/ast/src/imports/import_symbol.rs index 20d8650793..cc7a038dad 100644 --- a/ast/src/imports/import_symbol.rs +++ b/ast/src/imports/import_symbol.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{Identifier, Span}; -use leo_grammar::imports::ImportSymbol as GrammarImportSymbol; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,16 +26,6 @@ pub struct ImportSymbol { pub span: Span, } -impl<'ast> From> for ImportSymbol { - fn from(symbol: GrammarImportSymbol<'ast>) -> Self { - ImportSymbol { - symbol: Identifier::from(symbol.value), - alias: symbol.alias.map(Identifier::from), - span: Span::from(symbol.span), - } - } -} - impl fmt::Display for ImportSymbol { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.alias.is_some() { diff --git a/ast/src/imports/package.rs b/ast/src/imports/package.rs index 091e72142d..1ccd3007b1 100644 --- a/ast/src/imports/package.rs +++ b/ast/src/imports/package.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{common::Identifier, PackageAccess, Span}; -use leo_grammar::imports::Package as GrammarPackage; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,16 +26,6 @@ pub struct Package { pub span: Span, } -impl<'ast> From> for Package { - fn from(package: GrammarPackage<'ast>) -> Self { - Package { - name: Identifier::from(package.name), - access: PackageAccess::from(package.access), - span: Span::from(package.span), - } - } -} - impl Package { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}.{}", self.name, self.access) diff --git a/ast/src/imports/package_access.rs b/ast/src/imports/package_access.rs index b329cc6b82..7245f900af 100644 --- a/ast/src/imports/package_access.rs +++ b/ast/src/imports/package_access.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::{ImportSymbol, Package, Packages, Span}; -use leo_grammar::imports::PackageAccess as GrammarPackageAccess; +use crate::{ImportSymbol, Node, Package, Packages, Span}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -28,13 +27,22 @@ pub enum PackageAccess { Multiple(Packages), } -impl<'ast> From> for PackageAccess { - fn from(access: GrammarPackageAccess<'ast>) -> Self { - match access { - 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(packages) => PackageAccess::Multiple(Packages::from(packages)), +impl Node for PackageAccess { + fn span(&self) -> &Span { + match self { + PackageAccess::Star(span) => span, + PackageAccess::SubPackage(package) => &package.span, + PackageAccess::Symbol(package) => &package.span, + PackageAccess::Multiple(package) => &package.span, + } + } + + fn set_span(&mut self, span: Span) { + match self { + PackageAccess::Star(package) => *package = span, + PackageAccess::SubPackage(package) => package.span = span, + PackageAccess::Symbol(package) => package.span = span, + PackageAccess::Multiple(package) => package.span = span, } } } diff --git a/ast/src/imports/package_or_packages.rs b/ast/src/imports/package_or_packages.rs index 2f1b9bc717..7f42d57fd7 100644 --- a/ast/src/imports/package_or_packages.rs +++ b/ast/src/imports/package_or_packages.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::{Package, Packages}; -use leo_grammar::imports::PackageOrPackages as GrammarPackageOrPackages; +use crate::{Node, Package, Packages, Span}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,15 +25,6 @@ pub enum PackageOrPackages { Packages(Packages), } -impl<'ast> From> for PackageOrPackages { - fn from(package_or_packages: GrammarPackageOrPackages<'ast>) -> Self { - match package_or_packages { - GrammarPackageOrPackages::Package(package) => PackageOrPackages::Package(Package::from(package)), - GrammarPackageOrPackages::Packages(packages) => PackageOrPackages::Packages(Packages::from(packages)), - } - } -} - impl PackageOrPackages { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { @@ -64,3 +54,19 @@ impl fmt::Display for PackageOrPackages { self.format(f) } } + +impl Node for PackageOrPackages { + fn span(&self) -> &Span { + match self { + PackageOrPackages::Package(package) => &package.span, + PackageOrPackages::Packages(packages) => &packages.span, + } + } + + fn set_span(&mut self, span: Span) { + match self { + PackageOrPackages::Package(package) => package.span = span, + PackageOrPackages::Packages(packages) => packages.span = span, + } + } +} diff --git a/ast/src/imports/packages.rs b/ast/src/imports/packages.rs index fab9542716..e561080807 100644 --- a/ast/src/imports/packages.rs +++ b/ast/src/imports/packages.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{common::Identifier, PackageAccess, Span}; -use leo_grammar::imports::Packages as GrammarPackages; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,16 +26,6 @@ pub struct Packages { pub span: Span, } -impl<'ast> From> for Packages { - fn from(packages: GrammarPackages<'ast>) -> Self { - Packages { - name: Identifier::from(packages.name), - accesses: packages.accesses.into_iter().map(PackageAccess::from).collect(), - span: Span::from(packages.span), - } - } -} - impl Packages { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}.(", self.name)?; diff --git a/ast/src/input/input_value.rs b/ast/src/input/input_value.rs index 5d6fba2a9e..daa4194dc9 100644 --- a/ast/src/input/input_value.rs +++ b/ast/src/input/input_value.rs @@ -114,7 +114,7 @@ impl InputValue { 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 array_dimensions = parse_array_dimensions(array_dimensions_type, &array_type.span)?; // Return an error if the outer array dimension does not equal the number of array elements. if array_dimensions[0] != inline.expressions.len() { @@ -146,7 +146,7 @@ impl InputValue { initializer: ArrayInitializerExpression, ) -> Result { let array_dimensions_type = ArrayDimensions::from(initializer.dimensions.clone()); - let array_dimensions = parse_array_dimensions(array_dimensions_type, array_type.span.clone())?; + let array_dimensions = parse_array_dimensions(array_dimensions_type, &array_type.span)?; if array_dimensions.len() > 1 { // The expression is an array initializer with tuple syntax @@ -169,7 +169,7 @@ impl InputValue { return Err(InputParserError::array_init_length( array_dimensions, initializer_dimensions, - initializer.span, + &initializer.span, )); } @@ -199,7 +199,7 @@ impl InputValue { 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 array_dimensions = parse_array_dimensions(array_dimensions_type, &array_type.span)?; let current_array_dimension = array_dimensions[0]; let current_initializer_dimension = initializer_dimensions[0]; @@ -209,7 +209,7 @@ impl InputValue { return Err(InputParserError::array_init_length( array_dimensions, initializer_dimensions, - initializer.span, + &initializer.span, )); } @@ -235,11 +235,7 @@ impl InputValue { let num_values = tuple.expressions.len(); if num_types != num_values { - return Err(InputParserError::tuple_length( - num_types, - num_values, - tuple_type.span.clone(), - )); + return Err(InputParserError::tuple_length(num_types, num_values, &tuple_type.span)); } let mut values = Vec::with_capacity(tuple_type.types_.len()); @@ -260,7 +256,7 @@ impl InputValue { /// 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> { +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()); @@ -271,7 +267,7 @@ fn parse_array_dimensions(array_dimensions_type: ArrayDimensions, span: Span) -> // 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())), + Err(_) => return Err(InputParserError::array_index(dimension_string, span)), }; // Collect dimension usize values. @@ -292,7 +288,7 @@ fn fetch_nested_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())?; + let mut current_dimension = parse_array_dimensions(array_dimensions_type, &array_type.span)?; array_dimensions.append(&mut current_dimension); diff --git a/ast/src/lib.rs b/ast/src/lib.rs index 51fd09e848..661cc3e3e1 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -19,9 +19,6 @@ //! 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::*; @@ -61,8 +58,6 @@ pub use self::types::*; mod node; pub use node::*; -use leo_grammar::Grammar; - /// The abstract syntax tree (AST) for a Leo program. /// /// The [`Ast`] type represents a Leo program as a series of recursive data types. @@ -75,11 +70,9 @@ pub struct Ast { } impl Ast { - /// Creates a new AST from a given program name and grammar tree. - pub fn new<'ast>(program_name: &str, grammar: &Grammar<'ast>) -> Result { - Ok(Self { - ast: Program::from(program_name, grammar.as_repr())?, - }) + /// Creates a new AST from a given program tree. + pub fn new(program: Program) -> Self { + Self { ast: program } } /// Returns a reference to the inner program AST representation. @@ -87,6 +80,10 @@ impl Ast { &self.ast } + pub fn into_repr(self) -> Program { + self.ast + } + /// Serializes the ast into a JSON string. pub fn to_json_string(&self) -> Result { serde_json::to_string_pretty(&self.ast) @@ -98,3 +95,9 @@ impl Ast { Ok(Self { ast }) } } + +impl AsRef for Ast { + fn as_ref(&self) -> &Program { + &self.ast + } +} diff --git a/ast/src/main.rs b/ast/src/main.rs deleted file mode 100644 index 02f627cc4a..0000000000 --- a/ast/src/main.rs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_ast::{Ast, AstError}; -use leo_grammar::Grammar; -use std::{env, fs, path::Path}; - -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)?; - - // Parses the Leo file and constructs a pest ast. - let ast = Grammar::new(&program_filepath, &program_string)?; - - // Parse the pest ast and constructs a ast. - let leo_ast = Ast::new("leo_tree", &ast)?; - - let serialized_leo_ast = Ast::to_json_string(&leo_ast)?; - - Ok(serialized_leo_ast) -} - -fn main() -> Result<(), AstError> { - // Parse the command-line arguments as strings. - let cli_arguments = env::args().collect::>(); - - // Check that the correct number of command-line arguments were passed in. - 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" - ); - return Ok(()); // Exit innocently - } - - // Construct the input filepath. - let input_filepath = Path::new(&cli_arguments[1]); - - // 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 { - true => format!( - "{}/{}.json", - cli_arguments[2], - input_filepath.file_stem().unwrap().to_str().unwrap() - ), - false => format!("./{}.json", input_filepath.file_stem().unwrap().to_str().unwrap()), - }; - - // 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 531a6316bb..41602aac30 100644 --- a/ast/src/program.rs +++ b/ast/src/program.rs @@ -17,17 +17,7 @@ //! A Leo program consists of import, circuit, and function definitions. //! Each defined type consists of ast statements and expressions. -use crate::{ - load_annotation, - Circuit, - DeprecatedError, - Function, - FunctionInput, - Identifier, - ImportStatement, - TestFunction, -}; -use leo_grammar::{definitions::Definition, files::File}; +use crate::{Circuit, Function, FunctionInput, Identifier, ImportStatement}; use indexmap::IndexMap; use serde::{Deserialize, Serialize}; @@ -41,7 +31,12 @@ pub struct Program { pub imports: Vec, pub circuits: IndexMap, pub functions: IndexMap, - pub tests: IndexMap, +} + +impl AsRef for Program { + fn as_ref(&self) -> &Program { + self + } } impl fmt::Display for Program { @@ -60,80 +55,10 @@ impl fmt::Display for Program { function.fmt(f)?; writeln!(f,)?; } - for (_, test) in self.tests.iter() { - write!(f, "test ")?; - test.function.fmt(f)?; - writeln!(f,)?; - } write!(f, "") } } -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>) -> Result { - let mut imports = vec![]; - let mut circuits = IndexMap::new(); - let mut functions = IndexMap::new(); - let mut tests = IndexMap::new(); - let mut expected_input = vec![]; - - program_ast - .definitions - .to_owned() - .into_iter() - // Use of Infallible to say we never expect an Some(Ok(...)) - .find_map::, _>(|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); - if function.identifier.name.eq(MAIN_FUNCTION_NAME) { - expected_input = function.input.clone(); - } - functions.insert(function.identifier.clone(), function); - None - } - Definition::Deprecated(deprecated) => { - Some(Err(DeprecatedError::from(deprecated))) - } - Definition::Annotated(annotated_definition) => { - let loaded_annotation = load_annotation( - annotated_definition, - &mut imports, - &mut circuits, - &mut functions, - &mut tests, - &mut expected_input, - ); - - match loaded_annotation { - Ok(_) => None, - Err(deprecated_err) => Some(Err(deprecated_err)) - } - } - }) - .transpose()?; - - Ok(Self { - name: program_name.to_string(), - expected_input, - imports, - circuits, - functions, - tests, - }) - } -} - impl Program { pub fn new(name: String) -> Self { Self { @@ -142,7 +67,6 @@ impl Program { imports: vec![], circuits: IndexMap::new(), functions: IndexMap::new(), - tests: IndexMap::new(), } } diff --git a/ast/src/statements/assign/assignee.rs b/ast/src/statements/assign/assignee.rs index e84cccf2a9..da73eb9d38 100644 --- a/ast/src/statements/assign/assignee.rs +++ b/ast/src/statements/assign/assignee.rs @@ -15,10 +15,6 @@ // along with the Leo library. If not, see . use crate::{Expression, Identifier, PositiveNumber, Span}; -use leo_grammar::{ - access::{ArrayAccess, AssigneeAccess as GrammarAssigneeAccess}, - common::{Assignee as GrammarAssignee, Range, RangeOrExpression}, -}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -31,25 +27,6 @@ pub enum AssigneeAccess { Member(Identifier), } -impl<'ast> From> for AssigneeAccess { - fn from(access: GrammarAssigneeAccess<'ast>) -> Self { - match access { - GrammarAssigneeAccess::Array(ArrayAccess { - expression: RangeOrExpression::Range(Range { from, to, .. }), - .. - }) => AssigneeAccess::ArrayRange(from.map(Expression::from), to.map(Expression::from)), - GrammarAssigneeAccess::Array(ArrayAccess { - expression: RangeOrExpression::Expression(index), - .. - }) => AssigneeAccess::ArrayIndex(Expression::from(index)), - GrammarAssigneeAccess::Tuple(tuple) => { - AssigneeAccess::Tuple(PositiveNumber::from(tuple.number), Span::from(tuple.span)) - } - GrammarAssigneeAccess::Member(member) => AssigneeAccess::Member(Identifier::from(member.identifier)), - } - } -} - /// Definition assignee: v, arr[0..2], Point p.x #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Assignee { @@ -65,20 +42,6 @@ impl Assignee { } } -impl<'ast> From> for Assignee { - fn from(assignee: GrammarAssignee<'ast>) -> Self { - Assignee { - identifier: Identifier::from(assignee.name), - accesses: assignee - .accesses - .into_iter() - .map(AssigneeAccess::from) - .collect::>(), - span: Span::from(assignee.span), - } - } -} - impl fmt::Display for Assignee { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.identifier)?; diff --git a/ast/src/statements/assign/mod.rs b/ast/src/statements/assign/mod.rs index 947472d14c..ae88fda809 100644 --- a/ast/src/statements/assign/mod.rs +++ b/ast/src/statements/assign/mod.rs @@ -16,8 +16,6 @@ use crate::{Expression, Node, Span}; -pub use leo_grammar::operations::AssignOperation as GrammarAssignOperation; -use leo_grammar::statements::AssignStatement as GrammarAssignStatement; use serde::{Deserialize, Serialize}; use std::fmt; @@ -32,6 +30,15 @@ pub enum AssignOperation { Mul, Div, Pow, + Or, + And, + BitOr, + BitAnd, + BitXor, + Shr, + ShrSigned, + Shl, + Mod, } impl AsRef for AssignOperation { @@ -43,6 +50,15 @@ impl AsRef for AssignOperation { AssignOperation::Mul => "*=", AssignOperation::Div => "/=", AssignOperation::Pow => "**=", + AssignOperation::Or => "||=", + AssignOperation::And => "&&=", + AssignOperation::BitOr => "|=", + AssignOperation::BitAnd => "&=", + AssignOperation::BitXor => "^=", + AssignOperation::Shr => ">>=", + AssignOperation::ShrSigned => ">>>=", + AssignOperation::Shl => "<<=", + AssignOperation::Mod => "%=", } } } @@ -61,24 +77,6 @@ impl fmt::Display for AssignStatement { } } -impl<'ast> From> for AssignStatement { - fn from(statement: GrammarAssignStatement<'ast>) -> Self { - AssignStatement { - operation: match statement.assign { - GrammarAssignOperation::Assign(_) => AssignOperation::Assign, - GrammarAssignOperation::AddAssign(_) => AssignOperation::Add, - GrammarAssignOperation::SubAssign(_) => AssignOperation::Sub, - GrammarAssignOperation::MulAssign(_) => AssignOperation::Mul, - GrammarAssignOperation::DivAssign(_) => AssignOperation::Div, - GrammarAssignOperation::PowAssign(_) => AssignOperation::Pow, - }, - assignee: Assignee::from(statement.assignee), - value: Expression::from(statement.expression), - span: Span::from(statement.span), - } - } -} - impl Node for AssignStatement { fn span(&self) -> &Span { &self.span diff --git a/ast/src/statements/block.rs b/ast/src/statements/block.rs index d6cb72f26f..71270e0d19 100644 --- a/ast/src/statements/block.rs +++ b/ast/src/statements/block.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{Node, Span, Statement}; -use leo_grammar::statements::Block as GrammarBlock; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,15 +25,6 @@ pub struct Block { pub span: Span, } -impl<'ast> From> for Block { - fn from(block: GrammarBlock<'ast>) -> Self { - Block { - statements: block.statements.into_iter().map(Statement::from).collect(), - span: Span::from(block.span), - } - } -} - impl fmt::Display for Block { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "{{")?; diff --git a/ast/src/statements/conditional.rs b/ast/src/statements/conditional.rs index cf836ef3ed..e2b11d98af 100644 --- a/ast/src/statements/conditional.rs +++ b/ast/src/statements/conditional.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{Block, Expression, Node, Span, Statement}; -use leo_grammar::statements::{ConditionalNestedOrEndStatement, ConditionalStatement as GrammarConditionalStatement}; use serde::{Deserialize, Serialize}; use std::fmt; @@ -28,25 +27,6 @@ pub struct ConditionalStatement { pub span: Span, } -impl<'ast> From> for ConditionalStatement { - fn from(statement: GrammarConditionalStatement<'ast>) -> Self { - ConditionalStatement { - condition: Expression::from(statement.condition), - block: Block::from(statement.block), - next: statement - .next - .map(|nested_statement| match nested_statement { - ConditionalNestedOrEndStatement::Nested(conditional_statement) => { - Statement::Conditional(ConditionalStatement::from(*conditional_statement)) - } - ConditionalNestedOrEndStatement::End(block) => Statement::Block(Block::from(block)), - }) - .map(Box::new), - span: Span::from(statement.span), - } - } -} - impl fmt::Display for ConditionalStatement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "if ({}) {}", self.condition, self.block)?; diff --git a/ast/src/statements/console/console_function.rs b/ast/src/statements/console/console_function.rs index 7e9f9892ca..16115878ce 100644 --- a/ast/src/statements/console/console_function.rs +++ b/ast/src/statements/console/console_function.rs @@ -14,19 +14,12 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Expression, FormattedString}; -use leo_grammar::console::{ - ConsoleAssert as GrammarConsoleAssert, - ConsoleDebug as GrammarConsoleDebug, - ConsoleError as GrammarConsoleError, - ConsoleFunction as GrammarConsoleFunction, - ConsoleLog as GrammarConsoleLog, -}; +use crate::{Expression, FormattedString, Node, Span}; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] pub enum ConsoleFunction { Assert(Expression), Debug(FormattedString), @@ -34,41 +27,6 @@ pub enum ConsoleFunction { Log(FormattedString), } -impl<'ast> From> for ConsoleFunction { - fn from(console_function: GrammarConsoleFunction<'ast>) -> Self { - match console_function { - 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: GrammarConsoleAssert<'ast>) -> Self { - ConsoleFunction::Assert(Expression::from(assert.expression)) - } -} - -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: GrammarConsoleError<'ast>) -> Self { - ConsoleFunction::Error(FormattedString::from(error.string)) - } -} - -impl<'ast> From> for ConsoleFunction { - fn from(log: GrammarConsoleLog<'ast>) -> Self { - ConsoleFunction::Log(FormattedString::from(log.string)) - } -} - impl fmt::Display for ConsoleFunction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { @@ -79,3 +37,23 @@ impl fmt::Display for ConsoleFunction { } } } + +impl Node for ConsoleFunction { + fn span(&self) -> &Span { + match self { + ConsoleFunction::Assert(assert) => assert.span(), + ConsoleFunction::Debug(formatted) | ConsoleFunction::Error(formatted) | ConsoleFunction::Log(formatted) => { + &formatted.span + } + } + } + + fn set_span(&mut self, span: Span) { + match self { + ConsoleFunction::Assert(assert) => assert.set_span(span), + ConsoleFunction::Debug(formatted) | ConsoleFunction::Error(formatted) | ConsoleFunction::Log(formatted) => { + formatted.set_span(span) + } + } + } +} diff --git a/ast/src/statements/console/console_statement.rs b/ast/src/statements/console/console_statement.rs index ad837f42f5..de916205fa 100644 --- a/ast/src/statements/console/console_statement.rs +++ b/ast/src/statements/console/console_statement.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{ConsoleFunction, Node, Span}; -use leo_grammar::console::ConsoleFunctionCall as GrammarConsoleFunctionCall; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,15 +25,6 @@ pub struct ConsoleStatement { pub span: Span, } -impl<'ast> From> for ConsoleStatement { - fn from(console: GrammarConsoleFunctionCall<'ast>) -> Self { - ConsoleStatement { - function: ConsoleFunction::from(console.function), - span: Span::from(console.span), - } - } -} - impl fmt::Display for ConsoleStatement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "console.{};", self.function) diff --git a/ast/src/statements/console/formatted_container.rs b/ast/src/statements/console/formatted_container.rs index 4634aa4c4a..cca1a17220 100644 --- a/ast/src/statements/console/formatted_container.rs +++ b/ast/src/statements/console/formatted_container.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{Node, Span}; -use leo_grammar::console::FormattedContainer as GrammarFormattedContainer; use serde::{Deserialize, Serialize}; use std::fmt; @@ -25,14 +24,6 @@ pub struct FormattedContainer { pub span: Span, } -impl<'ast> From> for FormattedContainer { - fn from(container: GrammarFormattedContainer<'ast>) -> Self { - Self { - span: Span::from(container.span), - } - } -} - impl fmt::Display for FormattedContainer { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{{}}") diff --git a/ast/src/statements/console/formatted_string.rs b/ast/src/statements/console/formatted_string.rs index f96baa1fe1..e5e653e745 100644 --- a/ast/src/statements/console/formatted_string.rs +++ b/ast/src/statements/console/formatted_string.rs @@ -14,39 +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, FormattedContainer, Node, Span}; -use leo_grammar::console::FormattedString as GrammarFormattedString; +use crate::{Expression, Node, Span}; use serde::{Deserialize, Serialize}; use std::fmt; +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub enum FormattedStringPart { + Const(String), + Container, +} + #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] pub struct FormattedString { - pub string: String, - pub containers: Vec, + pub parts: Vec, pub parameters: Vec, pub span: Span, } -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(); - let parameters = formatted.parameters.into_iter().map(Expression::from).collect(); - - Self { - string, - containers, - parameters, - span, - } - } -} - impl fmt::Display for FormattedString { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.string) + write!( + f, + "{}", + self.parts + .iter() + .map(|x| match x { + FormattedStringPart::Const(x) => x, + FormattedStringPart::Container => "{}", + }) + .collect::>() + .join("") + ) } } diff --git a/ast/src/statements/definition/declare.rs b/ast/src/statements/definition/declare.rs index de00d5f210..1c70e13fdc 100644 --- a/ast/src/statements/definition/declare.rs +++ b/ast/src/statements/definition/declare.rs @@ -14,8 +14,6 @@ // 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 GrammarDeclare; - use serde::{Deserialize, Serialize}; use std::fmt; @@ -25,15 +23,6 @@ pub enum Declare { Let, } -impl<'ast> From for Declare { - fn from(declare: GrammarDeclare) -> Self { - match declare { - GrammarDeclare::Const(_) => Declare::Const, - GrammarDeclare::Let(_) => Declare::Let, - } - } -} - impl fmt::Display for Declare { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { diff --git a/ast/src/statements/definition/mod.rs b/ast/src/statements/definition/mod.rs index 78ad5ea933..15d2893b2d 100644 --- a/ast/src/statements/definition/mod.rs +++ b/ast/src/statements/definition/mod.rs @@ -24,7 +24,6 @@ pub use variable_name::*; mod declare; pub use declare::*; -use leo_grammar::statements::DefinitionStatement as GrammarDefinitionStatement; #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] pub struct DefinitionStatement { @@ -60,27 +59,6 @@ impl fmt::Display for DefinitionStatement { } } -impl<'ast> From> for DefinitionStatement { - fn from(statement: GrammarDefinitionStatement<'ast>) -> Self { - let variable_names = statement - .variables - .names - .into_iter() - .map(VariableName::from) - .collect::>(); - - let type_ = statement.variables.type_.map(Type::from); - - DefinitionStatement { - declaration_type: Declare::from(statement.declare), - variable_names, - type_, - value: Expression::from(statement.expression), - span: Span::from(statement.span), - } - } -} - impl Node for DefinitionStatement { fn span(&self) -> &Span { &self.span diff --git a/ast/src/statements/definition/variable_name.rs b/ast/src/statements/definition/variable_name.rs index 7384b8ee1d..c0fc5b09d6 100644 --- a/ast/src/statements/definition/variable_name.rs +++ b/ast/src/statements/definition/variable_name.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{Identifier, Node, Span}; -use leo_grammar::common::VariableName as GrammarVariableName; use serde::{Deserialize, Serialize}; use std::fmt; @@ -27,16 +26,6 @@ pub struct VariableName { pub span: Span, } -impl<'ast> From> for VariableName { - fn from(name: GrammarVariableName<'ast>) -> Self { - Self { - mutable: name.mutable.is_some(), - identifier: Identifier::from(name.identifier), - span: Span::from(name.span), - } - } -} - impl fmt::Display for VariableName { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.mutable { diff --git a/ast/src/statements/expression.rs b/ast/src/statements/expression.rs index f9ff66313c..9b86ea41a2 100644 --- a/ast/src/statements/expression.rs +++ b/ast/src/statements/expression.rs @@ -16,7 +16,6 @@ use crate::{Expression, Node, Span}; -use leo_grammar::statements::ExpressionStatement as GrammarExpressionStatement; use serde::{Deserialize, Serialize}; use std::fmt; @@ -32,16 +31,6 @@ impl fmt::Display for ExpressionStatement { } } -impl<'ast> From> for ExpressionStatement { - fn from(statement: GrammarExpressionStatement<'ast>) -> Self { - // why do we have this span-setting logic? - let span = Span::from(statement.span); - let mut expression = Expression::from(statement.expression); - expression.set_span(span.clone()); - ExpressionStatement { expression, span } - } -} - impl Node for ExpressionStatement { fn span(&self) -> &Span { &self.span diff --git a/ast/src/statements/iteration.rs b/ast/src/statements/iteration.rs index 70126ff8ad..a935f959f3 100644 --- a/ast/src/statements/iteration.rs +++ b/ast/src/statements/iteration.rs @@ -16,7 +16,6 @@ use crate::{Block, Expression, Identifier, Node, Span}; -use leo_grammar::statements::ForStatement; use serde::{Deserialize, Serialize}; use std::fmt; @@ -39,18 +38,6 @@ impl fmt::Display for IterationStatement { } } -impl<'ast> From> for IterationStatement { - fn from(statement: ForStatement<'ast>) -> Self { - IterationStatement { - variable: Identifier::from(statement.index), - start: Expression::from(statement.start), - stop: Expression::from(statement.stop), - block: Block::from(statement.block), - span: Span::from(statement.span), - } - } -} - impl Node for IterationStatement { fn span(&self) -> &Span { &self.span diff --git a/ast/src/statements/return_statement.rs b/ast/src/statements/return_statement.rs index e1279b09c2..4e2f813466 100644 --- a/ast/src/statements/return_statement.rs +++ b/ast/src/statements/return_statement.rs @@ -16,7 +16,6 @@ use crate::{Expression, Node, Span}; -use leo_grammar::statements::ReturnStatement as GrammarReturnStatement; use serde::{Deserialize, Serialize}; use std::fmt; @@ -32,15 +31,6 @@ impl fmt::Display for ReturnStatement { } } -impl<'ast> From> for ReturnStatement { - fn from(statement: GrammarReturnStatement<'ast>) -> Self { - ReturnStatement { - expression: Expression::from(statement.expression), - span: Span::from(statement.span), - } - } -} - impl Node for ReturnStatement { fn span(&self) -> &Span { &self.span diff --git a/ast/src/statements/statement.rs b/ast/src/statements/statement.rs index 31067093e7..f60c019edb 100644 --- a/ast/src/statements/statement.rs +++ b/ast/src/statements/statement.rs @@ -16,8 +16,6 @@ use crate::{ConditionalStatement, Node, Span}; -use leo_grammar::statements::Statement as GrammarStatement; - use super::*; use serde::{Deserialize, Serialize}; use std::fmt; @@ -35,21 +33,6 @@ pub enum Statement { Block(Block), } -impl<'ast> From> for Statement { - fn from(statement: GrammarStatement<'ast>) -> Self { - match statement { - GrammarStatement::Return(statement) => Statement::Return(ReturnStatement::from(statement)), - GrammarStatement::Definition(statement) => Statement::Definition(DefinitionStatement::from(statement)), - GrammarStatement::Assign(statement) => Statement::Assign(AssignStatement::from(statement)), - GrammarStatement::Conditional(statement) => Statement::Conditional(ConditionalStatement::from(statement)), - GrammarStatement::Iteration(statement) => Statement::Iteration(IterationStatement::from(statement)), - GrammarStatement::Console(statement) => Statement::Console(ConsoleStatement::from(statement)), - GrammarStatement::Expression(statement) => Statement::Expression(ExpressionStatement::from(statement)), - GrammarStatement::Block(statement) => Statement::Block(Block::from(statement)), - } - } -} - impl fmt::Display for Statement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { diff --git a/ast/src/types/integer_type.rs b/ast/src/types/integer_type.rs index 1ced1e76f7..579ca2c6c0 100644 --- a/ast/src/types/integer_type.rs +++ b/ast/src/types/integer_type.rs @@ -14,11 +14,6 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_grammar::types::{ - IntegerType as GrammarIntegerType, - SignedIntegerType as GrammarSignedIntegerType, - UnsignedIntegerType as GrammarUnsignedIntegerType, -}; use leo_input::types::{ IntegerType as InputIntegerType, SignedIntegerType as InputSignedIntegerType, @@ -44,36 +39,10 @@ pub enum IntegerType { I128, } -impl From for IntegerType { - fn from(integer_type: GrammarIntegerType) -> Self { - match integer_type { - GrammarIntegerType::Signed(signed) => Self::from(signed), - GrammarIntegerType::Unsigned(unsigned) => Self::from(unsigned), - } - } -} - -impl From for IntegerType { - fn from(integer_type: GrammarUnsignedIntegerType) -> Self { - match integer_type { - 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: GrammarSignedIntegerType) -> Self { - match integer_type { - 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 IntegerType { + pub fn is_signed(&self) -> bool { + use IntegerType::*; + matches!(self, I8 | I16 | I32 | I64 | I128) } } diff --git a/ast/src/types/type_.rs b/ast/src/types/type_.rs index 1d20699c31..f919ce8df2 100644 --- a/ast/src/types/type_.rs +++ b/ast/src/types/type_.rs @@ -15,7 +15,6 @@ // along with the Leo library. If not, see . use crate::{ArrayDimensions, Identifier, IntegerType}; -use leo_grammar::types::{ArrayType, CircuitType, DataType, TupleType, Type as GrammarType}; use leo_input::types::{ ArrayType as InputArrayType, DataType as InputDataType, @@ -102,55 +101,6 @@ impl Type { } } -/// pest ast -> Explicit Type for defining circuit members and function params - -impl From for Type { - fn from(data_type: DataType) -> Self { - match data_type { - DataType::Address(_type) => Type::Address, - DataType::Boolean(_type) => Type::Boolean, - DataType::Field(_type) => Type::Field, - DataType::Group(_type) => Type::Group, - DataType::Integer(_type) => Type::IntegerType(IntegerType::from(_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 = ArrayDimensions::from(array_type.dimensions); - - Type::Array(element_type, dimensions) - } -} - -impl<'ast> From> for Type { - fn from(tuple_type: TupleType<'ast>) -> Self { - let types = tuple_type.types.into_iter().map(Type::from).collect(); - - Type::Tuple(types) - } -} - -impl<'ast> From> for Type { - fn from(circuit_type: CircuitType<'ast>) -> Self { - Type::Circuit(Identifier::from(circuit_type.identifier)) - } -} - -impl<'ast> From> for Type { - fn from(type_: GrammarType<'ast>) -> Self { - match type_ { - 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, - } - } -} - /// input pest ast -> Explicit Type impl From for Type { diff --git a/ast/tests/serialization/expected_leo_ast.json b/ast/tests/serialization/expected_leo_ast.json deleted file mode 100644 index 6227b135e6..0000000000 --- a/ast/tests/serialization/expected_leo_ast.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "leo_tree", - "expected_input": [], - "imports": [], - "circuits": {}, - "functions": { - "{\"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": [], - "output": null, - "block" : { - "statements": [ - { - "Return": { - "expression": { - "Binary": { - "left": { - "Value": { - "Implicit": [ - "1", - { - "text": " return 1 + 1", - "line": 2, - "start": 12, - "end": 13 - } - ] - } - }, - "op": "Add", - "right": { - "Value": { - "Implicit": [ - "1", - { - "text": " return 1 + 1", - "line": 2, - "start": 16, - "end": 17 - } - ] - } - }, - "span": { - "text": " return 1 + 1", - "line": 2, - "start": 12, - "end": 17 - } - } - }, - "span" : { - "text": " return 1 + 1", - "line": 2, - "start": 5, - "end": 17 - } - } - } - ], - "span" : { - "text": " return 1 + 1", - "line": 2, - "start": 5, - "end": 17 - } - }, - "span": { - "text": " function main() {", - "line": 1, - "start": 1, - "end": 1 - } - } - }, - "tests": {} -} \ No newline at end of file diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 9f44f8b213..dab18d38a9 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -25,10 +25,6 @@ version = "1.2.3" path = "../gadgets" version = "1.2.3" -[dependencies.leo-grammar] -path = "../grammar" -version = "1.2.3" - [dependencies.leo-imports] path = "../imports" version = "1.2.3" @@ -49,6 +45,10 @@ version = "1.2.3" path = "../asg" version = "1.2.3" +[dependencies.leo-parser] +path = "../parser" +version = "1.2.3" + [dependencies.snarkvm-curves] version = "0.2.0" default-features = false @@ -116,4 +116,4 @@ default-features = false [features] default = [ ] -ci_skip = [ "leo-grammar/ci_skip", "leo-ast/ci_skip" ] +ci_skip = [ "leo-ast/ci_skip" ] diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 9410ca7100..c5f2a3b880 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -23,11 +23,13 @@ use crate::{ OutputBytes, OutputFile, }; +use indexmap::IndexMap; use leo_asg::Asg; -use leo_ast::{Ast, Input, MainInput, Program}; -use leo_grammar::Grammar; +pub use leo_asg::{new_context, AsgContext as Context, AsgContext}; +use leo_ast::{Input, LeoError, MainInput, Program}; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; +use leo_parser::parse_ast; use leo_state::verify_local_data_commitment; use snarkvm_dpc::{base_dpc::instantiated::Components, SystemParameters}; @@ -36,13 +38,13 @@ use snarkvm_r1cs::{ConstraintSynthesizer, ConstraintSystem, SynthesisError}; use sha2::{Digest, Sha256}; use std::{ + cell::RefCell, fs, marker::PhantomData, path::{Path, PathBuf}, + rc::Rc, }; -pub use leo_asg::{new_context, AsgContext as Context, AsgContext}; - thread_local! { static THREAD_GLOBAL_CONTEXT: AsgContext<'static> = { let leaked = Box::leak(Box::new(leo_asg::new_alloc_context())); @@ -50,7 +52,7 @@ thread_local! { } } -/// Conventience function to return a leaked thread-local global context. Should only be used for transient programs (like cli). +/// Convenience function to return a leaked thread-local global context. Should only be used for transient programs (like cli). pub fn thread_leaked_context() -> AsgContext<'static> { THREAD_GLOBAL_CONTEXT.with(|f| *f) } @@ -65,6 +67,7 @@ pub struct Compiler<'a, F: PrimeField, G: GroupType> { program_input: Input, context: AsgContext<'a>, asg: Option>, + file_contents: RefCell>>>, _engine: PhantomData, _group: PhantomData, } @@ -87,6 +90,7 @@ impl<'a, F: PrimeField, G: GroupType> Compiler<'a, F, G> { program_input: Input::new(), asg: None, context, + file_contents: RefCell::new(IndexMap::new()), _engine: PhantomData, _group: PhantomData, } @@ -153,23 +157,35 @@ impl<'a, F: PrimeField, G: GroupType> Compiler<'a, F, G> { state_path: &Path, ) -> Result<(), CompilerError> { let input_syntax_tree = LeoInputParser::parse_file(&input_string).map_err(|mut e| { - e.set_path(input_path); + e.set_path( + input_path.to_str().unwrap_or_default(), + &input_string.lines().map(|x| x.to_string()).collect::>()[..], + ); e })?; let state_syntax_tree = LeoInputParser::parse_file(&state_string).map_err(|mut e| { - e.set_path(state_path); + e.set_path( + state_path.to_str().unwrap_or_default(), + &state_string.lines().map(|x| x.to_string()).collect::>()[..], + ); e })?; self.program_input.parse_input(input_syntax_tree).map_err(|mut e| { - e.set_path(input_path); + e.set_path( + input_path.to_str().unwrap_or_default(), + &input_string.lines().map(|x| x.to_string()).collect::>()[..], + ); e })?; self.program_input.parse_state(state_syntax_tree).map_err(|mut e| { - e.set_path(state_path); + e.set_path( + state_path.to_str().unwrap_or_default(), + &state_string.lines().map(|x| x.to_string()).collect::>()[..], + ); e })?; @@ -177,6 +193,20 @@ impl<'a, F: PrimeField, G: GroupType> Compiler<'a, F, G> { Ok(()) } + fn resolve_content(&self, path: &str) -> Result>, CompilerError> { + let mut file_contents = self.file_contents.borrow_mut(); + if file_contents.contains_key(path) { + // using this pattern because of mutable reference in branch below + Ok(file_contents.get(path).unwrap().clone()) + } else { + let content = fs::read_to_string(path).map_err(|e| CompilerError::FileReadError(PathBuf::from(path), e))?; + + let content = Rc::new(content.lines().map(|x| x.to_string()).collect::>()); + file_contents.insert(path.to_string(), content); + Ok(file_contents.get(path).unwrap().clone()) + } + } + /// /// Parses and stores the main program file, constructs a syntax tree, and generates a program. /// @@ -184,9 +214,10 @@ impl<'a, F: PrimeField, G: GroupType> Compiler<'a, F, G> { /// pub fn parse_program(&mut self) -> Result<(), CompilerError> { // Load the program file. - let program_string = Grammar::load_file(&self.main_file_path)?; + let content = fs::read_to_string(&self.main_file_path) + .map_err(|e| CompilerError::FileReadError(self.main_file_path.clone(), e))?; - self.parse_program_from_string(&program_string) + self.parse_program_from_string(&content) } /// @@ -194,23 +225,23 @@ impl<'a, F: PrimeField, G: GroupType> Compiler<'a, F, G> { /// file path. /// pub fn parse_program_from_string(&mut self, program_string: &str) -> Result<(), CompilerError> { - // Use the parser to construct the pest abstract syntax tree (ast). - let grammar = Grammar::new(&self.main_file_path, &program_string).map_err(|mut e| { - e.set_path(&self.main_file_path); + // Use the parser to construct the abstract syntax tree (ast). + let lines = program_string.lines().map(|x| x.to_string()).collect(); + self.file_contents.borrow_mut().insert( + self.main_file_path.to_str().map(|x| x.to_string()).unwrap_or_default(), + Rc::new(lines), + ); - e - })?; - - // Construct the AST from the grammar. - let core_ast = Ast::new(&self.program_name, &grammar)?; + let ast = parse_ast(self.main_file_path.to_str().unwrap_or_default(), program_string)?; // Store the main program file. - self.program = core_ast.as_repr().clone(); + self.program = ast.into_repr(); + self.program.name = self.program_name.clone(); tracing::debug!("Program parsing complete\n{:#?}", self.program); // Create a new symbol table from the program, imported_programs, and program_input. - let asg = Asg::new(self.context, &core_ast, &mut leo_imports::ImportParser::default())?; + let asg = Asg::new(self.context, &self.program, &mut leo_imports::ImportParser::default())?; tracing::debug!("ASG generation complete"); @@ -225,7 +256,13 @@ impl<'a, F: PrimeField, G: GroupType> Compiler<'a, F, G> { /// pub fn compile_constraints>(&self, cs: &mut CS) -> Result { generate_constraints::(cs, &self.asg.as_ref().unwrap(), &self.program_input).map_err(|mut error| { - error.set_path(&self.main_file_path); + if let Some(path) = error.get_path().map(|x| x.to_string()) { + let content = match self.resolve_content(&path) { + Err(e) => return e, + Ok(x) => x, + }; + error.set_path(&path, &content[..]); + } error }) } @@ -248,7 +285,7 @@ impl<'a, F: PrimeField, G: GroupType> Compiler<'a, F, G> { pub fn checksum(&self) -> Result { // Read in the main file as string let unparsed_file = fs::read_to_string(&self.main_file_path) - .map_err(|_| CompilerError::FileReadError(self.main_file_path.clone()))?; + .map_err(|e| CompilerError::FileReadError(self.main_file_path.clone(), e))?; // Hash the file contents let mut hasher = Sha256::new(); diff --git a/compiler/src/console/assert.rs b/compiler/src/console/assert.rs index cab7f1cf11..d10658bc2a 100644 --- a/compiler/src/console/assert.rs +++ b/compiler/src/console/assert.rs @@ -50,16 +50,13 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { let result_option = match assert_expression { ConstrainedValue::Boolean(boolean) => boolean.get_value(), _ => { - return Err(ConsoleError::assertion_must_be_boolean( - span.text.clone(), - span.to_owned(), - )); + return Err(ConsoleError::assertion_must_be_boolean(span)); } }; - let result_bool = result_option.ok_or_else(|| ConsoleError::assertion_depends_on_input(span.to_owned()))?; + let result_bool = result_option.ok_or_else(|| ConsoleError::assertion_depends_on_input(span))?; if !result_bool { - return Err(ConsoleError::assertion_failed(span.text.clone(), span.to_owned())); + return Err(ConsoleError::assertion_failed(span)); } Ok(()) diff --git a/compiler/src/console/format.rs b/compiler/src/console/format.rs index 2a20f389ac..507770543d 100644 --- a/compiler/src/console/format.rs +++ b/compiler/src/console/format.rs @@ -18,7 +18,7 @@ use crate::{errors::ConsoleError, program::ConstrainedProgram, GroupType}; use leo_asg::FormattedString; - +use leo_ast::FormattedStringPart; use snarkvm_fields::PrimeField; use snarkvm_r1cs::ConstraintSystem; @@ -29,30 +29,33 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { formatted: &FormattedString<'a>, ) -> Result { // Check that containers and parameters match - if formatted.containers.len() != formatted.parameters.len() { + let container_count = formatted + .parts + .iter() + .filter(|x| matches!(x, FormattedStringPart::Container)) + .count(); + if container_count != formatted.parameters.len() { return Err(ConsoleError::length( - formatted.containers.len(), + container_count, formatted.parameters.len(), - formatted.span.clone(), + &formatted.span, )); } - // Trim starting double quote `"` - let mut string = formatted.string.as_str(); - string = string.trim_start_matches('\"'); - - // Trim everything after the ending double quote `"` - let string = string.split('\"').next().unwrap(); - - // Insert the parameter for each container `{}` - let mut result = string.to_string(); - + let mut executed_containers = Vec::with_capacity(formatted.parameters.len()); for parameter in formatted.parameters.iter() { - let parameter_value = self.enforce_expression(cs, parameter.get())?; - - result = result.replacen("{}", ¶meter_value.to_string(), 1); + executed_containers.push(self.enforce_expression(cs, parameter.get())?.to_string()); } - Ok(result) + let mut out = vec![]; + let mut parameters = executed_containers.iter(); + for part in formatted.parts.iter() { + match part { + FormattedStringPart::Const(c) => out.push(&**c), + FormattedStringPart::Container => out.push(&**parameters.next().unwrap()), + } + } + + Ok(out.join("")) } } diff --git a/compiler/src/constraints/constraints.rs b/compiler/src/constraints/constraints.rs index a1d574cfba..7ecb34b21f 100644 --- a/compiler/src/constraints/constraints.rs +++ b/compiler/src/constraints/constraints.rs @@ -18,7 +18,7 @@ use crate::{errors::CompilerError, ConstrainedProgram, GroupType, OutputBytes, OutputFile}; use leo_asg::Asg; -use leo_ast::Input; +use leo_ast::{Input, LeoError}; use leo_input::LeoInputParser; use leo_package::inputs::InputPairs; @@ -61,22 +61,33 @@ pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType>( // Get default input let default = input.pairs.get(&program_name); - let tests = &program.test_functions; + let tests = program + .functions + .iter() + .filter(|(_name, func)| func.is_test()) + .collect::>(); tracing::info!("Running {} tests", tests.len()); // Count passed and failed tests let mut passed = 0; let mut failed = 0; - for (test_name, (function, input_file)) in tests.into_iter() { + for (test_name, function) in tests.into_iter() { let cs = &mut TestConstraintSystem::::new(); let full_test_name = format!("{}::{}", program_name.clone(), test_name); let mut output_file_name = program_name.clone(); + let input_file = function + .annotations + .iter() + .find(|x| x.name.name == "test") + .unwrap() + .arguments + .get(0); // get input file name from annotation or use test_name let input_pair = match input_file { Some(file_id) => { - let file_name = file_id.name.clone(); + let file_name = file_id.clone(); output_file_name = file_name.clone(); @@ -127,7 +138,7 @@ pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType>( (false, _) => { // Set file location of error let mut error = result.unwrap_err(); - error.set_path(main_file_path); + error.set_path(main_file_path.to_str().unwrap_or_default(), &[]); tracing::error!("{} failed due to error\n\n{}\n", full_test_name, error); diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index c8e7b496a9..23a99a96f2 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -16,19 +16,19 @@ use crate::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError}; use leo_asg::AsgConvertError; -use leo_ast::AstError; -use leo_grammar::ParserError; +use leo_ast::LeoError; use leo_imports::ImportParserError; use leo_input::InputParserError; +use leo_parser::SyntaxError; use leo_state::LocalDataVerificationError; use bincode::Error as SerdeError; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; #[derive(Debug, Error)] pub enum CompilerError { #[error("{}", _0)] - AstError(#[from] AstError), + SyntaxError(#[from] SyntaxError), #[error("{}", _0)] ImportError(#[from] ImportError), @@ -45,8 +45,8 @@ pub enum CompilerError { #[error("{}", _0)] FunctionError(#[from] FunctionError), - #[error("Cannot read from the provided file path - {:?}", _0)] - FileReadError(PathBuf), + #[error("Cannot read from the provided file path '{:?}': {}", _0, _1)] + FileReadError(PathBuf, std::io::Error), #[error("{}", _0)] LocalDataVerificationError(#[from] LocalDataVerificationError), @@ -66,9 +66,6 @@ pub enum CompilerError { #[error("{}", _0)] OutputStringError(#[from] OutputBytesError), - #[error("{}", _0)] - ParserError(#[from] ParserError), - #[error("{}", _0)] SerdeError(#[from] SerdeError), @@ -76,12 +73,29 @@ pub enum CompilerError { AsgConvertError(#[from] AsgConvertError), } -impl CompilerError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for CompilerError { + fn get_path(&self) -> Option<&str> { match self { - CompilerError::InputParserError(error) => error.set_path(path), - CompilerError::FunctionError(error) => error.set_path(path), - CompilerError::OutputStringError(error) => error.set_path(path), + CompilerError::SyntaxError(error) => error.get_path(), + CompilerError::ImportError(error) => error.get_path(), + CompilerError::ImportParserError(error) => error.get_path(), + CompilerError::InputParserError(error) => error.get_path(), + CompilerError::FunctionError(error) => error.get_path(), + CompilerError::OutputStringError(error) => error.get_path(), + CompilerError::AsgConvertError(error) => error.get_path(), + _ => None, + } + } + + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + CompilerError::SyntaxError(error) => error.set_path(path, contents), + CompilerError::ImportError(error) => error.set_path(path, contents), + CompilerError::ImportParserError(error) => error.set_path(path, contents), + CompilerError::InputParserError(error) => error.set_path(path, contents), + CompilerError::FunctionError(error) => error.set_path(path, contents), + CompilerError::OutputStringError(error) => error.set_path(path, contents), + CompilerError::AsgConvertError(error) => error.set_path(path, contents), _ => {} } } diff --git a/compiler/src/errors/console.rs b/compiler/src/errors/console.rs index c68a0035dd..b6862c12a8 100644 --- a/compiler/src/errors/console.rs +++ b/compiler/src/errors/console.rs @@ -15,9 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::ExpressionError; -use leo_ast::{Error as FormattedError, Span}; - -use std::path::Path; +use leo_ast::{FormattedError, LeoError, Span}; #[derive(Debug, Error)] pub enum ConsoleError { @@ -28,19 +26,28 @@ pub enum ConsoleError { Expression(#[from] ExpressionError), } -impl ConsoleError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for ConsoleError { + fn get_path(&self) -> Option<&str> { match self { - ConsoleError::Expression(error) => error.set_path(path), - ConsoleError::Error(error) => error.set_path(path), + ConsoleError::Error(error) => error.get_path(), + ConsoleError::Expression(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + ConsoleError::Error(error) => error.set_path(path, contents), + ConsoleError::Expression(error) => error.set_path(path, contents), + } + } +} + +impl ConsoleError { + fn new_from_span(message: String, span: &Span) -> Self { ConsoleError::Error(FormattedError::new_from_span(message, span)) } - pub fn length(containers: usize, parameters: usize, span: Span) -> Self { + pub fn length(containers: usize, parameters: usize, span: &Span) -> Self { let message = format!( "Formatter given {} containers and found {} parameters", containers, parameters @@ -49,21 +56,21 @@ impl ConsoleError { Self::new_from_span(message, span) } - pub fn assertion_depends_on_input(span: Span) -> Self { + pub fn assertion_depends_on_input(span: &Span) -> Self { let message = "console.assert() failed to evaluate. This error is caused by empty input file values".to_string(); Self::new_from_span(message, span) } - pub fn assertion_failed(expression: String, span: Span) -> Self { - let message = format!("Assertion `{}` failed", expression); + pub fn assertion_failed(span: &Span) -> Self { + let message = "Assertion failed".to_string(); Self::new_from_span(message, span) } - pub fn assertion_must_be_boolean(expression: String, span: Span) -> Self { - let message = format!("Assertion expression `{}` must evaluate to a boolean value", expression); + pub fn assertion_must_be_boolean(span: &Span) -> Self { + let message = "Assertion expression must evaluate to a boolean value".to_string(); Self::new_from_span(message, span) } diff --git a/compiler/src/errors/expression.rs b/compiler/src/errors/expression.rs index ac58aada16..cfa4c2525d 100644 --- a/compiler/src/errors/expression.rs +++ b/compiler/src/errors/expression.rs @@ -15,10 +15,8 @@ // 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, PositiveNumber, Span}; - +use leo_ast::{ArrayDimensions, FormattedError, Identifier, LeoError, PositiveNumber, Span}; use snarkvm_r1cs::SynthesisError; -use std::path::Path; #[derive(Debug, Error)] pub enum ExpressionError { @@ -47,25 +45,40 @@ pub enum ExpressionError { ValueError(#[from] ValueError), } -impl ExpressionError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for ExpressionError { + fn get_path(&self) -> Option<&str> { match self { - ExpressionError::AddressError(error) => error.set_path(path), - ExpressionError::BooleanError(error) => error.set_path(path), - ExpressionError::Error(error) => error.set_path(path), - ExpressionError::FieldError(error) => error.set_path(path), - ExpressionError::FunctionError(error) => error.set_path(path), - ExpressionError::GroupError(error) => error.set_path(path), - ExpressionError::IntegerError(error) => error.set_path(path), - ExpressionError::ValueError(error) => error.set_path(path), + ExpressionError::AddressError(error) => error.get_path(), + ExpressionError::BooleanError(error) => error.get_path(), + ExpressionError::Error(error) => error.get_path(), + ExpressionError::FieldError(error) => error.get_path(), + ExpressionError::FunctionError(error) => error.get_path(), + ExpressionError::GroupError(error) => error.get_path(), + ExpressionError::IntegerError(error) => error.get_path(), + ExpressionError::ValueError(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + ExpressionError::AddressError(error) => error.set_path(path, contents), + ExpressionError::BooleanError(error) => error.set_path(path, contents), + ExpressionError::Error(error) => error.set_path(path, contents), + ExpressionError::FieldError(error) => error.set_path(path, contents), + ExpressionError::FunctionError(error) => error.set_path(path, contents), + ExpressionError::GroupError(error) => error.set_path(path, contents), + ExpressionError::IntegerError(error) => error.set_path(path, contents), + ExpressionError::ValueError(error) => error.set_path(path, contents), + } + } +} + +impl ExpressionError { + fn new_from_span(message: String, span: &Span) -> Self { ExpressionError::Error(FormattedError::new_from_span(message, span)) } - pub fn cannot_enforce(operation: String, error: SynthesisError, span: Span) -> Self { + pub fn cannot_enforce(operation: String, error: SynthesisError, span: &Span) -> Self { let message = format!( "the gadget operation `{}` failed due to synthesis error `{:?}`", operation, error, @@ -74,37 +87,37 @@ impl ExpressionError { Self::new_from_span(message, span) } - pub fn cannot_evaluate(operation: String, span: Span) -> Self { + pub fn cannot_evaluate(operation: String, span: &Span) -> Self { let message = format!("Mismatched types found for operation `{}`", operation); Self::new_from_span(message, span) } - pub fn conditional_boolean(actual: String, span: Span) -> Self { + pub fn conditional_boolean(actual: String, span: &Span) -> Self { let message = format!("if, else conditional must resolve to a boolean, found `{}`", actual); Self::new_from_span(message, span) } - pub fn expected_circuit_member(expected: String, span: Span) -> Self { + pub fn expected_circuit_member(expected: String, span: &Span) -> Self { let message = format!("expected circuit member `{}`, not found", expected); Self::new_from_span(message, span) } - pub fn incompatible_types(operation: String, span: Span) -> Self { + pub fn incompatible_types(operation: String, span: &Span) -> Self { let message = format!("no implementation for `{}`", operation); Self::new_from_span(message, span) } - pub fn index_out_of_bounds(index: usize, span: Span) -> Self { + pub fn index_out_of_bounds(index: usize, span: &Span) -> Self { let message = format!("cannot access index {} of tuple out of bounds", index); Self::new_from_span(message, span) } - pub fn invalid_dimensions(expected: &ArrayDimensions, actual: &ArrayDimensions, span: Span) -> Self { + pub fn invalid_dimensions(expected: &ArrayDimensions, actual: &ArrayDimensions, span: &Span) -> Self { let message = format!( "expected array dimensions {}, found array dimensions {}", expected, actual @@ -113,7 +126,7 @@ impl ExpressionError { Self::new_from_span(message, span) } - pub fn invalid_first_dimension(expected: &PositiveNumber, actual: &PositiveNumber, span: Span) -> Self { + pub fn invalid_first_dimension(expected: &PositiveNumber, actual: &PositiveNumber, span: &Span) -> Self { let message = format!( "expected array dimension {}, found array dimension {}", expected, actual @@ -125,58 +138,58 @@ impl ExpressionError { 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.to_owned()) + Self::new_from_span(message, span) } - pub fn invalid_length(expected: usize, actual: usize, span: Span) -> Self { + pub fn invalid_length(expected: usize, actual: usize, span: &Span) -> Self { let message = format!("expected array length {}, found one with length {}", expected, actual); Self::new_from_span(message, span) } - pub fn invalid_spread(actual: String, span: Span) -> Self { + pub fn invalid_spread(actual: String, span: &Span) -> Self { let message = format!("spread should contain an array, found `{}`", actual); Self::new_from_span(message, span) } - pub fn invalid_member_access(member: String, span: Span) -> Self { + pub fn invalid_member_access(member: String, span: &Span) -> Self { let message = format!("non-static member `{}` must be accessed using `.` syntax", member); Self::new_from_span(message, span) } - pub fn invalid_static_access(member: String, span: Span) -> Self { + pub fn invalid_static_access(member: String, span: &Span) -> Self { let message = format!("static member `{}` must be accessed using `::` syntax", member); Self::new_from_span(message, span) } - pub fn function_no_return(function: String, span: Span) -> Self { + pub fn function_no_return(function: String, span: &Span) -> Self { let message = format!("inline function call to `{}` did not return", function); Self::new_from_span(message, span) } - pub fn self_keyword(span: Span) -> Self { + pub fn self_keyword(span: &Span) -> Self { let message = "cannot call keyword `Self` outside of a circuit function".to_string(); Self::new_from_span(message, span) } - pub fn undefined_array(actual: String, span: Span) -> Self { + pub fn undefined_array(actual: String, span: &Span) -> Self { let message = format!("array `{}` must be declared before it is used in an expression", actual); Self::new_from_span(message, span) } - pub fn undefined_tuple(actual: String, span: Span) -> Self { + 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 { + pub fn undefined_circuit(actual: String, span: &Span) -> Self { let message = format!( "circuit `{}` must be declared before it is used in an expression", actual @@ -185,13 +198,13 @@ impl ExpressionError { Self::new_from_span(message, span) } - pub fn undefined_first_dimension(span: Span) -> Self { + 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, span) } - pub fn undefined_function(function: String, span: Span) -> Self { + pub fn undefined_function(function: String, span: &Span) -> Self { let message = format!( "function `{}` must be declared before it is used in an inline expression", function @@ -203,28 +216,28 @@ impl ExpressionError { 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) + Self::new_from_span(message, &identifier.span) } - pub fn undefined_member_access(circuit: String, member: String, span: Span) -> Self { + pub fn undefined_member_access(circuit: String, member: String, span: &Span) -> Self { let message = format!("Circuit `{}` has no member `{}`", circuit, member); Self::new_from_span(message, span) } - pub fn undefined_static_access(circuit: String, member: String, span: Span) -> Self { + pub fn undefined_static_access(circuit: String, member: String, span: &Span) -> Self { let message = format!("Circuit `{}` has no static member `{}`", circuit, member); Self::new_from_span(message, span) } - pub fn unexpected_array(expected: String, span: Span) -> Self { + pub fn unexpected_array(expected: String, span: &Span) -> Self { let message = format!("expected type `{}`, found array with elements", expected); Self::new_from_span(message, span) } - pub fn unexpected_tuple(expected: String, actual: String, span: Span) -> Self { + pub fn unexpected_tuple(expected: String, actual: String, span: &Span) -> Self { let message = format!("expected type `{}`, found tuple with values `{}`", expected, actual); Self::new_from_span(message, span) diff --git a/compiler/src/errors/function.rs b/compiler/src/errors/function.rs index 5422761581..43a2179365 100644 --- a/compiler/src/errors/function.rs +++ b/compiler/src/errors/function.rs @@ -26,9 +26,7 @@ use crate::errors::{ ValueError, }; use leo_asg::AsgConvertError; -use leo_ast::{Error as FormattedError, Span}; - -use std::path::Path; +use leo_ast::{FormattedError, LeoError, Span}; #[derive(Debug, Error)] pub enum FunctionError { @@ -66,34 +64,52 @@ pub enum FunctionError { ImportASGError(#[from] AsgConvertError), } -impl FunctionError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for FunctionError { + fn get_path(&self) -> Option<&str> { match self { - FunctionError::AddressError(error) => error.set_path(path), - FunctionError::BooleanError(error) => error.set_path(path), - FunctionError::ExpressionError(error) => error.set_path(path), - FunctionError::Error(error) => error.set_path(path), - FunctionError::FieldError(error) => error.set_path(path), - FunctionError::GroupError(error) => error.set_path(path), - FunctionError::IntegerError(error) => error.set_path(path), - FunctionError::OutputStringError(error) => error.set_path(path), - FunctionError::StatementError(error) => error.set_path(path), - FunctionError::ValueError(error) => error.set_path(path), - FunctionError::ImportASGError(_error) => (), + FunctionError::AddressError(error) => error.get_path(), + FunctionError::BooleanError(error) => error.get_path(), + FunctionError::ExpressionError(error) => error.get_path(), + FunctionError::Error(error) => error.get_path(), + FunctionError::FieldError(error) => error.get_path(), + FunctionError::GroupError(error) => error.get_path(), + FunctionError::IntegerError(error) => error.get_path(), + FunctionError::OutputStringError(error) => error.get_path(), + FunctionError::StatementError(error) => error.get_path(), + FunctionError::ValueError(error) => error.get_path(), + FunctionError::ImportASGError(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + FunctionError::AddressError(error) => error.set_path(path, contents), + FunctionError::BooleanError(error) => error.set_path(path, contents), + FunctionError::ExpressionError(error) => error.set_path(path, contents), + FunctionError::Error(error) => error.set_path(path, contents), + FunctionError::FieldError(error) => error.set_path(path, contents), + FunctionError::GroupError(error) => error.set_path(path, contents), + FunctionError::IntegerError(error) => error.set_path(path, contents), + FunctionError::OutputStringError(error) => error.set_path(path, contents), + FunctionError::StatementError(error) => error.set_path(path, contents), + FunctionError::ValueError(error) => error.set_path(path, contents), + FunctionError::ImportASGError(error) => error.set_path(path, contents), + } + } +} + +impl FunctionError { + fn new_from_span(message: String, span: &Span) -> Self { FunctionError::Error(FormattedError::new_from_span(message, span)) } - pub fn invalid_array(actual: String, span: Span) -> Self { + pub fn invalid_array(actual: String, span: &Span) -> Self { let message = format!("Expected function input array, found `{}`", actual); Self::new_from_span(message, span) } - pub fn invalid_input_array_dimensions(expected: usize, actual: usize, span: Span) -> Self { + pub fn invalid_input_array_dimensions(expected: usize, actual: usize, span: &Span) -> Self { let message = format!( "Input array dimensions mismatch expected {}, found array dimensions {}", expected, actual @@ -102,25 +118,25 @@ impl FunctionError { Self::new_from_span(message, span) } - pub fn invalid_tuple(actual: String, span: Span) -> Self { + pub fn invalid_tuple(actual: String, span: &Span) -> Self { let message = format!("Expected function input tuple, found `{}`", actual); Self::new_from_span(message, span) } - pub fn return_arguments_length(expected: usize, actual: usize, span: Span) -> Self { + pub fn return_arguments_length(expected: usize, actual: usize, span: &Span) -> Self { let message = format!("function expected {} returns, found {} returns", expected, actual); Self::new_from_span(message, span) } - pub fn return_argument_type(expected: String, actual: String, span: Span) -> Self { + pub fn return_argument_type(expected: String, actual: String, span: &Span) -> Self { let message = format!("Expected function return type `{}`, found `{}`", expected, actual); Self::new_from_span(message, span) } - pub fn input_not_found(expected: String, span: Span) -> Self { + pub fn input_not_found(expected: String, span: &Span) -> Self { let message = format!("main function input {} not found", expected); Self::new_from_span(message, span) diff --git a/compiler/src/errors/import.rs b/compiler/src/errors/import.rs index 74ee48cc83..a61b41000f 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_ast::{Error as FormattedError, Identifier, ImportSymbol, Span}; +use leo_ast::{FormattedError, Identifier, ImportSymbol, LeoError, Span}; #[derive(Debug, Error)] pub enum ImportError { @@ -22,8 +22,22 @@ pub enum ImportError { Error(#[from] FormattedError), } +impl LeoError for ImportError { + fn get_path(&self) -> Option<&str> { + match self { + ImportError::Error(error) => error.get_path(), + } + } + + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + ImportError::Error(error) => error.set_path(path, contents), + } + } +} + impl ImportError { - fn new_from_span(message: String, span: Span) -> Self { + fn new_from_span(message: String, span: &Span) -> Self { ImportError::Error(FormattedError::new_from_span(message, span)) } @@ -33,12 +47,12 @@ impl ImportError { identifier.name ); - Self::new_from_span(message, identifier.span) + Self::new_from_span(message, &identifier.span) } pub fn unknown_symbol(symbol: ImportSymbol, file: String) -> Self { let message = format!("cannot find imported symbol `{}` in imported file `{}`", symbol, file); - let error = FormattedError::new_from_span(message, symbol.span); + let error = FormattedError::new_from_span(message, &symbol.span); ImportError::Error(error) } diff --git a/compiler/src/errors/output_bytes.rs b/compiler/src/errors/output_bytes.rs index 71649b0910..0dd08b026b 100644 --- a/compiler/src/errors/output_bytes.rs +++ b/compiler/src/errors/output_bytes.rs @@ -16,9 +16,7 @@ use crate::errors::ValueError; use leo_asg::{AsgConvertError, Type}; -use leo_ast::{Error as FormattedError, Span}; - -use std::path::Path; +use leo_ast::{FormattedError, LeoError, Span}; #[derive(Debug, Error)] pub enum OutputBytesError { @@ -32,26 +30,36 @@ pub enum OutputBytesError { AsgConvertError(#[from] AsgConvertError), } -impl OutputBytesError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for OutputBytesError { + fn get_path(&self) -> Option<&str> { match self { - OutputBytesError::Error(error) => error.set_path(path), - OutputBytesError::ValueError(error) => error.set_path(path), - OutputBytesError::AsgConvertError(_error) => (), + OutputBytesError::Error(error) => error.get_path(), + OutputBytesError::ValueError(error) => error.get_path(), + OutputBytesError::AsgConvertError(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + OutputBytesError::Error(error) => error.set_path(path, contents), + OutputBytesError::ValueError(error) => error.set_path(path, contents), + OutputBytesError::AsgConvertError(error) => error.set_path(path, contents), + } + } +} + +impl OutputBytesError { + fn new_from_span(message: String, span: &Span) -> Self { OutputBytesError::Error(FormattedError::new_from_span(message, span)) } - pub fn not_enough_registers(span: Span) -> Self { + pub fn not_enough_registers(span: &Span) -> Self { let message = "number of input registers must be greater than or equal to output registers".to_string(); Self::new_from_span(message, span) } - pub fn mismatched_output_types(left: &Type, right: &Type, span: Span) -> Self { + pub fn mismatched_output_types(left: &Type, right: &Type, span: &Span) -> Self { let message = format!( "Mismatched types. Expected register output type `{}`, found type `{}`.", left, right diff --git a/compiler/src/errors/statement.rs b/compiler/src/errors/statement.rs index d915d40dff..4255d273ad 100644 --- a/compiler/src/errors/statement.rs +++ b/compiler/src/errors/statement.rs @@ -16,9 +16,7 @@ use crate::errors::{AddressError, BooleanError, ConsoleError, ExpressionError, IntegerError, ValueError}; use leo_asg::Type; -use leo_ast::{Error as FormattedError, Span}; - -use std::path::Path; +use leo_ast::{FormattedError, LeoError, Span}; #[derive(Debug, Error)] pub enum StatementError { @@ -44,48 +42,62 @@ pub enum StatementError { ValueError(#[from] ValueError), } -impl StatementError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for StatementError { + fn get_path(&self) -> Option<&str> { match self { - StatementError::AddressError(error) => error.set_path(path), - StatementError::BooleanError(error) => error.set_path(path), - StatementError::Error(error) => error.set_path(path), - StatementError::ExpressionError(error) => error.set_path(path), - StatementError::IntegerError(error) => error.set_path(path), - StatementError::MacroError(error) => error.set_path(path), - StatementError::ValueError(error) => error.set_path(path), + StatementError::AddressError(error) => error.get_path(), + StatementError::BooleanError(error) => error.get_path(), + StatementError::Error(error) => error.get_path(), + StatementError::ExpressionError(error) => error.get_path(), + StatementError::IntegerError(error) => error.get_path(), + StatementError::MacroError(error) => error.get_path(), + StatementError::ValueError(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + StatementError::AddressError(error) => error.set_path(path, contents), + StatementError::BooleanError(error) => error.set_path(path, contents), + StatementError::Error(error) => error.set_path(path, contents), + StatementError::ExpressionError(error) => error.set_path(path, contents), + StatementError::IntegerError(error) => error.set_path(path, contents), + StatementError::MacroError(error) => error.set_path(path, contents), + StatementError::ValueError(error) => error.set_path(path, contents), + } + } +} + +impl StatementError { + fn new_from_span(message: String, span: &Span) -> Self { StatementError::Error(FormattedError::new_from_span(message, span)) } - pub fn arguments_type(expected: &Type, actual: &Type, span: Span) -> Self { + pub fn arguments_type(expected: &Type, actual: &Type, span: &Span) -> Self { let message = format!("expected return argument type `{}`, found type `{}`", expected, actual); Self::new_from_span(message, span) } - pub fn array_assign_index(span: Span) -> Self { + pub fn array_assign_index(span: &Span) -> Self { let message = "Cannot assign single index to array of values".to_string(); Self::new_from_span(message, span) } - pub fn array_assign_interior_index(span: Span) -> Self { + pub fn array_assign_interior_index(span: &Span) -> Self { let message = "Cannot assign single index to interior of array of values".to_string(); Self::new_from_span(message, span) } - pub fn array_assign_range(span: Span) -> Self { + pub fn array_assign_range(span: &Span) -> Self { let message = "Cannot assign range of array values to single value".to_string(); Self::new_from_span(message, span) } - pub fn array_assign_index_bounds(index: usize, length: usize, span: Span) -> Self { + pub fn array_assign_index_bounds(index: usize, length: usize, span: &Span) -> Self { let message = format!( "Array assign index `{}` out of range for array of length `{}`", index, length @@ -94,7 +106,7 @@ impl StatementError { Self::new_from_span(message, span) } - pub fn array_assign_range_order(start: usize, stop: usize, length: usize, span: Span) -> Self { + pub fn array_assign_range_order(start: usize, stop: usize, length: usize, span: &Span) -> Self { let message = format!( "Array assign range `{}`..`{}` out of range for array of length `{}`", start, stop, length @@ -103,31 +115,31 @@ impl StatementError { Self::new_from_span(message, span) } - pub fn conditional_boolean(actual: String, span: Span) -> Self { + pub fn conditional_boolean(actual: String, span: &Span) -> Self { let message = format!("If, else conditional must resolve to a boolean, found `{}`", actual); Self::new_from_span(message, span) } - pub fn immutable_assign(name: String, span: Span) -> Self { + pub fn immutable_assign(name: String, span: &Span) -> Self { let message = format!("Cannot assign to immutable variable `{}`", name); Self::new_from_span(message, span) } - pub fn immutable_circuit_function(name: String, span: Span) -> Self { + pub fn immutable_circuit_function(name: String, span: &Span) -> Self { let message = format!("Cannot mutate circuit function, `{}`", name); Self::new_from_span(message, span) } - pub fn immutable_circuit_variable(name: String, span: Span) -> Self { + pub fn immutable_circuit_variable(name: String, span: &Span) -> Self { let message = format!("Circuit member variable `{}` is immutable", name); Self::new_from_span(message, span) } - pub fn indicator_calculation(name: String, span: Span) -> Self { + pub fn indicator_calculation(name: String, span: &Span) -> Self { let message = format!( "Constraint system failed to evaluate branch selection indicator `{}`", name @@ -136,7 +148,7 @@ impl StatementError { Self::new_from_span(message, span) } - pub fn invalid_number_of_definitions(expected: usize, actual: usize, span: Span) -> Self { + pub fn invalid_number_of_definitions(expected: usize, actual: usize, span: &Span) -> Self { let message = format!( "Multiple definition statement expected {} return values, found {} values", expected, actual @@ -145,7 +157,7 @@ impl StatementError { Self::new_from_span(message, span) } - pub fn invalid_number_of_returns(expected: usize, actual: usize, span: Span) -> Self { + pub fn invalid_number_of_returns(expected: usize, actual: usize, span: &Span) -> Self { let message = format!( "Function return statement expected {} return values, found {} values", expected, actual @@ -154,20 +166,20 @@ impl StatementError { Self::new_from_span(message, span) } - pub fn multiple_definition(value: String, span: Span) -> Self { + pub fn multiple_definition(value: String, span: &Span) -> Self { let message = format!("cannot assign multiple variables to a single value: {}", value,); Self::new_from_span(message, span) } - pub fn multiple_returns(span: Span) -> Self { + pub fn multiple_returns(span: &Span) -> Self { let message = "This function returns multiple times and produces unreachable circuits with undefined behavior." .to_string(); Self::new_from_span(message, span) } - pub fn no_returns(expected: &Type, span: Span) -> Self { + pub fn no_returns(expected: &Type, span: &Span) -> Self { let message = format!( "function expected `{}` return type but no valid branches returned a result", expected @@ -176,7 +188,7 @@ impl StatementError { Self::new_from_span(message, span) } - pub fn select_fail(first: String, second: String, span: Span) -> Self { + pub fn select_fail(first: String, second: String, span: &Span) -> Self { let message = format!( "Conditional select gadget failed to select between `{}` or `{}`", first, second @@ -185,13 +197,13 @@ impl StatementError { Self::new_from_span(message, span) } - pub fn tuple_assign_index(span: Span) -> Self { + pub fn tuple_assign_index(span: &Span) -> Self { let message = "Cannot assign single index to tuple of values".to_string(); Self::new_from_span(message, span) } - pub fn tuple_assign_index_bounds(index: usize, length: usize, span: Span) -> Self { + pub fn tuple_assign_index_bounds(index: usize, length: usize, span: &Span) -> Self { let message = format!( "Tuple assign index `{}` out of range for tuple of length `{}`", index, length @@ -200,31 +212,31 @@ impl StatementError { Self::new_from_span(message, span) } - pub fn tuple_type(type_: String, span: Span) -> Self { + pub fn tuple_type(type_: String, span: &Span) -> Self { let message = format!("Expected tuple type, found type `{}`", type_); Self::new_from_span(message, span) } - pub fn unassigned(name: String, span: Span) -> Self { - let message = format!("Expected assignment of return values for expression `{}`", name); + pub fn unassigned(span: &Span) -> Self { + let message = "Expected assignment of return values for expression".to_string(); Self::new_from_span(message, span) } - pub fn undefined_variable(name: String, span: Span) -> Self { + 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) } - pub fn undefined_circuit(name: String, span: Span) -> Self { + pub fn undefined_circuit(name: String, span: &Span) -> Self { let message = format!("Attempted to assign to unknown circuit `{}`", name); Self::new_from_span(message, span) } - pub fn undefined_circuit_variable(name: String, span: Span) -> Self { + pub fn undefined_circuit_variable(name: String, span: &Span) -> Self { let message = format!("Attempted to assign to unknown circuit member variable `{}`", name); Self::new_from_span(message, span) diff --git a/compiler/src/errors/value/address.rs b/compiler/src/errors/value/address.rs index a6dfdd840d..6bcae566f9 100644 --- a/compiler/src/errors/value/address.rs +++ b/compiler/src/errors/value/address.rs @@ -14,11 +14,9 @@ // 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 leo_ast::{FormattedError, LeoError, Span}; use snarkvm_dpc::AccountError; use snarkvm_r1cs::SynthesisError; -use std::path::Path; #[derive(Debug, Error)] pub enum AddressError { @@ -26,24 +24,32 @@ pub enum AddressError { Error(#[from] FormattedError), } -impl AddressError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for AddressError { + fn get_path(&self) -> Option<&str> { match self { - AddressError::Error(error) => error.set_path(path), + AddressError::Error(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + AddressError::Error(error) => error.set_path(path, contents), + } + } +} + +impl AddressError { + fn new_from_span(message: String, span: &Span) -> Self { AddressError::Error(FormattedError::new_from_span(message, span)) } - pub fn account_error(error: AccountError, span: Span) -> Self { + pub fn account_error(error: AccountError, span: &Span) -> Self { let message = format!("account creation failed due to `{}`", error); Self::new_from_span(message, span) } - pub fn cannot_enforce(operation: String, error: SynthesisError, span: Span) -> Self { + pub fn cannot_enforce(operation: String, error: SynthesisError, span: &Span) -> Self { let message = format!( "the address operation `{:?}` failed due to the synthesis error `{}`", operation, error, @@ -52,19 +58,19 @@ impl AddressError { Self::new_from_span(message, span) } - pub fn cannot_evaluate(operation: String, span: Span) -> Self { + pub fn cannot_evaluate(operation: String, span: &Span) -> Self { let message = format!("no implementation found for `{}`", operation); Self::new_from_span(message, span) } - pub fn invalid_address(actual: String, span: Span) -> Self { + pub fn invalid_address(actual: String, span: &Span) -> Self { let message = format!("expected address input type, found `{}`", actual); Self::new_from_span(message, span) } - pub fn missing_address(span: Span) -> Self { + pub fn missing_address(span: &Span) -> Self { let message = "expected address input not found".to_string(); Self::new_from_span(message, span) diff --git a/compiler/src/errors/value/boolean.rs b/compiler/src/errors/value/boolean.rs index 7f7c264148..abb5cafab3 100644 --- a/compiler/src/errors/value/boolean.rs +++ b/compiler/src/errors/value/boolean.rs @@ -14,10 +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::{Error as FormattedError, Span}; - +use leo_ast::{FormattedError, LeoError, Span}; use snarkvm_r1cs::SynthesisError; -use std::path::Path; #[derive(Debug, Error)] pub enum BooleanError { @@ -25,18 +23,26 @@ pub enum BooleanError { Error(#[from] FormattedError), } -impl BooleanError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for BooleanError { + fn get_path(&self) -> Option<&str> { match self { - BooleanError::Error(error) => error.set_path(path), + BooleanError::Error(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + BooleanError::Error(error) => error.set_path(path, contents), + } + } +} + +impl BooleanError { + fn new_from_span(message: String, span: &Span) -> Self { BooleanError::Error(FormattedError::new_from_span(message, span)) } - pub fn cannot_enforce(operation: String, error: SynthesisError, span: Span) -> Self { + pub fn cannot_enforce(operation: String, error: SynthesisError, span: &Span) -> Self { let message = format!( "the boolean operation `{}` failed due to the synthesis error `{:?}`", operation, error, @@ -45,19 +51,19 @@ impl BooleanError { Self::new_from_span(message, span) } - pub fn cannot_evaluate(operation: String, span: Span) -> Self { + pub fn cannot_evaluate(operation: String, span: &Span) -> Self { let message = format!("no implementation found for `{}`", operation); Self::new_from_span(message, span) } - pub fn invalid_boolean(actual: String, span: Span) -> Self { + pub fn invalid_boolean(actual: String, span: &Span) -> Self { let message = format!("expected boolean input type, found `{}`", actual); Self::new_from_span(message, span) } - pub fn missing_boolean(expected: String, span: Span) -> Self { + pub fn missing_boolean(expected: String, span: &Span) -> Self { let message = format!("expected boolean input `{}` not found", expected); Self::new_from_span(message, span) diff --git a/compiler/src/errors/value/field.rs b/compiler/src/errors/value/field.rs index 0a6766f3e1..463996d540 100644 --- a/compiler/src/errors/value/field.rs +++ b/compiler/src/errors/value/field.rs @@ -14,10 +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::{Error as FormattedError, Span}; - +use leo_ast::{FormattedError, LeoError, Span}; use snarkvm_r1cs::SynthesisError; -use std::path::Path; #[derive(Debug, Error)] pub enum FieldError { @@ -25,24 +23,32 @@ pub enum FieldError { Error(#[from] FormattedError), } -impl FieldError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for FieldError { + fn get_path(&self) -> Option<&str> { match self { - FieldError::Error(error) => error.set_path(path), + FieldError::Error(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + FieldError::Error(error) => error.set_path(path, contents), + } + } +} + +impl FieldError { + fn new_from_span(message: String, span: &Span) -> Self { FieldError::Error(FormattedError::new_from_span(message, span)) } - pub fn negate_operation(error: SynthesisError, span: Span) -> Self { + pub fn negate_operation(error: SynthesisError, span: &Span) -> Self { let message = format!("field negation failed due to synthesis error `{:?}`", error,); Self::new_from_span(message, span) } - pub fn binary_operation(operation: String, error: SynthesisError, span: Span) -> Self { + pub fn binary_operation(operation: String, error: SynthesisError, span: &Span) -> Self { let message = format!( "the field binary operation `{}` failed due to synthesis error `{:?}`", operation, error, @@ -51,25 +57,25 @@ impl FieldError { Self::new_from_span(message, span) } - pub fn invalid_field(actual: String, span: Span) -> Self { + pub fn invalid_field(actual: String, span: &Span) -> Self { let message = format!("expected field element input type, found `{}`", actual); Self::new_from_span(message, span) } - pub fn missing_field(expected: String, span: Span) -> Self { + pub fn missing_field(expected: String, span: &Span) -> Self { let message = format!("expected field input `{}` not found", expected); Self::new_from_span(message, span) } - pub fn no_inverse(field: String, span: Span) -> Self { + pub fn no_inverse(field: String, span: &Span) -> Self { let message = format!("no multiplicative inverse found for field `{}`", field); Self::new_from_span(message, span) } - pub fn synthesis_error(error: SynthesisError, span: Span) -> Self { + pub fn synthesis_error(error: SynthesisError, span: &Span) -> Self { let message = format!("compilation failed due to field synthesis error `{:?}`", error); Self::new_from_span(message, span) diff --git a/compiler/src/errors/value/group.rs b/compiler/src/errors/value/group.rs index e83d8af596..c1d5fda7c6 100644 --- a/compiler/src/errors/value/group.rs +++ b/compiler/src/errors/value/group.rs @@ -14,10 +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::{Error as FormattedError, Span}; - +use leo_ast::{FormattedError, LeoError, Span}; use snarkvm_r1cs::SynthesisError; -use std::path::Path; #[derive(Debug, Error)] pub enum GroupError { @@ -25,24 +23,32 @@ pub enum GroupError { Error(#[from] FormattedError), } -impl GroupError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for GroupError { + fn get_path(&self) -> Option<&str> { match self { - GroupError::Error(error) => error.set_path(path), + GroupError::Error(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + GroupError::Error(error) => error.set_path(path, contents), + } + } +} + +impl GroupError { + fn new_from_span(message: String, span: &Span) -> Self { GroupError::Error(FormattedError::new_from_span(message, span)) } - pub fn negate_operation(error: SynthesisError, span: Span) -> Self { + pub fn negate_operation(error: SynthesisError, span: &Span) -> Self { let message = format!("group negation failed due to the synthesis error `{:?}`", error,); Self::new_from_span(message, span) } - pub fn binary_operation(operation: String, error: SynthesisError, span: Span) -> Self { + pub fn binary_operation(operation: String, error: SynthesisError, span: &Span) -> Self { let message = format!( "the group binary operation `{}` failed due to the synthesis error `{:?}`", operation, error, @@ -51,55 +57,55 @@ impl GroupError { Self::new_from_span(message, span) } - pub fn invalid_group(actual: String, span: Span) -> Self { + pub fn invalid_group(actual: String, span: &Span) -> Self { let message = format!("expected group affine point input type, found `{}`", actual); Self::new_from_span(message, span) } - pub fn missing_group(expected: String, span: Span) -> Self { + pub fn missing_group(expected: String, span: &Span) -> Self { let message = format!("expected group input `{}` not found", expected); Self::new_from_span(message, span) } - pub fn synthesis_error(error: SynthesisError, span: Span) -> Self { + pub fn synthesis_error(error: SynthesisError, span: &Span) -> Self { let message = format!("compilation failed due to group synthesis error `{:?}`", error); Self::new_from_span(message, span) } - pub fn x_invalid(x: String, span: Span) -> Self { + pub fn x_invalid(x: String, span: &Span) -> Self { let message = format!("invalid x coordinate `{}`", x); Self::new_from_span(message, span) } - pub fn y_invalid(y: String, span: Span) -> Self { + pub fn y_invalid(y: String, span: &Span) -> Self { let message = format!("invalid y coordinate `{}`", y); Self::new_from_span(message, span) } - pub fn not_on_curve(element: String, span: Span) -> Self { + pub fn not_on_curve(element: String, span: &Span) -> Self { let message = format!("group element `{}` is not on the supported curve", element); Self::new_from_span(message, span) } - pub fn x_recover(span: Span) -> Self { + pub fn x_recover(span: &Span) -> Self { let message = "could not recover group element from x coordinate".to_string(); Self::new_from_span(message, span) } - pub fn y_recover(span: Span) -> Self { + pub fn y_recover(span: &Span) -> Self { let message = "could not recover group element from y coordinate".to_string(); Self::new_from_span(message, span) } - pub fn n_group(number: String, span: Span) -> Self { + pub fn n_group(number: String, span: &Span) -> Self { let message = format!("cannot multiply group generator by \"{}\"", number); Self::new_from_span(message, span) diff --git a/compiler/src/errors/value/integer.rs b/compiler/src/errors/value/integer.rs index bd8f44cad3..175141d828 100644 --- a/compiler/src/errors/value/integer.rs +++ b/compiler/src/errors/value/integer.rs @@ -14,11 +14,9 @@ // 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, IntegerType, Span, Type}; +use leo_ast::{FormattedError, IntegerType, LeoError, Span, Type}; use leo_gadgets::errors::SignedIntegerError; - use snarkvm_r1cs::SynthesisError; -use std::path::Path; #[derive(Debug, Error)] pub enum IntegerError { @@ -26,18 +24,26 @@ pub enum IntegerError { Error(#[from] FormattedError), } -impl IntegerError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for IntegerError { + fn get_path(&self) -> Option<&str> { match self { - IntegerError::Error(error) => error.set_path(path), + IntegerError::Error(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + IntegerError::Error(error) => error.set_path(path, contents), + } + } +} + +impl IntegerError { + fn new_from_span(message: String, span: &Span) -> Self { IntegerError::Error(FormattedError::new_from_span(message, span)) } - pub fn cannot_enforce(operation: String, error: SynthesisError, span: Span) -> Self { + pub fn cannot_enforce(operation: String, error: SynthesisError, span: &Span) -> Self { let message = format!( "the integer operation `{}` failed due to the synthesis error `{:?}`", operation, error, @@ -46,19 +52,19 @@ impl IntegerError { Self::new_from_span(message, span) } - pub fn signed(error: SignedIntegerError, span: Span) -> Self { + pub fn signed(error: SignedIntegerError, span: &Span) -> Self { let message = format!("integer operation failed due to the signed integer error `{:?}`", error,); Self::new_from_span(message, span) } - pub fn synthesis(error: SynthesisError, span: Span) -> Self { + pub fn synthesis(error: SynthesisError, span: &Span) -> Self { let message = format!("integer operation failed due to the synthesis error `{}`", error,); Self::new_from_span(message, span) } - pub fn signed_error(operation: String, error: SignedIntegerError, span: Span) -> Self { + pub fn signed_error(operation: String, error: SignedIntegerError, span: &Span) -> Self { let message = format!( "the integer operation `{}` failed due to the signed integer error `{:?}`", operation, error @@ -67,13 +73,13 @@ impl IntegerError { Self::new_from_span(message, span) } - pub fn negate_operation(span: Span) -> Self { + pub fn negate_operation(span: &Span) -> Self { let message = "integer negation can only be enforced on signed integers".to_string(); Self::new_from_span(message, span) } - pub fn binary_operation(operation: String, span: Span) -> Self { + pub fn binary_operation(operation: String, span: &Span) -> Self { let message = format!( "the integer binary operation `{}` can only be enforced on integers of the same type", operation @@ -82,7 +88,7 @@ impl IntegerError { Self::new_from_span(message, span) } - pub fn invalid_index(span: Span) -> Self { + pub fn invalid_index(span: &Span) -> Self { let message = "index must be a constant value unsigned integer. allocated indices produce a circuit of unknown size" .to_string(); @@ -90,27 +96,33 @@ impl IntegerError { Self::new_from_span(message, span) } - pub fn invalid_integer(actual: String, span: Span) -> Self { + pub fn invalid_integer(actual: String, span: &Span) -> Self { let message = format!("failed to parse `{}` as expected integer type", actual); Self::new_from_span(message, span) } - pub fn invalid_integer_type(expected: &IntegerType, actual: &IntegerType, span: Span) -> Self { + 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 { + 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 { + pub fn missing_integer(expected: String, span: &Span) -> Self { let message = format!("expected integer input `{}` not found", expected); Self::new_from_span(message, span) } + + pub fn cannot_evaluate(operation: String, span: &Span) -> Self { + let message = format!("no implementation found for `{}`", operation); + + Self::new_from_span(message, span) + } } diff --git a/compiler/src/errors/value/value.rs b/compiler/src/errors/value/value.rs index 66a7d50e83..d3afeb8f73 100644 --- a/compiler/src/errors/value/value.rs +++ b/compiler/src/errors/value/value.rs @@ -15,9 +15,7 @@ // along with the Leo library. If not, see . use crate::errors::{AddressError, BooleanError, FieldError, GroupError, IntegerError}; -use leo_ast::{Error as FormattedError, Span}; - -use std::path::Path; +use leo_ast::{FormattedError, LeoError, Span}; #[derive(Debug, Error)] pub enum ValueError { @@ -40,29 +38,42 @@ pub enum ValueError { IntegerError(#[from] IntegerError), } -impl ValueError { - pub fn set_path(&mut self, path: &Path) { +impl LeoError for ValueError { + fn get_path(&self) -> Option<&str> { match self { - ValueError::AddressError(error) => error.set_path(path), - ValueError::BooleanError(error) => error.set_path(path), - ValueError::Error(error) => error.set_path(path), - ValueError::FieldError(error) => error.set_path(path), - ValueError::GroupError(error) => error.set_path(path), - ValueError::IntegerError(error) => error.set_path(path), + ValueError::AddressError(error) => error.get_path(), + ValueError::BooleanError(error) => error.get_path(), + ValueError::Error(error) => error.get_path(), + ValueError::FieldError(error) => error.get_path(), + ValueError::GroupError(error) => error.get_path(), + ValueError::IntegerError(error) => error.get_path(), } } - fn new_from_span(message: String, span: Span) -> Self { + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + ValueError::AddressError(error) => error.set_path(path, contents), + ValueError::BooleanError(error) => error.set_path(path, contents), + ValueError::Error(error) => error.set_path(path, contents), + ValueError::FieldError(error) => error.set_path(path, contents), + ValueError::GroupError(error) => error.set_path(path, contents), + ValueError::IntegerError(error) => error.set_path(path, contents), + } + } +} + +impl ValueError { + fn new_from_span(message: String, span: &Span) -> Self { ValueError::Error(FormattedError::new_from_span(message, span)) } - pub fn implicit(value: String, span: Span) -> Self { + pub fn implicit(value: String, span: &Span) -> Self { let message = format!("explicit type needed for `{}`", value); Self::new_from_span(message, span) } - pub fn implicit_group(span: Span) -> Self { + pub fn implicit_group(span: &Span) -> Self { let message = "group coordinates should be in (x, y)group format".to_string(); Self::new_from_span(message, span) diff --git a/compiler/src/expression/arithmetic/add.rs b/compiler/src/expression/arithmetic/add.rs index 67baf70950..a5c787f948 100644 --- a/compiler/src/expression/arithmetic/add.rs +++ b/compiler/src/expression/arithmetic/add.rs @@ -40,7 +40,7 @@ pub fn enforce_add<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( } (val_1, val_2) => Err(ExpressionError::incompatible_types( format!("{} + {}", val_1, val_2), - span.to_owned(), + span, )), } } diff --git a/grammar/src/console/console_debug.rs b/compiler/src/expression/arithmetic/bit_not.rs similarity index 58% rename from grammar/src/console/console_debug.rs rename to compiler/src/expression/arithmetic/bit_not.rs index 81b463947e..c040836e61 100644 --- a/grammar/src/console/console_debug.rs +++ b/compiler/src/expression/arithmetic/bit_not.rs @@ -14,24 +14,19 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{ast::Rule, console::FormattedString, SpanDef}; +//! Enforces a logical `!` operator in a resolved Leo program. -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; +use crate::{errors::IntegerError, value::ConstrainedValue, GroupType}; +use leo_asg::Span; -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::console_debug))] -pub struct ConsoleDebug<'ast> { - pub string: FormattedString<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} +use snarkvm_fields::PrimeField; -impl<'ast> fmt::Display for ConsoleDebug<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "debug({})", self.string) +pub fn evaluate_bit_not<'a, F: PrimeField, G: GroupType>( + value: ConstrainedValue<'a, F, G>, + span: &Span, +) -> Result, IntegerError> { + match value { + // ConstrainedValue::Integer(i) => Ok(ConstrainedValue::Integer(i.not())), + value => Err(IntegerError::cannot_evaluate(format!("~{}", value), span)), } } diff --git a/compiler/src/expression/arithmetic/div.rs b/compiler/src/expression/arithmetic/div.rs index 37fec2c641..dee8aeac58 100644 --- a/compiler/src/expression/arithmetic/div.rs +++ b/compiler/src/expression/arithmetic/div.rs @@ -37,7 +37,7 @@ pub fn enforce_div<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( } (val_1, val_2) => Err(ExpressionError::incompatible_types( format!("{} / {}", val_1, val_2,), - span.to_owned(), + span, )), } } diff --git a/compiler/src/expression/arithmetic/mod.rs b/compiler/src/expression/arithmetic/mod.rs index 5e5914ff2d..ac3b50d26b 100644 --- a/compiler/src/expression/arithmetic/mod.rs +++ b/compiler/src/expression/arithmetic/mod.rs @@ -33,3 +33,6 @@ pub use self::div::*; pub mod pow; pub use self::pow::*; + +pub mod bit_not; +pub use self::bit_not::*; diff --git a/compiler/src/expression/arithmetic/mul.rs b/compiler/src/expression/arithmetic/mul.rs index 995ba21002..92468eb7a4 100644 --- a/compiler/src/expression/arithmetic/mul.rs +++ b/compiler/src/expression/arithmetic/mul.rs @@ -37,7 +37,7 @@ pub fn enforce_mul<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( } (val_1, val_2) => Err(ExpressionError::incompatible_types( format!("{} * {}", val_1, val_2), - span.to_owned(), + span, )), } } diff --git a/compiler/src/expression/arithmetic/negate.rs b/compiler/src/expression/arithmetic/negate.rs index bee6106f34..2781f66148 100644 --- a/compiler/src/expression/arithmetic/negate.rs +++ b/compiler/src/expression/arithmetic/negate.rs @@ -31,9 +31,6 @@ pub fn enforce_negate<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem Ok(ConstrainedValue::Integer(integer.negate(cs, span)?)), ConstrainedValue::Field(field) => Ok(ConstrainedValue::Field(field.negate(cs, span)?)), ConstrainedValue::Group(group) => Ok(ConstrainedValue::Group(group.negate(cs, span)?)), - value => Err(ExpressionError::incompatible_types( - format!("-{}", value), - span.to_owned(), - )), + value => Err(ExpressionError::incompatible_types(format!("-{}", value), span)), } } diff --git a/compiler/src/expression/arithmetic/pow.rs b/compiler/src/expression/arithmetic/pow.rs index 48230b49e6..001d9be286 100644 --- a/compiler/src/expression/arithmetic/pow.rs +++ b/compiler/src/expression/arithmetic/pow.rs @@ -34,7 +34,7 @@ pub fn enforce_pow<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( } (val_1, val_2) => Err(ExpressionError::incompatible_types( format!("{} ** {}", val_1, val_2,), - span.to_owned(), + span, )), } } diff --git a/compiler/src/expression/arithmetic/sub.rs b/compiler/src/expression/arithmetic/sub.rs index a86c154956..cf12de9c53 100644 --- a/compiler/src/expression/arithmetic/sub.rs +++ b/compiler/src/expression/arithmetic/sub.rs @@ -40,7 +40,7 @@ pub fn enforce_sub<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( } (val_1, val_2) => Err(ExpressionError::incompatible_types( format!("{} - {}", val_1, val_2), - span.to_owned(), + span, )), } } diff --git a/compiler/src/expression/array/access.rs b/compiler/src/expression/array/access.rs index 363f552087..97210afd47 100644 --- a/compiler/src/expression/array/access.rs +++ b/compiler/src/expression/array/access.rs @@ -33,7 +33,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { ) -> Result, ExpressionError> { let array = match self.enforce_expression(cs, array)? { ConstrainedValue::Array(array) => array, - value => return Err(ExpressionError::undefined_array(value.to_string(), span.to_owned())), + value => return Err(ExpressionError::undefined_array(value.to_string(), span)), }; let index_resolved = self.enforce_index(cs, index, span)?; @@ -51,7 +51,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { ) -> Result, ExpressionError> { let array = match self.enforce_expression(cs, array)? { ConstrainedValue::Array(array) => array, - value => return Err(ExpressionError::undefined_array(value.to_string(), span.to_owned())), + value => return Err(ExpressionError::undefined_array(value.to_string(), span)), }; let from_resolved = match left { diff --git a/compiler/src/expression/array/array.rs b/compiler/src/expression/array/array.rs index 0630bf0869..f643850bc0 100644 --- a/compiler/src/expression/array/array.rs +++ b/compiler/src/expression/array/array.rs @@ -30,7 +30,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { &mut self, cs: &mut CS, array: &[(Cell<&'a Expression<'a>>, bool)], - span: Span, + span: &Span, ) -> Result, ExpressionError> { let expected_dimension = None; diff --git a/compiler/src/expression/circuit/access.rs b/compiler/src/expression/circuit/access.rs index 87e6ec7320..671e6543cc 100644 --- a/compiler/src/expression/circuit/access.rs +++ b/compiler/src/expression/circuit/access.rs @@ -41,19 +41,19 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { Err(ExpressionError::undefined_member_access( expr.circuit.get().name.borrow().to_string(), expr.member.to_string(), - expr.member.span.clone(), + &expr.member.span, )) } } value => Err(ExpressionError::undefined_circuit( value.to_string(), - target.span().cloned().unwrap_or_default(), + &target.span().cloned().unwrap_or_default(), )), } } else { Err(ExpressionError::invalid_static_access( expr.member.to_string(), - expr.member.span.clone(), + &expr.member.span, )) } } diff --git a/compiler/src/expression/circuit/circuit.rs b/compiler/src/expression/circuit/circuit.rs index 7ad2eb7079..91ab5feb78 100644 --- a/compiler/src/expression/circuit/circuit.rs +++ b/compiler/src/expression/circuit/circuit.rs @@ -49,7 +49,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { let variable_value = self.enforce_expression(cs, inner.get())?; resolved_members.push(ConstrainedCircuitMember(name.clone(), variable_value)); } - _ => return Err(ExpressionError::expected_circuit_member(name.to_string(), span.clone())), + _ => return Err(ExpressionError::expected_circuit_member(name.to_string(), span)), } } diff --git a/compiler/src/expression/conditional/conditional.rs b/compiler/src/expression/conditional/conditional.rs index 0fab6b027b..697d358b52 100644 --- a/compiler/src/expression/conditional/conditional.rs +++ b/compiler/src/expression/conditional/conditional.rs @@ -36,7 +36,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { ) -> Result, ExpressionError> { let conditional_value = match self.enforce_expression(cs, conditional)? { ConstrainedValue::Boolean(resolved) => resolved, - value => return Err(ExpressionError::conditional_boolean(value.to_string(), span.to_owned())), + value => return Err(ExpressionError::conditional_boolean(value.to_string(), span)), }; let first_value = self.enforce_expression(cs, first)?; @@ -46,11 +46,11 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { let unique_namespace = cs.ns(|| { format!( "select {} or {} {}:{}", - first_value, second_value, span.line, span.start + first_value, second_value, span.line_start, span.col_start ) }); ConstrainedValue::conditionally_select(unique_namespace, &conditional_value, &first_value, &second_value) - .map_err(|e| ExpressionError::cannot_enforce("conditional select".to_string(), e, span.to_owned())) + .map_err(|e| ExpressionError::cannot_enforce("conditional select".to_string(), e, span)) } } diff --git a/compiler/src/expression/expression.rs b/compiler/src/expression/expression.rs index 49eaf97a5b..45f545daa8 100644 --- a/compiler/src/expression/expression.rs +++ b/compiler/src/expression/expression.rs @@ -39,18 +39,21 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { cs: &mut CS, expression: &'a Expression<'a>, ) -> Result, ExpressionError> { - let span = expression.span().cloned().unwrap_or_default(); + let span = &expression.span().cloned().unwrap_or_default(); match expression { + // Cast + Expression::Cast(_) => unimplemented!("casts not implemented"), + // Variables Expression::VariableRef(variable_ref) => self.evaluate_ref(variable_ref), // Values Expression::Constant(Constant { value, .. }) => { Ok(match value { - ConstValue::Address(value) => ConstrainedValue::Address(Address::constant(value.clone(), &span)?), + ConstValue::Address(value) => ConstrainedValue::Address(Address::constant(value.clone(), span)?), ConstValue::Boolean(value) => ConstrainedValue::Boolean(Boolean::Constant(*value)), - ConstValue::Field(value) => ConstrainedValue::Field(FieldType::constant(value.to_string(), &span)?), - ConstValue::Group(value) => ConstrainedValue::Group(G::constant(value, &span)?), + ConstValue::Field(value) => ConstrainedValue::Field(FieldType::constant(value.to_string(), span)?), + ConstValue::Group(value) => ConstrainedValue::Group(G::constant(value, span)?), ConstValue::Int(value) => ConstrainedValue::Integer(Integer::new(value)), ConstValue::Tuple(_) | ConstValue::Array(_) => unimplemented!(), // shouldnt be in the asg here }) @@ -63,24 +66,25 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { let (resolved_left, resolved_right) = self.enforce_binary_expression(cs, left.get(), right.get())?; match operation { - BinaryOperation::Add => enforce_add(cs, resolved_left, resolved_right, &span), - BinaryOperation::Sub => enforce_sub(cs, resolved_left, resolved_right, &span), - BinaryOperation::Mul => enforce_mul(cs, resolved_left, resolved_right, &span), - BinaryOperation::Div => enforce_div(cs, resolved_left, resolved_right, &span), - BinaryOperation::Pow => enforce_pow(cs, resolved_left, resolved_right, &span), + BinaryOperation::Add => enforce_add(cs, resolved_left, resolved_right, span), + BinaryOperation::Sub => enforce_sub(cs, resolved_left, resolved_right, span), + BinaryOperation::Mul => enforce_mul(cs, resolved_left, resolved_right, span), + BinaryOperation::Div => enforce_div(cs, resolved_left, resolved_right, span), + BinaryOperation::Pow => enforce_pow(cs, resolved_left, resolved_right, span), BinaryOperation::Or => { - enforce_or(cs, resolved_left, resolved_right, &span).map_err(ExpressionError::BooleanError) + enforce_or(cs, resolved_left, resolved_right, span).map_err(ExpressionError::BooleanError) } BinaryOperation::And => { - enforce_and(cs, resolved_left, resolved_right, &span).map_err(ExpressionError::BooleanError) + enforce_and(cs, resolved_left, resolved_right, span).map_err(ExpressionError::BooleanError) } - BinaryOperation::Eq => evaluate_eq(cs, resolved_left, resolved_right, &span), - BinaryOperation::Ne => evaluate_not(evaluate_eq(cs, resolved_left, resolved_right, &span)?, &span) + BinaryOperation::Eq => evaluate_eq(cs, resolved_left, resolved_right, span), + BinaryOperation::Ne => evaluate_not(evaluate_eq(cs, resolved_left, resolved_right, span)?, span) .map_err(ExpressionError::BooleanError), - BinaryOperation::Ge => evaluate_ge(cs, resolved_left, resolved_right, &span), - BinaryOperation::Gt => evaluate_gt(cs, resolved_left, resolved_right, &span), - BinaryOperation::Le => evaluate_le(cs, resolved_left, resolved_right, &span), - BinaryOperation::Lt => evaluate_lt(cs, resolved_left, resolved_right, &span), + BinaryOperation::Ge => evaluate_ge(cs, resolved_left, resolved_right, span), + BinaryOperation::Gt => evaluate_gt(cs, resolved_left, resolved_right, span), + BinaryOperation::Le => evaluate_le(cs, resolved_left, resolved_right, span), + BinaryOperation::Lt => evaluate_lt(cs, resolved_left, resolved_right, span), + _ => unimplemented!("unimplemented binary operator"), } } @@ -88,9 +92,10 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { Expression::Unary(UnaryExpression { inner, operation, .. }) => match operation { UnaryOperation::Negate => { let resolved_inner = self.enforce_expression(cs, inner.get())?; - enforce_negate(cs, resolved_inner, &span) + enforce_negate(cs, resolved_inner, span) } - UnaryOperation::Not => Ok(evaluate_not(self.enforce_expression(cs, inner.get())?, &span)?), + UnaryOperation::Not => Ok(evaluate_not(self.enforce_expression(cs, inner.get())?, span)?), + _ => unimplemented!("unimplemented unary operator"), }, Expression::Ternary(TernaryExpression { @@ -98,7 +103,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { if_true, if_false, .. - }) => self.enforce_conditional_expression(cs, condition.get(), if_true.get(), if_false.get(), &span), + }) => self.enforce_conditional_expression(cs, condition.get(), if_true.get(), if_false.get(), span), // Arrays Expression::ArrayInline(ArrayInlineExpression { elements, .. }) => { @@ -108,20 +113,20 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { self.enforce_array_initializer(cs, element.get(), *len) } Expression::ArrayAccess(ArrayAccessExpression { array, index, .. }) => { - self.enforce_array_access(cs, array.get(), index.get(), &span) + self.enforce_array_access(cs, array.get(), index.get(), span) } Expression::ArrayRangeAccess(ArrayRangeAccessExpression { array, left, right, .. }) => { - self.enforce_array_range_access(cs, array.get(), left.get(), right.get(), &span) + self.enforce_array_range_access(cs, array.get(), left.get(), right.get(), span) } // Tuples Expression::TupleInit(TupleInitExpression { elements, .. }) => self.enforce_tuple(cs, &elements[..]), Expression::TupleAccess(TupleAccessExpression { tuple_ref, index, .. }) => { - self.enforce_tuple_access(cs, tuple_ref.get(), *index, &span) + self.enforce_tuple_access(cs, tuple_ref.get(), *index, span) } // Circuits - Expression::CircuitInit(expr) => self.enforce_circuit(cs, expr, &span), + Expression::CircuitInit(expr) => self.enforce_circuit(cs, expr, span), Expression::CircuitAccess(expr) => self.enforce_circuit_access(cs, expr), // Functions @@ -141,11 +146,11 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { function.get(), target.get(), &arguments[..], - &span, + span, ); } } - self.enforce_function_call_expression(cs, function.get(), target.get(), &arguments[..], &span) + self.enforce_function_call_expression(cs, function.get(), target.get(), &arguments[..], span) } } } diff --git a/compiler/src/expression/function/function.rs b/compiler/src/expression/function/function.rs index 3276918328..e67700d7a8 100644 --- a/compiler/src/expression/function/function.rs +++ b/compiler/src/expression/function/function.rs @@ -38,8 +38,8 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { format!( "function call {} {}:{}", function.name.borrow().clone(), - span.line, - span.start, + span.line_start, + span.col_start, ) }; diff --git a/compiler/src/expression/logical/and.rs b/compiler/src/expression/logical/and.rs index 623feb844c..86b81f7fc2 100644 --- a/compiler/src/expression/logical/and.rs +++ b/compiler/src/expression/logical/and.rs @@ -33,14 +33,14 @@ pub fn enforce_and<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) { let result = Boolean::and( - cs.ns(|| format!("{} {}:{}", name, span.line, span.start)), + cs.ns(|| format!("{} {}:{}", name, span.line_start, span.col_start)), &left_bool, &right_bool, ) - .map_err(|e| BooleanError::cannot_enforce("&&".to_string(), e, span.to_owned()))?; + .map_err(|e| BooleanError::cannot_enforce("&&".to_string(), e, span))?; return Ok(ConstrainedValue::Boolean(result)); } - Err(BooleanError::cannot_evaluate(name, span.to_owned())) + Err(BooleanError::cannot_evaluate(name, span)) } diff --git a/compiler/src/expression/logical/not.rs b/compiler/src/expression/logical/not.rs index 06556dc13f..98fc04317f 100644 --- a/compiler/src/expression/logical/not.rs +++ b/compiler/src/expression/logical/not.rs @@ -27,6 +27,6 @@ pub fn evaluate_not<'a, F: PrimeField, G: GroupType>( ) -> Result, BooleanError> { match value { ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())), - value => Err(BooleanError::cannot_evaluate(format!("!{}", value), span.clone())), + value => Err(BooleanError::cannot_evaluate(format!("!{}", value), span)), } } diff --git a/compiler/src/expression/logical/or.rs b/compiler/src/expression/logical/or.rs index b6e37fd459..0a067926b6 100644 --- a/compiler/src/expression/logical/or.rs +++ b/compiler/src/expression/logical/or.rs @@ -33,14 +33,14 @@ pub fn enforce_or<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) { let result = Boolean::or( - cs.ns(|| format!("{} {}:{}", name, span.line, span.start)), + cs.ns(|| format!("{} {}:{}", name, span.line_start, span.col_start)), &left_bool, &right_bool, ) - .map_err(|e| BooleanError::cannot_enforce("||".to_string(), e, span.to_owned()))?; + .map_err(|e| BooleanError::cannot_enforce("||".to_string(), e, span))?; return Ok(ConstrainedValue::Boolean(result)); } - Err(BooleanError::cannot_evaluate(name, span.to_owned())) + Err(BooleanError::cannot_evaluate(name, span)) } diff --git a/compiler/src/expression/relational/eq.rs b/compiler/src/expression/relational/eq.rs index 325a35f466..8c4661bf17 100644 --- a/compiler/src/expression/relational/eq.rs +++ b/compiler/src/expression/relational/eq.rs @@ -29,7 +29,7 @@ pub fn evaluate_eq<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( right: ConstrainedValue<'a, F, G>, span: &Span, ) -> Result, ExpressionError> { - let namespace_string = format!("evaluate {} == {} {}:{}", left, right, span.line, span.start); + let namespace_string = format!("evaluate {} == {} {}:{}", left, right, span.line_start, span.col_start); let constraint_result = match (left, right) { (ConstrainedValue::Address(address_1), ConstrainedValue::Address(address_2)) => { let unique_namespace = cs.ns(|| namespace_string); @@ -73,12 +73,12 @@ pub fn evaluate_eq<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( (val_1, val_2) => { return Err(ExpressionError::incompatible_types( format!("{} == {}", val_1, val_2,), - span.to_owned(), + span, )); } }; - let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("==".to_string(), span.to_owned()))?; + let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("==".to_string(), span))?; Ok(ConstrainedValue::Boolean(boolean)) } diff --git a/compiler/src/expression/relational/ge.rs b/compiler/src/expression/relational/ge.rs index 18e44ff0c8..a7913f11c7 100644 --- a/compiler/src/expression/relational/ge.rs +++ b/compiler/src/expression/relational/ge.rs @@ -29,7 +29,7 @@ pub fn evaluate_ge<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( right: ConstrainedValue<'a, F, G>, span: &Span, ) -> Result, ExpressionError> { - let unique_namespace = cs.ns(|| format!("evaluate {} >= {} {}:{}", left, right, span.line, span.start)); + let unique_namespace = cs.ns(|| format!("evaluate {} >= {} {}:{}", left, right, span.line_start, span.col_start)); let constraint_result = match (left, right) { (ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => { num_1.greater_than_or_equal(unique_namespace, &num_2) @@ -37,12 +37,12 @@ pub fn evaluate_ge<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( (val_1, val_2) => { return Err(ExpressionError::incompatible_types( format!("{} >= {}", val_1, val_2), - span.to_owned(), + span, )); } }; - let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(">=".to_string(), span.to_owned()))?; + let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(">=".to_string(), span))?; Ok(ConstrainedValue::Boolean(boolean)) } diff --git a/compiler/src/expression/relational/gt.rs b/compiler/src/expression/relational/gt.rs index 726d81da2a..bc1deccf95 100644 --- a/compiler/src/expression/relational/gt.rs +++ b/compiler/src/expression/relational/gt.rs @@ -29,7 +29,7 @@ pub fn evaluate_gt<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( right: ConstrainedValue<'a, F, G>, span: &Span, ) -> Result, ExpressionError> { - let unique_namespace = cs.ns(|| format!("evaluate {} > {} {}:{}", left, right, span.line, span.start)); + let unique_namespace = cs.ns(|| format!("evaluate {} > {} {}:{}", left, right, span.line_start, span.col_start)); let constraint_result = match (left, right) { (ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => { num_1.greater_than(unique_namespace, &num_2) @@ -37,12 +37,12 @@ pub fn evaluate_gt<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( (val_1, val_2) => { return Err(ExpressionError::incompatible_types( format!("{} > {}", val_1, val_2), - span.to_owned(), + span, )); } }; - let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(">".to_string(), span.to_owned()))?; + let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(">".to_string(), span))?; Ok(ConstrainedValue::Boolean(boolean)) } diff --git a/compiler/src/expression/relational/le.rs b/compiler/src/expression/relational/le.rs index 547aa519a1..3dd23855c5 100644 --- a/compiler/src/expression/relational/le.rs +++ b/compiler/src/expression/relational/le.rs @@ -29,7 +29,7 @@ pub fn evaluate_le<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( right: ConstrainedValue<'a, F, G>, span: &Span, ) -> Result, ExpressionError> { - let unique_namespace = cs.ns(|| format!("evaluate {} <= {} {}:{}", left, right, span.line, span.start)); + let unique_namespace = cs.ns(|| format!("evaluate {} <= {} {}:{}", left, right, span.line_start, span.col_start)); let constraint_result = match (left, right) { (ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => { num_1.less_than_or_equal(unique_namespace, &num_2) @@ -37,12 +37,12 @@ pub fn evaluate_le<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( (val_1, val_2) => { return Err(ExpressionError::incompatible_types( format!("{} <= {}", val_1, val_2), - span.to_owned(), + span, )); } }; - let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("<=".to_string(), span.to_owned()))?; + let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("<=".to_string(), span))?; Ok(ConstrainedValue::Boolean(boolean)) } diff --git a/compiler/src/expression/relational/lt.rs b/compiler/src/expression/relational/lt.rs index a47f1f8735..0bbd4a4219 100644 --- a/compiler/src/expression/relational/lt.rs +++ b/compiler/src/expression/relational/lt.rs @@ -29,7 +29,7 @@ pub fn evaluate_lt<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( right: ConstrainedValue<'a, F, G>, span: &Span, ) -> Result, ExpressionError> { - let unique_namespace = cs.ns(|| format!("evaluate {} < {} {}:{}", left, right, span.line, span.start)); + let unique_namespace = cs.ns(|| format!("evaluate {} < {} {}:{}", left, right, span.line_start, span.col_start)); let constraint_result = match (left, right) { (ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => { num_1.less_than(unique_namespace, &num_2) @@ -37,12 +37,12 @@ pub fn evaluate_lt<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( (val_1, val_2) => { return Err(ExpressionError::incompatible_types( format!("{} < {}", val_1, val_2), - span.to_owned(), + span, )); } }; - let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("<".to_string(), span.to_owned()))?; + let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("<".to_string(), span))?; Ok(ConstrainedValue::Boolean(boolean)) } diff --git a/compiler/src/expression/tuple/access.rs b/compiler/src/expression/tuple/access.rs index 40e5efe64e..11135b810e 100644 --- a/compiler/src/expression/tuple/access.rs +++ b/compiler/src/expression/tuple/access.rs @@ -34,13 +34,13 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { // Get the tuple values. let tuple = match self.enforce_expression(cs, tuple)? { ConstrainedValue::Tuple(tuple) => tuple, - value => return Err(ExpressionError::undefined_array(value.to_string(), span.to_owned())), + value => return Err(ExpressionError::undefined_array(value.to_string(), span)), }; // Check for out of bounds access. if index > tuple.len() - 1 { // probably safe to be a panic here - return Err(ExpressionError::index_out_of_bounds(index, span.to_owned())); + return Err(ExpressionError::index_out_of_bounds(index, span)); } Ok(tuple[index].to_owned()) diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index 840c3d5619..165f8e2135 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -49,7 +49,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { if function.arguments.len() != arguments.len() { return Err(FunctionError::input_not_found( "arguments length invalid".to_string(), - function.span.clone().unwrap_or_default(), + &function.span.clone().unwrap_or_default(), )); } diff --git a/compiler/src/function/input/array.rs b/compiler/src/function/input/array.rs index dcb88e6422..5ac984e118 100644 --- a/compiler/src/function/input/array.rs +++ b/compiler/src/function/input/array.rs @@ -43,7 +43,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { return Err(FunctionError::invalid_input_array_dimensions( arr.len(), array_len, - span.clone(), + span, )); } @@ -69,10 +69,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { } } _ => { - return Err(FunctionError::invalid_array( - input_value.unwrap().to_string(), - span.to_owned(), - )); + return Err(FunctionError::invalid_array(input_value.unwrap().to_string(), span)); } } diff --git a/compiler/src/function/input/input_keyword.rs b/compiler/src/function/input/input_keyword.rs index 1a5dcd6e34..63bd2767b4 100644 --- a/compiler/src/function/input/input_keyword.rs +++ b/compiler/src/function/input/input_keyword.rs @@ -30,7 +30,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { pub fn allocate_input_keyword>( &mut self, cs: &mut CS, - span: Span, + span: &Span, expected_type: &'a Circuit<'a>, input: &Input, ) -> Result, FunctionError> { @@ -50,7 +50,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { }; let state_leaf_name = Identifier { name: STATE_LEAF_VARIABLE_NAME.to_string(), - span, + span: span.clone(), }; // Fetch each input variable's definitions diff --git a/compiler/src/function/input/tuple.rs b/compiler/src/function/input/tuple.rs index e83133e279..e31a20620e 100644 --- a/compiler/src/function/input/tuple.rs +++ b/compiler/src/function/input/tuple.rs @@ -53,10 +53,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { } } _ => { - return Err(FunctionError::invalid_tuple( - input_value.unwrap().to_string(), - span.to_owned(), - )); + return Err(FunctionError::invalid_tuple(input_value.unwrap().to_string(), span)); } } diff --git a/compiler/src/function/main_function.rs b/compiler/src/function/main_function.rs index 5ce77a009f..8a77d3fd21 100644 --- a/compiler/src/function/main_function.rs +++ b/compiler/src/function/main_function.rs @@ -42,12 +42,8 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { .resolve_input() .expect("no input variable in scope when function is qualified"); - let value = self.allocate_input_keyword( - cs, - function.name.borrow().span.clone(), - &asg_input.container_circuit, - input, - )?; + let value = + self.allocate_input_keyword(cs, &function.name.borrow().span, &asg_input.container_circuit, input)?; self.store(asg_input.container.borrow().id, value); } @@ -66,7 +62,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { let input_variable = input_variable.get().borrow(); let name = input_variable.name.name.clone(); let input_option = input.get(&name).ok_or_else(|| { - FunctionError::input_not_found(name.clone(), function.span.clone().unwrap_or_default()) + FunctionError::input_not_found(name.clone(), &function.span.clone().unwrap_or_default()) })?; let input_value = self.allocate_main_function_input( cs, @@ -90,7 +86,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { let span = function.span.clone().unwrap_or_default(); let result_value = self.enforce_function(cs, function, None, &arguments)?; - let output_bytes = OutputBytes::new_from_constrained_value(&self.asg, registers, result_value, span)?; + let output_bytes = OutputBytes::new_from_constrained_value(&self.asg, registers, result_value, &span)?; Ok(output_bytes) } diff --git a/compiler/src/function/mut_target.rs b/compiler/src/function/mut_target.rs index 00a7c17d6d..913cd974ce 100644 --- a/compiler/src/function/mut_target.rs +++ b/compiler/src/function/mut_target.rs @@ -50,19 +50,16 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { let inner = self.prepare_mut_access(cs, array.get(), span, output)?; let start_index = left .get() - .map(|start| self.enforce_index(cs, start, &span)) - .transpose()?; - let stop_index = right - .get() - .map(|stop| self.enforce_index(cs, stop, &span)) + .map(|start| self.enforce_index(cs, start, span)) .transpose()?; + let stop_index = right.get().map(|stop| self.enforce_index(cs, stop, span)).transpose()?; output.push(ResolvedAssigneeAccess::ArrayRange(start_index, stop_index)); Ok(inner) } Expression::ArrayAccess(ArrayAccessExpression { array, index, .. }) => { let inner = self.prepare_mut_access(cs, array.get(), span, output)?; - let index = self.enforce_index(cs, index.get(), &span)?; + let index = self.enforce_index(cs, index.get(), span)?; output.push(ResolvedAssigneeAccess::ArrayIndex(index)); Ok(inner) @@ -95,10 +92,10 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { cs: &mut CS, assignee: &'a Expression<'a>, ) -> Result>>, StatementError> { - let span = assignee.span().cloned().unwrap_or_default(); + let span = &assignee.span().cloned().unwrap_or_default(); let mut accesses = vec![]; - let target = self.prepare_mut_access(cs, assignee, &span, &mut accesses)?; + let target = self.prepare_mut_access(cs, assignee, span, &mut accesses)?; if target.is_none() { return Ok(None); } @@ -111,7 +108,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { }]; for access in accesses { - result = Self::resolve_assignee_access(access, &span, result)?; + result = Self::resolve_assignee_access(access, span, result)?; } Ok(Some(result)) } diff --git a/compiler/src/function/result/result.rs b/compiler/src/function/result/result.rs index 29b6aed420..f29669983d 100644 --- a/compiler/src/function/result/result.rs +++ b/compiler/src/function/result/result.rs @@ -60,7 +60,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { if get_indicator_value(&indicator) { // Error if we already have a return value. if return_value.is_some() { - return Err(StatementError::multiple_returns(span.to_owned())); + return Err(StatementError::multiple_returns(span)); } else { // Set the function return value. return_value = Some(result); @@ -79,12 +79,12 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { if let Some(value) = &return_value { return_value = Some( ConstrainedValue::conditionally_select( - cs.ns(|| format!("select result {} {}:{}", i, span.line, span.start)), + cs.ns(|| format!("select result {} {}:{}", i, span.line_start, span.col_start)), &indicator, &result, &value, ) - .map_err(|_| StatementError::select_fail(result.to_string(), value.to_string(), span.to_owned()))?, + .map_err(|_| StatementError::select_fail(result.to_string(), value.to_string(), span))?, ); } else { return_value = Some(result); // we ignore indicator for default -- questionable @@ -94,7 +94,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { if expected_return.is_unit() { Ok(ConstrainedValue::Tuple(vec![])) } else { - return_value.ok_or_else(|| StatementError::no_returns(&expected_return, span.to_owned())) + return_value.ok_or_else(|| StatementError::no_returns(&expected_return, span)) } } } diff --git a/compiler/src/output/output_bytes.rs b/compiler/src/output/output_bytes.rs index ecbaffe408..028bea45fa 100644 --- a/compiler/src/output/output_bytes.rs +++ b/compiler/src/output/output_bytes.rs @@ -35,7 +35,7 @@ impl OutputBytes { program: &Program<'a>, registers: &Registers, value: ConstrainedValue<'a, F, G>, - span: Span, + span: &Span, ) -> Result { let return_values = match value { ConstrainedValue::Tuple(values) => values, @@ -68,7 +68,7 @@ impl OutputBytes { // Check register type == return value type. let register_type = program.scope.resolve_ast_type(¶meter.type_)?; - let return_value_type = value.to_type(&span)?; + let return_value_type = value.to_type(span)?; if !register_type.is_assignable_from(&return_value_type) { return Err(OutputBytesError::mismatched_output_types( diff --git a/compiler/src/prelude/blake2s.rs b/compiler/src/prelude/blake2s.rs index c8659425ad..17e47b1196 100644 --- a/compiler/src/prelude/blake2s.rs +++ b/compiler/src/prelude/blake2s.rs @@ -61,15 +61,13 @@ impl<'a, F: PrimeField, G: GroupType> CoreCircuit<'a, F, G> for Blake2s { let input = unwrap_argument(arguments.remove(1)); let seed = unwrap_argument(arguments.remove(0)); - let digest = - Blake2sGadget::check_evaluation_gadget(cs.ns(|| "blake2s hash"), &seed[..], &input[..]).map_err(|e| { - ExpressionError::cannot_enforce("Blake2s check evaluation gadget".to_owned(), e, span.clone()) - })?; + let digest = Blake2sGadget::check_evaluation_gadget(cs.ns(|| "blake2s hash"), &seed[..], &input[..]) + .map_err(|e| ExpressionError::cannot_enforce("Blake2s check evaluation gadget".to_owned(), e, span))?; Ok(ConstrainedValue::Array( digest .to_bytes(cs) - .map_err(|e| ExpressionError::cannot_enforce("Vec ToBytes".to_owned(), e, span.clone()))? + .map_err(|e| ExpressionError::cannot_enforce("Vec ToBytes".to_owned(), e, span))? .into_iter() .map(Integer::U8) .map(ConstrainedValue::Integer) diff --git a/compiler/src/statement/assign/assign.rs b/compiler/src/statement/assign/assign.rs index 232d03d125..397da041ce 100644 --- a/compiler/src/statement/assign/assign.rs +++ b/compiler/src/statement/assign/assign.rs @@ -41,7 +41,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { Self::enforce_assign_operation( cs, indicator, - format!("select {} {}:{}", new_value, &span.line, &span.start), + format!("select {} {}:{}", new_value, &span.line_start, &span.col_start), &statement.operation, resolved_assignee[0], new_value, @@ -58,7 +58,10 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { Self::enforce_assign_operation( cs, indicator, - format!("select-splice {} {} {}:{}", i, new_value, &span.line, &span.start), + format!( + "select-splice {} {} {}:{}", + i, new_value, &span.line_start, &span.col_start + ), &statement.operation, old_ref, new_value, @@ -68,7 +71,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { } _ => { return Err(StatementError::array_assign_range( - statement.span.clone().unwrap_or_default(), + &statement.span.clone().unwrap_or_default(), )); } }; @@ -93,9 +96,10 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { AssignOperation::Mul => enforce_mul(cs, target.clone(), new_value, span)?, AssignOperation::Div => enforce_div(cs, target.clone(), new_value, span)?, AssignOperation::Pow => enforce_pow(cs, target.clone(), new_value, span)?, + _ => unimplemented!("unimplemented assign operator"), }; let selected_value = ConstrainedValue::conditionally_select(cs.ns(|| scope), condition, &new_value, target) - .map_err(|_| StatementError::select_fail(new_value.to_string(), target.to_string(), span.clone()))?; + .map_err(|_| StatementError::select_fail(new_value.to_string(), target.to_string(), span))?; *target = selected_value; Ok(()) diff --git a/compiler/src/statement/assign/assignee.rs b/compiler/src/statement/assign/assignee.rs index 71e758688d..1ae232f289 100644 --- a/compiler/src/statement/assign/assignee.rs +++ b/compiler/src/statement/assign/assignee.rs @@ -63,7 +63,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { let mut result = vec![match self.get_mut(variable.id) { Some(value) => value, - None => return Err(StatementError::undefined_variable(variable.name.to_string(), span)), + None => return Err(StatementError::undefined_variable(variable.name.to_string(), &span)), }]; for access in resolved_accesses { @@ -78,16 +78,12 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { start_index, stop_index, len, - span.clone(), + span, )) } else if start_index > len { - Err(StatementError::array_assign_index_bounds( - start_index, - len, - span.clone(), - )) + Err(StatementError::array_assign_index_bounds(start_index, len, span)) } else if stop_index > len { - Err(StatementError::array_assign_index_bounds(stop_index, len, span.clone())) + Err(StatementError::array_assign_index_bounds(stop_index, len, span)) } else { Ok(()) } @@ -102,21 +98,17 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { match access { ResolvedAssigneeAccess::ArrayIndex(index) => { if value.len() != 1 { - return Err(StatementError::array_assign_interior_index(span.clone())); + return Err(StatementError::array_assign_interior_index(span)); } match value.remove(0) { ConstrainedValue::Array(old) => { if index > old.len() { - Err(StatementError::array_assign_index_bounds( - index, - old.len(), - span.clone(), - )) + Err(StatementError::array_assign_index_bounds(index, old.len(), span)) } else { Ok(vec![old.get_mut(index).unwrap()]) } } - _ => Err(StatementError::array_assign_index(span.clone())), + _ => Err(StatementError::array_assign_index(span)), } } ResolvedAssigneeAccess::ArrayRange(start_index, stop_index) => { @@ -127,38 +119,38 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { match value.remove(0) { ConstrainedValue::Array(old) => { let stop_index = stop_index.unwrap_or(old.len()); - Self::check_range_index(start_index, stop_index, old.len(), &span)?; + Self::check_range_index(start_index, stop_index, old.len(), span)?; Ok(old[start_index..stop_index].iter_mut().collect()) } - _ => Err(StatementError::array_assign_index(span.clone())), + _ => Err(StatementError::array_assign_index(span)), } } else { // range of a range let stop_index = stop_index.unwrap_or(value.len()); - Self::check_range_index(start_index, stop_index, value.len(), &span)?; + Self::check_range_index(start_index, stop_index, value.len(), span)?; Ok(value.drain(start_index..stop_index).collect()) } } ResolvedAssigneeAccess::Tuple(index, span) => { if value.len() != 1 { - return Err(StatementError::array_assign_interior_index(span)); + return Err(StatementError::array_assign_interior_index(&span)); } match value.remove(0) { ConstrainedValue::Tuple(old) => { if index > old.len() { - Err(StatementError::tuple_assign_index_bounds(index, old.len(), span)) + Err(StatementError::tuple_assign_index_bounds(index, old.len(), &span)) } else { Ok(vec![&mut old[index]]) } } - _ => Err(StatementError::tuple_assign_index(span)), + _ => Err(StatementError::tuple_assign_index(&span)), } } ResolvedAssigneeAccess::Member(name) => { if value.len() != 1 { - return Err(StatementError::array_assign_interior_index(span.clone())); + return Err(StatementError::array_assign_interior_index(span)); } match value.remove(0) { ConstrainedValue::CircuitExpression(_variable, members) => { @@ -169,15 +161,12 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { Some(member) => Ok(vec![&mut member.1]), None => { // Throw an error if the circuit variable does not exist in the circuit - Err(StatementError::undefined_circuit_variable( - name.to_string(), - span.to_owned(), - )) + Err(StatementError::undefined_circuit_variable(name.to_string(), span)) } } } // Throw an error if the circuit definition does not exist in the file - x => Err(StatementError::undefined_circuit(x.to_string(), span.to_owned())), + x => Err(StatementError::undefined_circuit(x.to_string(), span)), } } } diff --git a/compiler/src/statement/conditional/conditional.rs b/compiler/src/statement/conditional/conditional.rs index 84368ed307..5b86992414 100644 --- a/compiler/src/statement/conditional/conditional.rs +++ b/compiler/src/statement/conditional/conditional.rs @@ -57,7 +57,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { let inner_indicator = match self.enforce_expression(cs, statement.condition.get())? { ConstrainedValue::Boolean(resolved) => resolved, value => { - return Err(StatementError::conditional_boolean(value.to_string(), span)); + return Err(StatementError::conditional_boolean(value.to_string(), &span)); } }; @@ -69,11 +69,11 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { outer_indicator_string, inner_indicator_string ); let branch_1_indicator = Boolean::and( - &mut cs.ns(|| format!("branch 1 {} {}:{}", span.text, &span.line, &span.start)), + &mut cs.ns(|| format!("branch 1 {}:{}", &span.line_start, &span.col_start)), outer_indicator, &inner_indicator, ) - .map_err(|_| StatementError::indicator_calculation(branch_1_name, span.clone()))?; + .map_err(|_| StatementError::indicator_calculation(branch_1_name, &span))?; let mut results = vec![]; @@ -90,11 +90,11 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { outer_indicator_string, inner_indicator_string ); let branch_2_indicator = Boolean::and( - &mut cs.ns(|| format!("branch 2 {} {}:{}", span.text, &span.line, &span.start)), + &mut cs.ns(|| format!("branch 2 {}:{}", &span.line_start, &span.col_start)), &outer_indicator, &inner_indicator, ) - .map_err(|_| StatementError::indicator_calculation(branch_2_name, span.clone()))?; + .map_err(|_| StatementError::indicator_calculation(branch_2_name, &span))?; // Evaluate branch 2 let mut branch_2_result = match statement.next.get() { diff --git a/compiler/src/statement/definition/definition.rs b/compiler/src/statement/definition/definition.rs index a021b52ed1..e0b7eca6ea 100644 --- a/compiler/src/statement/definition/definition.rs +++ b/compiler/src/statement/definition/definition.rs @@ -33,7 +33,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { return Err(StatementError::invalid_number_of_definitions( values.len(), variable_names.len(), - span.to_owned(), + span, )); } @@ -63,7 +63,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { let values = match expression { // ConstrainedValue::Return(values) => values, ConstrainedValue::Tuple(values) => values, - value => return Err(StatementError::multiple_definition(value.to_string(), span)), + value => return Err(StatementError::multiple_definition(value.to_string(), &span)), }; self.enforce_multiple_definition(&statement.variables[..], values, &span) diff --git a/compiler/src/statement/iteration/iteration.rs b/compiler/src/statement/iteration/iteration.rs index a5fe0e8b30..0a2b3226af 100644 --- a/compiler/src/statement/iteration/iteration.rs +++ b/compiler/src/statement/iteration/iteration.rs @@ -58,7 +58,7 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { // Evaluate statements and possibly return early let result = self.enforce_statement( - &mut cs.ns(|| format!("for loop iteration {} {}:{}", i, &span.line, &span.start)), + &mut cs.ns(|| format!("for loop iteration {} {}:{}", i, &span.line_start, &span.col_start)), indicator, statement.body.get(), )?; diff --git a/compiler/src/statement/statement.rs b/compiler/src/statement/statement.rs index 135c7932fd..c3a1ec1ad4 100644 --- a/compiler/src/statement/statement.rs +++ b/compiler/src/statement/statement.rs @@ -78,17 +78,14 @@ impl<'a, F: PrimeField, G: GroupType> ConstrainedProgram<'a, F, G> { } } _ => { - return Err(StatementError::unassigned( - statement.span.as_ref().map(|x| x.text.clone()).unwrap_or_default(), - statement.span.clone().unwrap_or_default(), - )); + return Err(StatementError::unassigned(&statement.span.clone().unwrap_or_default())); } } } Statement::Block(statement) => { let span = statement.span.clone().unwrap_or_default(); let result = self.evaluate_block( - &mut cs.ns(|| format!("block {}:{}", &span.line, &span.start)), + &mut cs.ns(|| format!("block {}:{}", &span.line_start, &span.col_start)), indicator, statement, )?; diff --git a/compiler/src/value/address/address.rs b/compiler/src/value/address/address.rs index b7d9e013b2..51f27b2b8b 100644 --- a/compiler/src/value/address/address.rs +++ b/compiler/src/value/address/address.rs @@ -39,8 +39,7 @@ pub struct Address { impl Address { pub(crate) fn constant(address: String, span: &Span) -> Result { - let address = - AccountAddress::from_str(&address).map_err(|error| AddressError::account_error(error, span.to_owned()))?; + let address = AccountAddress::from_str(&address).map_err(|error| AddressError::account_error(error, span))?; let mut address_bytes = vec![]; address.write(&mut address_bytes).unwrap(); @@ -69,17 +68,17 @@ impl Address { if let InputValue::Address(string) = input { Some(string) } else { - return Err(AddressError::invalid_address(name.to_owned(), span.to_owned())); + return Err(AddressError::invalid_address(name.to_owned(), span)); } } None => None, }; let address = Address::alloc( - cs.ns(|| format!("`{}: address` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: address` {}:{}", name, span.line_start, span.col_start)), || address_value.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| AddressError::missing_address(span.to_owned()))?; + .map_err(|_| AddressError::missing_address(span))?; Ok(ConstrainedValue::Address(address)) } diff --git a/compiler/src/value/boolean/input.rs b/compiler/src/value/boolean/input.rs index e60cda1a68..2c8860a6db 100644 --- a/compiler/src/value/boolean/input.rs +++ b/compiler/src/value/boolean/input.rs @@ -30,10 +30,10 @@ pub(crate) fn allocate_bool>( span: &Span, ) -> Result { Boolean::alloc( - cs.ns(|| format!("`{}: bool` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: bool` {}:{}", name, span.line_start, span.col_start)), || option.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| BooleanError::missing_boolean(format!("{}: bool", name), span.to_owned())) + .map_err(|_| BooleanError::missing_boolean(format!("{}: bool", name), span)) } pub(crate) fn bool_from_input<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( @@ -48,7 +48,7 @@ pub(crate) fn bool_from_input<'a, F: PrimeField, G: GroupType, CS: Constraint if let InputValue::Boolean(bool) = input { Some(bool) } else { - return Err(BooleanError::invalid_boolean(name.to_owned(), span.to_owned())); + return Err(BooleanError::invalid_boolean(name.to_owned(), span)); } } None => None, diff --git a/compiler/src/value/field/field_type.rs b/compiler/src/value/field/field_type.rs index 21819c6ed3..5ccdcb1afe 100644 --- a/compiler/src/value/field/field_type.rs +++ b/compiler/src/value/field/field_type.rs @@ -57,10 +57,8 @@ impl FieldType { let number_info = number_string_typing(&string); let value = match number_info { - (number, neg) if neg => { - -F::from_str(&number).map_err(|_| FieldError::invalid_field(string, span.to_owned()))? - } - (number, _) => F::from_str(&number).map_err(|_| FieldError::invalid_field(string, span.to_owned()))?, + (number, neg) if neg => -F::from_str(&number).map_err(|_| FieldError::invalid_field(string, span))?, + (number, _) => F::from_str(&number).map_err(|_| FieldError::invalid_field(string, span))?, }; Ok(FieldType::Constant(value)) @@ -70,9 +68,7 @@ impl FieldType { match self { FieldType::Constant(field) => Ok(FieldType::Constant(field.neg())), FieldType::Allocated(field) => { - let result = field - .negate(cs) - .map_err(|e| FieldError::negate_operation(e, span.to_owned()))?; + let result = field.negate(cs).map_err(|e| FieldError::negate_operation(e, span))?; Ok(FieldType::Allocated(result)) } @@ -88,7 +84,7 @@ impl FieldType { (FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => { let result = self_value .add(cs, other_value) - .map_err(|e| FieldError::binary_operation("+".to_string(), e, span.to_owned()))?; + .map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?; Ok(FieldType::Allocated(result)) } @@ -97,7 +93,7 @@ impl FieldType { | (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated( allocated_value .add_constant(cs, constant_value) - .map_err(|e| FieldError::binary_operation("+".to_string(), e, span.to_owned()))?, + .map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?, )), } } @@ -111,7 +107,7 @@ impl FieldType { (FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => { let result = self_value .sub(cs, other_value) - .map_err(|e| FieldError::binary_operation("-".to_string(), e, span.to_owned()))?; + .map_err(|e| FieldError::binary_operation("-".to_string(), e, span))?; Ok(FieldType::Allocated(result)) } @@ -120,7 +116,7 @@ impl FieldType { | (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated( allocated_value .sub_constant(cs, constant_value) - .map_err(|e| FieldError::binary_operation("+".to_string(), e, span.to_owned()))?, + .map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?, )), } } @@ -134,7 +130,7 @@ impl FieldType { (FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => { let result = self_value .mul(cs, other_value) - .map_err(|e| FieldError::binary_operation("*".to_string(), e, span.to_owned()))?; + .map_err(|e| FieldError::binary_operation("*".to_string(), e, span))?; Ok(FieldType::Allocated(result)) } @@ -143,7 +139,7 @@ impl FieldType { | (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated( allocated_value .mul_by_constant(cs, constant_value) - .map_err(|e| FieldError::binary_operation("*".to_string(), e, span.to_owned()))?, + .map_err(|e| FieldError::binary_operation("*".to_string(), e, span))?, )), } } @@ -153,14 +149,14 @@ impl FieldType { FieldType::Constant(constant) => { let constant_inverse = constant .inverse() - .ok_or_else(|| FieldError::no_inverse(constant.to_string(), span.to_owned()))?; + .ok_or_else(|| FieldError::no_inverse(constant.to_string(), span))?; FieldType::Constant(constant_inverse) } FieldType::Allocated(allocated) => { let allocated_inverse = allocated .inverse(&mut cs) - .map_err(|e| FieldError::binary_operation("+".to_string(), e, span.to_owned()))?; + .map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?; FieldType::Allocated(allocated_inverse) } diff --git a/compiler/src/value/field/input.rs b/compiler/src/value/field/input.rs index 4172fa23b0..af2d8998f8 100644 --- a/compiler/src/value/field/input.rs +++ b/compiler/src/value/field/input.rs @@ -35,19 +35,19 @@ pub(crate) fn allocate_field>( match number_info { (number, neg) if neg => FieldType::alloc( - cs.ns(|| format!("`{}: field` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: field` {}:{}", name, span.line_start, span.col_start)), || Some(number).ok_or(SynthesisError::AssignmentMissing), ) .map(|value| value.negate(cs, span)) - .map_err(|_| FieldError::missing_field(format!("{}: field", name), span.to_owned()))?, + .map_err(|_| FieldError::missing_field(format!("{}: field", name), span))?, (number, _) => FieldType::alloc( - cs.ns(|| format!("`{}: field` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: field` {}:{}", name, span.line_start, span.col_start)), || Some(number).ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| FieldError::missing_field(format!("{}: field", name), span.to_owned())), + .map_err(|_| FieldError::missing_field(format!("{}: field", name), span)), } } - None => Err(FieldError::missing_field(format!("{}: field", name), span.to_owned())), + None => Err(FieldError::missing_field(format!("{}: field", name), span)), } } @@ -63,7 +63,7 @@ pub(crate) fn field_from_input<'a, F: PrimeField, G: GroupType, CS: Constrain if let InputValue::Field(string) = input { Some(string) } else { - return Err(FieldError::invalid_field(input.to_string(), span.to_owned())); + return Err(FieldError::invalid_field(input.to_string(), span)); } } None => None, diff --git a/compiler/src/value/group/input.rs b/compiler/src/value/group/input.rs index df56ff5564..e3d53ada8a 100644 --- a/compiler/src/value/group/input.rs +++ b/compiler/src/value/group/input.rs @@ -30,10 +30,10 @@ pub(crate) fn allocate_group, CS: ConstraintSyste span: &Span, ) -> Result { G::alloc( - cs.ns(|| format!("`{}: group` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: group` {}:{}", name, span.line_start, span.col_start)), || option.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| GroupError::missing_group(format!("{}: group", name), span.to_owned())) + .map_err(|_| GroupError::missing_group(format!("{}: group", name), span)) } pub(crate) fn group_from_input<'a, F: PrimeField, G: GroupType, CS: ConstraintSystem>( @@ -48,7 +48,7 @@ pub(crate) fn group_from_input<'a, F: PrimeField, G: GroupType, CS: Constrain if let InputValue::Group(string) = input { Some(string) } else { - return Err(GroupError::invalid_group(input.to_string(), span.to_owned())); + return Err(GroupError::invalid_group(input.to_string(), span)); } } None => None, diff --git a/compiler/src/value/group/targets/edwards_bls12.rs b/compiler/src/value/group/targets/edwards_bls12.rs index 9c8cecb525..2776970afc 100644 --- a/compiler/src/value/group/targets/edwards_bls12.rs +++ b/compiler/src/value/group/targets/edwards_bls12.rs @@ -62,9 +62,9 @@ impl GroupType for EdwardsGroupType { } fn to_allocated>(&self, mut cs: CS, span: &Span) -> Result { - self.allocated(cs.ns(|| format!("allocate affine point {}:{}", span.line, span.start))) + self.allocated(cs.ns(|| format!("allocate affine point {}:{}", span.line_start, span.col_start))) .map(|ebg| EdwardsGroupType::Allocated(Box::new(ebg))) - .map_err(|error| GroupError::synthesis_error(error, span.to_owned())) + .map_err(|error| GroupError::synthesis_error(error, span)) } fn negate>(&self, cs: CS, span: &Span) -> Result { @@ -72,7 +72,7 @@ impl GroupType for EdwardsGroupType { EdwardsGroupType::Constant(group) => Ok(EdwardsGroupType::Constant(group.neg())), EdwardsGroupType::Allocated(group) => { let result = , Fq>>::negate(group, cs) - .map_err(|e| GroupError::negate_operation(e, span.to_owned()))?; + .map_err(|e| GroupError::negate_operation(e, span))?; Ok(EdwardsGroupType::Allocated(Box::new(result))) } @@ -91,7 +91,7 @@ impl GroupType for EdwardsGroupType { cs, other_value, ) - .map_err(|e| GroupError::binary_operation("+".to_string(), e, span.to_owned()))?; + .map_err(|e| GroupError::binary_operation("+".to_string(), e, span))?; Ok(EdwardsGroupType::Allocated(Box::new(result))) } @@ -101,7 +101,7 @@ impl GroupType for EdwardsGroupType { Ok(EdwardsGroupType::Allocated(Box::new( allocated_value .add_constant(cs, constant_value) - .map_err(|e| GroupError::binary_operation("+".to_string(), e, span.to_owned()))?, + .map_err(|e| GroupError::binary_operation("+".to_string(), e, span))?, ))) } } @@ -119,7 +119,7 @@ impl GroupType for EdwardsGroupType { cs, other_value, ) - .map_err(|e| GroupError::binary_operation("-".to_string(), e, span.to_owned()))?; + .map_err(|e| GroupError::binary_operation("-".to_string(), e, span))?; Ok(EdwardsGroupType::Allocated(Box::new(result))) } @@ -129,7 +129,7 @@ impl GroupType for EdwardsGroupType { Ok(EdwardsGroupType::Allocated(Box::new( allocated_value .sub_constant(cs, constant_value) - .map_err(|e| GroupError::binary_operation("-".to_string(), e, span.to_owned()))?, + .map_err(|e| GroupError::binary_operation("-".to_string(), e, span))?, ))) } } @@ -152,10 +152,8 @@ impl EdwardsGroupType { } else { let one = edwards_affine_one(); let number_value = match number_info { - (number, neg) if neg => { - -Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span.clone()))? - } - (number, _) => Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span.clone()))?, + (number, neg) if neg => -Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span))?, + (number, _) => Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span))?, }; let result: EdwardsAffine = one.mul(&number_value); @@ -206,7 +204,7 @@ impl EdwardsGroupType { Self::edwards_affine_from_y_str(number_string_typing(&y_string), span, None, span) } // Invalid - (x, y) => Err(GroupError::invalid_group(format!("({}, {})", x, y), span.clone())), + (x, y) => Err(GroupError::invalid_group(format!("({}, {})", x, y), span)), } } @@ -217,14 +215,14 @@ impl EdwardsGroupType { element_span: &Span, ) -> Result { let x = match x_info { - (x_str, neg) if neg => -Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str, x_span.clone()))?, - (x_str, _) => Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str, x_span.clone()))?, + (x_str, neg) if neg => -Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str, x_span))?, + (x_str, _) => Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str, x_span))?, }; match greatest { // Sign provided Some(greatest) => { - EdwardsAffine::from_x_coordinate(x, greatest).ok_or_else(|| GroupError::x_recover(element_span.clone())) + EdwardsAffine::from_x_coordinate(x, greatest).ok_or_else(|| GroupError::x_recover(element_span)) } // Sign inferred None => { @@ -239,7 +237,7 @@ impl EdwardsGroupType { } // Otherwise return error. - Err(GroupError::x_recover(element_span.clone())) + Err(GroupError::x_recover(element_span)) } } } @@ -251,14 +249,14 @@ impl EdwardsGroupType { element_span: &Span, ) -> Result { let y = match y_info { - (y_str, neg) if neg => -Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str, y_span.clone()))?, - (y_str, _) => Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str, y_span.clone()))?, + (y_str, neg) if neg => -Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str, y_span))?, + (y_str, _) => Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str, y_span))?, }; match greatest { // Sign provided Some(greatest) => { - EdwardsAffine::from_y_coordinate(y, greatest).ok_or_else(|| GroupError::y_recover(element_span.clone())) + EdwardsAffine::from_y_coordinate(y, greatest).ok_or_else(|| GroupError::y_recover(element_span)) } // Sign inferred None => { @@ -273,7 +271,7 @@ impl EdwardsGroupType { } // Otherwise return error. - Err(GroupError::y_recover(element_span.clone())) + Err(GroupError::y_recover(element_span)) } } } @@ -287,16 +285,16 @@ impl EdwardsGroupType { ) -> Result { let x = match x_info { (x_str, neg) if neg => { - -Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str.to_string(), x_span.clone()))? + -Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str.to_string(), x_span))? } - (x_str, _) => Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str.to_string(), x_span.clone()))?, + (x_str, _) => Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str.to_string(), x_span))?, }; let y = match y_info { (y_str, neg) if neg => { - -Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str.to_string(), y_span.clone()))? + -Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str.to_string(), y_span))? } - (y_str, _) => Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str.to_string(), y_span.clone()))?, + (y_str, _) => Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str.to_string(), y_span))?, }; let element = EdwardsAffine::new(x, y); @@ -304,7 +302,7 @@ impl EdwardsGroupType { if element.is_on_curve() { Ok(element) } else { - Err(GroupError::not_on_curve(element.to_string(), element_span.clone())) + Err(GroupError::not_on_curve(element.to_string(), element_span)) } } diff --git a/compiler/src/value/integer/integer.rs b/compiler/src/value/integer/integer.rs index 812aa457ef..49b157573f 100644 --- a/compiler/src/value/integer/integer.rs +++ b/compiler/src/value/integer/integer.rs @@ -88,6 +88,26 @@ impl Integer { match_integer!(integer => integer.get_bits()) } + // pub fn get_bits_typed(&self) -> (Vec, IntegerType) { + // let integer = self; + // (match_integer!(integer => integer.to_bits_le()), self.get_type()) + // } + + // pub fn from_bits_typed(type_: &IntegerType, bits: &[Boolean]) -> Integer { + // match type_ { + // IntegerType::U8 => Integer::U8(UInt8::from_bits_le(bits)), + // IntegerType::U16 => Integer::U16(UInt16::from_bits_le(bits)), + // IntegerType::U32 => Integer::U32(UInt32::from_bits_le(bits)), + // IntegerType::U64 => Integer::U64(UInt64::from_bits_le(bits)), + // IntegerType::U128 => Integer::U128(UInt128::from_bits_le(bits)), + // IntegerType::I8 => Integer::I8(Int8::from_bits_le(bits)), + // IntegerType::I16 => Integer::I16(Int16::from_bits_le(bits)), + // IntegerType::I32 => Integer::I32(Int32::from_bits_le(bits)), + // IntegerType::I64 => Integer::I64(Int64::from_bits_le(bits)), + // IntegerType::I128 => Integer::I128(Int128::from_bits_le(bits)), + // } + // } + pub fn get_value(&self) -> Option { let integer = self; match_integer!(integer => integer.get_value()) @@ -97,10 +117,10 @@ impl Integer { let unsigned_integer = self; let value_option: Option = match_unsigned_integer!(unsigned_integer => unsigned_integer.get_value()); - let value = value_option.ok_or_else(|| IntegerError::invalid_index(span.to_owned()))?; + let value = value_option.ok_or_else(|| IntegerError::invalid_index(span))?; let value_usize = value .parse::() - .map_err(|_| IntegerError::invalid_integer(value, span.to_owned()))?; + .map_err(|_| IntegerError::invalid_integer(value, span))?; Ok(value_usize) } @@ -131,70 +151,71 @@ impl Integer { IntegerType::U8 => { let u8_option = option.map(|s| { s.parse::() - .map_err(|_| IntegerError::invalid_integer(s, span.to_owned())) + .map_err(|_| IntegerError::invalid_integer(s, span)) .unwrap() }); - let u8_result = UInt8::alloc(cs.ns(|| format!("`{}: u8` {}:{}", name, span.line, span.start)), || { - u8_option.ok_or(SynthesisError::AssignmentMissing) - }) - .map_err(|_| IntegerError::missing_integer(format!("{}: u8", name), span.to_owned()))?; + let u8_result = UInt8::alloc( + cs.ns(|| format!("`{}: u8` {}:{}", name, span.line_start, span.col_start)), + || u8_option.ok_or(SynthesisError::AssignmentMissing), + ) + .map_err(|_| IntegerError::missing_integer(format!("{}: u8", name), span))?; Integer::U8(u8_result) } IntegerType::U16 => { let u16_option = option.map(|s| { s.parse::() - .map_err(|_| IntegerError::invalid_integer(s, span.to_owned())) + .map_err(|_| IntegerError::invalid_integer(s, span)) .unwrap() }); let u16_result = UInt16::alloc( - cs.ns(|| format!("`{}: u16` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: u16` {}:{}", name, span.line_start, span.col_start)), || u16_option.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| IntegerError::missing_integer(format!("{}: u16", name), span.to_owned()))?; + .map_err(|_| IntegerError::missing_integer(format!("{}: u16", name), span))?; Integer::U16(u16_result) } IntegerType::U32 => { let u32_option = option.map(|s| { s.parse::() - .map_err(|_| IntegerError::invalid_integer(s, span.to_owned())) + .map_err(|_| IntegerError::invalid_integer(s, span)) .unwrap() }); let u32_result = UInt32::alloc( - cs.ns(|| format!("`{}: u32` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: u32` {}:{}", name, span.line_start, span.col_start)), || u32_option.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| IntegerError::missing_integer(format!("{}: u32", name), span.to_owned()))?; + .map_err(|_| IntegerError::missing_integer(format!("{}: u32", name), span))?; Integer::U32(u32_result) } IntegerType::U64 => { let u64_option = option.map(|s| { s.parse::() - .map_err(|_| IntegerError::invalid_integer(s, span.to_owned())) + .map_err(|_| IntegerError::invalid_integer(s, span)) .unwrap() }); let u64_result = UInt64::alloc( - cs.ns(|| format!("`{}: u64` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: u64` {}:{}", name, span.line_start, span.col_start)), || u64_option.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| IntegerError::missing_integer(format!("{}: u64", name), span.to_owned()))?; + .map_err(|_| IntegerError::missing_integer(format!("{}: u64", name), span))?; Integer::U64(u64_result) } IntegerType::U128 => { let u128_option = option.map(|s| { s.parse::() - .map_err(|_| IntegerError::invalid_integer(s, span.to_owned())) + .map_err(|_| IntegerError::invalid_integer(s, span)) .unwrap() }); let u128_result = UInt128::alloc( - cs.ns(|| format!("`{}: u128` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: u128` {}:{}", name, span.line_start, span.col_start)), || u128_option.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| IntegerError::missing_integer(format!("{}: u128", name), span.to_owned()))?; + .map_err(|_| IntegerError::missing_integer(format!("{}: u128", name), span))?; Integer::U128(u128_result) } @@ -202,69 +223,70 @@ impl Integer { IntegerType::I8 => { let i8_option = option.map(|s| { s.parse::() - .map_err(|_| IntegerError::invalid_integer(s, span.to_owned())) + .map_err(|_| IntegerError::invalid_integer(s, span)) .unwrap() }); - let i8_result = Int8::alloc(cs.ns(|| format!("`{}: i8` {}:{}", name, span.line, span.start)), || { - i8_option.ok_or(SynthesisError::AssignmentMissing) - }) - .map_err(|_| IntegerError::missing_integer(format!("{}: i8", name), span.to_owned()))?; + let i8_result = Int8::alloc( + cs.ns(|| format!("`{}: i8` {}:{}", name, span.line_start, span.col_start)), + || i8_option.ok_or(SynthesisError::AssignmentMissing), + ) + .map_err(|_| IntegerError::missing_integer(format!("{}: i8", name), span))?; Integer::I8(i8_result) } IntegerType::I16 => { let i16_option = option.map(|s| { s.parse::() - .map_err(|_| IntegerError::invalid_integer(s, span.to_owned())) + .map_err(|_| IntegerError::invalid_integer(s, span)) .unwrap() }); let i16_result = Int16::alloc( - cs.ns(|| format!("`{}: i16` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: i16` {}:{}", name, span.line_start, span.col_start)), || i16_option.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| IntegerError::missing_integer(format!("{}: i16", name), span.to_owned()))?; + .map_err(|_| IntegerError::missing_integer(format!("{}: i16", name), span))?; Integer::I16(i16_result) } IntegerType::I32 => { let i32_option = option.map(|s| { s.parse::() - .map_err(|_| IntegerError::invalid_integer(s, span.to_owned())) + .map_err(|_| IntegerError::invalid_integer(s, span)) .unwrap() }); let i32_result = Int32::alloc( - cs.ns(|| format!("`{}: i32` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: i32` {}:{}", name, span.line_start, span.col_start)), || i32_option.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| IntegerError::missing_integer(format!("{}: i32", name), span.to_owned()))?; + .map_err(|_| IntegerError::missing_integer(format!("{}: i32", name), span))?; Integer::I32(i32_result) } IntegerType::I64 => { let i64_option = option.map(|s| { s.parse::() - .map_err(|_| IntegerError::invalid_integer(s, span.to_owned())) + .map_err(|_| IntegerError::invalid_integer(s, span)) .unwrap() }); let i64_result = Int64::alloc( - cs.ns(|| format!("`{}: i64` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: i64` {}:{}", name, span.line_start, span.col_start)), || i64_option.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| IntegerError::missing_integer(format!("{}: i64", name), span.to_owned()))?; + .map_err(|_| IntegerError::missing_integer(format!("{}: i64", name), span))?; Integer::I64(i64_result) } IntegerType::I128 => { let i128_option = option.map(|s| { s.parse::() - .map_err(|_| IntegerError::invalid_integer(s, span.to_owned())) + .map_err(|_| IntegerError::invalid_integer(s, span)) .unwrap() }); let i128_result = Int128::alloc( - cs.ns(|| format!("`{}: i128` {}:{}", name, span.line, span.start)), + cs.ns(|| format!("`{}: i128` {}:{}", name, span.line_start, span.col_start)), || i128_option.ok_or(SynthesisError::AssignmentMissing), ) - .map_err(|_| IntegerError::missing_integer(format!("{}: i128", name), span.to_owned()))?; + .map_err(|_| IntegerError::missing_integer(format!("{}: i128", name), span))?; Integer::I128(i128_result) } @@ -284,7 +306,7 @@ impl Integer { if let InputValue::Integer(_type_, number) = input { Some(number) } else { - return Err(IntegerError::invalid_integer(input.to_string(), span.to_owned())); + return Err(IntegerError::invalid_integer(input.to_string(), span)); } } None => None, @@ -298,13 +320,13 @@ impl Integer { cs: &mut CS, span: &Span, ) -> Result { - let unique_namespace = format!("enforce -{} {}:{}", self, span.line, span.start); + let unique_namespace = format!("enforce -{} {}:{}", self, span.line_start, span.col_start); let a = self; let result = match_signed_integer!(a, span => a.neg(cs.ns(|| unique_namespace))); - result.ok_or_else(|| IntegerError::negate_operation(span.to_owned())) + result.ok_or_else(|| IntegerError::negate_operation(span)) } pub fn add>( @@ -313,14 +335,14 @@ impl Integer { other: Self, span: &Span, ) -> Result { - let unique_namespace = format!("enforce {} + {} {}:{}", self, other, span.line, span.start); + let unique_namespace = format!("enforce {} + {} {}:{}", self, other, span.line_start, span.col_start); let a = self; let b = other; let result = match_integers_span!((a, b), span => a.add(cs.ns(|| unique_namespace), &b)); - result.ok_or_else(|| IntegerError::binary_operation("+".to_string(), span.to_owned())) + result.ok_or_else(|| IntegerError::binary_operation("+".to_string(), span)) } pub fn sub>( @@ -329,14 +351,14 @@ impl Integer { other: Self, span: &Span, ) -> Result { - let unique_namespace = format!("enforce {} - {} {}:{}", self, other, span.line, span.start); + let unique_namespace = format!("enforce {} - {} {}:{}", self, other, span.line_start, span.col_start); let a = self; let b = other; let result = match_integers_span!((a, b), span => a.sub(cs.ns(|| unique_namespace), &b)); - result.ok_or_else(|| IntegerError::binary_operation("-".to_string(), span.to_owned())) + result.ok_or_else(|| IntegerError::binary_operation("-".to_string(), span)) } pub fn mul>( @@ -345,14 +367,14 @@ impl Integer { other: Self, span: &Span, ) -> Result { - let unique_namespace = format!("enforce {} * {} {}:{}", self, other, span.line, span.start); + let unique_namespace = format!("enforce {} * {} {}:{}", self, other, span.line_start, span.col_start); let a = self; let b = other; let result = match_integers_span!((a, b), span => a.mul(cs.ns(|| unique_namespace), &b)); - result.ok_or_else(|| IntegerError::binary_operation("*".to_string(), span.to_owned())) + result.ok_or_else(|| IntegerError::binary_operation("*".to_string(), span)) } pub fn div>( @@ -361,14 +383,14 @@ impl Integer { other: Self, span: &Span, ) -> Result { - let unique_namespace = format!("enforce {} ÷ {} {}:{}", self, other, span.line, span.start); + let unique_namespace = format!("enforce {} ÷ {} {}:{}", self, other, span.line_start, span.col_start); let a = self; let b = other; let result = match_integers_span!((a, b), span => a.div(cs.ns(|| unique_namespace), &b)); - result.ok_or_else(|| IntegerError::binary_operation("÷".to_string(), span.to_owned())) + result.ok_or_else(|| IntegerError::binary_operation("÷".to_string(), span)) } pub fn pow>( @@ -377,14 +399,14 @@ impl Integer { other: Self, span: &Span, ) -> Result { - let unique_namespace = format!("enforce {} ** {} {}:{}", self, other, span.line, span.start); + let unique_namespace = format!("enforce {} ** {} {}:{}", self, other, span.line_start, span.col_start); let a = self; let b = other; let result = match_integers_span!((a, b), span => a.pow(cs.ns(|| unique_namespace), &b)); - result.ok_or_else(|| IntegerError::binary_operation("**".to_string(), span.to_owned())) + result.ok_or_else(|| IntegerError::binary_operation("**".to_string(), span)) } } diff --git a/compiler/src/value/integer/macros.rs b/compiler/src/value/integer/macros.rs index 13d0ad2b2a..9cdab71779 100644 --- a/compiler/src/value/integer/macros.rs +++ b/compiler/src/value/integer/macros.rs @@ -84,21 +84,11 @@ macro_rules! match_unsigned_integer { macro_rules! match_signed_integer { ($integer: ident, $span: ident => $expression: expr) => { match $integer { - Integer::I8($integer) => Some(Integer::I8( - $expression.map_err(|e| IntegerError::signed(e, $span.to_owned()))?, - )), - Integer::I16($integer) => Some(Integer::I16( - $expression.map_err(|e| IntegerError::signed(e, $span.to_owned()))?, - )), - Integer::I32($integer) => Some(Integer::I32( - $expression.map_err(|e| IntegerError::signed(e, $span.to_owned()))?, - )), - Integer::I64($integer) => Some(Integer::I64( - $expression.map_err(|e| IntegerError::signed(e, $span.to_owned()))?, - )), - Integer::I128($integer) => Some(Integer::I128( - $expression.map_err(|e| IntegerError::signed(e, $span.to_owned()))?, - )), + Integer::I8($integer) => Some(Integer::I8($expression.map_err(|e| IntegerError::signed(e, $span))?)), + Integer::I16($integer) => Some(Integer::I16($expression.map_err(|e| IntegerError::signed(e, $span))?)), + Integer::I32($integer) => Some(Integer::I32($expression.map_err(|e| IntegerError::signed(e, $span))?)), + Integer::I64($integer) => Some(Integer::I64($expression.map_err(|e| IntegerError::signed(e, $span))?)), + Integer::I128($integer) => Some(Integer::I128($expression.map_err(|e| IntegerError::signed(e, $span))?)), _ => None, } @@ -129,37 +119,37 @@ macro_rules! match_integers { macro_rules! match_integers_span { (($a: ident, $b: ident), $span: ident => $expression:expr) => { match ($a, $b) { - (Integer::U8($a), Integer::U8($b)) => Some(Integer::U8( - $expression.map_err(|e| IntegerError::synthesis(e, $span.to_owned()))?, - )), + (Integer::U8($a), Integer::U8($b)) => { + Some(Integer::U8($expression.map_err(|e| IntegerError::synthesis(e, $span))?)) + } (Integer::U16($a), Integer::U16($b)) => Some(Integer::U16( - $expression.map_err(|e| IntegerError::synthesis(e, $span.to_owned()))?, + $expression.map_err(|e| IntegerError::synthesis(e, $span))?, )), (Integer::U32($a), Integer::U32($b)) => Some(Integer::U32( - $expression.map_err(|e| IntegerError::synthesis(e, $span.to_owned()))?, + $expression.map_err(|e| IntegerError::synthesis(e, $span))?, )), (Integer::U64($a), Integer::U64($b)) => Some(Integer::U64( - $expression.map_err(|e| IntegerError::synthesis(e, $span.to_owned()))?, + $expression.map_err(|e| IntegerError::synthesis(e, $span))?, )), (Integer::U128($a), Integer::U128($b)) => Some(Integer::U128( - $expression.map_err(|e| IntegerError::synthesis(e, $span.to_owned()))?, + $expression.map_err(|e| IntegerError::synthesis(e, $span))?, )), - (Integer::I8($a), Integer::I8($b)) => Some(Integer::I8( - $expression.map_err(|e| IntegerError::signed(e, $span.to_owned()))?, - )), - (Integer::I16($a), Integer::I16($b)) => Some(Integer::I16( - $expression.map_err(|e| IntegerError::signed(e, $span.to_owned()))?, - )), - (Integer::I32($a), Integer::I32($b)) => Some(Integer::I32( - $expression.map_err(|e| IntegerError::signed(e, $span.to_owned()))?, - )), - (Integer::I64($a), Integer::I64($b)) => Some(Integer::I64( - $expression.map_err(|e| IntegerError::signed(e, $span.to_owned()))?, - )), - (Integer::I128($a), Integer::I128($b)) => Some(Integer::I128( - $expression.map_err(|e| IntegerError::signed(e, $span.to_owned()))?, - )), + (Integer::I8($a), Integer::I8($b)) => { + Some(Integer::I8($expression.map_err(|e| IntegerError::signed(e, $span))?)) + } + (Integer::I16($a), Integer::I16($b)) => { + Some(Integer::I16($expression.map_err(|e| IntegerError::signed(e, $span))?)) + } + (Integer::I32($a), Integer::I32($b)) => { + Some(Integer::I32($expression.map_err(|e| IntegerError::signed(e, $span))?)) + } + (Integer::I64($a), Integer::I64($b)) => { + Some(Integer::I64($expression.map_err(|e| IntegerError::signed(e, $span))?)) + } + (Integer::I128($a), Integer::I128($b)) => { + Some(Integer::I128($expression.map_err(|e| IntegerError::signed(e, $span))?)) + } (_, _) => None, } }; diff --git a/compiler/tests/address/ternary.leo b/compiler/tests/address/ternary.leo index 29ecccb918..bdd88b9d92 100644 --- a/compiler/tests/address/ternary.leo +++ b/compiler/tests/address/ternary.leo @@ -2,7 +2,7 @@ function main(s: bool, c: address) { let a = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8); let b = address(aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r); - let r = if s? a: b; + let r = s? a: b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/circuits/pedersen_mock.leo b/compiler/tests/circuits/pedersen_mock.leo index 0b42c64a6e..559ebb7614 100644 --- a/compiler/tests/circuits/pedersen_mock.leo +++ b/compiler/tests/circuits/pedersen_mock.leo @@ -8,7 +8,7 @@ circuit PedersenHash { function hash(self, bits: [bool; 512]) -> u32 { let mut digest: u32 = 0; for i in 0..512 { - let base = if bits[i] ? self.parameters[i] : 0u32; + let base = bits[i] ? self.parameters[i] : 0u32; digest += base; } return digest diff --git a/compiler/tests/field/ternary.leo b/compiler/tests/field/ternary.leo index 49cd6a4e62..f193ad82a3 100644 --- a/compiler/tests/field/ternary.leo +++ b/compiler/tests/field/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: field, b: field, c: field) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/group/mod.rs b/compiler/tests/group/mod.rs index d7fca2a4cd..f40cad73f6 100644 --- a/compiler/tests/group/mod.rs +++ b/compiler/tests/group/mod.rs @@ -39,8 +39,8 @@ pub fn group_element_to_input_value(g: EdwardsAffine) -> GroupValue { }; GroupValue::Tuple(GroupTuple { - x: GroupCoordinate::Number(x, fake_span.clone()), - y: GroupCoordinate::Number(y, fake_span.clone()), + x: GroupCoordinate::Number(x, fake_span), + y: GroupCoordinate::Number(y, fake_span), span: fake_span, }) } diff --git a/compiler/tests/group/ternary.leo b/compiler/tests/group/ternary.leo index b213bb1419..fb69b74521 100644 --- a/compiler/tests/group/ternary.leo +++ b/compiler/tests/group/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: group, b: group, c: group) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/integers/i128/ternary.leo b/compiler/tests/integers/i128/ternary.leo index 5c2f199499..a923c428e6 100644 --- a/compiler/tests/integers/i128/ternary.leo +++ b/compiler/tests/integers/i128/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: i128, b: i128, c: i128) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/integers/i16/ternary.leo b/compiler/tests/integers/i16/ternary.leo index ccf29bfd50..4586b87bb4 100644 --- a/compiler/tests/integers/i16/ternary.leo +++ b/compiler/tests/integers/i16/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: i16, b: i16, c: i16) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/integers/i32/ternary.leo b/compiler/tests/integers/i32/ternary.leo index 3066547ae3..7927c2998b 100644 --- a/compiler/tests/integers/i32/ternary.leo +++ b/compiler/tests/integers/i32/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: i32, b: i32, c: i32) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/integers/i64/ternary.leo b/compiler/tests/integers/i64/ternary.leo index 811c759bdf..1a2d03a77f 100644 --- a/compiler/tests/integers/i64/ternary.leo +++ b/compiler/tests/integers/i64/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: i64, b: i64, c: i64) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/integers/i8/ternary.leo b/compiler/tests/integers/i8/ternary.leo index de797c6e3b..e1ec1943c9 100644 --- a/compiler/tests/integers/i8/ternary.leo +++ b/compiler/tests/integers/i8/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: i8, b: i8, c: i8) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/integers/u128/ternary.leo b/compiler/tests/integers/u128/ternary.leo index 48299fac66..22e2e67058 100644 --- a/compiler/tests/integers/u128/ternary.leo +++ b/compiler/tests/integers/u128/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: u128, b: u128, c: u128) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/integers/u16/ternary.leo b/compiler/tests/integers/u16/ternary.leo index 2e2752a130..11d836570d 100644 --- a/compiler/tests/integers/u16/ternary.leo +++ b/compiler/tests/integers/u16/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: u16, b: u16, c: u16) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/integers/u32/ternary.leo b/compiler/tests/integers/u32/ternary.leo index fde04ac4b8..3c96a7236c 100644 --- a/compiler/tests/integers/u32/ternary.leo +++ b/compiler/tests/integers/u32/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: u32, b: u32, c: u32) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/integers/u64/ternary.leo b/compiler/tests/integers/u64/ternary.leo index 315fd7400b..4c4ddd8e0c 100644 --- a/compiler/tests/integers/u64/ternary.leo +++ b/compiler/tests/integers/u64/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: u64, b: u64, c: u64) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/integers/u8/ternary.leo b/compiler/tests/integers/u8/ternary.leo index ce868a5ec9..1b436aa054 100644 --- a/compiler/tests/integers/u8/ternary.leo +++ b/compiler/tests/integers/u8/ternary.leo @@ -1,5 +1,5 @@ function main(s: bool, a: u8, b: u8, c: u8) { - let r = if s ? a : b; + let r = s ? a : b; console.assert(r == c); } \ No newline at end of file diff --git a/compiler/tests/statements/conditional/for_loop.leo b/compiler/tests/statements/conditional/for_loop.leo index 060d27d965..2dca076858 100644 --- a/compiler/tests/statements/conditional/for_loop.leo +++ b/compiler/tests/statements/conditional/for_loop.leo @@ -7,7 +7,7 @@ function main(a: bool) { } } - let r: u32 = if a ? 6 : 0; + let r: u32 = a ? 6 : 0; console.assert(r == b); } diff --git a/compiler/tests/statements/ternary_basic.leo b/compiler/tests/statements/ternary_basic.leo index 1f9c1f65a2..675b681fa9 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; + let c = a ? true : false; let d = c == b; } \ No newline at end of file diff --git a/compiler/tests/syntax/mod.rs b/compiler/tests/syntax/mod.rs index 2fb1a100ea..009835c15d 100644 --- a/compiler/tests/syntax/mod.rs +++ b/compiler/tests/syntax/mod.rs @@ -16,7 +16,6 @@ use crate::{expect_asg_error, parse_input, parse_program}; use leo_compiler::errors::CompilerError; -use leo_grammar::ParserError; use leo_input::InputParserError; pub mod identifiers; @@ -28,7 +27,7 @@ fn test_semicolon() { let error = parse_program(program_string).err().unwrap(); match error { - CompilerError::ParserError(ParserError::SyntaxError(_)) => {} + CompilerError::SyntaxError(_) => {} _ => panic!("test_semicolon failed the wrong expected error, should be a ParserError"), } } diff --git a/grammar/LICENSE.md b/grammar/LICENSE.md deleted file mode 100644 index b95c626e2a..0000000000 --- a/grammar/LICENSE.md +++ /dev/null @@ -1,596 +0,0 @@ -GNU General Public License -========================== - -Version 3, 29 June 2007 - -Copyright © 2007 Free Software Foundation, Inc. <> - -Everyone is permitted to copy and distribute verbatim copies of this license -document, but changing it is not allowed. - -## Preamble - -The GNU General Public License is a free, copyleft license for software and other -kinds of works. - -The licenses for most software and other practical works are designed to take away -your freedom to share and change the works. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change all versions of a -program--to make sure it remains free software for all its users. We, the Free -Software Foundation, use the GNU General Public License for most of our software; it -applies also to any other work released this way by its authors. You can apply it to -your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our General -Public Licenses are designed to make sure that you have the freedom to distribute -copies of free software (and charge for them if you wish), that you receive source -code or can get it if you want it, that you can change the software or use pieces of -it in new free programs, and that you know you can do these things. - -To protect your rights, we need to prevent others from denying you these rights or -asking you to surrender the rights. Therefore, you have certain responsibilities if -you distribute copies of the software, or if you modify it: responsibilities to -respect the freedom of others. - -For example, if you distribute copies of such a program, whether gratis or for a fee, -you must pass on to the recipients the same freedoms that you received. You must make -sure that they, too, receive or can get the source code. And you must show them these -terms so they know their rights. - -Developers that use the GNU GPL protect your rights with two steps: **(1)** assert -copyright on the software, and **(2)** offer you this License giving you legal permission -to copy, distribute and/or modify it. - -For the developers' and authors' protection, the GPL clearly explains that there is -no warranty for this free software. For both users' and authors' sake, the GPL -requires that modified versions be marked as changed, so that their problems will not -be attributed erroneously to authors of previous versions. - -Some devices are designed to deny users access to install or run modified versions of -the software inside them, although the manufacturer can do so. This is fundamentally -incompatible with the aim of protecting users' freedom to change the software. The -systematic pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we have designed -this version of the GPL to prohibit the practice for those products. If such problems -arise substantially in other domains, we stand ready to extend this provision to -those domains in future versions of the GPL, as needed to protect the freedom of -users. - -Finally, every program is threatened constantly by software patents. States should -not allow patents to restrict development and use of software on general-purpose -computers, but in those that do, we wish to avoid the special danger that patents -applied to a free program could make it effectively proprietary. To prevent this, the -GPL assures that patents cannot be used to render the program non-free. - -The precise terms and conditions for copying, distribution and modification follow. - -## TERMS AND CONDITIONS - -### 0. Definitions - -“This License” refers to version 3 of the GNU General Public License. - -“Copyright” also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - -“The Program” refers to any copyrightable work licensed under this -License. Each licensee is addressed as “you”. “Licensees” and -“recipients” may be individuals or organizations. - -To “modify” a work means to copy from or adapt all or part of the work in -a fashion requiring copyright permission, other than the making of an exact copy. The -resulting work is called a “modified version” of the earlier work or a -work “based on” the earlier work. - -A “covered work” means either the unmodified Program or a work based on -the Program. - -To “propagate” a work means to do anything with it that, without -permission, would make you directly or secondarily liable for infringement under -applicable copyright law, except executing it on a computer or modifying a private -copy. Propagation includes copying, distribution (with or without modification), -making available to the public, and in some countries other activities as well. - -To “convey” a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through a computer -network, with no transfer of a copy, is not conveying. - -An interactive user interface displays “Appropriate Legal Notices” to the -extent that it includes a convenient and prominently visible feature that **(1)** -displays an appropriate copyright notice, and **(2)** tells the user that there is no -warranty for the work (except to the extent that warranties are provided), that -licensees may convey the work under this License, and how to view a copy of this -License. If the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - -### 1. Source Code - -The “source code” for a work means the preferred form of the work for -making modifications to it. “Object code” means any non-source form of a -work. - -A “Standard Interface” means an interface that either is an official -standard defined by a recognized standards body, or, in the case of interfaces -specified for a particular programming language, one that is widely used among -developers working in that language. - -The “System Libraries” of an executable work include anything, other than -the work as a whole, that **(a)** is included in the normal form of packaging a Major -Component, but which is not part of that Major Component, and **(b)** serves only to -enable use of the work with that Major Component, or to implement a Standard -Interface for which an implementation is available to the public in source code form. -A “Major Component”, in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system (if any) on which -the executable work runs, or a compiler used to produce the work, or an object code -interpreter used to run it. - -The “Corresponding Source” for a work in object code form means all the -source code needed to generate, install, and (for an executable work) run the object -code and to modify the work, including scripts to control those activities. However, -it does not include the work's System Libraries, or general-purpose tools or -generally available free programs which are used unmodified in performing those -activities but which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for the work, and -the source code for shared libraries and dynamically linked subprograms that the work -is specifically designed to require, such as by intimate data communication or -control flow between those subprograms and other parts of the work. - -The Corresponding Source need not include anything that users can regenerate -automatically from other parts of the Corresponding Source. - -The Corresponding Source for a work in source code form is that same work. - -### 2. Basic Permissions - -All rights granted under this License are granted for the term of copyright on the -Program, and are irrevocable provided the stated conditions are met. This License -explicitly affirms your unlimited permission to run the unmodified Program. The -output from running a covered work is covered by this License only if the output, -given its content, constitutes a covered work. This License acknowledges your rights -of fair use or other equivalent, as provided by copyright law. - -You may make, run and propagate covered works that you do not convey, without -conditions so long as your license otherwise remains in force. You may convey covered -works to others for the sole purpose of having them make modifications exclusively -for you, or provide you with facilities for running those works, provided that you -comply with the terms of this License in conveying all material for which you do not -control copyright. Those thus making or running the covered works for you must do so -exclusively on your behalf, under your direction and control, on terms that prohibit -them from making any copies of your copyrighted material outside their relationship -with you. - -Conveying under any other circumstances is permitted solely under the conditions -stated below. Sublicensing is not allowed; section 10 makes it unnecessary. - -### 3. Protecting Users' Legal Rights From Anti-Circumvention Law - -No covered work shall be deemed part of an effective technological measure under any -applicable law fulfilling obligations under article 11 of the WIPO copyright treaty -adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention -of such measures. - -When you convey a covered work, you waive any legal power to forbid circumvention of -technological measures to the extent such circumvention is effected by exercising -rights under this License with respect to the covered work, and you disclaim any -intention to limit operation or modification of the work as a means of enforcing, -against the work's users, your or third parties' legal rights to forbid circumvention -of technological measures. - -### 4. Conveying Verbatim Copies - -You may convey verbatim copies of the Program's source code as you receive it, in any -medium, provided that you conspicuously and appropriately publish on each copy an -appropriate copyright notice; keep intact all notices stating that this License and -any non-permissive terms added in accord with section 7 apply to the code; keep -intact all notices of the absence of any warranty; and give all recipients a copy of -this License along with the Program. - -You may charge any price or no price for each copy that you convey, and you may offer -support or warranty protection for a fee. - -### 5. Conveying Modified Source Versions - -You may convey a work based on the Program, or the modifications to produce it from -the Program, in the form of source code under the terms of section 4, provided that -you also meet all of these conditions: - -* **a)** The work must carry prominent notices stating that you modified it, and giving a -relevant date. -* **b)** The work must carry prominent notices stating that it is released under this -License and any conditions added under section 7. This requirement modifies the -requirement in section 4 to “keep intact all notices”. -* **c)** You must license the entire work, as a whole, under this License to anyone who -comes into possession of a copy. This License will therefore apply, along with any -applicable section 7 additional terms, to the whole of the work, and all its parts, -regardless of how they are packaged. This License gives no permission to license the -work in any other way, but it does not invalidate such permission if you have -separately received it. -* **d)** If the work has interactive user interfaces, each must display Appropriate Legal -Notices; however, if the Program has interactive interfaces that do not display -Appropriate Legal Notices, your work need not make them do so. - -A compilation of a covered work with other separate and independent works, which are -not by their nature extensions of the covered work, and which are not combined with -it such as to form a larger program, in or on a volume of a storage or distribution -medium, is called an “aggregate” if the compilation and its resulting -copyright are not used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work in an aggregate -does not cause this License to apply to the other parts of the aggregate. - -### 6. Conveying Non-Source Forms - -You may convey a covered work in object code form under the terms of sections 4 and -5, provided that you also convey the machine-readable Corresponding Source under the -terms of this License, in one of these ways: - -* **a)** Convey the object code in, or embodied in, a physical product (including a -physical distribution medium), accompanied by the Corresponding Source fixed on a -durable physical medium customarily used for software interchange. -* **b)** Convey the object code in, or embodied in, a physical product (including a -physical distribution medium), accompanied by a written offer, valid for at least -three years and valid for as long as you offer spare parts or customer support for -that product model, to give anyone who possesses the object code either **(1)** a copy of -the Corresponding Source for all the software in the product that is covered by this -License, on a durable physical medium customarily used for software interchange, for -a price no more than your reasonable cost of physically performing this conveying of -source, or **(2)** access to copy the Corresponding Source from a network server at no -charge. -* **c)** Convey individual copies of the object code with a copy of the written offer to -provide the Corresponding Source. This alternative is allowed only occasionally and -noncommercially, and only if you received the object code with such an offer, in -accord with subsection 6b. -* **d)** Convey the object code by offering access from a designated place (gratis or for -a charge), and offer equivalent access to the Corresponding Source in the same way -through the same place at no further charge. You need not require recipients to copy -the Corresponding Source along with the object code. If the place to copy the object -code is a network server, the Corresponding Source may be on a different server -(operated by you or a third party) that supports equivalent copying facilities, -provided you maintain clear directions next to the object code saying where to find -the Corresponding Source. Regardless of what server hosts the Corresponding Source, -you remain obligated to ensure that it is available for as long as needed to satisfy -these requirements. -* **e)** Convey the object code using peer-to-peer transmission, provided you inform -other peers where the object code and Corresponding Source of the work are being -offered to the general public at no charge under subsection 6d. - -A separable portion of the object code, whose source code is excluded from the -Corresponding Source as a System Library, need not be included in conveying the -object code work. - -A “User Product” is either **(1)** a “consumer product”, which -means any tangible personal property which is normally used for personal, family, or -household purposes, or **(2)** anything designed or sold for incorporation into a -dwelling. In determining whether a product is a consumer product, doubtful cases -shall be resolved in favor of coverage. For a particular product received by a -particular user, “normally used” refers to a typical or common use of -that class of product, regardless of the status of the particular user or of the way -in which the particular user actually uses, or expects or is expected to use, the -product. A product is a consumer product regardless of whether the product has -substantial commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - -“Installation Information” for a User Product means any methods, -procedures, authorization keys, or other information required to install and execute -modified versions of a covered work in that User Product from a modified version of -its Corresponding Source. The information must suffice to ensure that the continued -functioning of the modified object code is in no case prevented or interfered with -solely because modification has been made. - -If you convey an object code work under this section in, or with, or specifically for -use in, a User Product, and the conveying occurs as part of a transaction in which -the right of possession and use of the User Product is transferred to the recipient -in perpetuity or for a fixed term (regardless of how the transaction is -characterized), the Corresponding Source conveyed under this section must be -accompanied by the Installation Information. But this requirement does not apply if -neither you nor any third party retains the ability to install modified object code -on the User Product (for example, the work has been installed in ROM). - -The requirement to provide Installation Information does not include a requirement to -continue to provide support service, warranty, or updates for a work that has been -modified or installed by the recipient, or for the User Product in which it has been -modified or installed. Access to a network may be denied when the modification itself -materially and adversely affects the operation of the network or violates the rules -and protocols for communication across the network. - -Corresponding Source conveyed, and Installation Information provided, in accord with -this section must be in a format that is publicly documented (and with an -implementation available to the public in source code form), and must require no -special password or key for unpacking, reading or copying. - -### 7. Additional Terms - -“Additional permissions” are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. Additional -permissions that are applicable to the entire Program shall be treated as though they -were included in this License, to the extent that they are valid under applicable -law. If additional permissions apply only to part of the Program, that part may be -used separately under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - -When you convey a copy of a covered work, you may at your option remove any -additional permissions from that copy, or from any part of it. (Additional -permissions may be written to require their own removal in certain cases when you -modify the work.) You may place additional permissions on material, added by you to a -covered work, for which you have or can give appropriate copyright permission. - -Notwithstanding any other provision of this License, for material you add to a -covered work, you may (if authorized by the copyright holders of that material) -supplement the terms of this License with terms: - -* **a)** Disclaiming warranty or limiting liability differently from the terms of -sections 15 and 16 of this License; or -* **b)** Requiring preservation of specified reasonable legal notices or author -attributions in that material or in the Appropriate Legal Notices displayed by works -containing it; or -* **c)** Prohibiting misrepresentation of the origin of that material, or requiring that -modified versions of such material be marked in reasonable ways as different from the -original version; or -* **d)** Limiting the use for publicity purposes of names of licensors or authors of the -material; or -* **e)** Declining to grant rights under trademark law for use of some trade names, -trademarks, or service marks; or -* **f)** Requiring indemnification of licensors and authors of that material by anyone -who conveys the material (or modified versions of it) with contractual assumptions of -liability to the recipient, for any liability that these contractual assumptions -directly impose on those licensors and authors. - -All other non-permissive additional terms are considered “further -restrictions” within the meaning of section 10. If the Program as you received -it, or any part of it, contains a notice stating that it is governed by this License -along with a term that is a further restriction, you may remove that term. If a -license document contains a further restriction but permits relicensing or conveying -under this License, you may add to a covered work material governed by the terms of -that license document, provided that the further restriction does not survive such -relicensing or conveying. - -If you add terms to a covered work in accord with this section, you must place, in -the relevant source files, a statement of the additional terms that apply to those -files, or a notice indicating where to find the applicable terms. - -Additional terms, permissive or non-permissive, may be stated in the form of a -separately written license, or stated as exceptions; the above requirements apply -either way. - -### 8. Termination - -You may not propagate or modify a covered work except as expressly provided under -this License. Any attempt otherwise to propagate or modify it is void, and will -automatically terminate your rights under this License (including any patent licenses -granted under the third paragraph of section 11). - -However, if you cease all violation of this License, then your license from a -particular copyright holder is reinstated **(a)** provisionally, unless and until the -copyright holder explicitly and finally terminates your license, and **(b)** permanently, -if the copyright holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - -Moreover, your license from a particular copyright holder is reinstated permanently -if the copyright holder notifies you of the violation by some reasonable means, this -is the first time you have received notice of violation of this License (for any -work) from that copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - -Termination of your rights under this section does not terminate the licenses of -parties who have received copies or rights from you under this License. If your -rights have been terminated and not permanently reinstated, you do not qualify to -receive new licenses for the same material under section 10. - -### 9. Acceptance Not Required for Having Copies - -You are not required to accept this License in order to receive or run a copy of the -Program. Ancillary propagation of a covered work occurring solely as a consequence of -using peer-to-peer transmission to receive a copy likewise does not require -acceptance. However, nothing other than this License grants you permission to -propagate or modify any covered work. These actions infringe copyright if you do not -accept this License. Therefore, by modifying or propagating a covered work, you -indicate your acceptance of this License to do so. - -### 10. Automatic Licensing of Downstream Recipients - -Each time you convey a covered work, the recipient automatically receives a license -from the original licensors, to run, modify and propagate that work, subject to this -License. You are not responsible for enforcing compliance by third parties with this -License. - -An “entity transaction” is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an organization, or -merging organizations. If propagation of a covered work results from an entity -transaction, each party to that transaction who receives a copy of the work also -receives whatever licenses to the work the party's predecessor in interest had or -could give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if the predecessor -has it or can get it with reasonable efforts. - -You may not impose any further restrictions on the exercise of the rights granted or -affirmed under this License. For example, you may not impose a license fee, royalty, -or other charge for exercise of rights granted under this License, and you may not -initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging -that any patent claim is infringed by making, using, selling, offering for sale, or -importing the Program or any portion of it. - -### 11. Patents - -A “contributor” is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The work thus -licensed is called the contributor's “contributor version”. - -A contributor's “essential patent claims” are all patent claims owned or -controlled by the contributor, whether already acquired or hereafter acquired, that -would be infringed by some manner, permitted by this License, of making, using, or -selling its contributor version, but do not include claims that would be infringed -only as a consequence of further modification of the contributor version. For -purposes of this definition, “control” includes the right to grant patent -sublicenses in a manner consistent with the requirements of this License. - -Each contributor grants you a non-exclusive, worldwide, royalty-free patent license -under the contributor's essential patent claims, to make, use, sell, offer for sale, -import and otherwise run, modify and propagate the contents of its contributor -version. - -In the following three paragraphs, a “patent license” is any express -agreement or commitment, however denominated, not to enforce a patent (such as an -express permission to practice a patent or covenant not to sue for patent -infringement). To “grant” such a patent license to a party means to make -such an agreement or commitment not to enforce a patent against the party. - -If you convey a covered work, knowingly relying on a patent license, and the -Corresponding Source of the work is not available for anyone to copy, free of charge -and under the terms of this License, through a publicly available network server or -other readily accessible means, then you must either **(1)** cause the Corresponding -Source to be so available, or **(2)** arrange to deprive yourself of the benefit of the -patent license for this particular work, or **(3)** arrange, in a manner consistent with -the requirements of this License, to extend the patent license to downstream -recipients. “Knowingly relying” means you have actual knowledge that, but -for the patent license, your conveying the covered work in a country, or your -recipient's use of the covered work in a country, would infringe one or more -identifiable patents in that country that you have reason to believe are valid. - -If, pursuant to or in connection with a single transaction or arrangement, you -convey, or propagate by procuring conveyance of, a covered work, and grant a patent -license to some of the parties receiving the covered work authorizing them to use, -propagate, modify or convey a specific copy of the covered work, then the patent -license you grant is automatically extended to all recipients of the covered work and -works based on it. - -A patent license is “discriminatory” if it does not include within the -scope of its coverage, prohibits the exercise of, or is conditioned on the -non-exercise of one or more of the rights that are specifically granted under this -License. You may not convey a covered work if you are a party to an arrangement with -a third party that is in the business of distributing software, under which you make -payment to the third party based on the extent of your activity of conveying the -work, and under which the third party grants, to any of the parties who would receive -the covered work from you, a discriminatory patent license **(a)** in connection with -copies of the covered work conveyed by you (or copies made from those copies), or **(b)** -primarily for and in connection with specific products or compilations that contain -the covered work, unless you entered into that arrangement, or that patent license -was granted, prior to 28 March 2007. - -Nothing in this License shall be construed as excluding or limiting any implied -license or other defenses to infringement that may otherwise be available to you -under applicable patent law. - -### 12. No Surrender of Others' Freedom - -If conditions are imposed on you (whether by court order, agreement or otherwise) -that contradict the conditions of this License, they do not excuse you from the -conditions of this License. If you cannot convey a covered work so as to satisfy -simultaneously your obligations under this License and any other pertinent -obligations, then as a consequence you may not convey it at all. For example, if you -agree to terms that obligate you to collect a royalty for further conveying from -those to whom you convey the Program, the only way you could satisfy both those terms -and this License would be to refrain entirely from conveying the Program. - -### 13. Use with the GNU Affero General Public License - -Notwithstanding any other provision of this License, you have permission to link or -combine any covered work with a work licensed under version 3 of the GNU Affero -General Public License into a single combined work, and to convey the resulting work. -The terms of this License will continue to apply to the part which is the covered -work, but the special requirements of the GNU Affero General Public License, section -13, concerning interaction through a network will apply to the combination as such. - -### 14. Revised Versions of this License - -The Free Software Foundation may publish revised and/or new versions of the GNU -General Public License from time to time. Such new versions will be similar in spirit -to the present version, but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Program specifies that -a certain numbered version of the GNU General Public License “or any later -version” applies to it, you have the option of following the terms and -conditions either of that numbered version or of any later version published by the -Free Software Foundation. If the Program does not specify a version number of the GNU -General Public License, you may choose any version ever published by the Free -Software Foundation. - -If the Program specifies that a proxy can decide which future versions of the GNU -General Public License can be used, that proxy's public statement of acceptance of a -version permanently authorizes you to choose that version for the Program. - -Later license versions may give you additional or different permissions. However, no -additional obligations are imposed on any author or copyright holder as a result of -your choosing to follow a later version. - -### 15. Disclaimer of Warranty - -THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE -QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE -DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -### 16. Limitation of Liability - -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY -COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS -PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, -INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE -OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE -WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - -### 17. Interpretation of Sections 15 and 16 - -If the disclaimer of warranty and limitation of liability provided above cannot be -given local legal effect according to their terms, reviewing courts shall apply local -law that most closely approximates an absolute waiver of all civil liability in -connection with the Program, unless a warranty or assumption of liability accompanies -a copy of the Program in return for a fee. - -_END OF TERMS AND CONDITIONS_ - -## How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible use to -the public, the best way to achieve this is to make it free software which everyone -can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach them -to the start of each source file to most effectively state the exclusion of warranty; -and each file should have at least the “copyright” line and a pointer to -where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - -If the program does terminal interaction, make it output a short notice like this -when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type 'show c' for details. - -The hypothetical commands `show w` and `show c` should show the appropriate parts of -the General Public License. Of course, your program's commands might be different; -for a GUI interface, you would use an “about box”. - -You should also get your employer (if you work as a programmer) or school, if any, to -sign a “copyright disclaimer” for the program, if necessary. For more -information on this, and how to apply and follow the GNU GPL, see -<>. - -The GNU General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may consider it -more useful to permit linking proprietary applications with the library. If this is -what you want to do, use the GNU Lesser General Public License instead of this -License. But first, please read -<>. diff --git a/grammar/README.md b/grammar/README.md deleted file mode 100644 index 1fd44dbf0d..0000000000 --- a/grammar/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# leo-grammar - -[![Crates.io](https://img.shields.io/crates/v/leo-grammar.svg?color=neon)](https://crates.io/crates/leo-grammar) -[![Authors](https://img.shields.io/badge/authors-Aleo-orange.svg)](../AUTHORS) -[![License](https://img.shields.io/badge/License-GPLv3-blue.svg)](./LICENSE.md) - -## Command-line instructions - -To generate an AST of the Leo program and save it as a JSON file , run: -``` -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/grammar/benches/grammar.rs b/grammar/benches/grammar.rs deleted file mode 100644 index ec24d5edb7..0000000000 --- a/grammar/benches/grammar.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::Grammar; - -use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use std::path::Path; - -fn leo_grammar<'ast>(filepath: &'ast Path, program_string: &'ast str) { - let result = Grammar::<'ast>::new(filepath, program_string).unwrap(); - black_box(result); -} - -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("Grammar::new", |b| b.iter(|| leo_grammar(&filepath, program_string))); -} - -criterion_group!(benches, criterion_benchmark); -criterion_main!(benches); diff --git a/grammar/benches/main.leo b/grammar/benches/main.leo deleted file mode 100644 index aafe79bcce..0000000000 --- a/grammar/benches/main.leo +++ /dev/null @@ -1,26 +0,0 @@ -circuit PedersenHash { - parameters: [group; 256], - - // Instantiates a Pedersen hash circuit - function new(self, parameters: [group; 256]) -> Self { - return Self { parameters: parameters } - } - - function hash(bits: [bool; 256]) -> group { - let mut digest: group = 0; - for i in 0..256 { - if bits[i] { - digest += self.parameters[i]; - } - } - return digest - } -} - -// The 'pedersen-hash' main function. -function main() -> group { - let parameters = [1group; 256]; - let pedersen = PedersenHash::new(parameters); - let hash_input: [bool; 256] = [true; 256]; - return pedersen.hash(hash_input) -} diff --git a/grammar/src/access/access.rs b/grammar/src/access/access.rs deleted file mode 100644 index 1c33808692..0000000000 --- a/grammar/src/access/access.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{access::*, ast::Rule}; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::access))] -pub enum Access<'ast> { - Array(ArrayAccess<'ast>), - Tuple(TupleAccess<'ast>), - Call(CallAccess<'ast>), - Object(MemberAccess<'ast>), - StaticObject(StaticMemberAccess<'ast>), -} diff --git a/grammar/src/access/array_access.rs b/grammar/src/access/array_access.rs deleted file mode 100644 index fe98590ce9..0000000000 --- a/grammar/src/access/array_access.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::RangeOrExpression, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::access_array))] -pub struct ArrayAccess<'ast> { - pub expression: RangeOrExpression<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/access/assignee_access.rs b/grammar/src/access/assignee_access.rs deleted file mode 100644 index 880ad65255..0000000000 --- a/grammar/src/access/assignee_access.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - access::{ArrayAccess, MemberAccess, TupleAccess}, - ast::Rule, -}; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::access_assignee))] -pub enum AssigneeAccess<'ast> { - Array(ArrayAccess<'ast>), - Tuple(TupleAccess<'ast>), - Member(MemberAccess<'ast>), -} - -impl<'ast> fmt::Display for AssigneeAccess<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - AssigneeAccess::Array(ref array) => write!(f, "[{}]", array.expression), - AssigneeAccess::Tuple(ref tuple) => write!(f, ".{}", tuple.number), - AssigneeAccess::Member(ref member) => write!(f, ".{}", member.identifier), - } - } -} diff --git a/grammar/src/access/call_access.rs b/grammar/src/access/call_access.rs deleted file mode 100644 index 398c05a3f9..0000000000 --- a/grammar/src/access/call_access.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, expressions::Expression, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::access_call))] -pub struct CallAccess<'ast> { - pub expressions: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/access/member_access.rs b/grammar/src/access/member_access.rs deleted file mode 100644 index a3e2e9e030..0000000000 --- a/grammar/src/access/member_access.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Identifier, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::access_member))] -pub struct MemberAccess<'ast> { - pub identifier: Identifier<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/access/mod.rs b/grammar/src/access/mod.rs deleted file mode 100644 index 927ebc16cb..0000000000 --- a/grammar/src/access/mod.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -#![allow(clippy::module_inception)] - -pub mod access; -pub use access::*; - -pub mod self_access; -pub use self_access::*; - -pub mod array_access; -pub use array_access::*; - -pub mod assignee_access; -pub use assignee_access::*; - -pub mod call_access; -pub use call_access::*; - -pub mod member_access; -pub use member_access::*; - -pub mod static_member_access; -pub use static_member_access::*; - -pub mod tuple_access; -pub use tuple_access::*; diff --git a/grammar/src/access/self_access.rs b/grammar/src/access/self_access.rs deleted file mode 100644 index 4c4c171835..0000000000 --- a/grammar/src/access/self_access.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{access::*, ast::Rule}; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::self_access))] -pub enum SelfAccess<'ast> { - Object(MemberAccess<'ast>), - StaticObject(StaticMemberAccess<'ast>), -} diff --git a/grammar/src/access/static_member_access.rs b/grammar/src/access/static_member_access.rs deleted file mode 100644 index 7452d3e804..0000000000 --- a/grammar/src/access/static_member_access.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Identifier, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::access_static_member))] -pub struct StaticMemberAccess<'ast> { - pub identifier: Identifier<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/access/tuple_access.rs b/grammar/src/access/tuple_access.rs deleted file mode 100644 index 952e6a426f..0000000000 --- a/grammar/src/access/tuple_access.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, values::PositiveNumber, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::access_tuple))] -pub struct TupleAccess<'ast> { - pub number: PositiveNumber<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/annotations/annotation_arguments.rs b/grammar/src/annotations/annotation_arguments.rs deleted file mode 100644 index bf58a2c358..0000000000 --- a/grammar/src/annotations/annotation_arguments.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::annotation_arguments))] -pub struct AnnotationArguments<'ast> { - pub arguments: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::annotation_argument))] -pub struct AnnotationArgument<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub value: String, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/annotations/annotation_name.rs b/grammar/src/annotations/annotation_name.rs deleted file mode 100644 index d7cb1c12c9..0000000000 --- a/grammar/src/annotations/annotation_name.rs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::annotation_name))] -pub enum AnnotationName<'ast> { - Context(Context<'ast>), - Test(Test<'ast>), -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::context))] -pub struct Context<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::test))] -pub struct Test<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/annotations/annotation_symbol.rs b/grammar/src/annotations/annotation_symbol.rs deleted file mode 100644 index 16f042be92..0000000000 --- a/grammar/src/annotations/annotation_symbol.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::annotation_symbol))] -pub struct AnnotationSymbol<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/annotations/annotations.rs b/grammar/src/annotations/annotations.rs deleted file mode 100644 index 045eb3a47e..0000000000 --- a/grammar/src/annotations/annotations.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - annotations::{AnnotationArguments, AnnotationName, AnnotationSymbol}, - ast::Rule, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::annotation))] -pub struct Annotation<'ast> { - pub symbol: AnnotationSymbol<'ast>, - pub name: AnnotationName<'ast>, - pub arguments: Option>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/annotations/mod.rs b/grammar/src/annotations/mod.rs deleted file mode 100644 index 1da61336ed..0000000000 --- a/grammar/src/annotations/mod.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -#![allow(clippy::module_inception)] - -pub mod annotations; -pub use annotations::*; - -pub mod annotation_symbol; -pub use annotation_symbol::*; - -pub mod annotation_name; -pub use annotation_name::*; - -pub mod annotation_arguments; -pub use annotation_arguments::*; diff --git a/grammar/src/ast.rs b/grammar/src/ast.rs deleted file mode 100644 index 87da0a1967..0000000000 --- a/grammar/src/ast.rs +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -//! Abstract syntax tree (ast) representation from leo.pest. -use crate::{ - common::Identifier, - expressions::{ - ArrayInitializerExpression, - ArrayInlineExpression, - CircuitInlineExpression, - Expression, - PostfixExpression, - SelfPostfixExpression, - TernaryExpression, - UnaryExpression, - }, - operations::{BinaryOperation, UnaryOperation}, - values::Value, -}; - -use crate::expressions::TupleExpression; -use from_pest::{ConversionError, FromPest, Void}; -use pest::{ - error::Error, - iterators::{Pair, Pairs}, - prec_climber::{Assoc, Operator, PrecClimber}, - Parser, - Span, -}; - -#[derive(Parser)] -#[grammar = "leo.pest"] -pub struct LanguageParser; - -pub fn parse(program_string: &str) -> Result, Error> { - LanguageParser::parse(Rule::file, program_string) -} - -pub(crate) fn span_into_string(span: Span) -> String { - span.as_str().to_string() -} - -lazy_static! { - static ref PRECEDENCE_CLIMBER: PrecClimber = precedence_climber(); -} - -// Expressions - -fn precedence_climber() -> PrecClimber { - PrecClimber::new(vec![ - Operator::new(Rule::operation_or, Assoc::Left), - Operator::new(Rule::operation_and, Assoc::Left), - Operator::new(Rule::operation_eq, Assoc::Left) - | Operator::new(Rule::operation_ne, Assoc::Left) - | Operator::new(Rule::operation_ge, Assoc::Left) - | Operator::new(Rule::operation_gt, Assoc::Left) - | Operator::new(Rule::operation_le, Assoc::Left) - | Operator::new(Rule::operation_lt, Assoc::Left), - Operator::new(Rule::operation_add, Assoc::Left) | Operator::new(Rule::operation_sub, Assoc::Left), - Operator::new(Rule::operation_mul, Assoc::Left) | Operator::new(Rule::operation_div, Assoc::Left), - Operator::new(Rule::operation_pow, Assoc::Left), - ]) -} - -fn parse_term(pair: Pair) -> Expression { - match pair.as_rule() { - Rule::expression_term => { - let clone = pair.clone(); - let next = clone.into_inner().next().unwrap(); - match next.as_rule() { - Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(), // Parenthesis case - Rule::expression_tuple => { - Expression::Tuple(TupleExpression::from_pest(&mut pair.into_inner()).unwrap()) - } - Rule::expression_array_inline => { - Expression::ArrayInline(ArrayInlineExpression::from_pest(&mut pair.into_inner()).unwrap()) - } - Rule::expression_array_initializer => Expression::ArrayInitializer(Box::new( - ArrayInitializerExpression::from_pest(&mut pair.into_inner()).unwrap(), - )), - Rule::expression_circuit_inline => { - Expression::CircuitInline(CircuitInlineExpression::from_pest(&mut pair.into_inner()).unwrap()) - } - Rule::expression_conditional => { - Expression::Ternary(Box::new(TernaryExpression::from_pest(&mut pair.into_inner()).unwrap())) - } - Rule::expression_unary => { - // The following is necessary to match with the unary operator and its unary expression - let span = next.as_span(); - let mut inner = next.into_inner(); - let operation = match inner.next().unwrap().as_rule() { - Rule::operation_unary => { - UnaryOperation::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap() - } - rule => unreachable!("`expression_unary` should yield `operation_unary`, found {:#?}", rule), - }; - let expression = parse_term(inner.next().unwrap()); - Expression::Unary(Box::new(UnaryExpression { - operation, - expression, - span, - })) - } - Rule::expression_postfix => { - Expression::Postfix(PostfixExpression::from_pest(&mut pair.into_inner()).unwrap()) - } - Rule::self_expression_postfix => { - Expression::SelfPostfix(SelfPostfixExpression::from_pest(&mut pair.into_inner()).unwrap()) - } - Rule::value => Expression::Value(Value::from_pest(&mut pair.into_inner()).unwrap()), - Rule::identifier => Expression::Identifier(Identifier::from_pest(&mut pair.into_inner()).unwrap()), - rule => unreachable!( - "`term` should contain one of ['value', 'identifier', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}", - rule - ), - } - } - rule => unreachable!( - "`parse_expression_term` should be invoked on `Rule::expression_term`, found {:#?}", - rule - ), - } -} - -fn binary_expression<'ast>(lhs: Expression<'ast>, pair: Pair<'ast, Rule>, rhs: Expression<'ast>) -> Expression<'ast> { - let (start, _) = lhs.span().clone().split(); - let (_, end) = rhs.span().clone().split(); - let span = start.span(&end); - - match pair.as_rule() { - Rule::operation_or => Expression::binary(BinaryOperation::Or, lhs, rhs, span), - Rule::operation_and => Expression::binary(BinaryOperation::And, lhs, rhs, span), - Rule::operation_eq => Expression::binary(BinaryOperation::Eq, lhs, rhs, span), - Rule::operation_ne => Expression::binary(BinaryOperation::Ne, lhs, rhs, span), - Rule::operation_ge => Expression::binary(BinaryOperation::Ge, lhs, rhs, span), - Rule::operation_gt => Expression::binary(BinaryOperation::Gt, lhs, rhs, span), - Rule::operation_le => Expression::binary(BinaryOperation::Le, lhs, rhs, span), - Rule::operation_lt => Expression::binary(BinaryOperation::Lt, lhs, rhs, span), - Rule::operation_add => Expression::binary(BinaryOperation::Add, lhs, rhs, span), - Rule::operation_sub => Expression::binary(BinaryOperation::Sub, lhs, rhs, span), - Rule::operation_mul => Expression::binary(BinaryOperation::Mul, lhs, rhs, span), - Rule::operation_div => Expression::binary(BinaryOperation::Div, lhs, rhs, span), - Rule::operation_pow => Expression::binary(BinaryOperation::Pow, lhs, rhs, span), - _ => unreachable!(), - } -} - -impl<'ast> FromPest<'ast> for Expression<'ast> { - type FatalError = Void; - type Rule = Rule; - - fn from_pest(pest: &mut Pairs<'ast, Rule>) -> Result> { - let pair = pest.peek().ok_or(::from_pest::ConversionError::NoMatch)?; - match pair.as_rule() { - Rule::expression => { - // advance the iterator - pest.next(); - Ok(PRECEDENCE_CLIMBER.climb(pair.into_inner(), parse_term, binary_expression)) - } - _ => Err(ConversionError::NoMatch), - } - } -} diff --git a/grammar/src/circuits/circuit.rs b/grammar/src/circuits/circuit.rs deleted file mode 100644 index a704df6962..0000000000 --- a/grammar/src/circuits/circuit.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, circuits::CircuitMember, common::Identifier, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::circuit))] -pub struct Circuit<'ast> { - pub identifier: Identifier<'ast>, - pub members: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/circuits/circuit_implied_variable.rs b/grammar/src/circuits/circuit_implied_variable.rs deleted file mode 100644 index eeb9aee4bb..0000000000 --- a/grammar/src/circuits/circuit_implied_variable.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, circuits::CircuitVariable, common::Identifier}; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::circuit_implied_variable))] -pub enum CircuitImpliedVariable<'ast> { - CircuitVariable(CircuitVariable<'ast>), - Identifier(Identifier<'ast>), -} diff --git a/grammar/src/circuits/circuit_member.rs b/grammar/src/circuits/circuit_member.rs deleted file mode 100644 index 6ce1c822b8..0000000000 --- a/grammar/src/circuits/circuit_member.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, circuits::CircuitVariableDefinition, functions::Function}; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::circuit_member))] -pub enum CircuitMember<'ast> { - CircuitVariableDefinition(CircuitVariableDefinition<'ast>), - CircuitFunction(Function<'ast>), -} diff --git a/grammar/src/circuits/circuit_variable.rs b/grammar/src/circuits/circuit_variable.rs deleted file mode 100644 index 30c35bbb0a..0000000000 --- a/grammar/src/circuits/circuit_variable.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Identifier, expressions::Expression, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::circuit_variable))] -pub struct CircuitVariable<'ast> { - pub identifier: Identifier<'ast>, - pub expression: Expression<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/circuits/circuit_variable_definition.rs b/grammar/src/circuits/circuit_variable_definition.rs deleted file mode 100644 index cef9933bc6..0000000000 --- a/grammar/src/circuits/circuit_variable_definition.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Identifier, types::Type, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::circuit_variable_definition))] -pub struct CircuitVariableDefinition<'ast> { - pub identifier: Identifier<'ast>, - pub type_: Type<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/circuits/mod.rs b/grammar/src/circuits/mod.rs deleted file mode 100644 index 7b9a25eed6..0000000000 --- a/grammar/src/circuits/mod.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod circuit; -pub use circuit::*; - -pub mod circuit_implied_variable; -pub use circuit_implied_variable::*; - -pub mod circuit_variable; -pub use circuit_variable::*; - -pub mod circuit_variable_definition; -pub use circuit_variable_definition::*; - -pub mod circuit_member; -pub use circuit_member::*; diff --git a/grammar/src/common/assignee.rs b/grammar/src/common/assignee.rs deleted file mode 100644 index 066fe1b0dd..0000000000 --- a/grammar/src/common/assignee.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{access::AssigneeAccess, ast::Rule, common::SelfKeywordOrIdentifier, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::assignee))] -pub struct Assignee<'ast> { - pub name: SelfKeywordOrIdentifier<'ast>, - pub accesses: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for Assignee<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.name)?; - for (i, access) in self.accesses.iter().enumerate() { - write!(f, "{}", access)?; - if i < self.accesses.len() - 1 { - write!(f, ", ")?; - } - } - write!(f, "") - } -} diff --git a/grammar/src/common/declare.rs b/grammar/src/common/declare.rs deleted file mode 100644 index c5a77ecacb..0000000000 --- a/grammar/src/common/declare.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::declare))] -pub enum Declare { - Const(Const), - Let(Let), -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::const_))] -pub struct Const {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::let_))] -pub struct Let {} diff --git a/grammar/src/common/eoi.rs b/grammar/src/common/eoi.rs deleted file mode 100644 index b37cf4f230..0000000000 --- a/grammar/src/common/eoi.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize, Deserialize)] -#[pest_ast(rule(Rule::EOI))] -pub struct EOI; diff --git a/grammar/src/common/identifier.rs b/grammar/src/common/identifier.rs deleted file mode 100644 index 0406e51336..0000000000 --- a/grammar/src/common/identifier.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::identifier))] -pub struct Identifier<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub value: String, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for Identifier<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.value) - } -} diff --git a/grammar/src/common/keyword_or_identifier.rs b/grammar/src/common/keyword_or_identifier.rs deleted file mode 100644 index 5ab05f5dad..0000000000 --- a/grammar/src/common/keyword_or_identifier.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Identifier, functions::InputKeyword, types::SelfType}; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::keyword_or_identifier))] -pub enum KeywordOrIdentifier<'ast> { - SelfType(SelfType<'ast>), - Input(InputKeyword<'ast>), - Identifier(Identifier<'ast>), -} - -impl<'ast> fmt::Display for KeywordOrIdentifier<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - KeywordOrIdentifier::SelfType(self_type) => write!(f, "{}", self_type), - KeywordOrIdentifier::Input(input_keyword) => write!(f, "{}", input_keyword), - KeywordOrIdentifier::Identifier(name) => write!(f, "{}", name), - } - } -} diff --git a/grammar/src/common/line_end.rs b/grammar/src/common/line_end.rs deleted file mode 100644 index bfbc27948a..0000000000 --- a/grammar/src/common/line_end.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::LINE_END))] -pub struct LineEnd; - -impl fmt::Display for LineEnd { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, ";") - } -} diff --git a/grammar/src/common/mod.rs b/grammar/src/common/mod.rs deleted file mode 100644 index d72b2ea578..0000000000 --- a/grammar/src/common/mod.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod assignee; -pub use assignee::*; - -pub mod declare; -pub use declare::*; - -pub mod eoi; -pub use eoi::*; - -pub mod identifier; -pub use identifier::*; - -pub mod keyword_or_identifier; -pub use keyword_or_identifier::*; - -pub mod line_end; -pub use line_end::*; - -pub mod mutable; -pub use mutable::*; - -pub mod mut_self_keyword; -pub use mut_self_keyword::*; - -pub mod range; -pub use range::*; - -pub mod range_or_expression; -pub use range_or_expression::*; - -pub mod self_keyword; -pub use self_keyword::*; - -pub mod self_keyword_or_identifier; -pub use self_keyword_or_identifier::*; - -pub mod spread; -pub use spread::*; - -pub mod spread_or_expression; -pub use spread_or_expression::*; - -pub mod static_; -pub use static_::*; - -pub mod variables; -pub use variables::*; - -pub mod variable_name; -pub use variable_name::*; diff --git a/grammar/src/common/mut_self_keyword.rs b/grammar/src/common/mut_self_keyword.rs deleted file mode 100644 index 1ddc0cfa57..0000000000 --- a/grammar/src/common/mut_self_keyword.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - common::{Mutable, SelfKeyword}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::mut_self_keyword))] -pub struct MutSelfKeyword<'ast> { - pub mutable: Mutable, - pub self_keyword: SelfKeyword<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for MutSelfKeyword<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "mut {}", self.self_keyword) - } -} diff --git a/grammar/src/common/mutable.rs b/grammar/src/common/mutable.rs deleted file mode 100644 index 283ec9eae1..0000000000 --- a/grammar/src/common/mutable.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::mutable))] -pub struct Mutable {} diff --git a/grammar/src/common/range.rs b/grammar/src/common/range.rs deleted file mode 100644 index cdb1f923f5..0000000000 --- a/grammar/src/common/range.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, expressions::Expression, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::range_operator))] -pub struct RangeOperator {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::range))] -pub struct Range<'ast> { - pub from: Option>, - pub operator: RangeOperator, - pub to: Option>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/common/range_or_expression.rs b/grammar/src/common/range_or_expression.rs deleted file mode 100644 index 2b7ae2eb68..0000000000 --- a/grammar/src/common/range_or_expression.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Range, expressions::Expression}; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::range_or_expression))] -pub enum RangeOrExpression<'ast> { - Range(Range<'ast>), - Expression(Expression<'ast>), -} - -impl<'ast> fmt::Display for RangeOrExpression<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - RangeOrExpression::Expression(ref expression) => write!(f, "{}", expression), - RangeOrExpression::Range(ref range) => write!( - f, - "{}..{}", - range - .from - .as_ref() - .map(|v| v.to_string()) - .unwrap_or_else(|| "".to_string()), - range - .to - .as_ref() - .map(|v| v.to_string()) - .unwrap_or_else(|| "".to_string()), - ), - } - } -} diff --git a/grammar/src/common/self_keyword.rs b/grammar/src/common/self_keyword.rs deleted file mode 100644 index 60721a7fab..0000000000 --- a/grammar/src/common/self_keyword.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::self_keyword))] -pub struct SelfKeyword<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub keyword: String, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for SelfKeyword<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.keyword) - } -} diff --git a/grammar/src/common/self_keyword_or_identifier.rs b/grammar/src/common/self_keyword_or_identifier.rs deleted file mode 100644 index 83e27901eb..0000000000 --- a/grammar/src/common/self_keyword_or_identifier.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - common::{Identifier, SelfKeyword}, -}; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::self_keyword_or_identifier))] -pub enum SelfKeywordOrIdentifier<'ast> { - SelfKeyword(SelfKeyword<'ast>), - Identifier(Identifier<'ast>), -} - -impl<'ast> fmt::Display for SelfKeywordOrIdentifier<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - SelfKeywordOrIdentifier::SelfKeyword(self_keyword) => write!(f, "{}", self_keyword), - SelfKeywordOrIdentifier::Identifier(identifier) => write!(f, "{}", identifier), - } - } -} diff --git a/grammar/src/common/spread_or_expression.rs b/grammar/src/common/spread_or_expression.rs deleted file mode 100644 index cd4bbc21d6..0000000000 --- a/grammar/src/common/spread_or_expression.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Spread, expressions::Expression}; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::spread_or_expression))] -pub enum SpreadOrExpression<'ast> { - Spread(Spread<'ast>), - Expression(Expression<'ast>), -} - -impl<'ast> fmt::Display for SpreadOrExpression<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - SpreadOrExpression::Spread(ref spread) => write!(f, "{}", spread), - SpreadOrExpression::Expression(ref expression) => write!(f, "{}", expression), - } - } -} diff --git a/grammar/src/common/static_.rs b/grammar/src/common/static_.rs deleted file mode 100644 index 82ee9edfd1..0000000000 --- a/grammar/src/common/static_.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::static_))] -pub struct Static {} diff --git a/grammar/src/common/variable_name.rs b/grammar/src/common/variable_name.rs deleted file mode 100644 index f9c6fe2e28..0000000000 --- a/grammar/src/common/variable_name.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - common::{Identifier, Mutable}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::variable_name))] -pub struct VariableName<'ast> { - pub mutable: Option, - pub identifier: Identifier<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for VariableName<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(ref _mutable) = self.mutable { - write!(f, "mut ")?; - } - - write!(f, "{}", self.identifier) - } -} diff --git a/grammar/src/common/variables.rs b/grammar/src/common/variables.rs deleted file mode 100644 index 939107fd7a..0000000000 --- a/grammar/src/common/variables.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::VariableName, types::Type, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::variables))] -pub struct Variables<'ast> { - pub names: Vec>, - pub type_: Option>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for Variables<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.names.len() == 1 { - // mut a - write!(f, "{}", self.names[0])?; - } else { - // (a, mut b) - let names = self.names.iter().map(|x| x.to_string()).collect::>().join(","); - - write!(f, "({})", names)?; - } - - if self.type_.is_some() { - write!(f, ": {}", self.type_.as_ref().unwrap())?; - } - - write!(f, "") - } -} diff --git a/grammar/src/console/console_assert.rs b/grammar/src/console/console_assert.rs deleted file mode 100644 index 681f10dfc9..0000000000 --- a/grammar/src/console/console_assert.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, expressions::Expression, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::console_assert))] -pub struct ConsoleAssert<'ast> { - pub expression: Expression<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for ConsoleAssert<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "assert({})", self.expression) - } -} diff --git a/grammar/src/console/console_error.rs b/grammar/src/console/console_error.rs deleted file mode 100644 index 8155c8d75f..0000000000 --- a/grammar/src/console/console_error.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, console::FormattedString, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::console_error))] -pub struct ConsoleError<'ast> { - pub string: FormattedString<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for ConsoleError<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "error({})", self.string) - } -} diff --git a/grammar/src/console/console_function.rs b/grammar/src/console/console_function.rs deleted file mode 100644 index b2cb97a418..0000000000 --- a/grammar/src/console/console_function.rs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - console::{ConsoleAssert, ConsoleDebug, ConsoleError, ConsoleLog}, -}; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::console_function))] -pub enum ConsoleFunction<'ast> { - Assert(ConsoleAssert<'ast>), - Debug(ConsoleDebug<'ast>), - Error(ConsoleError<'ast>), - Log(ConsoleLog<'ast>), -} - -impl<'ast> fmt::Display for ConsoleFunction<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - ConsoleFunction::Assert(assert) => write!(f, "{}", assert), - ConsoleFunction::Debug(debug) => write!(f, "{}", debug), - ConsoleFunction::Error(error) => write!(f, "{}", error), - ConsoleFunction::Log(log) => write!(f, "{}", log), - } - } -} diff --git a/grammar/src/console/console_function_call.rs b/grammar/src/console/console_function_call.rs deleted file mode 100644 index 18183927e9..0000000000 --- a/grammar/src/console/console_function_call.rs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - common::LineEnd, - console::{ConsoleFunction, ConsoleKeyword}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::console_function_call))] -pub struct ConsoleFunctionCall<'ast> { - pub keyword: ConsoleKeyword<'ast>, - pub function: ConsoleFunction<'ast>, - pub line_end: LineEnd, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for ConsoleFunctionCall<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "console.{};", self.function) - } -} diff --git a/grammar/src/console/console_keyword.rs b/grammar/src/console/console_keyword.rs deleted file mode 100644 index b9f98355ed..0000000000 --- a/grammar/src/console/console_keyword.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::console_keyword))] -pub struct ConsoleKeyword<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/console/console_log.rs b/grammar/src/console/console_log.rs deleted file mode 100644 index 06e6f457f0..0000000000 --- a/grammar/src/console/console_log.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, console::FormattedString, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::console_log))] -pub struct ConsoleLog<'ast> { - pub string: FormattedString<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for ConsoleLog<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "log({})", self.string) - } -} diff --git a/grammar/src/console/formatted_container.rs b/grammar/src/console/formatted_container.rs deleted file mode 100644 index 2943280b52..0000000000 --- a/grammar/src/console/formatted_container.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::formatted_container))] -pub struct FormattedContainer<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for FormattedContainer<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{{}}") - } -} diff --git a/grammar/src/console/formatted_string.rs b/grammar/src/console/formatted_string.rs deleted file mode 100644 index f0e80d3209..0000000000 --- a/grammar/src/console/formatted_string.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - console::FormattedContainer, - expressions::Expression, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::formatted_string))] -pub struct FormattedString<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub string: String, - pub containers: Vec>, - pub parameters: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for FormattedString<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.string) - } -} diff --git a/grammar/src/console/mod.rs b/grammar/src/console/mod.rs deleted file mode 100644 index 30bd4481ab..0000000000 --- a/grammar/src/console/mod.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod console_assert; -pub use console_assert::*; - -pub mod console_debug; -pub use console_debug::*; - -pub mod console_error; -pub use console_error::*; - -pub mod console_function; -pub use console_function::*; - -pub mod console_function_call; -pub use console_function_call::*; - -pub mod console_keyword; -pub use console_keyword::*; - -pub mod console_log; -pub use console_log::*; - -pub mod formatted_container; -pub use formatted_container::*; - -pub mod formatted_string; -pub use formatted_string::*; diff --git a/grammar/src/definitions/annotated_definition.rs b/grammar/src/definitions/annotated_definition.rs deleted file mode 100644 index 2bb3bf2d77..0000000000 --- a/grammar/src/definitions/annotated_definition.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{annotations::Annotation, ast::Rule, definitions::Definition, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::definition_annotated))] -pub struct AnnotatedDefinition<'ast> { - pub annotation: Annotation<'ast>, - pub definition: Box>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/definitions/definition.rs b/grammar/src/definitions/definition.rs deleted file mode 100644 index 7fd46ef7f5..0000000000 --- a/grammar/src/definitions/definition.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - circuits::Circuit, - definitions::{AnnotatedDefinition, Deprecated}, - functions::Function, - imports::Import, -}; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::definition))] -pub enum Definition<'ast> { - Annotated(AnnotatedDefinition<'ast>), - Import(Import<'ast>), - Circuit(Circuit<'ast>), - Function(Function<'ast>), - Deprecated(Deprecated<'ast>), -} diff --git a/grammar/src/definitions/deprecated.rs b/grammar/src/definitions/deprecated.rs deleted file mode 100644 index 5c8d514113..0000000000 --- a/grammar/src/definitions/deprecated.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -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>), -} diff --git a/grammar/src/definitions/mod.rs b/grammar/src/definitions/mod.rs deleted file mode 100644 index b1f44725ff..0000000000 --- a/grammar/src/definitions/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod annotated_definition; -pub use annotated_definition::*; - -pub mod definition; -pub use definition::*; - -pub mod deprecated; -pub use deprecated::*; diff --git a/grammar/src/errors/parser.rs b/grammar/src/errors/parser.rs deleted file mode 100644 index 6f831d0ec2..0000000000 --- a/grammar/src/errors/parser.rs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, errors::SyntaxError}; - -use pest::error::Error; -use std::path::{Path, PathBuf}; - -#[derive(Debug, Error)] -pub enum ParserError { - #[error("{}: {}", _0, _1)] - Crate(&'static str, String), - - #[error("Cannot read from the provided file path - {:?}", _0)] - FileReadError(PathBuf), - - #[error("{}", _0)] - IoError(#[from] std::io::Error), - - #[error("{}", _0)] - JsonError(#[from] serde_json::error::Error), - - #[error("{}", _0)] - SyntaxError(#[from] SyntaxError), - - #[error("Unable to construct program abstract syntax tree")] - SyntaxTreeError, -} - -impl ParserError { - pub fn set_path(&mut self, path: &Path) { - if let ParserError::SyntaxError(error) = self { - let new_error: Error = match error { - SyntaxError::Error(error) => { - let new_error = error.clone(); - new_error.with_path(path.to_str().unwrap()) - } - }; - - tracing::error!("{}", new_error); - - *error = SyntaxError::Error(new_error); - } - } -} - -impl From> for ParserError { - fn from(error: Error) -> Self { - ParserError::SyntaxError(SyntaxError::from(error)) - } -} diff --git a/grammar/src/errors/syntax.rs b/grammar/src/errors/syntax.rs deleted file mode 100644 index 9f8f98b81b..0000000000 --- a/grammar/src/errors/syntax.rs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest::error::Error; - -#[derive(Debug, Error)] -pub enum SyntaxError { - #[error("aborting due to syntax error")] - Error(Error), -} - -impl From> for SyntaxError { - fn from(mut error: Error) -> Self { - error = error.renamed_rules(|rule| match *rule { - Rule::LINE_END => "`;`".to_owned(), - Rule::type_integer => "`u32`".to_owned(), - Rule::type_field => "`field`".to_owned(), - Rule::type_group => "`group`".to_owned(), - Rule::address => "an aleo address: `aleo1...`".to_owned(), - Rule::file => "an import, circuit, or function".to_owned(), - Rule::identifier => "a variable name".to_owned(), - Rule::type_ => "a type".to_owned(), - Rule::access => "`.`, `::`, `()`".to_owned(), - - Rule::operation_and => "`&&`".to_owned(), - Rule::operation_or => "`||`".to_owned(), - Rule::operation_eq => "`==`".to_owned(), - Rule::operation_ne => "`!=`".to_owned(), - Rule::operation_ge => "`>=`".to_owned(), - Rule::operation_gt => "`>`".to_owned(), - Rule::operation_le => "`<=`".to_owned(), - Rule::operation_lt => "`<`".to_owned(), - Rule::operation_add => "`+`".to_owned(), - Rule::operation_sub => "`-`".to_owned(), - Rule::operation_mul => "`*`".to_owned(), - Rule::operation_div => "`/`".to_owned(), - Rule::operation_pow => "`**`".to_owned(), - - Rule::package => "package. Check package and import names for errors.".to_owned(), - Rule::package_name => { - "package name. Please use lowercase letters, numbers, and dashes `-` only.".to_owned() - } - - rule => format!("{:?}", rule), - }); - - SyntaxError::Error(error) - } -} diff --git a/grammar/src/expressions/array_initializer_expression.rs b/grammar/src/expressions/array_initializer_expression.rs deleted file mode 100644 index c2a73e0d09..0000000000 --- a/grammar/src/expressions/array_initializer_expression.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, expressions::Expression, types::ArrayDimensions, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::expression_array_initializer))] -pub struct ArrayInitializerExpression<'ast> { - pub expression: Expression<'ast>, - pub dimensions: ArrayDimensions<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/expressions/array_inline_expression.rs b/grammar/src/expressions/array_inline_expression.rs deleted file mode 100644 index 5b3f4b7810..0000000000 --- a/grammar/src/expressions/array_inline_expression.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::SpreadOrExpression, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::expression_array_inline))] -pub struct ArrayInlineExpression<'ast> { - pub expressions: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/expressions/binary_expression.rs b/grammar/src/expressions/binary_expression.rs deleted file mode 100644 index 1086121d5b..0000000000 --- a/grammar/src/expressions/binary_expression.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{expressions::Expression, operations::BinaryOperation, SpanDef}; - -use pest::Span; -use serde::Serialize; - -#[derive(Clone, Debug, PartialEq, Serialize)] -pub struct BinaryExpression<'ast> { - pub operation: BinaryOperation, - pub left: Expression<'ast>, - pub right: Expression<'ast>, - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/expressions/circuit_inline_expression.rs b/grammar/src/expressions/circuit_inline_expression.rs deleted file mode 100644 index 6a51792bae..0000000000 --- a/grammar/src/expressions/circuit_inline_expression.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, circuits::CircuitImpliedVariable, common::Identifier, types::SelfType, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::expression_circuit_inline))] -pub struct CircuitInlineExpression<'ast> { - pub name: CircuitName<'ast>, - pub members: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::circuit_name))] -pub enum CircuitName<'ast> { - SelfType(SelfType<'ast>), - Identifier(Identifier<'ast>), -} diff --git a/grammar/src/expressions/expression.rs b/grammar/src/expressions/expression.rs deleted file mode 100644 index 7d71761a5c..0000000000 --- a/grammar/src/expressions/expression.rs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{common::Identifier, expressions::*, operations::BinaryOperation, values::Value}; - -use pest::Span; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, PartialEq, Serialize)] -pub enum Expression<'ast> { - Value(Value<'ast>), - Identifier(Identifier<'ast>), - Unary(Box>), - Binary(Box>), - Ternary(Box>), - ArrayInline(ArrayInlineExpression<'ast>), - ArrayInitializer(Box>), - CircuitInline(CircuitInlineExpression<'ast>), - Postfix(PostfixExpression<'ast>), - SelfPostfix(SelfPostfixExpression<'ast>), - Tuple(TupleExpression<'ast>), -} - -impl<'ast> Expression<'ast> { - pub fn binary( - operation: BinaryOperation, - left: Expression<'ast>, - right: Expression<'ast>, - span: Span<'ast>, - ) -> Self { - Expression::Binary(Box::new(BinaryExpression { - operation, - left, - right, - span, - })) - } - - pub fn ternary( - first: Expression<'ast>, - second: Expression<'ast>, - third: Expression<'ast>, - span: Span<'ast>, - ) -> Self { - Expression::Ternary(Box::new(TernaryExpression { - first, - second, - third, - span, - })) - } - - pub fn span(&self) -> &Span<'ast> { - match self { - Expression::Value(expression) => &expression.span(), - Expression::Identifier(expression) => &expression.span, - Expression::Unary(expression) => &expression.span, - Expression::Binary(expression) => &expression.span, - Expression::Ternary(expression) => &expression.span, - Expression::ArrayInline(expression) => &expression.span, - Expression::ArrayInitializer(expression) => &expression.span, - Expression::CircuitInline(expression) => &expression.span, - Expression::Postfix(expression) => &expression.span, - Expression::SelfPostfix(expression) => &expression.span, - Expression::Tuple(expression) => &expression.span, - } - } -} - -impl<'ast> fmt::Display for Expression<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Expression::Value(ref expression) => write!(f, "{}", expression), - Expression::Identifier(ref expression) => write!(f, "{}", expression), - Expression::Unary(ref expression) => write!(f, "{}", expression), - Expression::Binary(ref expression) => write!(f, "{} == {}", expression.left, expression.right), - Expression::Ternary(ref expression) => write!( - f, - "if {} ? {} : {}", - expression.first, expression.second, expression.third - ), - Expression::ArrayInline(ref expression) => { - for (i, spread_or_expression) in expression.expressions.iter().enumerate() { - write!(f, "{}", spread_or_expression)?; - if i < expression.expressions.len() - 1 { - write!(f, ", ")?; - } - } - write!(f, "") - } - Expression::ArrayInitializer(ref expression) => { - write!(f, "[{} ; ({})]", expression.expression, expression.dimensions) - } - Expression::CircuitInline(ref expression) => write!(f, "{}", expression.span.as_str()), - Expression::Postfix(ref expression) => write!(f, "{}", expression.span.as_str()), - Expression::SelfPostfix(ref expression) => write!(f, "{}", expression.span.as_str()), - Expression::Tuple(ref expression) => write!(f, "{}", expression.span.as_str()), - } - } -} diff --git a/grammar/src/expressions/postfix_expression.rs b/grammar/src/expressions/postfix_expression.rs deleted file mode 100644 index 923de16161..0000000000 --- a/grammar/src/expressions/postfix_expression.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{access::Access, ast::Rule, common::KeywordOrIdentifier, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::expression_postfix))] -pub struct PostfixExpression<'ast> { - pub name: KeywordOrIdentifier<'ast>, - pub accesses: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/expressions/self_postfix_expression.rs b/grammar/src/expressions/self_postfix_expression.rs deleted file mode 100644 index 21017bda2d..0000000000 --- a/grammar/src/expressions/self_postfix_expression.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - access::{Access, SelfAccess}, - ast::Rule, - common::SelfKeyword, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::self_expression_postfix))] -pub struct SelfPostfixExpression<'ast> { - pub name: SelfKeyword<'ast>, - pub self_access: SelfAccess<'ast>, - pub accesses: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/expressions/ternary_expression.rs b/grammar/src/expressions/ternary_expression.rs deleted file mode 100644 index 163750bd61..0000000000 --- a/grammar/src/expressions/ternary_expression.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, expressions::Expression, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::expression_conditional))] -pub struct TernaryExpression<'ast> { - pub first: Expression<'ast>, - pub second: Expression<'ast>, - pub third: Expression<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/expressions/tuple_expression.rs b/grammar/src/expressions/tuple_expression.rs deleted file mode 100644 index 16b8727fe9..0000000000 --- a/grammar/src/expressions/tuple_expression.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, expressions::Expression, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::expression_tuple))] -pub struct TupleExpression<'ast> { - pub expressions: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/expressions/unary_expression.rs b/grammar/src/expressions/unary_expression.rs deleted file mode 100644 index b2d50fb4c4..0000000000 --- a/grammar/src/expressions/unary_expression.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, expressions::Expression, operations::UnaryOperation, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::expression_unary))] -pub struct UnaryExpression<'ast> { - pub operation: UnaryOperation, - pub expression: Expression<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for UnaryExpression<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}{}", self.operation, self.expression) - } -} diff --git a/grammar/src/files/file.rs b/grammar/src/files/file.rs deleted file mode 100644 index 6d1bc2fea3..0000000000 --- a/grammar/src/files/file.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::EOI, definitions::Definition, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::file))] -pub struct File<'ast> { - pub definitions: Vec>, - pub eoi: EOI, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/files/mod.rs b/grammar/src/files/mod.rs deleted file mode 100644 index da089614bf..0000000000 --- a/grammar/src/files/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod file; -pub use file::*; diff --git a/grammar/src/functions/function.rs b/grammar/src/functions/function.rs deleted file mode 100644 index cd342b34bf..0000000000 --- a/grammar/src/functions/function.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Identifier, functions::input::Input, statements::Block, types::Type, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::function))] -pub struct Function<'ast> { - pub identifier: Identifier<'ast>, - pub parameters: Vec>, - pub returns: Option>, - pub block: Block<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/functions/input/function_input.rs b/grammar/src/functions/input/function_input.rs deleted file mode 100644 index 3cac32b798..0000000000 --- a/grammar/src/functions/input/function_input.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - common::{Const, Identifier, Mutable}, - types::Type, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::function_input))] -pub struct FunctionInput<'ast> { - pub const_: Option, - pub mutable: Option, - pub identifier: Identifier<'ast>, - pub type_: Type<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/functions/input/input.rs b/grammar/src/functions/input/input.rs deleted file mode 100644 index 9b2ef22ab7..0000000000 --- a/grammar/src/functions/input/input.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - common::{MutSelfKeyword, SelfKeyword}, - functions::{FunctionInput, InputKeyword}, -}; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::input))] -pub enum Input<'ast> { - InputKeyword(InputKeyword<'ast>), - SelfKeyword(SelfKeyword<'ast>), - MutSelfKeyword(MutSelfKeyword<'ast>), - FunctionInput(FunctionInput<'ast>), -} diff --git a/grammar/src/functions/input/input_keyword.rs b/grammar/src/functions/input/input_keyword.rs deleted file mode 100644 index 5032ae4436..0000000000 --- a/grammar/src/functions/input/input_keyword.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::input_keyword))] -pub struct InputKeyword<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub keyword: String, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for InputKeyword<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.keyword) - } -} diff --git a/grammar/src/functions/input/mod.rs b/grammar/src/functions/input/mod.rs deleted file mode 100644 index d75e262d32..0000000000 --- a/grammar/src/functions/input/mod.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -#![allow(clippy::module_inception)] - -pub mod function_input; -pub use function_input::*; - -pub mod input; -pub use input::*; - -pub mod input_keyword; -pub use input_keyword::*; diff --git a/grammar/src/functions/mod.rs b/grammar/src/functions/mod.rs deleted file mode 100644 index f16e3448d2..0000000000 --- a/grammar/src/functions/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod function; -pub use function::*; - -pub mod input; -pub use input::*; - -pub mod test_function; -pub use test_function::*; diff --git a/grammar/src/functions/test_function.rs b/grammar/src/functions/test_function.rs deleted file mode 100644 index 1e28efc53c..0000000000 --- a/grammar/src/functions/test_function.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, functions::Function, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::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>, -} - -impl<'ast> From> for TestFunction<'ast> { - fn from(function: Function<'ast>) -> Self { - let span = function.span.clone(); - TestFunction { function, span } - } -} diff --git a/grammar/src/imports/import.rs b/grammar/src/imports/import.rs deleted file mode 100644 index 1b62df80f3..0000000000 --- a/grammar/src/imports/import.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::LineEnd, imports::PackageOrPackages, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::import))] -pub struct Import<'ast> { - pub package_or_packages: PackageOrPackages<'ast>, - pub line_end: LineEnd, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/imports/import_symbol.rs b/grammar/src/imports/import_symbol.rs deleted file mode 100644 index 3643406618..0000000000 --- a/grammar/src/imports/import_symbol.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Identifier, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::import_symbol))] -pub struct ImportSymbol<'ast> { - pub value: Identifier<'ast>, - pub alias: Option>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/imports/mod.rs b/grammar/src/imports/mod.rs deleted file mode 100644 index 7665e520c5..0000000000 --- a/grammar/src/imports/mod.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod import; -pub use import::*; - -pub mod import_symbol; -pub use import_symbol::*; - -pub mod package; -pub use package::*; - -pub mod packages; -pub use packages::*; - -pub mod package_or_packages; -pub use package_or_packages::*; - -pub mod package_access; -pub use package_access::*; - -pub mod package_name; -pub use package_name::*; - -pub mod star; -pub use star::*; diff --git a/grammar/src/imports/package.rs b/grammar/src/imports/package.rs deleted file mode 100644 index 0b3f1a0ecb..0000000000 --- a/grammar/src/imports/package.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - imports::{PackageAccess, PackageName}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::package))] -pub struct Package<'ast> { - pub name: PackageName<'ast>, - pub access: PackageAccess<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/imports/package_access.rs b/grammar/src/imports/package_access.rs deleted file mode 100644 index 7d172bd545..0000000000 --- a/grammar/src/imports/package_access.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - imports::{ImportSymbol, Package, Packages, Star}, -}; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::package_access))] -pub enum PackageAccess<'ast> { - Star(Star<'ast>), - SubPackage(Box>), - Symbol(ImportSymbol<'ast>), - Multiple(Packages<'ast>), -} diff --git a/grammar/src/imports/package_name.rs b/grammar/src/imports/package_name.rs deleted file mode 100644 index a2e400460e..0000000000 --- a/grammar/src/imports/package_name.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::package_name))] -pub struct PackageName<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub value: String, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for PackageName<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.value) - } -} diff --git a/grammar/src/imports/package_or_packages.rs b/grammar/src/imports/package_or_packages.rs deleted file mode 100644 index 3cd0324480..0000000000 --- a/grammar/src/imports/package_or_packages.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - imports::{Package, Packages}, -}; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::package_or_packages))] -pub enum PackageOrPackages<'ast> { - Package(Package<'ast>), - Packages(Packages<'ast>), -} diff --git a/grammar/src/imports/packages.rs b/grammar/src/imports/packages.rs deleted file mode 100644 index 32003ffb16..0000000000 --- a/grammar/src/imports/packages.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - imports::{PackageAccess, PackageName}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::packages))] -pub struct Packages<'ast> { - pub name: PackageName<'ast>, - pub accesses: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/imports/star.rs b/grammar/src/imports/star.rs deleted file mode 100644 index 29cb6b6e35..0000000000 --- a/grammar/src/imports/star.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::star))] -pub struct Star<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/leo.pest b/grammar/src/leo.pest deleted file mode 100644 index 4a5fbdde2e..0000000000 --- a/grammar/src/leo.pest +++ /dev/null @@ -1,560 +0,0 @@ -/// Common - -// Declared in common/assignee.rs -assignee = { self_keyword_or_identifier ~ access_assignee* } - -// Declared in files/file.rs -file = { SOI ~ definition* ~ EOI } - -// Declared in definitions/definition.rs -definition = { - definition_annotated - | import - | circuit - | function - | deprecated -} - -// Declared in definitions/deprecated.rs -deprecated = { - test_function -} - -// Declared in definitions/annotated_definition.rs -definition_annotated = { annotation ~ definition} - -// Declared in common/identifier.rs -identifier = @{ ((!protected_name ~ ASCII_ALPHA) | (protected_name ~ (ASCII_ALPHANUMERIC | "_"))) ~ (ASCII_ALPHANUMERIC | "_")* } -protected_name = { - "as" - | "circuit" - | "const" - | "console" - | "else" - | "for" - | "function" - | "if" - | "import" - | input_keyword - | "in" - | "let" - | "mut" - | "return" - | self_keyword - | "static" - | "string" - | "test" - | type_data - | type_self - | value_boolean -} - -// Declared in common/self_keyword.rs -self_keyword = { "self" } - -// Declared in common/mut_self_keyword.rs -mut_self_keyword = { mutable ~ self_keyword } - -// Declared in common/self_keyword_or_identifier.rs -self_keyword_or_identifier = { - self_keyword - | identifier -} - -// Declared in common/keyword_or_identifier.rs -keyword_or_identifier = { - input_keyword - | type_self - | identifier -} - -// Declared in common/line_end.rs -LINE_END = { ";" } - -// Declared in common/mutable.rs -mutable = { "mut " } - -// Declared in common/range.rs -range_operator = { ".." } -range = { expression? ~ range_operator ~ expression? } - -// Declared in common/range_or_expression.rs -range_or_expression = { range | expression } - -// Declared in common/spread.rs -spread = { "..." ~ expression } - -// Declared in common/spread_or_expression.rs -spread_or_expression = { spread | expression } - -// Declared in common/static_.rs -static_ = { "static " } - -// Declared in common/variable_name.rs - -variable_name = {mutable? ~ identifier} -variable_name_tuple = _{"(" ~ variable_name ~ ("," ~ variable_name)+ ~ ")"} - -// Declared in common/variables.rs -variables = { ( variable_name_tuple | variable_name ) ~ (":" ~ type_ )? } - -// Declared in common/declare.rs -declare = { let_ | const_ } -const_ = { "const " } -let_ = { "let " } - -/// Operations - -// Declared in operations/unary_operation.rs -operation_unary = { - operation_not - | operation_negate -} -operation_not = { "!" } -operation_negate = { "-" } - -// Declared in operations/binary_operation.rs -operation_and = { "&&" } -operation_or = { "||" } -operation_eq = { "==" } -operation_ne = { "!=" } -operation_ge = { ">=" } -operation_gt = { ">" } -operation_le = { "<=" } -operation_lt = { "<" } -operation_add = { "+" } -operation_sub = { "-" } -operation_mul = { "*" } -operation_div = { "/" } -operation_pow = { "**" } - -operation_compare = _{ - operation_eq | operation_ne | - operation_ge | operation_gt | - operation_le | operation_lt -} -operation_binary = _{ - operation_compare | operation_and | operation_or | - operation_add | operation_sub | operation_pow | operation_mul | operation_div -} - -// Declared in operations/assign_operation.rs -operation_assign = { - assign | operation_add_assign | operation_sub_assign | - operation_mul_assign | operation_div_assign | operation_pow_assign -} -assign = { "=" } -operation_add_assign = { "+=" } -operation_sub_assign = { "-=" } -operation_mul_assign = { "*=" } -operation_div_assign = { "/=" } -operation_pow_assign = { "**=" } - -/// Types - -// Declared in types/type_.rs -type_ = { type_self | type_tuple | type_array | type_data | type_circuit } - -// Declared in types/integer_type.rs -type_integer = { - type_integer_signed - | type_integer_unsigned -} - -// Declared in types/unsigned_integer_type.rs -type_u8 = { "u8" } -type_u16 = { "u16" } -type_u32 = { "u32" } -type_u64 = { "u64" } -type_u128 = { "u128" } - -type_integer_unsigned = { - type_u8 - | type_u16 - | type_u32 - | type_u64 - | type_u128 -} - -// Declared in types/signed_integer_type.rs -type_i8 = { "i8" } -type_i16 = { "i16" } -type_i32 = { "i32" } -type_i64 = { "i64" } -type_i128 = { "i128" } - -type_integer_signed = { - type_i8 - | type_i16 - | type_i32 - | type_i64 - | type_i128 -} - -// Declared in types/field_type.rs -type_field = { "field" } - -// Declared in types/group_type.rs -type_group = { "group" } - -// Declared in types/boolean_type.rs -type_boolean = { "bool" } - -// Declared in types/address_type.rs -type_address = { "address" } - -// Declared in types/data_type.rs -type_data = { - type_address - | type_boolean - | type_field - | type_group - | type_integer -} - -// Declared in types/self_type.rs -type_self = { "Self" } - -// Declared in types/self_type.rs -type_circuit = { identifier } - -// Declared in types/array_type.rs -type_array = { "[" ~ type_ ~ ";" ~ array_dimensions ~ "]" } - -// Declared in types/array_dimensions.rs -array_dimensions = { - dimension_single - | dimension_multiple -} - -// Declared in types/array_dimensions.rs -dimension_single = { - number_positive -} - -// Declared in types/array_dimensions.rs -dimension_multiple = { "(" ~ number_positive ~ ("," ~ number_positive)* ~ ")"} - -type_tuple = { "(" ~ (type_ ~ ("," ~ type_)+ ~ ","?)? ~ ")" } - -/// Values - -// Declared in values/value.rs -value = { - value_address - | value_boolean - | value_field - | value_group - | value_integer - | value_number // must be last as a catch all -} - -// Declared in values/number_value.rs -value_number = { number_negative | number_positive } - -// Declared in values/number_negative.rs -number_negative = @{ "-" ~ ASCII_DIGIT+ } - -// Declared in values/number_positive.rs -number_positive = @{ ASCII_DIGIT+ } - -// Declared in values/integer_value.rs -value_integer = { value_integer_signed | value_integer_unsigned} - -// Declared in values/signed_integer_value.rs -value_integer_signed = ${ value_number ~ type_integer_signed } - -// Declared in values/unsigned_integer_value.rs -value_integer_unsigned = ${ number_positive ~ type_integer_unsigned } - -// Declared in values/boolean_value.rs -value_boolean = { "true" | "false" } - -// Declared in values/field_value.rs -value_field = ${ value_number ~ type_field } - -// Declared in values/group_value.rs -value_group = ${ group_single_or_tuple ~ type_group } -group_single_or_tuple = {value_number | group_tuple} -group_tuple = !{"(" ~ group_coordinate ~ "," ~ group_coordinate ~ ")"} - -// Declared in values/group_coordinate.rs -group_coordinate = { - value_number - | sign_high - | sign_low - | inferred -} - -sign_high = @{"+"} -sign_low = @{"-"} -inferred = @{"_"} - -// Declared in values/address.rs -address = @{ "aleo1" ~ (LOWERCASE_LETTER | ASCII_DIGIT){58} } - -// Declared in values/address_value.rs -value_address = ${ type_address ~ "(" ~ address ~ ")" } - -/// Access - -// Declared in access/access.rs -access = { access_array | access_tuple | access_call | access_member | access_static_member } - -// Declared in access/self_access.rs -self_access = { access_member | access_static_member } - -// Declared in access/array_access.rs -access_array = !{ "[" ~ range_or_expression ~ "]" } - -// Declared in access/tuple_access.rs -access_tuple = ${ "." ~ number_positive } - -// Declared in access/assignee_access.rs -access_assignee = { access_array | access_tuple | access_member } - -// Declared in access/call_access.rs -access_call = !{ "(" ~ (expression ~ ("," ~ expression)*)? ~ ")" } - -// Declared in access/member_access.rs -access_member = ${ "." ~ identifier } - -// Declared in access/static_member_access.rs -access_static_member = ${ "::" ~ identifier } - -/// Circuits - -// Declared in circuits/circuit_definition.rs -circuit = { "circuit " ~ identifier ~ "{" ~ circuit_member* ~ "}" } - -// Declared in circuits/circuit_variable.rs -circuit_variable = { identifier ~ ":" ~ expression } - -// Declared in circuits/circuit_implied_variable.rs -circuit_implied_variable = { - circuit_variable - | identifier -} - -// Declared in circuits/circuit_variable_definition.rs -circuit_variable_definition = { identifier ~ ":" ~ type_ ~ ","?} - -// Declared in circuits/circuit_member.rs -circuit_member = { function | circuit_variable_definition} - -/// Conditionals - -expression_conditional = { "if " ~ expression ~ "? " ~ expression ~ ": " ~ expression} - -/// Expressions - -expression_term = { - value - | ("(" ~ expression ~ ")") - | expression_tuple - | expression_conditional - | expression_array_initializer - | expression_array_inline - | expression_circuit_inline - | expression_unary - | self_expression_postfix - | expression_postfix - | identifier -} - - -// Declared in expressions/expression.rs -expression = { expression_term ~ (operation_binary ~ expression_term)* } - -// Declared in expressions/expression_tuple.rs -expression_tuple = { "(" ~ (expression ~ ("," ~ expression)+)? ~ ")" } - -// Declared in expressions/array_initializer_expression.rs -expression_array_initializer = { "[" ~ expression ~ ";" ~ array_dimensions ~ "]" } - -// Declared in expressions/array_inline_expression.rs -expression_array_inline = { "[" ~ inline_array_inner ~ "]"} -inline_array_inner = _{(spread_or_expression ~ ("," ~ spread_or_expression)*)?} - -// Declared in expressions/circuit_inline_expression.rs -expression_circuit_inline = { circuit_name ~ "{" ~ circuit_variable_list ~ "}" } - -// Declared in expressions/circuit_inline_expression.rs -circuit_name = { - type_self - | identifier -} - -// Declared in expressions/circuit_inline_expression.rs -circuit_variable_list = _{ (circuit_implied_variable ~ ("," ~ circuit_implied_variable)*)? ~ ","? } - -// Declared in expressions/unary_expression.rs -expression_unary = { operation_unary ~ expression_term } - -// Declared in expressions/postfix_expression.rs -expression_postfix = ${ keyword_or_identifier ~ access+ } - -// Declared in expressions/self_postfix_expression.rs -self_expression_postfix = ${ self_keyword ~ self_access ~ access* } - -/// Statements - -// Declared in statements/statement.rs -statement = { - (statement_return - | statement_conditional - | statement_for - | console_function_call - | statement_definition - | statement_assign - | statement_expression - | block - ) -} - - -// Declared in statements/assign_statement.rs -statement_assign = { assignee ~ operation_assign ~ expression ~ LINE_END } - -block = { "{" ~ statement* ~ "}" } - -// Declared in statements/conditional_statement.rs -statement_conditional = {"if " ~ expression ~ block ~ ("else " ~ conditional_nested_or_end_statement)?} -conditional_nested_or_end_statement = { statement_conditional | block } - -// Declared in statements/definition_statement.rs -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 } - -// Declared in statements/return_statement.rs -statement_return = { "return " ~ expression} - -/// Functions - -// Declared in functions/function.rs -function = { "function " ~ identifier ~ input_tuple ~ ("->" ~ type_)? ~ block } - -// Declared in functions/input/function_input.rs -function_input = { const_? ~ mutable? ~ identifier ~ ":" ~ type_ } - -// Declared in functions/input/input_keyword.rs -input_keyword = { "input" } - -// Declared in functions/input/input.rs -input = { - input_keyword - | self_keyword - | mut_self_keyword - | function_input -} -input_tuple = _{ "(" ~ (input ~ ("," ~ input)* ~ ","?)? ~ ")"} - - -/// Imports - -// Declared in imports/import.rs -import = { "import " ~ package_or_packages ~ LINE_END} - -// Declared in imports/package_name.rs -package_name = @{ (ASCII_ALPHA_LOWER | ASCII_DIGIT)+ ~ ( "-" ~ (ASCII_ALPHA_LOWER | ASCII_DIGIT)+)* } - -// Declared in imports/package_or_packages.rs -package_or_packages = { - packages - | package -} -// Declared in imports/package.rs -package = { package_name ~ "." ~ package_access } -// Declared in imports/packages.rs -packages = { package_name ~ "." ~ multiple_package_access } - -// Declared in imports/package_access -package_access = { - star - | packages - | package // subpackage - | import_symbol -} - -multiple_package_access = _{ "(" ~ package_access ~ ("," ~ package_access)* ~ ","? ~ ")"} - -// Declared in imports/star.rs -star = {"*"} - -// Declared in imports/import_symbol.rs -import_symbol = { identifier ~ ("as " ~ identifier)? } - -/// Utilities - -COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) } -WHITESPACE = _{ (" " | "\t" | NEWLINE) ~ (NEWLINE)* } // pest implicit whitespace keyword - -/// Console Functions - -// Declared in console/console_function_call.rs -console_function_call = ${console_keyword ~ "." ~ console_function ~ LINE_END} - -// Declared in console/console_keyword.rs -console_keyword = {"console"} - -// Declared in console/console_function.rs -console_function = { - console_assert - | console_debug - | console_error - | console_log -} - -// Declared in console/console_assert.rs -console_assert = !{"assert(" ~ expression ~ ")"} - -// Declared in console/console_debug.rs -console_debug = !{"debug(" ~ formatted_string? ~ ")"} - -// Declared in console/console_error.rs -console_error = !{"error(" ~ formatted_string? ~ ")"} - -// Declared in console/console_log.rs -console_log = !{"log(" ~ formatted_string? ~ ")"} - -// Declared in console/formatted_string.rs -formatted_string = { - "\"" - ~ (!"\"" ~ (formatted_container | ANY))* - ~ "\"" - ~ ("," ~ expression)* -} - -// Declared in console/formatted_container.rs -formatted_container = { "{" ~ "}"} - -/// Annotations - -// Declared in annotations/annotation.rs -annotation = ${annotation_symbol ~ annotation_name ~ annotation_arguments? } - -// Declared in annotations/annotation_symbol.rs -annotation_symbol = ${"@"} - -// Declared in annotations/annotation_name.rs -annotation_name = { - context // deprecated - | test -} - -// Declared in annotations/annotation_name.rs -context = {"context"} -test = {"test"} - -// Declared in annotations/annotation_argument.rs -annotation_arguments = !{"(" ~ annotation_argument ~ ("," ~ annotation_argument)* ~ ","? ~ NEWLINE* ~ ")"} - -annotation_argument = @{ (ASCII_ALPHANUMERIC | "_")+ } diff --git a/grammar/src/lib.rs b/grammar/src/lib.rs deleted file mode 100644 index 2f9e0fac02..0000000000 --- a/grammar/src/lib.rs +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -//! The pest abstract syntax tree (ast) for a Leo program. -//! -//! 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 [`Ast`]. It should not be parsed by -//! any other pass of the compiler. -#[macro_use] -extern crate lazy_static; -#[macro_use] -extern crate pest_derive; -#[macro_use] -extern crate thiserror; - -pub mod ast; - -pub mod access; -pub mod annotations; -pub mod circuits; -pub mod common; -pub mod console; -pub mod definitions; -pub mod expressions; -pub mod files; -pub mod functions; -pub mod imports; -pub mod operations; -pub mod statements; -pub mod types; -pub mod values; - -pub mod errors; -pub use errors::*; - -pub(crate) mod span; -pub(crate) use span::*; - -use from_pest::FromPest; -use std::{fs, path::Path}; - -/// -/// The grammar of a Leo program, encoded as an abstract syntax tree (AST). -/// -/// 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`] type can be created from a `*.leo` file at a [`Path`]. -/// A [`Grammar`] type can be used to create a new [`Ast`] type. -/// -pub struct Grammar<'ast> { - ast: files::File<'ast>, -} - -impl<'ast> Grammar<'ast> { - /// - /// Creates a new abstract syntax tree from a given program string, and optional 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. - // assert_eq!(program_string, fs::read_to_string(file_path).map_err(|_| ParserError::FileReadError(file_path.clone()))?); - - // Parse the file using leo.pest - let file = &mut ast::parse(&program_string) - .map_err(|error| ParserError::from(error.with_path(file_path.to_str().unwrap())))?; - - // Builds the abstract syntax tree using pest derivation. - let ast = files::File::<'ast>::from_pest(file).map_err(|_| ParserError::SyntaxTreeError)?; - tracing::debug!("{:#?}", ast); - - Ok(Self { ast }) - } - - // TODO (howardwu): Remove this in favor of a dedicated file loader to verify checksums - // and maintain a global cache of program strings during the compilation process. - /// - /// Loads the Leo code as a string from the given file path. - /// - pub fn load_file(file_path: &'ast Path) -> Result { - fs::read_to_string(file_path).map_err(|_| ParserError::FileReadError(file_path.to_owned())) - } - - /// - /// Returns a reference to the inner abstract syntax tree representation. - /// - pub fn as_repr(&self) -> &files::File<'ast> { - &self.ast - } - - /// - /// Serializes the abstract syntax tree into a JSON string. - /// - pub fn to_json_string(&self) -> Result { - Ok(serde_json::to_string_pretty(&self.ast)?) - } -} diff --git a/grammar/src/main.rs b/grammar/src/main.rs deleted file mode 100644 index ae9259084c..0000000000 --- a/grammar/src/main.rs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::{Grammar, ParserError}; -use std::{env, fs, path::Path}; - -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 = Grammar::load_file(&program_filepath)?; - - // Parses the Leo file and constructs an abstract syntax tree. - let ast = Grammar::new(&program_filepath, &program_string)?; - - // Serializes the abstract syntax tree into JSON format. - let serialized_ast = Grammar::to_json_string(&ast)?; - - Ok(serialized_ast) -} - -fn main() -> Result<(), ParserError> { - // Parse the command-line arguments as strings. - let cli_arguments = env::args().collect::>(); - - // Check that the correct number of command-line arguments were passed in. - 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_grammar {{PATH/TO/INPUT_FILENAME}}.leo {{PATH/TO/OUTPUT_DIRECTORY (optional)}}\n" - ); - return Ok(()); // Exit innocently - } - - // Construct the input filepath. - let input_filepath = Path::new(&cli_arguments[1]); - - // Construct the serialized abstract syntax tree. - let serialized_ast = to_grammar(&input_filepath)?; - println!("{}", serialized_ast); - - // Determine the output directory. - let output_directory = match cli_arguments.len() == 3 { - true => format!( - "{}/{}.json", - cli_arguments[2], - input_filepath.file_stem().unwrap().to_str().unwrap() - ), - 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_ast)?; - - Ok(()) -} diff --git a/grammar/src/operations/assign_operation.rs b/grammar/src/operations/assign_operation.rs deleted file mode 100644 index 49ea705c3f..0000000000 --- a/grammar/src/operations/assign_operation.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::operation_assign))] -pub enum AssignOperation { - Assign(Assign), - AddAssign(AddAssign), - SubAssign(SubAssign), - MulAssign(MulAssign), - DivAssign(DivAssign), - PowAssign(PowAssign), -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::assign))] -pub struct Assign {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::operation_add_assign))] -pub struct AddAssign {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::operation_sub_assign))] -pub struct SubAssign {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::operation_mul_assign))] -pub struct MulAssign {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::operation_div_assign))] -pub struct DivAssign {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::operation_pow_assign))] -pub struct PowAssign {} diff --git a/grammar/src/operations/binary_operation.rs b/grammar/src/operations/binary_operation.rs deleted file mode 100644 index c6d0290c80..0000000000 --- a/grammar/src/operations/binary_operation.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::operation_binary))] -pub enum BinaryOperation { - Or, - And, - Eq, - Ne, - Ge, - Gt, - Le, - Lt, - Add, - Sub, - Mul, - Div, - Pow, -} diff --git a/grammar/src/operations/mod.rs b/grammar/src/operations/mod.rs deleted file mode 100644 index 60772f4b04..0000000000 --- a/grammar/src/operations/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod assign_operation; -pub use assign_operation::*; - -pub mod binary_operation; -pub use binary_operation::*; - -pub mod unary_operation; -pub use unary_operation::*; diff --git a/grammar/src/operations/unary_operation.rs b/grammar/src/operations/unary_operation.rs deleted file mode 100644 index f261fe7533..0000000000 --- a/grammar/src/operations/unary_operation.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::operation_unary))] -pub enum UnaryOperation { - Negate(Negate), - Not(Not), -} - -impl fmt::Display for UnaryOperation { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - UnaryOperation::Negate(_) => write!(f, "-"), - UnaryOperation::Not(_) => write!(f, "!"), - } - } -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::operation_not))] -pub struct Not {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::operation_negate))] -pub struct Negate {} diff --git a/grammar/src/span.rs b/grammar/src/span.rs deleted file mode 100644 index f7c0eae89d..0000000000 --- a/grammar/src/span.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use pest::Span; -use serde::{Deserialize, Serialize}; - -// Provide getters for every private field of the remote struct. The getter must -// return either `T` or `&T` where `T` is the type of the field. -#[derive(Serialize, Deserialize)] -#[serde(remote = "Span")] -pub(crate) struct SpanDef<'i> { - /// # Attention - /// - /// This getter only returns a subset of the input. - /// Namely, it returns `self.input[self.start..self.end]`. - /// This means you can only accurate serialize (and not deserialize). - #[serde(getter = "Span::as_str")] - input: &'i str, - /// # Safety - /// - /// Must be a valid character boundary index into `input`. - #[serde(getter = "Span::start")] - start: usize, - /// # Safety - /// - /// Must be a valid character boundary index into `input`. - #[serde(getter = "Span::end")] - end: usize, -} - -// Provide a conversion to construct the remote type. -impl<'i> From> for Span<'i> { - fn from(def: SpanDef) -> Span { - Span::new(def.input, def.start, def.end).unwrap() - } -} - -#[test] -fn test_span_def() { - // Wrapper serializable JSON struct - #[derive(Serialize)] - struct Element<'ast> { - #[serde(with = "SpanDef")] - span: Span<'ast>, - } - - // Starting value - let span = Span::new("hello world", 1, 5).unwrap(); - let element = Element { span }; - - // Attempt to serialize span to string. - let output = serde_json::to_string(&element).unwrap(); - - let expected_output = "{\"span\":{\"input\":\"ello\",\"start\":1,\"end\":5}}"; - assert_eq!(expected_output, output); -} diff --git a/grammar/src/statements/assign_statement.rs b/grammar/src/statements/assign_statement.rs deleted file mode 100644 index 5325fd7b17..0000000000 --- a/grammar/src/statements/assign_statement.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - common::{Assignee, LineEnd}, - expressions::Expression, - operations::AssignOperation, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::statement_assign))] -pub struct AssignStatement<'ast> { - pub assignee: Assignee<'ast>, - pub assign: AssignOperation, - pub expression: Expression<'ast>, - pub line_end: LineEnd, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for AssignStatement<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} = {};", self.assignee, self.expression) - } -} diff --git a/grammar/src/statements/block.rs b/grammar/src/statements/block.rs deleted file mode 100644 index bbbfe41ff7..0000000000 --- a/grammar/src/statements/block.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, statements::Statement, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::block))] -pub struct Block<'ast> { - pub statements: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for Block<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - writeln!(f, "{{")?; - if self.statements.is_empty() { - writeln!(f, "\t")?; - } else { - self.statements - .iter() - .try_for_each(|statement| writeln!(f, "\t{}", statement))?; - } - write!(f, "}}") - } -} diff --git a/grammar/src/statements/conditional_nested_or_end_statement.rs b/grammar/src/statements/conditional_nested_or_end_statement.rs deleted file mode 100644 index 3bab38d701..0000000000 --- a/grammar/src/statements/conditional_nested_or_end_statement.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - statements::{Block, ConditionalStatement}, -}; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::conditional_nested_or_end_statement))] -pub enum ConditionalNestedOrEndStatement<'ast> { - Nested(Box>), - End(Block<'ast>), -} - -impl<'ast> fmt::Display for ConditionalNestedOrEndStatement<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ConditionalNestedOrEndStatement::Nested(ref nested) => write!(f, "else {}", nested), - ConditionalNestedOrEndStatement::End(ref block) => write!(f, "else {}", block), - } - } -} diff --git a/grammar/src/statements/conditional_statement.rs b/grammar/src/statements/conditional_statement.rs deleted file mode 100644 index 2e6861f98b..0000000000 --- a/grammar/src/statements/conditional_statement.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - expressions::Expression, - statements::{Block, ConditionalNestedOrEndStatement}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::statement_conditional))] -pub struct ConditionalStatement<'ast> { - pub condition: Expression<'ast>, - pub block: Block<'ast>, - pub next: Option>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for ConditionalStatement<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "if ({}) {}", self.condition, self.block)?; - self.next - .as_ref() - .map(|n_or_e| write!(f, " {}", n_or_e)) - .unwrap_or_else(|| write!(f, "")) - } -} diff --git a/grammar/src/statements/definition_statement.rs b/grammar/src/statements/definition_statement.rs deleted file mode 100644 index c1db3c212d..0000000000 --- a/grammar/src/statements/definition_statement.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - common::{Declare, LineEnd, Variables}, - expressions::Expression, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::statement_definition))] -pub struct DefinitionStatement<'ast> { - pub declare: Declare, - pub variables: Variables<'ast>, - pub expression: Expression<'ast>, - pub line_end: LineEnd, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for DefinitionStatement<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "let {} = {};", self.variables, self.expression) - } -} diff --git a/grammar/src/statements/expression_statement.rs b/grammar/src/statements/expression_statement.rs deleted file mode 100644 index bbef3f3568..0000000000 --- a/grammar/src/statements/expression_statement.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::LineEnd, expressions::Expression, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::statement_expression))] -pub struct ExpressionStatement<'ast> { - pub expression: Expression<'ast>, - pub line_end: LineEnd, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/statements/for_statement.rs b/grammar/src/statements/for_statement.rs deleted file mode 100644 index c1be00e303..0000000000 --- a/grammar/src/statements/for_statement.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Identifier, expressions::Expression, statements::Block, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::statement_for))] -pub struct ForStatement<'ast> { - pub index: Identifier<'ast>, - pub start: Expression<'ast>, - pub stop: Expression<'ast>, - pub block: Block<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for ForStatement<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "for {} in {}..{} {}", self.index, self.start, self.stop, self.block) - } -} diff --git a/grammar/src/statements/mod.rs b/grammar/src/statements/mod.rs deleted file mode 100644 index b6ec4c1136..0000000000 --- a/grammar/src/statements/mod.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod assign_statement; -pub use assign_statement::*; - -pub mod conditional_statement; -pub use conditional_statement::*; - -pub mod conditional_nested_or_end_statement; -pub use conditional_nested_or_end_statement::*; - -pub mod definition_statement; -pub use definition_statement::*; - -pub mod expression_statement; -pub use expression_statement::*; - -pub mod for_statement; -pub use for_statement::*; - -pub mod return_statement; -pub use return_statement::*; - -pub mod statement; -pub use statement::*; - -pub mod block; -pub use block::*; diff --git a/grammar/src/statements/return_statement.rs b/grammar/src/statements/return_statement.rs deleted file mode 100644 index 11d6b4ddcb..0000000000 --- a/grammar/src/statements/return_statement.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, expressions::Expression, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::statement_return))] -pub struct ReturnStatement<'ast> { - pub expression: Expression<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for ReturnStatement<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "return {}", self.expression) - } -} diff --git a/grammar/src/statements/statement.rs b/grammar/src/statements/statement.rs deleted file mode 100644 index d01c5d072e..0000000000 --- a/grammar/src/statements/statement.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, console::ConsoleFunctionCall, statements::*}; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::statement))] -pub enum Statement<'ast> { - Return(ReturnStatement<'ast>), - Definition(DefinitionStatement<'ast>), - Assign(AssignStatement<'ast>), - Conditional(ConditionalStatement<'ast>), - Iteration(ForStatement<'ast>), - Console(ConsoleFunctionCall<'ast>), - Expression(ExpressionStatement<'ast>), - Block(Block<'ast>), -} - -impl<'ast> fmt::Display for Statement<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Statement::Return(ref statement) => write!(f, "{}", statement), - Statement::Definition(ref statement) => write!(f, "{}", statement), - Statement::Assign(ref statement) => write!(f, "{}", statement), - Statement::Conditional(ref statement) => write!(f, "{}", statement), - Statement::Iteration(ref statement) => write!(f, "{}", statement), - Statement::Console(ref statement) => write!(f, "{}", statement), - Statement::Expression(ref statement) => write!(f, "{}", statement.expression), - Statement::Block(ref block) => write!(f, "{}", block), - } - } -} diff --git a/grammar/src/types/address_type.rs b/grammar/src/types/address_type.rs deleted file mode 100644 index 5c55367b1a..0000000000 --- a/grammar/src/types/address_type.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_address))] -pub struct AddressType {} diff --git a/grammar/src/types/array_dimensions.rs b/grammar/src/types/array_dimensions.rs deleted file mode 100644 index eb0aa89b1c..0000000000 --- a/grammar/src/types/array_dimensions.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, values::PositiveNumber, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::array_dimensions))] -pub enum ArrayDimensions<'ast> { - Single(Single<'ast>), - Multiple(Multiple<'ast>), -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::dimension_single))] -pub struct Single<'ast> { - pub number: PositiveNumber<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::dimension_multiple))] -pub struct Multiple<'ast> { - pub numbers: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> std::fmt::Display for ArrayDimensions<'ast> { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match *self { - ArrayDimensions::Single(ref single) => write!(f, "{}", single.number), - ArrayDimensions::Multiple(ref multiple) => write!(f, "{:?}", multiple.numbers), - } - } -} diff --git a/grammar/src/types/array_type.rs b/grammar/src/types/array_type.rs deleted file mode 100644 index a91b08558b..0000000000 --- a/grammar/src/types/array_type.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - types::{ArrayDimensions, Type}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_array))] -pub struct ArrayType<'ast> { - pub type_: Box>, - pub dimensions: ArrayDimensions<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/types/boolean_type.rs b/grammar/src/types/boolean_type.rs deleted file mode 100644 index f5502067c7..0000000000 --- a/grammar/src/types/boolean_type.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_boolean))] -pub struct BooleanType {} diff --git a/grammar/src/types/circuit_type.rs b/grammar/src/types/circuit_type.rs deleted file mode 100644 index c0156e100a..0000000000 --- a/grammar/src/types/circuit_type.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, common::Identifier, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_circuit))] -pub struct CircuitType<'ast> { - pub identifier: Identifier<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/types/data_type.rs b/grammar/src/types/data_type.rs deleted file mode 100644 index 78143384a5..0000000000 --- a/grammar/src/types/data_type.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - types::{AddressType, BooleanType, FieldType, GroupType, IntegerType}, -}; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_data))] -pub enum DataType { - Address(AddressType), - Boolean(BooleanType), - Field(FieldType), - Group(GroupType), - Integer(IntegerType), -} diff --git a/grammar/src/types/field_type.rs b/grammar/src/types/field_type.rs deleted file mode 100644 index 6a5215e9cb..0000000000 --- a/grammar/src/types/field_type.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_field))] -pub struct FieldType {} diff --git a/grammar/src/types/group_type.rs b/grammar/src/types/group_type.rs deleted file mode 100644 index c1fe720dcd..0000000000 --- a/grammar/src/types/group_type.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_group))] -pub struct GroupType {} diff --git a/grammar/src/types/integer_type.rs b/grammar/src/types/integer_type.rs deleted file mode 100644 index 729ac0fcc4..0000000000 --- a/grammar/src/types/integer_type.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - types::{SignedIntegerType, UnsignedIntegerType}, -}; - -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_integer))] -pub enum IntegerType { - Signed(SignedIntegerType), - Unsigned(UnsignedIntegerType), -} diff --git a/grammar/src/types/mod.rs b/grammar/src/types/mod.rs deleted file mode 100644 index 20da13b6db..0000000000 --- a/grammar/src/types/mod.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod address_type; -pub use address_type::*; - -pub mod array_dimensions; -pub use array_dimensions::*; - -pub mod array_type; -pub use array_type::*; - -pub mod boolean_type; -pub use boolean_type::*; - -pub mod circuit_type; -pub use circuit_type::*; - -pub mod data_type; -pub use data_type::*; - -pub mod field_type; -pub use field_type::*; - -pub mod group_type; -pub use group_type::*; - -pub mod integer_type; -pub use integer_type::*; - -pub mod self_type; -pub use self_type::*; - -pub mod signed_integer_type; -pub use signed_integer_type::*; - -pub mod tuple_type; -pub use tuple_type::*; - -pub mod type_; -pub use type_::*; - -pub mod unsigned_integer_type; -pub use unsigned_integer_type::*; diff --git a/grammar/src/types/self_type.rs b/grammar/src/types/self_type.rs deleted file mode 100644 index e3fb6bd072..0000000000 --- a/grammar/src/types/self_type.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_self))] -pub struct SelfType<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub keyword: String, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for SelfType<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.keyword) - } -} diff --git a/grammar/src/types/signed_integer_type.rs b/grammar/src/types/signed_integer_type.rs deleted file mode 100644 index f615ffd747..0000000000 --- a/grammar/src/types/signed_integer_type.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_integer_signed))] -pub enum SignedIntegerType { - I8Type(I8Type), - I16Type(I16Type), - I32Type(I32Type), - I64Type(I64Type), - I128Type(I128Type), -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_i8))] -pub struct I8Type {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_i16))] -pub struct I16Type {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_i32))] -pub struct I32Type {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_i64))] -pub struct I64Type {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_i128))] -pub struct I128Type {} - -impl fmt::Display for SignedIntegerType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - SignedIntegerType::I8Type(_) => write!(f, "i8"), - SignedIntegerType::I16Type(_) => write!(f, "i16"), - SignedIntegerType::I32Type(_) => write!(f, "i32"), - SignedIntegerType::I64Type(_) => write!(f, "i64"), - SignedIntegerType::I128Type(_) => write!(f, "i128"), - } - } -} diff --git a/grammar/src/types/tuple_type.rs b/grammar/src/types/tuple_type.rs deleted file mode 100644 index 57f39c9261..0000000000 --- a/grammar/src/types/tuple_type.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, types::Type, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_tuple))] -pub struct TupleType<'ast> { - pub types: Vec>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/types/type_.rs b/grammar/src/types/type_.rs deleted file mode 100644 index d020a7ef07..0000000000 --- a/grammar/src/types/type_.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, types::*}; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_))] -pub enum Type<'ast> { - Basic(DataType), - Array(ArrayType<'ast>), - Tuple(TupleType<'ast>), - Circuit(CircuitType<'ast>), - SelfType(SelfType<'ast>), -} - -impl<'ast> fmt::Display for Type<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Type::Basic(ref _type) => write!(f, "basic"), - Type::Array(ref _type) => write!(f, "array"), - Type::Tuple(ref _type) => write!(f, "tuple"), - Type::Circuit(ref _type) => write!(f, "struct"), - Type::SelfType(ref type_) => write!(f, "{}", type_.keyword), - } - } -} diff --git a/grammar/src/types/unsigned_integer_type.rs b/grammar/src/types/unsigned_integer_type.rs deleted file mode 100644 index 734737604c..0000000000 --- a/grammar/src/types/unsigned_integer_type.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::ast::Rule; - -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_integer_unsigned))] -pub enum UnsignedIntegerType { - U8Type(U8Type), - U16Type(U16Type), - U32Type(U32Type), - U64Type(U64Type), - U128Type(U128Type), -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_u8))] -pub struct U8Type {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_u16))] -pub struct U16Type {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_u32))] -pub struct U32Type {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_u64))] -pub struct U64Type {} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::type_u128))] -pub struct U128Type {} - -impl fmt::Display for UnsignedIntegerType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - UnsignedIntegerType::U8Type(_) => write!(f, "u8"), - UnsignedIntegerType::U16Type(_) => write!(f, "u16"), - UnsignedIntegerType::U32Type(_) => write!(f, "u32"), - UnsignedIntegerType::U64Type(_) => write!(f, "u64"), - UnsignedIntegerType::U128Type(_) => write!(f, "u128"), - } - } -} diff --git a/grammar/src/values/address.rs b/grammar/src/values/address.rs deleted file mode 100644 index e1e815a6e7..0000000000 --- a/grammar/src/values/address.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::address))] -pub struct Address<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub value: String, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for Address<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.value) - } -} diff --git a/grammar/src/values/address_value.rs b/grammar/src/values/address_value.rs deleted file mode 100644 index decf47431e..0000000000 --- a/grammar/src/values/address_value.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, types::AddressType, values::address::Address, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::value_address))] -pub struct AddressValue<'ast> { - pub _type: AddressType, - pub address: Address<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for AddressValue<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.address) - } -} diff --git a/grammar/src/values/boolean_value.rs b/grammar/src/values/boolean_value.rs deleted file mode 100644 index 9e26d369f9..0000000000 --- a/grammar/src/values/boolean_value.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::value_boolean))] -pub struct BooleanValue<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub value: String, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for BooleanValue<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.value) - } -} diff --git a/grammar/src/values/field_value.rs b/grammar/src/values/field_value.rs deleted file mode 100644 index fad986b83e..0000000000 --- a/grammar/src/values/field_value.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, types::FieldType, values::NumberValue, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::value_field))] -pub struct FieldValue<'ast> { - pub number: NumberValue<'ast>, - pub _type: FieldType, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for FieldValue<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.number) - } -} diff --git a/grammar/src/values/group_coordinate.rs b/grammar/src/values/group_coordinate.rs deleted file mode 100644 index 4f12c477d4..0000000000 --- a/grammar/src/values/group_coordinate.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, values::NumberValue, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::group_coordinate))] -pub enum GroupCoordinate<'ast> { - Number(NumberValue<'ast>), - SignHigh(SignHigh<'ast>), - SignLow(SignLow<'ast>), - Inferred(Inferred<'ast>), -} - -impl<'ast> GroupCoordinate<'ast> { - pub fn span(&self) -> &Span<'ast> { - match self { - GroupCoordinate::Number(number) => &number.span(), - GroupCoordinate::SignHigh(sign_high) => &sign_high.span, - GroupCoordinate::SignLow(sign_low) => &sign_low.span, - GroupCoordinate::Inferred(inferred) => &inferred.span, - } - } -} - -impl<'ast> fmt::Display for GroupCoordinate<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - GroupCoordinate::Number(number) => write!(f, "{}", number), - GroupCoordinate::SignHigh(_) => write!(f, "+"), - GroupCoordinate::SignLow(_) => write!(f, "-"), - GroupCoordinate::Inferred(_) => write!(f, "_"), - } - } -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::sign_high))] -pub struct SignHigh<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::sign_low))] -pub struct SignLow<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::inferred))] -pub struct Inferred<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/grammar/src/values/group_value.rs b/grammar/src/values/group_value.rs deleted file mode 100644 index 56ab231908..0000000000 --- a/grammar/src/values/group_value.rs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - types::GroupType, - values::{GroupCoordinate, NumberValue}, - SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::value_group))] -pub struct GroupValue<'ast> { - pub value: GroupRepresentation<'ast>, - pub type_: GroupType, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for GroupValue<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.value) - } -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::group_single_or_tuple))] -pub enum GroupRepresentation<'ast> { - Single(NumberValue<'ast>), - Tuple(GroupTuple<'ast>), -} - -impl<'ast> fmt::Display for GroupRepresentation<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - GroupRepresentation::Single(number) => write!(f, "{}", number), - GroupRepresentation::Tuple(tuple) => write!(f, "{}", tuple), - } - } -} - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::group_tuple))] -pub struct GroupTuple<'ast> { - pub x: GroupCoordinate<'ast>, - pub y: GroupCoordinate<'ast>, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for GroupTuple<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "({}, {})", self.x, self.y) - } -} diff --git a/grammar/src/values/integer_value.rs b/grammar/src/values/integer_value.rs deleted file mode 100644 index 64c0ebd640..0000000000 --- a/grammar/src/values/integer_value.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - values::{SignedIntegerValue, UnsignedIntegerValue}, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::value_integer))] -pub enum IntegerValue<'ast> { - Signed(SignedIntegerValue<'ast>), - Unsigned(UnsignedIntegerValue<'ast>), -} - -impl<'ast> IntegerValue<'ast> { - pub fn span(&self) -> &Span<'ast> { - match self { - IntegerValue::Signed(integer) => &integer.span, - IntegerValue::Unsigned(integer) => &integer.span, - } - } -} - -impl<'ast> fmt::Display for IntegerValue<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - IntegerValue::Signed(integer) => write!(f, "{}", integer), - IntegerValue::Unsigned(integer) => write!(f, "{}", integer), - } - } -} diff --git a/grammar/src/values/mod.rs b/grammar/src/values/mod.rs deleted file mode 100644 index 8fd2211392..0000000000 --- a/grammar/src/values/mod.rs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -pub mod address; -pub use address_value::*; - -pub mod address_value; -pub use address_value::*; - -pub mod boolean_value; -pub use boolean_value::*; - -pub mod field_value; -pub use field_value::*; - -pub mod group_coordinate; -pub use group_coordinate::*; - -pub mod group_value; -pub use group_value::*; - -pub mod integer_value; -pub use integer_value::*; - -pub mod number_value; -pub use number_value::*; - -pub mod positive_number; -pub use positive_number::*; - -pub mod negative_number; -pub use negative_number::*; - -pub mod signed_integer_value; -pub use signed_integer_value::*; - -pub mod unsigned_integer_value; -pub use unsigned_integer_value::*; - -pub mod value; -pub use value::*; diff --git a/grammar/src/values/negative_number.rs b/grammar/src/values/negative_number.rs deleted file mode 100644 index 5cd52eaef0..0000000000 --- a/grammar/src/values/negative_number.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - span::SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::number_negative))] -pub struct NegativeNumber<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub value: String, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for NegativeNumber<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.value) - } -} diff --git a/grammar/src/values/number_value.rs b/grammar/src/values/number_value.rs deleted file mode 100644 index 1d090c7528..0000000000 --- a/grammar/src/values/number_value.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - values::{NegativeNumber, PositiveNumber}, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::value_number))] -pub enum NumberValue<'ast> { - Negative(NegativeNumber<'ast>), - Positive(PositiveNumber<'ast>), -} - -impl<'ast> NumberValue<'ast> { - pub fn span(&self) -> &Span<'ast> { - match self { - NumberValue::Negative(number) => &number.span, - NumberValue::Positive(number) => &number.span, - } - } -} - -impl<'ast> fmt::Display for NumberValue<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - NumberValue::Negative(number) => write!(f, "{}", number), - NumberValue::Positive(number) => write!(f, "{}", number), - } - } -} diff --git a/grammar/src/values/positive_number.rs b/grammar/src/values/positive_number.rs deleted file mode 100644 index 8fd522836f..0000000000 --- a/grammar/src/values/positive_number.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::{span_into_string, Rule}, - span::SpanDef, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::number_positive))] -pub struct PositiveNumber<'ast> { - #[pest_ast(outer(with(span_into_string)))] - pub value: String, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for PositiveNumber<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.value) - } -} diff --git a/grammar/src/values/signed_integer_value.rs b/grammar/src/values/signed_integer_value.rs deleted file mode 100644 index 5c49a0ebf1..0000000000 --- a/grammar/src/values/signed_integer_value.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, types::SignedIntegerType, values::NumberValue, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::value_integer_signed))] -pub struct SignedIntegerValue<'ast> { - pub number: NumberValue<'ast>, - pub type_: SignedIntegerType, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for SignedIntegerValue<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}{}", self.number, self.type_) - } -} diff --git a/grammar/src/values/unsigned_integer_value.rs b/grammar/src/values/unsigned_integer_value.rs deleted file mode 100644 index 9b85ae8eea..0000000000 --- a/grammar/src/values/unsigned_integer_value.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ast::Rule, types::UnsignedIntegerType, values::PositiveNumber, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::value_integer_unsigned))] -pub struct UnsignedIntegerValue<'ast> { - pub number: PositiveNumber<'ast>, - pub type_: UnsignedIntegerType, - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} - -impl<'ast> fmt::Display for UnsignedIntegerValue<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}{}", self.number, self.type_) - } -} diff --git a/grammar/src/values/value.rs b/grammar/src/values/value.rs deleted file mode 100644 index 2d92362c28..0000000000 --- a/grammar/src/values/value.rs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use crate::{ - ast::Rule, - values::{AddressValue, BooleanValue, FieldValue, GroupValue, IntegerValue, NumberValue}, -}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; -use std::fmt; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::value))] -pub enum Value<'ast> { - Address(AddressValue<'ast>), - Boolean(BooleanValue<'ast>), - Field(FieldValue<'ast>), - Group(GroupValue<'ast>), - Implicit(NumberValue<'ast>), - Integer(IntegerValue<'ast>), -} - -impl<'ast> Value<'ast> { - pub fn span(&self) -> &Span<'ast> { - match self { - Value::Address(value) => &value.span, - Value::Boolean(value) => &value.span, - Value::Field(value) => &value.span, - Value::Group(value) => &value.span, - Value::Implicit(value) => &value.span(), - Value::Integer(value) => &value.span(), - } - } -} - -impl<'ast> fmt::Display for Value<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Value::Address(ref value) => write!(f, "{}", value), - Value::Boolean(ref value) => write!(f, "{}", value), - Value::Field(ref value) => write!(f, "{}", value), - Value::Group(ref value) => write!(f, "{}", value), - Value::Implicit(ref value) => write!(f, "{}", value), - Value::Integer(ref value) => write!(f, "{}", value), - } - } -} diff --git a/grammar/tests/annotated.rs b/grammar/tests/annotated.rs deleted file mode 100644 index 32ac106dba..0000000000 --- a/grammar/tests/annotated.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::ast::{LanguageParser, Rule}; - -use pest::*; - -#[test] -fn test_annotation_no_context_test() { - parses_to! { - parser: LanguageParser, - input: "@test", - rule: Rule::annotation, - tokens: [ - annotation(0, 5, [annotation_symbol(0, 1, []), annotation_name(1, 5, [test(1, 5, [])])]) - ] - } -} - -#[test] -fn test_annotation_context_test() { - parses_to! { - parser: LanguageParser, - input: "@test(custom)", - rule: Rule::annotation, - tokens: [ - annotation(0, 13, [annotation_symbol(0, 1, []), annotation_name(1, 5, [test(1, 5, [])]), annotation_arguments(5, 13, [annotation_argument(6, 12, [])])]) - ] - } -} diff --git a/grammar/tests/circuits.rs b/grammar/tests/circuits.rs deleted file mode 100644 index 33c77151ca..0000000000 --- a/grammar/tests/circuits.rs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::ast::{LanguageParser, Rule}; - -use pest::*; - -#[test] -fn circuit_definition() { - parses_to! { - parser: LanguageParser, - input: "circuit Foo { a: u32, }", - rule: Rule::circuit, - tokens: [ - circuit(0, 23, [ - identifier(8, 11, []), - circuit_member(14, 21, - [circuit_variable_definition(14, 21, [ - identifier(14, 15, []), - type_(17, 20, [type_data(17, 20, [type_integer(17, 20, [type_integer_unsigned(17, 20, [type_u32(17, 20, [])])])])]) - ]) - ]) - ]) - ] - } -} - -#[test] -fn circuit_instantiation() { - parses_to! { - parser: LanguageParser, - input: r#"circuit Foo { a: u32, } - function main() { let foo = Foo { a, b: 1u32 }; }"#, - rule: Rule::file, - tokens: [ - file(0, 77, [ - definition(0, 23, [ - circuit(0, 23, [ - identifier(8, 11, []), - circuit_member(14, 21, - [circuit_variable_definition(14, 21, [ - identifier(14, 15, []), - type_(17, 20, [type_data(17, 20, [type_integer(17, 20, [type_integer_unsigned(17, 20, [type_u32(17, 20, [])])])])]) - ]) - ]) - ]), - ]), - definition(28, 77, [ - function(28, 77, [ - identifier(37, 41, []), - block(44, 77, [ - statement(46, 75, [ - statement_definition(46, 75, [ - declare(46, 50, [ - let_(46, 50, []), - ]), - variables(50, 54, [ - variable_name(50, 53, [ - identifier(50, 53, []) - ]) - ]), - expression(56, 74, [ - expression_term(56, 74, [ - expression_circuit_inline(56, 74, [ - circuit_name(56, 59, [ - identifier(56, 59, []) - ]), - circuit_implied_variable(62, 63, [ - identifier(62, 63, []) - ]), - circuit_implied_variable(65, 73, [ - circuit_variable(65, 73, [ - identifier(65, 66, []), - expression(68, 73, [ - expression_term(68, 72, [ - value(68, 72, [ - value_integer(68, 72, [ - value_integer_unsigned(68, 72, [ - number_positive(68, 69, []), - type_integer_unsigned(69, 72, [ - type_u32(69, 72, []) - ]) - ]), - ]) - ]) - ]) - ]) - ]) - ]) - ]) - ]) - ]), - LINE_END(74, 75, []) - ]) - ]) - ]) - ]) - ]), - EOI(77, 77, []) - ]) - ] - } -} diff --git a/grammar/tests/deprecated.rs b/grammar/tests/deprecated.rs deleted file mode 100644 index 5ff8f94cb0..0000000000 --- a/grammar/tests/deprecated.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::ast::{LanguageParser, Rule}; - -use pest::*; - -#[test] -fn test_deprecated_test_function() { - parses_to! { - parser: LanguageParser, - input: r#"test function old() { - return () -}"#, - rule: Rule::deprecated, - tokens: [ - deprecated(0, 37, [ - test_function(0, 37, [ - function(5, 37, [ - identifier(14, 17, []), - block(20, 37, [ - statement(26, 36, [ - statement_return(26, 36, [expression(33, 36, [expression_term(33, 35, [expression_tuple(33, 35, [])])])]) - ]) - ]) - ]) - ]) - ]) - ] - } -} - -#[test] -fn test_deprecated_context_function() { - parses_to! { - parser: LanguageParser, - input: "@context(custom)", - rule: Rule::annotation, - tokens: [ - annotation(0, 16, [annotation_symbol(0, 1, []), annotation_name(1, 8, [context(1, 8, [])]), annotation_arguments(8, 16, [annotation_argument(9, 15, [])])]) - ] - } -} diff --git a/grammar/tests/display.rs b/grammar/tests/display.rs deleted file mode 100644 index 38aaf42a70..0000000000 --- a/grammar/tests/display.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use from_pest::FromPest; -use leo_grammar::{ - ast::{LanguageParser, Rule}, - statements::ConditionalStatement, -}; - -use pest::*; - -#[test] -fn conditional_statement_display() { - let input = r#"if (true) { - -} else { - -}"#; - let conditional_statement = - ConditionalStatement::from_pest(&mut LanguageParser::parse(Rule::statement_conditional, input).unwrap()) - .unwrap(); - let displayed = format!("{}", conditional_statement); - - assert_eq!(input, displayed); -} diff --git a/grammar/tests/expression.rs b/grammar/tests/expression.rs deleted file mode 100644 index 589c16bcee..0000000000 --- a/grammar/tests/expression.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::ast::{LanguageParser, Rule}; - -use pest::*; - -#[test] -fn redundant_parens() { - parses_to! { - parser: LanguageParser, - input: "(true)", - rule: Rule::expression, - tokens: [ - expression(0, 6, [ - expression_term(0, 6, [expression(1, 5, [expression_term(1, 5, [value(1, 5, [value_boolean(1, 5, [])])])])]) - ]) - ] - } -} - -#[test] -fn multiple_redundant_parens() { - parses_to! { - parser: LanguageParser, - input: "(((true)))", - rule: Rule::expression, - tokens: [ - expression(0, 10, [ - expression_term(0, 10, [ - expression(1, 9, [expression_term(1, 9, [ - expression(2, 8, [expression_term(2, 8, [ - expression(3, 7, [expression_term(3, 7, [ - value(3, 7, [value_boolean(3, 7, [])]) - ])]) - ])]) - ])]) - ]) - ]) - ] - } -} diff --git a/grammar/tests/function.rs b/grammar/tests/function.rs deleted file mode 100644 index 4bc1de7bf7..0000000000 --- a/grammar/tests/function.rs +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::ast::{LanguageParser, Rule}; - -use pest::*; - -#[test] -fn call_wo_args() { - parses_to! { - parser: LanguageParser, - input: "x()", - rule: Rule::expression_postfix, - tokens: [ - expression_postfix(0, 3, [ - keyword_or_identifier(0, 1, [identifier(0, 1, [])]), - access(1, 3, [access_call(1, 3, [])]) - ]) - ] - } -} - -#[test] -fn call_with_arg() { - parses_to! { - parser: LanguageParser, - input: "x(true)", - rule: Rule::expression_postfix, - tokens: [ - expression_postfix(0, 7, [ - keyword_or_identifier(0, 1, [identifier(0, 1, [])]), - access(1, 7, [access_call(1, 7, [ - expression(2, 6, [expression_term(2, 6, [value(2, 6, [value_boolean(2, 6, [])])])]) - ])]) - ]) - ] - } -} - -#[test] -fn call_with_2_args() { - parses_to! { - parser: LanguageParser, - input: "x(true, false)", - rule: Rule::expression_postfix, - tokens: [ - expression_postfix(0, 14, [ - keyword_or_identifier(0, 1, [identifier(0, 1, [])]), - access(1, 14, [access_call(1, 14, [ - expression(2, 6, [expression_term(2, 6, [value(2, 6, [value_boolean(2, 6, [])])])]), - expression(8, 13, [expression_term(8, 13, [value(8, 13, [value_boolean(8, 13, [])])])]) - ])]) - ]) - ] - } -} - -#[test] -fn empty_def() { - parses_to! { - parser: LanguageParser, - input: "function x() {}", - rule: Rule::function, - tokens: [ - function(0, 15, [identifier(9, 10, []), block(13, 15, [])]) - ] - } -} - -#[test] -fn returning_unit_type() { - parses_to! { - parser: LanguageParser, - input: "function x() -> () {}", - rule: Rule::function, - tokens: [ - function(0, 21, [identifier(9, 10, []), type_(16, 18, [type_tuple(16, 18, [])]), block(19, 21, [])]) - ] - } -} - -#[test] -fn returning_unit_value() { - parses_to! { - parser: LanguageParser, - input: "function x() { return () }", - rule: Rule::function, - tokens: [ - function(0, 26, [identifier(9, 10, []), block(13, 26, [ - statement(15, 25, [ - statement_return(15, 25, [expression(22, 25, [expression_term(22, 24, [expression_tuple(22, 24, [])])])]) - ]) - ])]) - ] - } -} - -#[test] -fn id_def() { - parses_to! { - parser: LanguageParser, - input: "function id(x: u8) -> u8 { return x }", - rule: Rule::function, - tokens: [ - function(0, 37, [ - identifier(9, 11, []), - input(12, 17, [ - function_input(12, 17, [ - identifier(12, 13, []), - type_(15, 17, [type_data(15, 17, [type_integer(15, 17, [type_integer_unsigned(15, 17, [type_u8(15, 17, [])])])])]) - ]) - ]), - type_(22, 24, [type_data(22, 24, [type_integer(22, 24, [type_integer_unsigned(22, 24, [type_u8(22, 24, [])])])])]), - block(25, 37, [ - statement(27, 36, [statement_return(27, 36, [ - expression(34, 36, [expression_term(34, 35, [identifier(34, 35, [])])]) - ])]) - ]), - ]) - ] - } -} diff --git a/grammar/tests/imports.rs b/grammar/tests/imports.rs deleted file mode 100644 index 8ddd874e3d..0000000000 --- a/grammar/tests/imports.rs +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::ast::{LanguageParser, Rule}; - -use pest::*; - -#[test] -fn test_import_package_rule() { - parses_to! { - parser: LanguageParser, - input: "import p.*;", - rule: Rule::import, - tokens: [ - import(0, 11, [ - package_or_packages(7, 10, [ - package(7, 10, [ - package_name(7, 8, []), - package_access(9, 10, [star(9, 10, [])]) - ]) - ]), - LINE_END(10, 11, []) - ]), - ] - } -} - -#[test] -fn test_import_packages_rule() { - parses_to! { - parser: LanguageParser, - input: "import p.(x, y);", - rule: Rule::import, - tokens: [ - import(0, 16, [ - package_or_packages(7, 15, [ - packages(7, 15, [ - package_name(7, 8, []), - package_access(10, 11, [ - import_symbol(10, 11, [identifier(10, 11, [])]), - ]), - package_access(13, 14, [ - import_symbol(13, 14, [identifier(13, 14, [])]), - ]), - ]) - ]), - LINE_END(15, 16, []) - ]) - ] - } -} - -#[test] -fn test_complex_import_rule() { - parses_to! { - parser: LanguageParser, - input: "import p.(q.(x, y), z);", - rule: Rule::import, - tokens: [ - import(0, 23, [ - package_or_packages(7, 22, [ - packages(7, 22, [ - package_name(7, 8, []), - package_access(10, 18, [ - packages(10, 18, [ - package_name(10, 11, []), - package_access(13, 14, [import_symbol(13, 14, [identifier(13, 14, [])])]), - package_access(16, 17, [import_symbol(16, 17, [identifier(16, 17, [])])]), - ]), - ]), - package_access(20, 21, [import_symbol(20, 21, [identifier(20, 21, [])])]), - ]) - ]), - LINE_END(22, 23, []) - ]) - ] - } -} diff --git a/grammar/tests/leo-samples/multiline.leo b/grammar/tests/leo-samples/multiline.leo deleted file mode 100644 index 24eb4e5154..0000000000 --- a/grammar/tests/leo-samples/multiline.leo +++ /dev/null @@ -1,54 +0,0 @@ -// adding multiline support for Leo -// all the code in this file should compile just fine - -circuit BipBop { - bip - : - u32, - - bop - : u32, - - blup : - u32, - - function gimme_five() -> Self { - return Self { - bip: 1, - bop: 2, - blup: 3 - } - } - - function main() -> ( - u32 - , - u64 - ) { - return ( - 100 - , - 1000 - ) - } -} - -function main() -> ( - u32 - , - u64 -) { - let - a - : u32 - = 100 - ; - - let b : ( - u32, - u64 - ) = BipBop::gimme_five().main(); - - console.assert(true); -} - diff --git a/grammar/tests/mod.rs b/grammar/tests/mod.rs deleted file mode 100644 index 6b53d18df3..0000000000 --- a/grammar/tests/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -mod display; -mod expression; -mod function; -mod serialization; -mod tuple; diff --git a/grammar/tests/multiline.rs b/grammar/tests/multiline.rs deleted file mode 100644 index 2c3fca1706..0000000000 --- a/grammar/tests/multiline.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::ast::{LanguageParser, Rule}; -use pest::*; - -#[test] -fn multiline() { - let multiline_sample = include_str!("leo-samples/multiline.leo"); - LanguageParser::parse(Rule::file, multiline_sample).expect("Can't parse multiline expression"); -} diff --git a/grammar/tests/self.rs b/grammar/tests/self.rs deleted file mode 100644 index 8157639e42..0000000000 --- a/grammar/tests/self.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::ast::{LanguageParser, Rule}; -use pest::*; - -#[test] -fn self_call() { - parses_to! { - parser: LanguageParser, - input: "self.hello()", - rule: Rule::self_expression_postfix, - tokens: [ - self_expression_postfix(0, 12, [ - self_keyword(0, 4, []), - self_access(4, 10, [access_member(4, 10, [identifier(5, 10, [])])]), - access(10, 12, [access_call(10, 12, [])]) - ]) - ] - } -} - -#[test] -fn self_static() { - parses_to! { - parser: LanguageParser, - input: "self::hello()", - rule: Rule::self_expression_postfix, - tokens: [ - self_expression_postfix(0, 13, [ - self_keyword(0, 4, []), - self_access(4, 11, [access_static_member(4, 11, [identifier(6, 11, [])])]), - access(11, 13, [access_call(11, 13, [])]) - ]) - ] - } -} diff --git a/grammar/tests/serialization/expected_ast.json b/grammar/tests/serialization/expected_ast.json deleted file mode 100644 index cbbcf20a69..0000000000 --- a/grammar/tests/serialization/expected_ast.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "definitions": [ - { - "Function": { - "identifier": { - "value": "main", - "span": { - "input": "main", - "start": 9, - "end": 13 - } - }, - "parameters": [], - "returns": null, - "block": { - "statements": [ - { - "Return": { - "expression": { - "Binary": { - "operation": "Add", - "left": { - "Value": { - "Implicit": { - "Positive": { - "value": "1", - "span": { - "input": "1", - "start": 29, - "end": 30 - } - } - } - } - }, - "right": { - "Value": { - "Implicit": { - "Positive": { - "value": "1", - "span": { - "input": "1", - "start": 33, - "end": 34 - } - } - } - } - }, - "span": { - "input": "1 + 1", - "start": 29, - "end": 34 - } - } - }, - "span": { - "input": "return 1 + 1", - "start": 22, - "end": 34 - } - } - } - ], - "span": { - "input": "{\n return 1 + 1\n}", - "start": 16, - "end": 36 - } - }, - "span": { - "input": "function main() {\n return 1 + 1\n}", - "start": 0, - "end": 36 - } - } - } - ], - "eoi": null, - "span": { - "input": "function main() {\n return 1 + 1\n}\n", - "start": 0, - "end": 37 - } -} \ No newline at end of file diff --git a/grammar/tests/serialization/json.rs b/grammar/tests/serialization/json.rs deleted file mode 100644 index e940b4e764..0000000000 --- a/grammar/tests/serialization/json.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -#[test] -#[cfg(not(feature = "ci_skip"))] -fn test_serialize() { - use leo_grammar::Grammar; - use std::path::PathBuf; - - let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - program_filepath.push("tests/serialization/main.leo"); - - let expected = include_str!("./expected_ast.json"); - - // 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 an abstract syntax tree. - let ast = Grammar::new(&program_filepath, &program_string).unwrap(); - - // Serializes the abstract syntax tree into JSON format. - let serialized_ast = Grammar::to_json_string(&ast).unwrap(); - - assert_eq!(expected, serialized_ast); -} diff --git a/grammar/tests/serialization/main.leo b/grammar/tests/serialization/main.leo deleted file mode 100644 index ef22115243..0000000000 --- a/grammar/tests/serialization/main.leo +++ /dev/null @@ -1,3 +0,0 @@ -function main() { - return 1 + 1 -} diff --git a/grammar/tests/serialization/mod.rs b/grammar/tests/serialization/mod.rs deleted file mode 100644 index 5096607ede..0000000000 --- a/grammar/tests/serialization/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -mod json; diff --git a/grammar/tests/tuple.rs b/grammar/tests/tuple.rs deleted file mode 100644 index 1408d5c0d8..0000000000 --- a/grammar/tests/tuple.rs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (C) 2019-2021 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use leo_grammar::ast::{LanguageParser, Rule}; - -use pest::*; - -#[test] -fn implicitly_typed() { - parses_to! { - parser: LanguageParser, - input: "(true, false)", - rule: Rule::expression_tuple, - tokens: [ - expression_tuple(0, 13, [ - expression(1, 5, [expression_term(1, 5, [value(1, 5, [value_boolean(1, 5, [])])])]), - expression(7, 12, [expression_term(7, 12, [value(7, 12, [value_boolean(7, 12, [])])])]) - ]) - ] - } -} - -#[test] -fn explicitly_typed() { - parses_to! { - parser: LanguageParser, - input: "let tup: (bool, bool) = (true, false);", - rule: Rule::statement_definition, - tokens: [ - statement_definition(0, 38, [ - declare(0, 4, [let_(0, 4, [])]), - variables(4, 21, [ - variable_name(4, 7, [identifier(4, 7, [])]), - type_(9, 21, [type_tuple(9, 21, [ - type_(10, 14, [type_data(10, 14, [type_boolean(10, 14, [])])]), - type_(16, 20, [type_data(16, 20, [type_boolean(16, 20, [])])]), - ])]) - ]), - expression(24, 37, [expression_term(24, 37, [expression_tuple(24, 37, [ - expression(25, 29, [expression_term(25, 29, [value(25, 29, [value_boolean(25, 29, [])])])]), - expression(31, 36, [expression_term(31, 36, [value(31, 36, [value_boolean(31, 36, [])])])]), - ])])]), - LINE_END(37, 38, []) - ]) - ] - } -} - -#[test] -fn access() { - parses_to! { - parser: LanguageParser, - input: "x.0", - rule: Rule::expression_postfix, - tokens: [ - expression_postfix(0, 3, [ - keyword_or_identifier(0, 1, [identifier(0, 1, [])]), - access(1, 3, [access_tuple(1, 3, [number_positive(2, 3, [])])]) - ]) - ] - } -} - -#[test] -fn implicit_unit() { - parses_to! { - parser: LanguageParser, - input: "()", - rule: Rule::expression_tuple, - tokens: [ - expression_tuple(0, 2, []) - ] - } -} - -#[test] -fn explicit_unit() { - parses_to! { - parser: LanguageParser, - input: "let x: () = ();", - rule: Rule::statement_definition, - tokens: [ - statement_definition(0, 15, [ - declare(0, 4, [let_(0, 4, [])]), - variables(4, 9, [ - variable_name(4, 5, [identifier(4, 5, [])]), - type_(7, 9, [type_tuple(7, 9, [])]) - ]), - expression(12, 14, [expression_term(12, 14, [expression_tuple(12, 14, [])])]), - LINE_END(14, 15, []) - ]) - ] - } -} diff --git a/imports/Cargo.toml b/imports/Cargo.toml index f7a53f98fc..c7e143d0a1 100644 --- a/imports/Cargo.toml +++ b/imports/Cargo.toml @@ -21,14 +21,14 @@ edition = "2018" path = "../ast" version = "1.2.3" -[dependencies.leo-grammar] -path = "../grammar" -version = "1.2.3" - [dependencies.leo-asg] path = "../asg" version = "1.2.3" +[dependencies.leo-parser] +path = "../parser" +version = "1.2.3" + [dependencies.indexmap] version = "1.6.1" features = [ "serde-1" ] diff --git a/imports/src/errors/import_parser.rs b/imports/src/errors/import_parser.rs index f3d901560c..1272d7e1e5 100644 --- a/imports/src/errors/import_parser.rs +++ b/imports/src/errors/import_parser.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_asg::AsgConvertError; -use leo_ast::{AstError, DeprecatedError, Error as FormattedError, Identifier, Span}; -use leo_grammar::ParserError; +use leo_ast::{FormattedError, Identifier, LeoError, Span}; +use leo_parser::{DeprecatedError, SyntaxError}; use std::{io, path::Path}; @@ -28,44 +28,60 @@ pub enum ImportParserError { Error(#[from] FormattedError), #[error("{}", _0)] - ParserError(#[from] ParserError), + SyntaxError(#[from] SyntaxError), #[error("{}", _0)] AsgConvertError(#[from] AsgConvertError), } +impl LeoError for ImportParserError { + fn get_path(&self) -> Option<&str> { + match self { + ImportParserError::Error(error) => error.get_path(), + ImportParserError::SyntaxError(error) => error.get_path(), + ImportParserError::AsgConvertError(error) => error.get_path(), + ImportParserError::DeprecatedError(error) => error.get_path(), + } + } + + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + ImportParserError::Error(error) => error.set_path(path, contents), + ImportParserError::SyntaxError(error) => error.set_path(path, contents), + ImportParserError::AsgConvertError(error) => error.set_path(path, contents), + ImportParserError::DeprecatedError(error) => error.set_path(path, contents), + } + } +} + impl Into for ImportParserError { fn into(self) -> AsgConvertError { match self { ImportParserError::Error(x) => AsgConvertError::ImportError(x), - ImportParserError::ParserError(x) => x.into(), - ImportParserError::DeprecatedError(x) => AsgConvertError::AstError(AstError::DeprecatedError(x)), + ImportParserError::SyntaxError(x) => x.into(), + ImportParserError::DeprecatedError(x) => AsgConvertError::SyntaxError(SyntaxError::DeprecatedError(x)), ImportParserError::AsgConvertError(x) => x, } } } impl ImportParserError { - fn new_from_span(message: String, span: Span) -> Self { + 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: &Path) -> Self { - 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) + Self::new_from_span(message, &identifier.span) } pub fn recursive_imports(package: &str, span: &Span) -> Self { let message = format!("recursive imports for `{}`.", package); - Self::new_from_span(message, span.clone()) + Self::new_from_span(message, span) } /// @@ -74,13 +90,13 @@ impl ImportParserError { pub fn duplicate_core_package(identifier: Identifier) -> Self { let message = format!("Duplicate core_package import `{}`.", identifier.name); - Self::new_from_span(message, identifier.span) + 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 { + pub fn convert_os_string(span: &Span) -> Self { let message = "Failed to convert file string name, maybe an illegal character?".to_string(); Self::new_from_span(message, span) @@ -90,30 +106,28 @@ impl ImportParserError { /// Failed to find the directory of the current file. /// 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) + Self::new_from_span(message, &Span::default()) } /// /// Failed to open or get the name of a directory. /// - pub fn directory_error(error: io::Error, span: Span, path: &Path) -> Self { - let message = format!("Compilation failed due to directory error - {:?}.", error); + pub fn directory_error(error: io::Error, span: &Span, path: &Path) -> Self { + let message = format!( + "Compilation failed due to directory error @ '{}' - {:?}.", + path.to_str().unwrap_or_default(), + error + ); - Self::new_from_span_with_path(message, span, path) + Self::new_from_span(message, span) } /// /// Failed to import all symbols at a package path. /// - pub fn star(path: &Path, span: Span) -> Self { + pub fn star(path: &Path, span: &Span) -> Self { let message = format!("Cannot import `*` from path `{:?}`.", path); Self::new_from_span(message, span) @@ -122,11 +136,8 @@ impl ImportParserError { /// /// 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 `{}`.", - entry, span.text - ); + pub fn expected_lib_file(entry: String, span: &Span) -> Self { + let message = format!("Expected library file `{}`.", entry,); Self::new_from_span(message, span) } @@ -140,6 +151,12 @@ impl ImportParserError { identifier.name ); - Self::new_from_span(message, identifier.span) + Self::new_from_span(message, &identifier.span) + } + + pub fn io_error(span: &Span, path: &str, error: std::io::Error) -> Self { + let message = format!("cannot read imported file '{}': {:?}", path, error,); + + Self::new_from_span(message, span) } } diff --git a/imports/src/parser/parse_package.rs b/imports/src/parser/parse_package.rs index 3acd05e41b..546fc7df63 100644 --- a/imports/src/parser/parse_package.rs +++ b/imports/src/parser/parse_package.rs @@ -81,9 +81,9 @@ impl<'a> ImportParser<'a> { // Get a vector of all packages in the source directory. let entries = fs::read_dir(path) - .map_err(|error| ImportParserError::directory_error(error, span.clone(), &error_path))? + .map_err(|error| ImportParserError::directory_error(error, span, &error_path))? .collect::, std::io::Error>>() - .map_err(|error| ImportParserError::directory_error(error, span.clone(), &error_path))?; + .map_err(|error| ImportParserError::directory_error(error, span, &error_path))?; // Check if the imported package name is in the source directory. let matched_source_entry = entries.into_iter().find(|entry| { @@ -98,9 +98,9 @@ impl<'a> ImportParser<'a> { 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, span.clone(), &error_path))? + .map_err(|error| ImportParserError::directory_error(error, span, &error_path))? .collect::, std::io::Error>>() - .map_err(|error| ImportParserError::directory_error(error, span.clone(), &error_path))?; + .map_err(|error| ImportParserError::directory_error(error, span, &error_path))?; // Check if the imported package name is in the imports directory. let matched_import_entry = entries @@ -111,13 +111,13 @@ impl<'a> ImportParser<'a> { match (matched_source_entry, matched_import_entry) { (Some(_), Some(_)) => Err(ImportParserError::conflicting_imports(Identifier::new_with_span( package_name, - span, + span.clone(), ))), (Some(source_entry), None) => self.parse_package_access(context, &source_entry, &segments[1..], span), (None, Some(import_entry)) => self.parse_package_access(context, &import_entry, &segments[1..], span), (None, None) => Err(ImportParserError::unknown_package(Identifier::new_with_span( package_name, - span, + span.clone(), ))), } } else { @@ -126,7 +126,7 @@ impl<'a> ImportParser<'a> { Some(source_entry) => self.parse_package_access(context, &source_entry, &segments[1..], span), None => Err(ImportParserError::unknown_package(Identifier::new_with_span( package_name, - span, + span.clone(), ))), } } diff --git a/imports/src/parser/parse_symbol.rs b/imports/src/parser/parse_symbol.rs index 9b02656d75..e37e89a9f2 100644 --- a/imports/src/parser/parse_symbol.rs +++ b/imports/src/parser/parse_symbol.rs @@ -16,7 +16,6 @@ use crate::{errors::ImportParserError, ImportParser}; use leo_ast::{Program, Span}; -use leo_grammar::Grammar; use std::fs::DirEntry; @@ -32,11 +31,11 @@ impl<'a> ImportParser<'a> { // Get the package file type. let file_type = package .file_type() - .map_err(|error| ImportParserError::directory_error(error, span.clone(), &package.path()))?; + .map_err(|error| ImportParserError::directory_error(error, span, &package.path()))?; let file_name = package .file_name() .into_string() - .map_err(|_| ImportParserError::convert_os_string(span.clone()))?; + .map_err(|_| ImportParserError::convert_os_string(span))?; let mut file_path = package.path(); if file_type.is_dir() { @@ -45,16 +44,18 @@ impl<'a> ImportParser<'a> { if !file_path.exists() { return Err(ImportParserError::expected_lib_file( format!("{:?}", file_path.as_path()), - span.clone(), + span, )); } } - // Build the package abstract syntax tree. - let program_string = &Grammar::load_file(&file_path)?; - let ast = &Grammar::new(&file_path, &program_string)?; + let file_path_str = file_path.to_str().unwrap_or_default(); - // Build the package Leo syntax tree from the package abstract syntax tree. - Ok(Program::from(&file_name, ast.as_repr())?) + // Build the package abstract syntax tree. + let program_string = + &std::fs::read_to_string(&file_path).map_err(|x| ImportParserError::io_error(span, file_path_str, x))?; + let mut ast = leo_parser::parse(&file_path_str, &program_string)?; + ast.name = file_name; + Ok(ast) } } diff --git a/input/src/errors/parser.rs b/input/src/errors/parser.rs index 71bdbee253..e45cb94741 100644 --- a/input/src/errors/parser.rs +++ b/input/src/errors/parser.rs @@ -28,11 +28,7 @@ use pest::{ error::{Error, ErrorVariant}, Span, }; -use std::{ - num::ParseIntError, - path::{Path, PathBuf}, - str::ParseBoolError, -}; +use std::{num::ParseIntError, path::PathBuf, str::ParseBoolError}; #[derive(Debug, Error)] pub enum InputParserError { @@ -56,12 +52,12 @@ pub enum InputParserError { } impl InputParserError { - pub fn set_path(&mut self, path: &Path) { + pub fn set_path(&mut self, path: &str, _content: &[String]) { if let InputParserError::SyntaxError(error) = self { let new_error: Error = match error { InputSyntaxError::Error(error) => { let new_error = error.clone(); - new_error.with_path(path.to_str().unwrap()) + new_error.with_path(path) } }; @@ -71,13 +67,17 @@ impl InputParserError { } } - fn new_from_span(message: String, span: Span) -> Self { - let error = Error::new_from_span(ErrorVariant::CustomError { message }, span); + pub fn get_path(&self) -> Option<&str> { + None + } + + fn new_from_span(message: String, span: &Span) -> Self { + let error = Error::new_from_span(ErrorVariant::CustomError { message }, span.to_owned()); InputParserError::SyntaxError(InputSyntaxError::from(error)) } - pub fn array_index(actual: String, span: Span) -> Self { + 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) @@ -86,27 +86,26 @@ impl InputParserError { pub fn implicit_type(data_type: DataType, implicit: NumberValue) -> Self { let message = format!("expected `{}`, found `{}`", data_type, implicit); - Self::new_from_span(message, implicit.span().clone()) + Self::new_from_span(message, implicit.span()) } pub fn implicit_group(number: NumberValue) -> Self { let message = format!("group coordinates should be in (x, y)group format, found `{}`", number); - Self::new_from_span(message, number.span().clone()) + Self::new_from_span(message, number.span()) } pub fn data_type_mismatch(data_type: DataType, value: Value) -> Self { let message = format!("expected data type `{}`, found `{}`", data_type, value); - let span = value.span().to_owned(); - Self::new_from_span(message, span) + Self::new_from_span(message, value.span()) } pub fn expression_type_mismatch(type_: Type, expression: Expression) -> Self { let message = format!("expected expression type `{}`, found `{}`", type_, expression); let span = expression.span().to_owned(); - Self::new_from_span(message, span) + Self::new_from_span(message, &span) } pub fn array_inline_length(number: usize, array: ArrayInlineExpression) -> Self { @@ -117,10 +116,10 @@ impl InputParserError { ); let span = array.span.to_owned(); - Self::new_from_span(message, span) + Self::new_from_span(message, &span) } - pub fn array_init_length(expected: Vec, actual: Vec, span: Span) -> Self { + pub fn array_init_length(expected: Vec, actual: Vec, span: &Span) -> Self { let message = format!( "expected an array with a fixed size of {:?} elements, found one with {:?} elements", expected, actual @@ -133,21 +132,21 @@ impl InputParserError { let message = format!("the section header `{}` is not valid in an input `.in` file", header); let span = header.span(); - Self::new_from_span(message, span) + Self::new_from_span(message, &span) } pub fn public_section(header: Header) -> Self { let message = format!("the section header `{}` is not a public section", header); let span = header.span(); - Self::new_from_span(message, span) + Self::new_from_span(message, &span) } pub fn private_section(header: Header) -> Self { let message = format!("the section header `{}` is not a private section", header); let span = header.span(); - Self::new_from_span(message, span) + Self::new_from_span(message, &span) } pub fn table(table: Table) -> Self { @@ -156,16 +155,16 @@ impl InputParserError { table ); - Self::new_from_span(message, table.span) + Self::new_from_span(message, &table.span) } - pub fn tuple_length(expected: usize, actual: usize, span: Span) -> Self { + pub fn tuple_length(expected: usize, actual: usize, span: &Span) -> Self { let message = format!( "expected a tuple with {} elements, found a tuple with {} elements", expected, actual ); - Self::new_from_span(message, span) + Self::new_from_span(message, &span) } pub fn section(header: Header) -> Self { @@ -175,7 +174,7 @@ impl InputParserError { ); let span = header.span(); - Self::new_from_span(message, span) + Self::new_from_span(message, &span) } } diff --git a/grammar/Cargo.toml b/parser/Cargo.toml similarity index 74% rename from grammar/Cargo.toml rename to parser/Cargo.toml index 6f123a6d50..1a3a25e7d5 100644 --- a/grammar/Cargo.toml +++ b/parser/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "leo-grammar" +name = "leo-parser" version = "1.2.3" authors = [ "The Aleo Team " ] description = "AST generated by pest from the Leo grammar rules" @@ -17,30 +17,18 @@ include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] license = "GPL-3.0" edition = "2018" -[[bin]] -name = "leo_grammar" -path = "src/main.rs" - [[bench]] -name = "grammar" -path = "benches/grammar.rs" +name = "leo_ast" +path = "benches/leo_ast.rs" harness = false -[dependencies.from-pest] -version = "0.3.1" +[dependencies.leo-ast] +path = "../ast" +version = "1.2.3" [dependencies.lazy_static] version = "1.3.0" -[dependencies.pest] -version = "2.0" - -[dependencies.pest-ast] -version = "0.3.3" - -[dependencies.pest_derive] -version = "2.0" - [dependencies.serde] version = "1.0" features = [ "derive" ] @@ -57,6 +45,9 @@ version = "0.1" [dev-dependencies.criterion] version = "0.3" +[dependencies.indexmap] +version = "1.6" + [features] default = [ ] ci_skip = [ ] diff --git a/ast/benches/big_circuit.leo b/parser/benches/big_circuit.leo similarity index 100% rename from ast/benches/big_circuit.leo rename to parser/benches/big_circuit.leo diff --git a/ast/benches/big_if_else.leo b/parser/benches/big_if_else.leo similarity index 100% rename from ast/benches/big_if_else.leo rename to parser/benches/big_if_else.leo diff --git a/ast/benches/big_ternary.leo b/parser/benches/big_ternary.leo similarity index 100% rename from ast/benches/big_ternary.leo rename to parser/benches/big_ternary.leo diff --git a/ast/benches/leo_ast.rs b/parser/benches/leo_ast.rs similarity index 54% rename from ast/benches/leo_ast.rs rename to parser/benches/leo_ast.rs index d5420b0543..0777665e0d 100644 --- a/ast/benches/leo_ast.rs +++ b/parser/benches/leo_ast.rs @@ -14,70 +14,56 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use leo_ast::Ast; -use leo_grammar::Grammar; - use criterion::{criterion_group, criterion_main, Criterion}; -use std::{path::Path, time::Duration}; - -fn ast(ast: &Grammar) -> Ast { - Ast::new("leo_tree", &ast).unwrap() -} +use std::time::Duration; 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 grammar = Grammar::new(&filepath, program_string).unwrap(); + let ast = leo_parser::parse_ast("./big_if_else.leo", program_string).expect("failed to parse benchmark"); - c.bench_function("Ast::big_if_else", |b| b.iter(|| ast(&grammar))); + c.bench_function("Ast::big_if_else", |b| b.iter(|| &ast)); } 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 grammar = Grammar::new(&filepath, program_string).unwrap(); + let ast = leo_parser::parse_ast("./big_ternary.leo", program_string).expect("failed to parse benchmark"); - c.bench_function("Ast::big_ternary", |b| b.iter(|| ast(&grammar))); + c.bench_function("Ast::big_ternary", |b| b.iter(|| &ast)); } 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 grammar = Grammar::new(&filepath, program_string).unwrap(); + let ast = leo_parser::parse_ast("./big_circuit.leo", program_string).expect("failed to parse benchmark"); - c.bench_function("Ast::big_circuit", |b| b.iter(|| ast(&grammar))); + c.bench_function("Ast::big_circuit", |b| b.iter(|| &ast)); } 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 grammar = Grammar::new(&filepath, program_string).unwrap(); + let ast = leo_parser::parse_ast("./long_expr.leo", program_string).expect("failed to parse benchmark"); - c.bench_function("Ast::long_expr", |b| b.iter(|| ast(&grammar))); + c.bench_function("Ast::long_expr", |b| b.iter(|| &ast)); } 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 grammar = Grammar::new(&filepath, program_string).unwrap(); + let ast = leo_parser::parse_ast("./long_array.leo", program_string).expect("failed to parse benchmark"); - c.bench_function("Ast::long_array", |b| b.iter(|| ast(&grammar))); + c.bench_function("Ast::long_array", |b| b.iter(|| &ast)); } 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 grammar = Grammar::new(&filepath, program_string).unwrap(); + let ast = leo_parser::parse_ast("./many_foos.leo", program_string).expect("failed to parse benchmark"); - c.bench_function("Ast::many_foos", |b| b.iter(|| ast(&grammar))); + c.bench_function("Ast::many_foos", |b| b.iter(|| &ast)); } 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 grammar = Grammar::new(&filepath, program_string).unwrap(); + let ast = leo_parser::parse_ast("./many_assigns.leo", program_string).expect("failed to parse benchmark"); - c.bench_function("Ast::many_assigns", |b| b.iter(|| ast(&grammar))); + c.bench_function("Ast::many_assigns", |b| b.iter(|| &ast)); } criterion_group!( diff --git a/ast/benches/long_array.leo b/parser/benches/long_array.leo similarity index 100% rename from ast/benches/long_array.leo rename to parser/benches/long_array.leo diff --git a/ast/benches/long_expr.leo b/parser/benches/long_expr.leo similarity index 100% rename from ast/benches/long_expr.leo rename to parser/benches/long_expr.leo diff --git a/ast/benches/many_assigns.leo b/parser/benches/many_assigns.leo similarity index 100% rename from ast/benches/many_assigns.leo rename to parser/benches/many_assigns.leo diff --git a/ast/benches/many_foos.leo b/parser/benches/many_foos.leo similarity index 100% rename from ast/benches/many_foos.leo rename to parser/benches/many_foos.leo diff --git a/ast/src/errors/deprecated.rs b/parser/src/errors/deprecated.rs similarity index 51% rename from ast/src/errors/deprecated.rs rename to parser/src/errors/deprecated.rs index c22419d3ee..496c3db306 100644 --- a/ast/src/errors/deprecated.rs +++ b/parser/src/errors/deprecated.rs @@ -14,10 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . -use crate::{Error as FormattedError, Span}; -use leo_grammar::{annotations::AnnotationName, definitions::Deprecated}; - -use std::{convert::TryFrom, path::Path}; +use leo_ast::{FormattedError, LeoError, Span}; #[derive(Debug, Error)] pub enum DeprecatedError { @@ -26,38 +23,21 @@ pub enum DeprecatedError { } 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 { + fn new_from_span(message: String, span: &Span) -> Self { DeprecatedError::Error(FormattedError::new_from_span(message, span)) } } -impl<'ast> From> 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 annotation?".to_string(), - Span::from(test_function.span.clone()), - ), +impl LeoError for DeprecatedError { + fn get_path(&self) -> Option<&str> { + match self { + DeprecatedError::Error(error) => error.get_path(), } } -} -impl<'ast> TryFrom> for DeprecatedError { - type Error = bool; - - fn try_from(annotation_name: AnnotationName<'ast>) -> Result { - match annotation_name { - AnnotationName::Context(context) => Ok(DeprecatedError::new_from_span( - "\"@context(...)\" is deprecated. Did you mean @test annotation?".to_string(), - Span::from(context.span.clone()), - )), - _ => Err(false), + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + DeprecatedError::Error(error) => error.set_path(path, contents), } } } @@ -65,6 +45,16 @@ impl<'ast> TryFrom> for DeprecatedError { impl DeprecatedError { pub fn const_statement(span: &Span) -> Self { let message = "const _ = ... is deprecated. Did you mean let?".to_string(); - Self::new_from_span(message, span.clone()) + Self::new_from_span(message, span) + } + + pub fn test_function(span: &Span) -> Self { + let message = "\"test function...\" is deprecated. Did you mean @test annotation?".to_string(); + Self::new_from_span(message, span) + } + + pub fn context_annotation(span: &Span) -> Self { + let message = "\"@context(...)\" is deprecated. Did you mean @test annotation?".to_string(); + Self::new_from_span(message, span) } } diff --git a/grammar/src/errors/mod.rs b/parser/src/errors/mod.rs similarity index 90% rename from grammar/src/errors/mod.rs rename to parser/src/errors/mod.rs index 9a69051aaa..6138a74a98 100644 --- a/grammar/src/errors/mod.rs +++ b/parser/src/errors/mod.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 . -pub mod parser; -pub use parser::*; +pub mod token; +pub use token::*; pub mod syntax; pub use syntax::*; + +pub mod deprecated; +pub use deprecated::*; diff --git a/parser/src/errors/syntax.rs b/parser/src/errors/syntax.rs new file mode 100644 index 0000000000..c453625d94 --- /dev/null +++ b/parser/src/errors/syntax.rs @@ -0,0 +1,108 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use leo_ast::{FormattedError, LeoError, Span}; + +use crate::{DeprecatedError, Token, TokenError}; + +#[derive(Debug, Error)] +pub enum SyntaxError { + #[error("{}", _0)] + Error(#[from] FormattedError), + + #[error("{}", _0)] + TokenError(#[from] TokenError), + + #[error("{}", _0)] + DeprecatedError(#[from] DeprecatedError), +} + +impl LeoError for SyntaxError { + fn get_path(&self) -> Option<&str> { + match self { + SyntaxError::Error(error) => error.get_path(), + SyntaxError::TokenError(error) => error.get_path(), + SyntaxError::DeprecatedError(error) => error.get_path(), + } + } + + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + SyntaxError::Error(error) => error.set_path(path, contents), + SyntaxError::TokenError(error) => error.set_path(path, contents), + SyntaxError::DeprecatedError(error) => error.set_path(path, contents), + } + } +} + +impl SyntaxError { + fn new_from_span(message: String, span: &Span) -> Self { + SyntaxError::Error(FormattedError::new_from_span(message, span)) + } + + pub fn unexpected_eof(span: &Span) -> Self { + Self::new_from_span("unexpected EOF".to_string(), span) + } + + pub fn unexpected(got: &Token, expected: &[Token], span: &Span) -> Self { + Self::new_from_span( + format!( + "expected {} -- got '{}'", + expected + .iter() + .map(|x| format!("'{}'", x)) + .collect::>() + .join(", "), + got.to_string() + ), + span, + ) + } + + pub fn unexpected_ident(got: &str, expected: &[&str], span: &Span) -> Self { + Self::new_from_span( + format!( + "expected identifier {} -- got '{}'", + expected + .iter() + .map(|x| format!("'{}'", x)) + .collect::>() + .join(", "), + got + ), + span, + ) + } + + pub fn unexpected_str(got: &Token, expected: &str, span: &Span) -> Self { + Self::new_from_span(format!("expected '{}', got '{}'", expected, got.to_string()), span) + } + + pub fn spread_in_array_init(span: &Span) -> Self { + Self::new_from_span("illegal spread in array initializer".to_string(), span) + } + + pub fn invalid_assignment_target(span: &Span) -> Self { + Self::new_from_span("invalid assignment target".to_string(), span) + } + + pub fn invalid_package_name(span: &Span) -> Self { + Self::new_from_span( + "package names must be lowercase alphanumeric ascii with underscores and singular dashes".to_string(), + span, + ) + } +} diff --git a/parser/src/errors/token.rs b/parser/src/errors/token.rs new file mode 100644 index 0000000000..3a439646a7 --- /dev/null +++ b/parser/src/errors/token.rs @@ -0,0 +1,51 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use leo_ast::{FormattedError, LeoError, Span}; + +#[derive(Debug, Error)] +pub enum TokenError { + #[error("{}", _0)] + Error(#[from] FormattedError), +} + +impl LeoError for TokenError { + fn get_path(&self) -> Option<&str> { + match self { + TokenError::Error(error) => error.get_path(), + } + } + + fn set_path(&mut self, path: &str, contents: &[String]) { + match self { + TokenError::Error(error) => error.set_path(path, contents), + } + } +} + +impl TokenError { + fn new_from_span(message: String, span: &Span) -> Self { + TokenError::Error(FormattedError::new_from_span(message, span)) + } + + pub fn unexpected_token(token: &str, span: &Span) -> Self { + TokenError::new_from_span(format!("unexpected token: '{}'", token), span) + } + + pub fn invalid_address_lit(token: &str, span: &Span) -> Self { + TokenError::new_from_span(format!("invalid address literal: '{}'", token), span) + } +} diff --git a/grammar/src/expressions/mod.rs b/parser/src/lib.rs similarity index 54% rename from grammar/src/expressions/mod.rs rename to parser/src/lib.rs index 6eb2e47eda..de440802b4 100644 --- a/grammar/src/expressions/mod.rs +++ b/parser/src/lib.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 array_initializer_expression; -pub use array_initializer_expression::*; +//! The parser to convert Leo code text into an [`AST`] type. +//! +//! This module contains the [`parse_ast()`] method which calls the underlying [`parse()`] +//! method to create a new program ast. -pub mod array_inline_expression; -pub use array_inline_expression::*; +#[macro_use] +extern crate thiserror; -pub mod binary_expression; -pub use binary_expression::*; +pub(crate) mod tokenizer; +pub(crate) use tokenizer::*; -pub mod circuit_inline_expression; -pub use circuit_inline_expression::*; +pub mod errors; +pub use errors::*; -pub mod expression; -pub use expression::*; +pub mod parser; +pub use parser::*; -pub mod unary_expression; -pub use unary_expression::*; +use leo_ast::Ast; -pub mod postfix_expression; -pub use postfix_expression::*; +#[cfg(test)] +mod test; -pub mod self_postfix_expression; -pub use self_postfix_expression::*; - -pub mod ternary_expression; -pub use ternary_expression::*; - -pub mod tuple_expression; -pub use tuple_expression::*; +/// Creates a new AST from a given file path and source code text. +pub fn parse_ast, Y: AsRef>(path: T, source: Y) -> SyntaxResult { + Ok(Ast::new(parser::parse(path.as_ref(), source.as_ref())?)) +} diff --git a/parser/src/parser/context.rs b/parser/src/parser/context.rs new file mode 100644 index 0000000000..1c3f41f53e --- /dev/null +++ b/parser/src/parser/context.rs @@ -0,0 +1,327 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use std::unimplemented; + +use crate::{tokenizer::*, SyntaxError, SyntaxResult, Token, KEYWORD_TOKENS}; +use leo_ast::*; + +/// Stores a program in tokenized format plus additional context. +/// May be converted into a [`Program`] AST by parsing all tokens. +pub struct ParserContext { + tokens: Vec, + end_span: Span, + // true if parsing an expression for an if statement -- means circuit inits are not legal + pub(crate) fuzzy_struct_state: bool, +} + +impl Iterator for ParserContext { + type Item = SpannedToken; + + fn next(&mut self) -> Option { + self.tokens.pop() + } +} + +impl ParserContext { + /// + /// Returns a new [`ParserContext`] type given a vector of tokens. + /// + pub fn new(mut tokens: Vec) -> Self { + tokens.reverse(); + // todo: performance optimization here: drain filter + tokens = tokens + .into_iter() + .filter(|x| !matches!(x.token, Token::CommentLine(_) | Token::CommentBlock(_))) + .collect(); + ParserContext { + end_span: tokens.last().map(|x| x.span.clone()).unwrap_or_default(), + tokens, + fuzzy_struct_state: false, + } + } + + /// + /// Returns an unexpected end of function [`SyntaxError`]. + /// + pub fn eof(&self) -> SyntaxError { + SyntaxError::unexpected_eof(&self.end_span) + } + + /// + /// Returns a reference to the next token or error if it does not exist. + /// + pub fn peek(&self) -> SyntaxResult<&SpannedToken> { + self.tokens.last().ok_or_else(|| self.eof()) + } + + // pub fn peek_oneof(&self, token: &[Token]) -> SyntaxResult<&SpannedToken> { + // if let Some(spanned_token) = self.inner.last() { + // if token.iter().any(|x| x == &spanned_token.token) { + // Ok(spanned_token) + // } else { + // Err(SyntaxError::unexpected( + // &spanned_token.token, + // token, + // &spanned_token.span, + // )) + // } + // } else { + // Err(self.eof()) + // } + // } + + /// + /// Returns true if the next token exists. + /// + pub fn has_next(&self) -> bool { + !self.tokens.is_empty() + } + + /// + /// Removes the next token if it exists and returns it, or [None] if + /// the next token does not exist. + /// + pub fn eat(&mut self, token: Token) -> Option { + if let Some(SpannedToken { token: inner, .. }) = self.tokens.last() { + if &token == inner { + return self.tokens.pop(); + } + } + None + } + + /// + /// Appends a token to the back of the vector. + /// + pub fn backtrack(&mut self, token: SpannedToken) { + self.tokens.push(token); + } + + /// + /// Removes the next token if it is a [`Token::Ident(_)`] and returns it, or [None] if + /// the next token is not a [`Token::Ident(_)`] or if the next token does not exist. + /// + pub fn eat_identifier(&mut self) -> Option { + if let Some(SpannedToken { + token: Token::Ident(_), .. + }) = self.tokens.last() + { + let token = self.tokens.pop().unwrap(); + if let SpannedToken { + token: Token::Ident(name), + span, + } = token + { + return Some(Identifier { name, span }); + } else { + unimplemented!() + } + } + None + } + + /// + /// Returns a reference to the next token if it is a [`GroupCoordinate`], or [None] if + /// the next token is not a [`GroupCoordinate`]. + /// + fn peek_group_coordinate(&self, i: &mut usize) -> Option { + let token = self.tokens.get(*i)?; + *i -= 1; + Some(match &token.token { + Token::Add => GroupCoordinate::SignHigh, + Token::Minus => match self.tokens.get(*i) { + Some(SpannedToken { + token: Token::Int(value), + span, + }) => { + *i -= 1; + GroupCoordinate::Number(format!("-{}", value), span.clone()) + } + _ => GroupCoordinate::SignLow, + }, + Token::Ident(x) if x == "_" => GroupCoordinate::Inferred, + Token::Int(value) => GroupCoordinate::Number(value.clone(), token.span.clone()), + _ => return None, + }) + } + + /// + /// Removes the next two tokens if they are a pair of [`GroupCoordinate`] and returns them, + /// or [None] if the next token is not a [`GroupCoordinate`]. + /// + pub fn eat_group_partial(&mut self) -> Option<(GroupCoordinate, GroupCoordinate, Span)> { + let mut i = self.tokens.len() - 1; + let start_span = self.tokens.get(i)?.span.clone(); + let first = self.peek_group_coordinate(&mut i)?; + match self.tokens.get(i) { + Some(SpannedToken { + token: Token::Comma, .. + }) => { + i -= 1; + } + _ => { + return None; + } + } + let second = self.peek_group_coordinate(&mut i)?; + match self.tokens.get(i) { + Some(SpannedToken { + token: Token::RightParen, + .. + }) => { + i -= 1; + } + _ => { + return None; + } + } + let end_span; + match self.tokens.get(i) { + Some(SpannedToken { + token: Token::Group, + span, + }) => { + end_span = span.clone(); + i -= 1; + } + _ => { + return None; + } + } + + self.tokens.drain((i + 1)..); + Some((first, second, start_span + end_span)) + } + + /// + /// Removes the next token if it is a [`Token::Int(_)`] and returns it, or [None] if + /// the next token is not a [`Token::Int(_)`] or if the next token does not exist. + /// + pub fn eat_int(&mut self) -> Option<(PositiveNumber, Span)> { + if let Some(SpannedToken { + token: Token::Int(_), .. + }) = self.tokens.last() + { + let token = self.tokens.pop().unwrap(); + if let SpannedToken { + token: Token::Int(value), + span, + } = token + { + return Some((PositiveNumber { value }, span)); + } else { + unimplemented!() + } + } + None + } + + /// + /// Removes the next token if it exists and returns it, or [None] if + /// the next token does not exist. + /// + pub fn eat_any(&mut self, token: &[Token]) -> Option { + if let Some(SpannedToken { token: inner, .. }) = self.tokens.last() { + if token.iter().any(|x| x == inner) { + return self.tokens.pop(); + } + } + None + } + + /// + /// Returns the span of the next token if it is equal to the given [`Token`], or error. + /// + pub fn expect(&mut self, token: Token) -> SyntaxResult { + if let Some(SpannedToken { token: inner, span }) = self.tokens.last() { + if &token == inner { + Ok(self.tokens.pop().unwrap().span) + } else { + Err(SyntaxError::unexpected(inner, &[token], span)) + } + } else { + Err(self.eof()) + } + } + + /// + /// Returns the span of the next token if it is equal to one of the given [`Token`]s, or error. + /// + pub fn expect_oneof(&mut self, token: &[Token]) -> SyntaxResult { + if let Some(SpannedToken { token: inner, span }) = self.tokens.last() { + if token.iter().any(|x| x == inner) { + Ok(self.tokens.pop().unwrap()) + } else { + Err(SyntaxError::unexpected(inner, token, span)) + } + } else { + Err(self.eof()) + } + } + + /// + /// Returns the [`Identifier`] of the next token if it is a keyword, + /// [`Token::Int(_)`], or an [`Identifier`], or error. + /// + pub fn expect_loose_identifier(&mut self) -> SyntaxResult { + if let Some(token) = self.eat_any(KEYWORD_TOKENS) { + return Ok(Identifier { + name: token.token.to_string(), + span: token.span, + }); + } + if let Some((int, span)) = self.eat_int() { + return Ok(Identifier { name: int.value, span }); + } + self.expect_ident() + } + + /// + /// Returns the [`Identifier`] of the next token if it is an [`Identifier`], or error. + /// + pub fn expect_ident(&mut self) -> SyntaxResult { + if let Some(SpannedToken { token: inner, span }) = self.tokens.last() { + if let Token::Ident(_) = inner { + let token = self.tokens.pop().unwrap(); + if let SpannedToken { + token: Token::Ident(name), + span, + } = token + { + Ok(Identifier { name, span }) + } else { + unimplemented!() + } + } else { + Err(SyntaxError::unexpected_str(inner, "ident", span)) + } + } else { + Err(self.eof()) + } + } + + /// + /// Returns the next token if it exists or return end of function. + /// + pub fn expect_any(&mut self) -> SyntaxResult { + if let Some(x) = self.tokens.pop() { + Ok(x) + } else { + Err(self.eof()) + } + } +} diff --git a/parser/src/parser/expression.rs b/parser/src/parser/expression.rs new file mode 100644 index 0000000000..ec4df7c2cd --- /dev/null +++ b/parser/src/parser/expression.rs @@ -0,0 +1,707 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use super::*; + +const INT_TYPES: &[Token] = &[ + Token::I8, + Token::I16, + Token::I32, + Token::I64, + Token::I128, + Token::U8, + Token::U16, + Token::U32, + Token::U64, + Token::U128, + Token::Field, + Token::Group, +]; + +impl ParserContext { + /// + /// Returns an [`Expression`] AST node if the next token is an expression. + /// Includes circuit init expressions. + /// + pub fn parse_expression(&mut self) -> SyntaxResult { + // Store current parser state. + let prior_fuzzy_state = self.fuzzy_struct_state; + + // Allow circuit init expressions. + self.fuzzy_struct_state = false; + + // Parse expression. + let result = self.parse_expression_fuzzy(); + + // Restore prior parser state. + self.fuzzy_struct_state = prior_fuzzy_state; + + result + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent + /// a ternary expression. May or may not include circuit init expressions. + /// + /// Otherwise, tries to parse the next token using [`parse_or_expression`]. + /// + pub fn parse_expression_fuzzy(&mut self) -> SyntaxResult { + // Try to parse the next expression. Try BinaryOperation::Or. + let mut expr = self.parse_or_expression()?; + + // Parse the rest of the ternary expression. + if self.eat(Token::Question).is_some() { + let if_true = self.parse_expression()?; + self.expect(Token::Colon)?; + let if_false = self.parse_expression_fuzzy()?; + expr = Expression::Ternary(TernaryExpression { + span: expr.span() + if_false.span(), + condition: Box::new(expr), + if_true: Box::new(if_true), + if_false: Box::new(if_false), + }); + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent + /// a binary or expression. + /// + /// Otherwise, tries to parse the next token using [`parse_and_expression`]. + /// + pub fn parse_or_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_and_expression()?; + while self.eat(Token::Or).is_some() { + let right = self.parse_and_expression()?; + expr = Expression::Binary(BinaryExpression { + span: expr.span() + right.span(), + op: BinaryOperation::Or, + left: Box::new(expr), + right: Box::new(right), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// binary and expression. + /// + /// Otherwise, tries to parse the next token using [`parse_bit_or_expression`]. + /// + pub fn parse_and_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_bit_or_expression()?; + while self.eat(Token::And).is_some() { + let right = self.parse_bit_or_expression()?; + expr = Expression::Binary(BinaryExpression { + span: expr.span() + right.span(), + op: BinaryOperation::And, + left: Box::new(expr), + right: Box::new(right), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// binary bitwise or expression. + /// + /// Otherwise, tries to parse the next token using [`parse_bit_xor_expression`]. + /// + pub fn parse_bit_or_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_bit_xor_expression()?; + while self.eat(Token::BitOr).is_some() { + let right = self.parse_bit_xor_expression()?; + expr = Expression::Binary(BinaryExpression { + span: expr.span() + right.span(), + op: BinaryOperation::BitOr, + left: Box::new(expr), + right: Box::new(right), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// binary bitwise xor expression. + /// + /// Otherwise, tries to parse the next token using [`parse_bit_and_expression`]. + /// + pub fn parse_bit_xor_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_bit_and_expression()?; + while self.eat(Token::BitXor).is_some() { + let right = self.parse_bit_and_expression()?; + expr = Expression::Binary(BinaryExpression { + span: expr.span() + right.span(), + op: BinaryOperation::BitXor, + left: Box::new(expr), + right: Box::new(right), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// binary bitwise and expression. + /// + /// Otherwise, tries to parse the next token using [`parse_eq_expression`]. + /// + pub fn parse_bit_and_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_eq_expression()?; + while self.eat(Token::BitAnd).is_some() { + let right = self.parse_eq_expression()?; + expr = Expression::Binary(BinaryExpression { + span: expr.span() + right.span(), + op: BinaryOperation::BitAnd, + left: Box::new(expr), + right: Box::new(right), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// binary equals or not equals expression. + /// + /// Otherwise, tries to parse the next token using [`parse_rel_expression`]. + /// + pub fn parse_eq_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_rel_expression()?; + while let Some(SpannedToken { token: op, .. }) = self.eat_any(&[Token::Eq, Token::NotEq]) { + let right = self.parse_rel_expression()?; + expr = Expression::Binary(BinaryExpression { + span: expr.span() + right.span(), + op: match op { + Token::Eq => BinaryOperation::Eq, + Token::NotEq => BinaryOperation::Ne, + _ => unimplemented!(), + }, + left: Box::new(expr), + right: Box::new(right), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// binary relational expression: less than, less than or equals, greater than, greater than or equals. + /// + /// Otherwise, tries to parse the next token using [`parse_shift_expression`]. + /// + pub fn parse_rel_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_shift_expression()?; + while let Some(SpannedToken { token: op, .. }) = self.eat_any(&[Token::Lt, Token::LtEq, Token::Gt, Token::GtEq]) + { + let right = self.parse_shift_expression()?; + expr = Expression::Binary(BinaryExpression { + span: expr.span() + right.span(), + op: match op { + Token::Lt => BinaryOperation::Lt, + Token::LtEq => BinaryOperation::Le, + Token::Gt => BinaryOperation::Gt, + Token::GtEq => BinaryOperation::Ge, + _ => unimplemented!(), + }, + left: Box::new(expr), + right: Box::new(right), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// binary shift expression. + /// + /// Otherwise, tries to parse the next token using [`parse_add_sub_expression`]. + /// + pub fn parse_shift_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_add_sub_expression()?; + while let Some(SpannedToken { token: op, .. }) = self.eat_any(&[Token::Shl, Token::Shr, Token::ShrSigned]) { + let right = self.parse_add_sub_expression()?; + expr = Expression::Binary(BinaryExpression { + span: expr.span() + right.span(), + op: match op { + Token::Shl => BinaryOperation::Shl, + Token::Shr => BinaryOperation::Shr, + Token::ShrSigned => BinaryOperation::ShrSigned, + _ => unimplemented!(), + }, + left: Box::new(expr), + right: Box::new(right), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// binary addition or subtraction expression. + /// + /// Otherwise, tries to parse the next token using [`parse_mul_div_pow_expression`]. + /// + pub fn parse_add_sub_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_mul_div_mod_expression()?; + while let Some(SpannedToken { token: op, .. }) = self.eat_any(&[Token::Add, Token::Minus]) { + let right = self.parse_mul_div_mod_expression()?; + expr = Expression::Binary(BinaryExpression { + span: expr.span() + right.span(), + op: match op { + Token::Add => BinaryOperation::Add, + Token::Minus => BinaryOperation::Sub, + _ => unimplemented!(), + }, + left: Box::new(expr), + right: Box::new(right), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// binary multiplication, division, or modulus expression. + /// + /// Otherwise, tries to parse the next token using [`parse_exp_expression`]. + /// + pub fn parse_mul_div_mod_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_exp_expression()?; + while let Some(SpannedToken { token: op, .. }) = self.eat_any(&[Token::Mul, Token::Div, Token::Mod]) { + let right = self.parse_exp_expression()?; + expr = Expression::Binary(BinaryExpression { + span: expr.span() + right.span(), + op: match op { + Token::Mul => BinaryOperation::Mul, + Token::Div => BinaryOperation::Div, + Token::Mod => BinaryOperation::Mod, + _ => unimplemented!(), + }, + left: Box::new(expr), + right: Box::new(right), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// binary exponentiation expression. + /// + /// Otherwise, tries to parse the next token using [`parse_cast_expression`]. + /// + pub fn parse_exp_expression(&mut self) -> SyntaxResult { + let mut exprs = vec![]; + exprs.push(self.parse_cast_expression()?); + while self.eat(Token::Exp).is_some() { + exprs.push(self.parse_cast_expression()?); + } + let mut expr = exprs.remove(exprs.len() - 1); + while !exprs.is_empty() { + let sub_expr = exprs.remove(exprs.len() - 1); + expr = Expression::Binary(BinaryExpression { + span: expr.span() + sub_expr.span(), + op: BinaryOperation::Pow, + left: Box::new(sub_expr), + right: Box::new(expr), + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// type cast expression. + /// + /// Otherwise, tries to parse the next token using [`parse_unary_expression`]. + /// + pub fn parse_cast_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_unary_expression()?; + while self.eat(Token::As).is_some() { + let (type_, type_span) = self.parse_type()?; + expr = Expression::Cast(CastExpression { + span: expr.span() + &type_span, + inner: Box::new(expr), + target_type: type_, + }) + } + Ok(expr) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent a + /// unary not, negate, or bitwise not expression. + /// + /// Otherwise, tries to parse the next token using [`parse_access_expression`]. + /// + pub fn parse_unary_expression(&mut self) -> SyntaxResult { + let mut ops = vec![]; + while let Some(token) = self.eat_any(&[Token::Not, Token::Minus, Token::BitNot]) { + ops.push(token); + } + let mut inner = self.parse_access_expression()?; + for op in ops.into_iter().rev() { + let operation = match op.token { + Token::Not => UnaryOperation::Not, + Token::Minus => UnaryOperation::Negate, + Token::BitNot => UnaryOperation::BitNot, + _ => unimplemented!(), + }; + // hack for const signed integer overflow issues + if matches!(operation, UnaryOperation::Negate) { + if let Expression::Value(ValueExpression::Integer(type_, value, span)) = inner { + inner = Expression::Value(ValueExpression::Integer(type_, format!("-{}", value), &op.span + &span)); + continue; + } else if let Expression::Value(ValueExpression::Implicit(value, span)) = inner { + inner = Expression::Value(ValueExpression::Implicit(format!("-{}", value), &op.span + &span)); + continue; + } + } + inner = Expression::Unary(UnaryExpression { + span: &op.span + inner.span(), + op: operation, + inner: Box::new(inner), + }); + } + Ok(inner) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent an + /// array access, circuit member access, function call, or static function call expression. + /// + /// Otherwise, tries to parse the next token using [`parse_primary_expression`]. + /// + pub fn parse_access_expression(&mut self) -> SyntaxResult { + let mut expr = self.parse_primary_expression()?; + while let Some(token) = self.eat_any(&[Token::LeftSquare, Token::Dot, Token::LeftParen, Token::DoubleColon]) { + match token.token { + Token::LeftSquare => { + if self.eat(Token::DotDot).is_some() { + let right = if self.peek()?.token != Token::RightSquare { + Some(Box::new(self.parse_expression()?)) + } else { + None + }; + + let end = self.expect(Token::RightSquare)?; + expr = Expression::ArrayRangeAccess(ArrayRangeAccessExpression { + span: expr.span() + &end, + array: Box::new(expr), + left: None, + right, + }); + continue; + } + + let left = self.parse_expression()?; + if self.eat(Token::DotDot).is_some() { + let right = if self.peek()?.token != Token::RightSquare { + Some(Box::new(self.parse_expression()?)) + } else { + None + }; + + let end = self.expect(Token::RightSquare)?; + expr = Expression::ArrayRangeAccess(ArrayRangeAccessExpression { + span: expr.span() + &end, + array: Box::new(expr), + left: Some(Box::new(left)), + right, + }); + } else { + let end = self.expect(Token::RightSquare)?; + expr = Expression::ArrayAccess(ArrayAccessExpression { + span: expr.span() + &end, + array: Box::new(expr), + index: Box::new(left), + }); + } + } + Token::Dot => { + if let Some(ident) = self.eat_identifier() { + expr = Expression::CircuitMemberAccess(CircuitMemberAccessExpression { + span: expr.span() + &ident.span, + circuit: Box::new(expr), + name: ident, + }); + } else if let Some((num, span)) = self.eat_int() { + expr = Expression::TupleAccess(TupleAccessExpression { + span: expr.span() + &span, + tuple: Box::new(expr), + index: num, + }); + } else { + let next = self.peek()?; + return Err(SyntaxError::unexpected_str(&next.token, "int or ident", &next.span)); + } + } + Token::LeftParen => { + let mut arguments = vec![]; + let end_span; + loop { + let end = self.eat(Token::RightParen); + if let Some(end) = end { + end_span = end.span; + break; + } + arguments.push(self.parse_expression()?); + if self.eat(Token::Comma).is_none() { + end_span = self.expect(Token::RightParen)?; + break; + } + } + expr = Expression::Call(CallExpression { + span: expr.span() + &end_span, + function: Box::new(expr), + arguments, + }); + } + Token::DoubleColon => { + let ident = self.expect_ident()?; + expr = Expression::CircuitStaticFunctionAccess(CircuitStaticFunctionAccessExpression { + span: expr.span() + &ident.span, + circuit: Box::new(expr), + name: ident, + }); + } + _ => unimplemented!(), + } + } + Ok(expr) + } + + /// + /// Returns a [`SpreadOrExpression`] AST node if the next tokens represent an + /// spread or expression. + /// + /// This method should only be called in the context of an array access expression. + /// + pub fn parse_spread_or_expression(&mut self) -> SyntaxResult { + Ok(if self.eat(Token::DotDotDot).is_some() { + SpreadOrExpression::Spread(self.parse_expression()?) + } else { + SpreadOrExpression::Expression(self.parse_expression()?) + }) + } + + /// + /// Returns an [`Expression`] AST node if the next tokens represent an + /// circuit initialization expression. + /// + pub fn parse_circuit_init(&mut self, ident: Identifier) -> SyntaxResult { + self.expect(Token::LeftCurly)?; + let mut members = vec![]; + let end_span; + loop { + if let Some(end) = self.eat(Token::RightCurly) { + end_span = end.span; + break; + } + let name = self.expect_ident()?; + if self.eat(Token::Colon).is_some() { + let expression = self.parse_expression()?; + members.push(CircuitImpliedVariableDefinition { + identifier: name, + expression: Some(expression), + }); + } else { + members.push(CircuitImpliedVariableDefinition { + identifier: name.clone(), + expression: None, + }); + } + if self.eat(Token::Comma).is_none() { + end_span = self.expect(Token::RightCurly)?; + break; + } + } + Ok(Expression::CircuitInit(CircuitInitExpression { + span: &ident.span + &end_span, + name: ident, + members, + })) + } + + /// + /// Returns an [`Expression`] AST node if the next token is a primary expression: + /// - Scalar types: field, group, unsigned integer, signed integer, boolean, address + /// - Aggregate types: array, tuple + /// - Identifiers: variables, keywords + /// + /// Returns an expression error if the token cannot be matched. + /// + pub fn parse_primary_expression(&mut self) -> SyntaxResult { + let SpannedToken { token, span } = self.expect_any()?; + Ok(match token { + Token::Int(value) => { + let type_ = self.eat_any(INT_TYPES); + match type_ { + Some(SpannedToken { + token: Token::Field, + span: type_span, + }) => Expression::Value(ValueExpression::Field(value, span + type_span)), + Some(SpannedToken { + token: Token::Group, + span: type_span, + }) => Expression::Value(ValueExpression::Group(Box::new(GroupValue::Single( + value, + span + type_span, + )))), + Some(SpannedToken { token, span: type_span }) => Expression::Value(ValueExpression::Integer( + Self::token_to_int_type(token).expect("unknown int type token"), + value, + span + type_span, + )), + None => Expression::Value(ValueExpression::Implicit(value, span)), + } + } + Token::True => Expression::Value(ValueExpression::Boolean("true".to_string(), span)), + Token::False => Expression::Value(ValueExpression::Boolean("false".to_string(), span)), + Token::AddressLit(value) => Expression::Value(ValueExpression::Address(value, span)), + Token::Address => { + self.expect(Token::LeftParen)?; + let value = self.expect_any()?; + let value = if let SpannedToken { + token: Token::AddressLit(value), + .. + } = value + { + value + } else { + return Err(SyntaxError::unexpected_str(&value.token, "address", &value.span)); + }; + + let end = self.expect(Token::RightParen)?; + Expression::Value(ValueExpression::Address(value, span + end)) + } + Token::LeftParen => { + if let Some((left, right, span)) = self.eat_group_partial() { + return Ok(Expression::Value(ValueExpression::Group(Box::new(GroupValue::Tuple( + GroupTuple { + span, + x: left, + y: right, + }, + ))))); + } + let mut args = vec![]; + let end_span; + loop { + let end = self.eat(Token::RightParen); + if let Some(end) = end { + end_span = end.span; + break; + } + let expr = self.parse_expression()?; + args.push(expr); + if self.eat(Token::Comma).is_none() { + end_span = self.expect(Token::RightParen)?; + break; + } + } + if args.len() == 1 { + args.remove(0) + } else { + Expression::TupleInit(TupleInitExpression { + span: span + end_span, + elements: args, + }) + } + } + Token::LeftSquare => { + if let Some(end) = self.eat(Token::RightSquare) { + return Ok(Expression::ArrayInline(ArrayInlineExpression { + elements: vec![], + span: span + end.span, + })); + } + let first = self.parse_spread_or_expression()?; + if self.eat(Token::Semicolon).is_some() { + let dimensions = self.parse_array_dimensions()?; + let end = self.expect(Token::RightSquare)?; + let first = match first { + SpreadOrExpression::Spread(first) => { + let span = &span + first.span(); + return Err(SyntaxError::spread_in_array_init(&span)); + } + SpreadOrExpression::Expression(x) => x, + }; + Expression::ArrayInit(ArrayInitExpression { + span: span + end, + element: Box::new(first), + dimensions, + }) + } else { + let end_span; + let mut elements = vec![first]; + loop { + if let Some(token) = self.eat(Token::RightSquare) { + end_span = token.span; + break; + } + if elements.len() == 1 { + self.expect(Token::Comma)?; + } + elements.push(self.parse_spread_or_expression()?); + if self.eat(Token::Comma).is_none() { + end_span = self.expect(Token::RightSquare)?; + break; + } + } + Expression::ArrayInline(ArrayInlineExpression { + elements, + span: span + end_span, + }) + } + } + Token::Ident(name) => { + let ident = Identifier { name, span }; + if !self.fuzzy_struct_state && self.peek()?.token == Token::LeftCurly { + self.parse_circuit_init(ident)? + } else { + Expression::Identifier(ident) + } + } + Token::BigSelf => { + let ident = Identifier { + name: token.to_string(), + span, + }; + if !self.fuzzy_struct_state && self.peek()?.token == Token::LeftCurly { + self.parse_circuit_init(ident)? + } else { + Expression::Identifier(ident) + } + } + Token::Input | Token::LittleSelf => { + let ident = Identifier { + name: token.to_string(), + span, + }; + Expression::Identifier(ident) + } + token => { + return Err(SyntaxError::unexpected_str(&token, "expression", &span)); + } + }) + } +} diff --git a/parser/src/parser/file.rs b/parser/src/parser/file.rs new file mode 100644 index 0000000000..36dca63852 --- /dev/null +++ b/parser/src/parser/file.rs @@ -0,0 +1,382 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::KEYWORD_TOKENS; + +use super::*; + +impl ParserContext { + /// + /// Returns a [`Program`] AST if all tokens can be consumed and represent a valid Leo program. + /// + pub fn parse_program(&mut self) -> SyntaxResult { + let mut imports = vec![]; + let mut circuits = IndexMap::new(); + let mut functions = IndexMap::new(); + // let mut tests = IndexMap::new(); + + while self.has_next() { + let token = self.peek()?; + match &token.token { + Token::Import => { + imports.push(self.parse_import()?); + } + Token::Circuit => { + let (id, circuit) = self.parse_circuit()?; + circuits.insert(id, circuit); + } + Token::Function | Token::At => { + let (id, function) = self.parse_function()?; + functions.insert(id, function); + } + Token::Ident(ident) if ident == "test" => { + return Err(SyntaxError::DeprecatedError(DeprecatedError::test_function( + &token.span, + ))); + // self.expect(Token::Test)?; + // let (id, function) = self.parse_function()?; + // tests.insert(id, TestFunction { + // function, + // input_file: None, + // }); + } + _ => { + return Err(SyntaxError::unexpected( + &token.token, + &[ + Token::Import, + Token::Circuit, + Token::Function, + Token::Ident("test".to_string()), + Token::At, + ], + &token.span, + )); + } + } + } + Ok(Program { + name: String::new(), + expected_input: vec![], + imports, + circuits, + functions, + }) + } + + /// + /// Returns an [`Annotation`] AST node if the next tokens represent a supported annotation. + /// + pub fn parse_annotation(&mut self) -> SyntaxResult { + let start = self.expect(Token::At)?; + let name = self.expect_ident()?; + if name.name == "context" { + return Err(SyntaxError::DeprecatedError(DeprecatedError::context_annotation( + &name.span, + ))); + } + let end_span; + let arguments = if self.eat(Token::LeftParen).is_some() { + let mut args = vec![]; + loop { + if let Some(end) = self.eat(Token::RightParen) { + end_span = end.span; + break; + } + if let Some(ident) = self.eat_identifier() { + args.push(ident.name); + } else if let Some((int, _)) = self.eat_int() { + args.push(int.value); + } else { + let token = self.peek()?; + return Err(SyntaxError::unexpected_str(&token.token, "ident or int", &token.span)); + } + if self.eat(Token::Comma).is_none() { + end_span = self.expect(Token::RightParen)?; + break; + } + } + args + } else { + end_span = name.span.clone(); + vec![] + }; + Ok(Annotation { + name, + arguments, + span: start + end_span, + }) + } + + /// + /// Returns a vector of [`PackageAccess`] AST nodes if the next tokens represent package access + /// expressions within an import statement. + /// + pub fn parse_package_accesses(&mut self) -> SyntaxResult> { + let mut out = vec![]; + self.expect(Token::LeftParen)?; + while self.eat(Token::RightParen).is_none() { + let access = self.parse_package_access()?; + out.push(access); + if self.eat(Token::Comma).is_none() { + self.expect(Token::RightParen)?; + break; + } + } + Ok(out) + } + + /// + /// Returns a [`PackageAccess`] AST node if the next tokens represent a package access expression + /// within an import statement. + /// + pub fn parse_package_access(&mut self) -> SyntaxResult { + if let Some(SpannedToken { span, .. }) = self.eat(Token::Mul) { + Ok(PackageAccess::Star(span)) + } else { + let name = self.expect_ident()?; + if self.peek()?.token == Token::Dot { + self.backtrack(SpannedToken { + token: Token::Ident(name.name), + span: name.span, + }); + Ok(match self.parse_package_or_packages()? { + PackageOrPackages::Package(p) => PackageAccess::SubPackage(Box::new(p)), + PackageOrPackages::Packages(p) => PackageAccess::Multiple(p), + }) + } else if self.eat(Token::As).is_some() { + let alias = self.expect_ident()?; + Ok(PackageAccess::Symbol(ImportSymbol { + span: &name.span + &alias.span, + symbol: name, + alias: Some(alias), + })) + } else { + Ok(PackageAccess::Symbol(ImportSymbol { + span: name.span.clone(), + symbol: name, + alias: None, + })) + } + } + } + + /// + /// Returns an [`Identifier`] AST node if the next tokens represent a valid package name. + /// + pub fn parse_package_name(&mut self) -> SyntaxResult { + // Build the package name, starting with valid characters up to a dash `-` (Token::Minus). + let mut base = self.expect_loose_identifier()?; + + // Build the rest of the package name including dashes. + loop { + match &self.peek()?.token { + Token::Minus => { + let span = self.expect(Token::Minus)?; + base.name += "-"; + base.span = base.span + span; + let next = self.expect_loose_identifier()?; + base.name += &next.name; + base.span = base.span + next.span; + } + Token::Int(_) => { + let (num, span) = self.eat_int().unwrap(); + base.name += &num.value; + base.span = base.span + span; + } + Token::Ident(_) => { + let next = self.expect_ident()?; + base.name += &next.name; + base.span = base.span + next.span; + } + x if KEYWORD_TOKENS.contains(&x) => { + let next = self.expect_loose_identifier()?; + base.name += &next.name; + base.span = base.span + next.span; + } + _ => break, + } + } + + // Return an error if the package name contains a keyword. + if let Some(token) = KEYWORD_TOKENS.iter().find(|x| x.to_string() == base.name) { + return Err(SyntaxError::unexpected_str(token, "package name", &base.span)); + } + + // Return an error if the package name contains invalid characters. + if !base + .name + .chars() + .all(|x| x.is_ascii_lowercase() || x.is_ascii_digit() || x == '-' || x == '_') + { + return Err(SyntaxError::invalid_package_name(&base.span)); + } + + // Return the package name. + Ok(base) + } + + /// + /// Returns a [`PackageOrPackages`] AST node if the next tokens represent a valid package import + /// with accesses. + /// + pub fn parse_package_or_packages(&mut self) -> SyntaxResult { + let package_name = self.parse_package_name()?; + self.expect(Token::Dot)?; + if self.peek()?.token == Token::LeftParen { + let accesses = self.parse_package_accesses()?; + Ok(PackageOrPackages::Packages(Packages { + span: &package_name.span + accesses.last().map(|x| x.span()).unwrap_or(&package_name.span), + name: package_name, + accesses, + })) + } else { + let access = self.parse_package_access()?; + Ok(PackageOrPackages::Package(Package { + span: &package_name.span + access.span(), + name: package_name, + access, + })) + } + } + + /// + /// Returns a [`ImportStatement`] AST node if the next tokens represent an import statement. + /// + pub fn parse_import(&mut self) -> SyntaxResult { + self.expect(Token::Import)?; + let package_or_packages = self.parse_package_or_packages()?; + self.expect(Token::Semicolon)?; + Ok(ImportStatement { + span: package_or_packages.span().clone(), + package_or_packages, + }) + } + + /// + /// Returns a [`CircuitMember`] AST node if the next tokens represent a circuit member variable + /// or circuit member function. + /// + pub fn parse_circuit_member(&mut self) -> SyntaxResult { + let peeked = &self.peek()?.token; + if peeked == &Token::Function || peeked == &Token::At { + let function = self.parse_function()?; + Ok(CircuitMember::CircuitFunction(function.1)) + } else { + // circuit variable + let name = self.expect_ident()?; + self.expect(Token::Colon)?; + let type_ = self.parse_type()?.0; + self.eat(Token::Comma); + Ok(CircuitMember::CircuitVariable(name, type_)) + } + } + + /// + /// Returns an [`(Identifier, Circuit)`] tuple of AST nodes if the next tokens represent a + /// circuit name and definition statement. + /// + pub fn parse_circuit(&mut self) -> SyntaxResult<(Identifier, Circuit)> { + self.expect(Token::Circuit)?; + let name = self.expect_ident()?; + self.expect(Token::LeftCurly)?; + let mut members = vec![]; + while self.eat(Token::RightCurly).is_none() { + let member = self.parse_circuit_member()?; + members.push(member); + } + Ok((name.clone(), Circuit { + circuit_name: name, + members, + })) + } + + /// + /// Returns a [`FunctionInput`] AST node if the next tokens represent a function parameter. + /// + pub fn parse_function_input(&mut self) -> SyntaxResult { + if let Some(token) = self.eat(Token::Input) { + return Ok(FunctionInput::InputKeyword(InputKeyword { span: token.span })); + } + let const_ = self.eat(Token::Const); + let mutable = self.eat(Token::Mut); + let name = if let Some(token) = self.eat(Token::LittleSelf) { + Identifier { + name: token.token.to_string(), + span: token.span, + } + } else { + self.expect_ident()? + }; + if name.name == "self" { + if const_.is_some() { + //error + } + if let Some(mutable) = &mutable { + return Ok(FunctionInput::MutSelfKeyword(MutSelfKeyword { + span: &mutable.span + &name.span, + })); + } + return Ok(FunctionInput::SelfKeyword(SelfKeyword { span: name.span })); + } + self.expect(Token::Colon)?; + let type_ = self.parse_type()?.0; + Ok(FunctionInput::Variable(FunctionInputVariable { + const_: const_.is_some(), + mutable: mutable.is_some(), + type_, + span: name.span.clone(), + identifier: name, + })) + } + + /// + /// Returns an [`(Identifier, Function)`] AST node if the next tokens represent a function name + /// and function definition. + /// + pub fn parse_function(&mut self) -> SyntaxResult<(Identifier, Function)> { + let mut annotations = vec![]; + while self.peek()?.token == Token::At { + annotations.push(self.parse_annotation()?); + } + let start = self.expect(Token::Function)?; + let name = self.expect_ident()?; + self.expect(Token::LeftParen)?; + let mut inputs = vec![]; + while self.eat(Token::RightParen).is_none() { + let input = self.parse_function_input()?; + inputs.push(input); + if self.eat(Token::Comma).is_none() { + self.expect(Token::RightParen)?; + break; + } + } + let output = if self.eat(Token::Arrow).is_some() { + Some(self.parse_type()?.0) + } else { + None + }; + let block = self.parse_block()?; + Ok((name.clone(), Function { + annotations, + identifier: name, + input: inputs, + output, + span: start + block.span.clone(), + block, + })) + } +} diff --git a/parser/src/parser/mod.rs b/parser/src/parser/mod.rs new file mode 100644 index 0000000000..0801bf4cf4 --- /dev/null +++ b/parser/src/parser/mod.rs @@ -0,0 +1,52 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +//! The parser to convert Leo code text into an [`Program`] AST type. +//! +//! This module contains the [`parse()`] method which calls the underlying [`tokenize()`] +//! method to create a new program ast. + +mod context; +use context::*; + +mod expression; +mod file; +mod statement; +mod type_; + +use std::unimplemented; + +use crate::{tokenizer::*, DeprecatedError, SyntaxError, Token}; +use indexmap::IndexMap; +use leo_ast::*; + +pub type SyntaxResult = Result; + +/// Creates a new program from a given file path and source code text. +pub fn parse(path: &str, source: &str) -> SyntaxResult { + let mut tokens = ParserContext::new(crate::tokenize(path, source)?); + + match tokens.parse_program() { + Ok(x) => Ok(x), + Err(mut e) => { + e.set_path( + path, + &source.lines().map(|x| x.to_string()).collect::>()[..], + ); + Err(e) + } + } +} diff --git a/parser/src/parser/statement.rs b/parser/src/parser/statement.rs new file mode 100644 index 0000000000..c01190fa0b --- /dev/null +++ b/parser/src/parser/statement.rs @@ -0,0 +1,345 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use super::*; + +const ASSIGN_TOKENS: &[Token] = &[ + Token::Assign, + Token::AddEq, + Token::MinusEq, + Token::MulEq, + Token::DivEq, + Token::ExpEq, + Token::BitAndEq, + Token::BitOrEq, + Token::BitXorEq, + Token::ShlEq, + Token::ShrEq, + Token::ShrSignedEq, + Token::ModEq, + Token::OrEq, + Token::AndEq, +]; + +impl ParserContext { + /// + /// Returns an [`Identifier`] AST node if the given [`Expression`] AST node evaluates to an + /// identifier access. The access is stored in the given accesses. + /// + pub fn construct_assignee_access(expr: Expression, accesses: &mut Vec) -> SyntaxResult { + let identifier; + match expr { + Expression::CircuitMemberAccess(expr) => { + identifier = Self::construct_assignee_access(*expr.circuit, accesses)?; + accesses.push(AssigneeAccess::Member(expr.name)); + } + Expression::TupleAccess(expr) => { + identifier = Self::construct_assignee_access(*expr.tuple, accesses)?; + accesses.push(AssigneeAccess::Tuple(expr.index, expr.span)); + } + Expression::ArrayRangeAccess(expr) => { + identifier = Self::construct_assignee_access(*expr.array, accesses)?; + accesses.push(AssigneeAccess::ArrayRange( + expr.left.map(|x| *x), + expr.right.map(|x| *x), + )); + } + Expression::ArrayAccess(expr) => { + identifier = Self::construct_assignee_access(*expr.array, accesses)?; + accesses.push(AssigneeAccess::ArrayIndex(*expr.index)); + } + Expression::Identifier(id) => identifier = id, + _ => return Err(SyntaxError::invalid_assignment_target(expr.span())), + } + Ok(identifier) + } + + /// + /// Returns an [`Assignee`] AST node from the given [`Expression`] AST node with accesses. + /// + pub fn construct_assignee(expr: Expression) -> SyntaxResult { + let expr_span = expr.span().clone(); + let mut accesses = vec![]; + let identifier = Self::construct_assignee_access(expr, &mut accesses)?; + + Ok(Assignee { + span: expr_span, + identifier, + accesses, + }) + } + + /// + /// Returns a [`Statement`] AST node if the next tokens represent a statement. + /// + pub fn parse_statement(&mut self) -> SyntaxResult { + match &self.peek()?.token { + Token::Return => Ok(Statement::Return(self.parse_return_statement()?)), + Token::If => Ok(Statement::Conditional(self.parse_conditional_statement()?)), + Token::For => Ok(Statement::Iteration(self.parse_for_statement()?)), + Token::Console => Ok(Statement::Console(self.parse_console_statement()?)), + Token::Let | Token::Const => Ok(Statement::Definition(self.parse_definition_statement()?)), + Token::LeftCurly => Ok(Statement::Block(self.parse_block()?)), + _ => { + let expr = self.parse_expression()?; + + if let Some(operator) = self.eat_any(ASSIGN_TOKENS) { + let value = self.parse_expression()?; + let assignee = Self::construct_assignee(expr)?; + self.expect(Token::Semicolon)?; + Ok(Statement::Assign(AssignStatement { + span: &assignee.span + value.span(), + assignee, + operation: match operator.token { + Token::Assign => AssignOperation::Assign, + Token::AddEq => AssignOperation::Add, + Token::MinusEq => AssignOperation::Sub, + Token::MulEq => AssignOperation::Mul, + Token::DivEq => AssignOperation::Div, + Token::ExpEq => AssignOperation::Pow, + Token::OrEq => AssignOperation::Or, + Token::AndEq => AssignOperation::And, + Token::BitOrEq => AssignOperation::BitOr, + Token::BitAndEq => AssignOperation::BitAnd, + Token::BitXorEq => AssignOperation::BitXor, + Token::ShrEq => AssignOperation::Shr, + Token::ShrSignedEq => AssignOperation::ShrSigned, + Token::ShlEq => AssignOperation::Shl, + Token::ModEq => AssignOperation::Mod, + _ => unimplemented!(), + }, + value, + })) + } else { + self.expect(Token::Semicolon)?; + Ok(Statement::Expression(ExpressionStatement { + span: expr.span().clone(), + expression: expr, + })) + } + } + } + } + + /// + /// Returns a [`Block`] AST node if the next tokens represent a block of statements. + /// + pub fn parse_block(&mut self) -> SyntaxResult { + let start = self.expect(Token::LeftCurly)?; + let mut statements = vec![]; + loop { + match self.eat(Token::RightCurly) { + None => { + statements.push(self.parse_statement()?); + } + Some(end) => { + return Ok(Block { + span: start + end.span, + statements, + }); + } + } + } + } + + /// + /// Returns a [`ReturnStatement`] AST node if the next tokens represent a return statement. + /// + pub fn parse_return_statement(&mut self) -> SyntaxResult { + let start = self.expect(Token::Return)?; + let expr = self.parse_expression()?; + self.eat(Token::Comma); + + Ok(ReturnStatement { + span: &start + expr.span(), + expression: expr, + }) + } + + /// + /// Returns a [`ConditionalStatement`] AST node if the next tokens represent a conditional statement. + /// + pub fn parse_conditional_statement(&mut self) -> SyntaxResult { + let start = self.expect(Token::If)?; + self.fuzzy_struct_state = true; + let expr = self.parse_expression_fuzzy()?; + self.fuzzy_struct_state = false; + let body = self.parse_block()?; + let next = if self.eat(Token::Else).is_some() { + Some(Box::new(self.parse_statement()?)) + } else { + None + }; + + Ok(ConditionalStatement { + span: &start + next.as_ref().map(|x| x.span()).unwrap_or(&body.span), + condition: expr, + block: body, + next, + }) + } + + /// + /// Returns an [`IterationStatement`] AST node if the next tokens represent an iteration statement. + /// + pub fn parse_for_statement(&mut self) -> SyntaxResult { + let start_span = self.expect(Token::For)?; + let ident = self.expect_ident()?; + self.expect(Token::In)?; + let start = self.parse_expression()?; + self.expect(Token::DotDot)?; + self.fuzzy_struct_state = true; + let stop = self.parse_expression_fuzzy()?; + self.fuzzy_struct_state = false; + let block = self.parse_block()?; + + Ok(IterationStatement { + span: start_span + block.span.clone(), + variable: ident, + start, + stop, + block, + }) + } + + /// + /// Returns a [`FormattedString`] AST node if the next tokens represent a formatted string. + /// + pub fn parse_formatted_string(&mut self) -> SyntaxResult { + let start_span; + let parts = match self.expect_any()? { + SpannedToken { + token: Token::FormattedString(parts), + span, + } => { + start_span = span; + parts + } + SpannedToken { token, span } => return Err(SyntaxError::unexpected_str(&token, "formatted string", &span)), + }; + let mut parameters = vec![]; + while self.eat(Token::Comma).is_some() { + let param = self.parse_expression()?; + parameters.push(param); + } + + Ok(FormattedString { + parts: parts + .into_iter() + .map(|x| match x { + crate::FormattedStringPart::Const(value) => FormattedStringPart::Const(value), + crate::FormattedStringPart::Container => FormattedStringPart::Container, + }) + .collect(), + span: &start_span + parameters.last().map(|x| x.span()).unwrap_or(&start_span), + parameters, + }) + } + + /// + /// Returns a [`ConsoleStatement`] AST node if the next tokens represent a console statement. + /// + pub fn parse_console_statement(&mut self) -> SyntaxResult { + let keyword = self.expect(Token::Console)?; + self.expect(Token::Dot)?; + let function = self.expect_ident()?; + self.expect(Token::LeftParen)?; + let function = match &*function.name { + "assert" => { + let expr = self.parse_expression()?; + ConsoleFunction::Assert(expr) + } + "debug" => ConsoleFunction::Debug(self.parse_formatted_string()?), + "error" => ConsoleFunction::Error(self.parse_formatted_string()?), + "log" => ConsoleFunction::Log(self.parse_formatted_string()?), + x => { + return Err(SyntaxError::unexpected_ident( + &x, + &["assert", "debug", "error", "log"], + &function.span, + )); + } + }; + self.expect(Token::RightParen)?; + self.expect(Token::Semicolon)?; + + Ok(ConsoleStatement { + span: &keyword + function.span(), + function, + }) + } + + /// + /// Returns a [`VariableName`] AST node if the next tokens represent a variable name with + /// valid keywords. + /// + pub fn parse_variable_name(&mut self) -> SyntaxResult { + let mutable = self.eat(Token::Mut); + let name = self.expect_ident()?; + Ok(VariableName { + span: mutable + .as_ref() + .map(|x| &x.span + &name.span) + .unwrap_or_else(|| name.span.clone()), + mutable: mutable.is_some(), + identifier: name, + }) + } + + /// + /// Returns a [`DefinitionStatement`] AST node if the next tokens represent a definition statement. + /// + pub fn parse_definition_statement(&mut self) -> SyntaxResult { + let declare = self.expect_oneof(&[Token::Let, Token::Const])?; + let mut variable_names = vec![]; + if self.eat(Token::LeftParen).is_some() { + variable_names.push(self.parse_variable_name()?); + while self.eat(Token::Comma).is_some() { + variable_names.push(self.parse_variable_name()?); + } + self.expect(Token::RightParen)?; + } else { + variable_names.push(self.parse_variable_name()?); + } + + let type_ = if self.eat(Token::Colon).is_some() { + Some(self.parse_type()?.0) + } else { + None + }; + + self.expect(Token::Assign)?; + let expr = self.parse_expression()?; + self.expect(Token::Semicolon)?; + + Ok(DefinitionStatement { + span: &declare.span + expr.span(), + declaration_type: match declare.token { + Token::Let => Declare::Let, + Token::Const => { + return Err(SyntaxError::DeprecatedError(DeprecatedError::const_statement( + &declare.span, + ))); + //Declare::Const + } + _ => unimplemented!(), + }, + variable_names, + type_, + value: expr, + }) + } +} diff --git a/parser/src/parser/type_.rs b/parser/src/parser/type_.rs new file mode 100644 index 0000000000..cac76bbd3c --- /dev/null +++ b/parser/src/parser/type_.rs @@ -0,0 +1,126 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use super::*; + +const TYPE_TOKENS: &[Token] = &[ + Token::I8, + Token::I16, + Token::I32, + Token::I64, + Token::I128, + Token::U8, + Token::U16, + Token::U32, + Token::U64, + Token::U128, + Token::Field, + Token::Group, + Token::Address, + Token::Bool, +]; + +impl ParserContext { + /// + /// Returns a [`IntegerType`] AST node if the given token is a supported integer type, or [`None`]. + /// + pub fn token_to_int_type(token: Token) -> Option { + Some(match token { + Token::I8 => IntegerType::I8, + Token::I16 => IntegerType::I16, + Token::I32 => IntegerType::I32, + Token::I64 => IntegerType::I64, + Token::I128 => IntegerType::I128, + Token::U8 => IntegerType::U8, + Token::U16 => IntegerType::U16, + Token::U32 => IntegerType::U32, + Token::U64 => IntegerType::U64, + Token::U128 => IntegerType::U128, + _ => return None, + }) + } + + /// + /// Returns an [`ArrayDimensions`] AST node if the next tokens represent dimensions for an array type. + /// + pub fn parse_array_dimensions(&mut self) -> SyntaxResult { + Ok(if let Some((int, _)) = self.eat_int() { + ArrayDimensions(vec![int]) + } else { + self.expect(Token::LeftParen)?; + let mut dimensions = vec![]; + loop { + if let Some((int, _)) = self.eat_int() { + dimensions.push(int); + } else { + let token = self.peek()?; + return Err(SyntaxError::unexpected_str(&token.token, "int", &token.span)); + } + if self.eat(Token::Comma).is_none() { + break; + } + } + self.expect(Token::RightParen)?; + ArrayDimensions(dimensions) + }) + } + + /// + /// Returns a [`(Type, Span)`] tuple of AST nodes if the next token represents a type. Also + /// returns the span of the parsed token. + /// + pub fn parse_type(&mut self) -> SyntaxResult<(Type, Span)> { + Ok(if let Some(token) = self.eat(Token::BigSelf) { + (Type::SelfType, token.span) + } else if let Some(ident) = self.eat_identifier() { + let span = ident.span.clone(); + (Type::Circuit(ident), span) + } else if let Some(token) = self.eat(Token::LeftParen) { + let mut types = vec![]; + let end_span; + loop { + if let Some(end) = self.eat(Token::RightParen) { + end_span = end.span; + break; + } + types.push(self.parse_type()?.0); + if self.eat(Token::Comma).is_none() { + end_span = self.expect(Token::RightParen)?; + break; + } + } + (Type::Tuple(types), token.span + end_span) + } else if let Some(token) = self.eat(Token::LeftSquare) { + let (inner, _) = self.parse_type()?; + self.expect(Token::Semicolon)?; + let dimensions = self.parse_array_dimensions()?; + let end_span = self.expect(Token::RightSquare)?; + (Type::Array(Box::new(inner), dimensions), token.span + end_span) + } else { + let token = self.expect_oneof(TYPE_TOKENS)?; + ( + match token.token { + Token::Field => Type::Field, + Token::Group => Type::Group, + Token::Address => Type::Address, + Token::Bool => Type::Boolean, + x => Type::IntegerType(Self::token_to_int_type(x).expect("invalid int type")), + }, + token.span, + ) + }) + } +} diff --git a/parser/src/test.rs b/parser/src/test.rs new file mode 100644 index 0000000000..ad123ca63d --- /dev/null +++ b/parser/src/test.rs @@ -0,0 +1,106 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use std::{ + fs, + path::{Path, PathBuf}, +}; + +use crate::SyntaxError; + +struct TestFailure { + path: String, + error: SyntaxError, +} + +pub fn find_tests>(path: T, out: &mut Vec<(String, String)>) { + for entry in fs::read_dir(path).expect("fail to read tests").into_iter() { + let entry = entry.expect("fail to read tests").path(); + if entry.is_dir() { + find_tests(entry.as_path(), out); + continue; + } else if entry.extension().map(|x| x.to_str()).flatten().unwrap_or_default() != "leo" { + continue; + } + let content = fs::read_to_string(entry.as_path()).expect("failed to read test"); + out.push((entry.as_path().to_str().unwrap_or_default().to_string(), content)); + } +} + +#[test] +pub fn parser_pass_tests() { + let mut pass = 0; + let mut fail = vec![]; + let mut tests = vec![]; + let mut test_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + test_dir.push("../tests/pass/parse/"); + find_tests(&test_dir, &mut tests); + for (path, content) in tests.into_iter() { + match crate::parse(&path, &content) { + Ok(_) => { + pass += 1; + } + Err(e) => { + fail.push(TestFailure { path, error: e }); + } + } + } + if !fail.is_empty() { + for (i, fail) in fail.iter().enumerate() { + println!( + "\n\n-----------------TEST #{} FAILED (and shouldn't have)-----------------", + i + 1 + ); + println!("File: {}", fail.path); + println!("{}", fail.error); + } + panic!("failed {}/{} tests", fail.len(), fail.len() + pass); + } else { + println!("passed {}/{} tests", pass, pass); + } +} + +#[test] +pub fn parser_fail_tests() { + let mut pass = 0; + let mut fail = vec![]; + let mut tests = vec![]; + let mut test_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + test_dir.push("../tests/fail/parse/"); + find_tests(&test_dir, &mut tests); + for (path, content) in tests.into_iter() { + match crate::parse(&path, &content) { + Ok(_) => { + fail.push(path); + } + Err(_e) => { + pass += 1; + } + } + } + if !fail.is_empty() { + for (i, fail) in fail.iter().enumerate() { + println!( + "\n\n-----------------TEST #{} PASSED (and shouldn't have)-----------------", + i + 1 + ); + println!("File: {}", fail); + } + panic!("failed {}/{} tests", fail.len(), fail.len() + pass); + } else { + println!("passed {}/{} tests", pass, pass); + } +} diff --git a/parser/src/tokenizer/lexer.rs b/parser/src/tokenizer/lexer.rs new file mode 100644 index 0000000000..8236e85362 --- /dev/null +++ b/parser/src/tokenizer/lexer.rs @@ -0,0 +1,397 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::tokenizer::{FormattedStringPart, Token}; +use leo_ast::Span; +use serde::{Deserialize, Serialize}; + +use std::fmt; + +/// +/// Returns a reference to bytes from the given input if the given string is equal to the bytes, +/// otherwise returns [`None`]. +/// +fn eat<'a>(input: &'a [u8], wanted: &str) -> Option<&'a [u8]> { + let wanted = wanted.as_bytes(); + if input.len() < wanted.len() { + return None; + } + if &input[0..wanted.len()] == wanted { + return Some(&input[wanted.len()..]); + } + None +} + +/// +/// Returns a reference to the bytes of an identifier and the remaining bytes from the given input. +/// Returns [`None`] if the bytes do not represent an identifier. +/// +fn eat_identifier(input: &[u8]) -> Option<(&[u8], &[u8])> { + if input.is_empty() { + return None; + } + if !input[0].is_ascii_alphabetic() && input[0] != b'_' { + return None; + } + let mut i = 1usize; + while i < input.len() { + if !input[i].is_ascii_alphanumeric() && input[i] != b'_' { + break; + } + i += 1; + } + Some((&input[0..i], &input[i..])) +} + +impl Token { + /// + /// Returns a reference to the remaining bytes and the bytes of a number from the given input. + /// Returns [`None`] if the bytes do not represent a number. + /// + fn gobble_int(input: &[u8]) -> (&[u8], Option) { + if input.is_empty() { + return (input, None); + } + if !input[0].is_ascii_digit() { + return (input, None); + } + let mut i = 1; + let mut is_hex = false; + while i < input.len() { + if i == 1 && input[0] == b'0' && input[i] == b'x' { + is_hex = true; + i += 1; + continue; + } + if is_hex { + if !input[i].is_ascii_hexdigit() { + break; + } + } else if !input[i].is_ascii_digit() { + break; + } + + i += 1; + } + ( + &input[i..], + Some(Token::Int(String::from_utf8(input[0..i].to_vec()).unwrap_or_default())), + ) + } + + /// + /// Returns a reference to the remaining bytes and the bytes of a [`Token`] from the given input. + /// Returns [`None`] if the bytes do not represent a token. + /// + pub(crate) fn gobble(input: &[u8]) -> (&[u8], Option) { + if input.is_empty() { + return (input, None); + } + match input[0] { + x if x.is_ascii_whitespace() => return (&input[1..], None), + b'"' => { + let mut i = 1; + let mut in_escape = false; + let mut start = 1usize; + let mut segments = vec![]; + while i < input.len() { + if !in_escape { + if input[i] == b'"' { + break; + } + if input[i] == b'\\' { + in_escape = !in_escape; + } else if i < input.len() - 1 && input[i] == b'{' { + if i < input.len() - 2 && input[i + 1] == b'{' { + i += 2; + continue; + } else if input[i + 1] != b'}' { + i += 1; + continue; + } + if start < i { + segments.push(FormattedStringPart::Const( + String::from_utf8_lossy(&input[start..i]).to_string(), + )); + } + segments.push(FormattedStringPart::Container); + start = i + 2; + i = start; + continue; + } + } else { + in_escape = false; + } + i += 1; + } + if i == input.len() { + return (input, None); + } + if start < i { + segments.push(FormattedStringPart::Const( + String::from_utf8_lossy(&input[start..i]).to_string(), + )); + } + return (&input[(i + 1)..], Some(Token::FormattedString(segments))); + } + x if x.is_ascii_digit() => { + return Self::gobble_int(input); + } + b'!' => { + if let Some(input) = eat(input, "!=") { + return (input, Some(Token::NotEq)); + } + return (&input[1..], Some(Token::Not)); + } + b'?' => { + return (&input[1..], Some(Token::Question)); + } + b'&' => { + if let Some(input) = eat(input, "&&") { + if let Some(input) = eat(input, "=") { + return (input, Some(Token::AndEq)); + } + return (input, Some(Token::And)); + } else if let Some(input) = eat(input, "&=") { + return (input, Some(Token::BitAndEq)); + } + return (&input[1..], Some(Token::BitAnd)); + } + b'(' => return (&input[1..], Some(Token::LeftParen)), + b')' => return (&input[1..], Some(Token::RightParen)), + b'*' => { + if let Some(input) = eat(input, "**") { + if let Some(input) = eat(input, "=") { + return (input, Some(Token::ExpEq)); + } + return (input, Some(Token::Exp)); + } else if let Some(input) = eat(input, "*=") { + return (input, Some(Token::MulEq)); + } + return (&input[1..], Some(Token::Mul)); + } + b'+' => { + if let Some(input) = eat(input, "+=") { + return (input, Some(Token::AddEq)); + } + return (&input[1..], Some(Token::Add)); + } + b',' => return (&input[1..], Some(Token::Comma)), + b'-' => { + if let Some(input) = eat(input, "->") { + return (input, Some(Token::Arrow)); + } else if let Some(input) = eat(input, "-=") { + return (input, Some(Token::MinusEq)); + } + return (&input[1..], Some(Token::Minus)); + } + b'.' => { + if let Some(input) = eat(input, "...") { + return (input, Some(Token::DotDotDot)); + } else if let Some(input) = eat(input, "..") { + return (input, Some(Token::DotDot)); + } + return (&input[1..], Some(Token::Dot)); + } + b'/' => { + if eat(input, "//").is_some() { + let eol = input.iter().position(|x| *x == b'\n'); + let (input, comment) = if let Some(eol) = eol { + (&input[(eol + 1)..], &input[..eol]) + } else { + (&input[input.len()..input.len()], &input[..]) + }; + return ( + input, + Some(Token::CommentLine(String::from_utf8_lossy(comment).to_string())), + ); + } else if eat(input, "/*").is_some() { + if input.is_empty() { + return (input, None); + } + let eol = input.windows(2).skip(2).position(|x| x[0] == b'*' && x[1] == b'/'); + let (input, comment) = if let Some(eol) = eol { + (&input[(eol + 4)..], &input[..eol + 4]) + } else { + (&input[input.len()..input.len()], &input[..]) + }; + return ( + input, + Some(Token::CommentBlock(String::from_utf8_lossy(comment).to_string())), + ); + } else if let Some(input) = eat(input, "/=") { + return (input, Some(Token::DivEq)); + } + return (&input[1..], Some(Token::Div)); + } + b':' => { + if let Some(input) = eat(input, "::") { + return (input, Some(Token::DoubleColon)); + } else { + return (&input[1..], Some(Token::Colon)); + } + } + b';' => return (&input[1..], Some(Token::Semicolon)), + b'<' => { + if let Some(input) = eat(input, "<=") { + return (input, Some(Token::LtEq)); + } else if let Some(input) = eat(input, "<<") { + if let Some(input) = eat(input, "=") { + return (input, Some(Token::ShlEq)); + } + return (input, Some(Token::Shl)); + } + return (&input[1..], Some(Token::Lt)); + } + b'>' => { + if let Some(input) = eat(input, ">=") { + return (input, Some(Token::GtEq)); + } else if let Some(input) = eat(input, ">>") { + if let Some(input) = eat(input, "=") { + return (input, Some(Token::ShrEq)); + } else if let Some(input) = eat(input, ">") { + if let Some(input) = eat(input, "=") { + return (input, Some(Token::ShrSignedEq)); + } + return (input, Some(Token::ShrSigned)); + } + return (input, Some(Token::Shr)); + } + return (&input[1..], Some(Token::Gt)); + } + b'=' => { + if let Some(input) = eat(input, "==") { + return (input, Some(Token::Eq)); + } + return (&input[1..], Some(Token::Assign)); + } + b'@' => return (&input[1..], Some(Token::At)), + b'[' => return (&input[1..], Some(Token::LeftSquare)), + b']' => return (&input[1..], Some(Token::RightSquare)), + b'{' => return (&input[1..], Some(Token::LeftCurly)), + b'}' => return (&input[1..], Some(Token::RightCurly)), + b'|' => { + if let Some(input) = eat(input, "||") { + if let Some(input) = eat(input, "=") { + return (input, Some(Token::OrEq)); + } + return (input, Some(Token::Or)); + } else if let Some(input) = eat(input, "|=") { + return (input, Some(Token::BitOrEq)); + } + return (&input[1..], Some(Token::BitOr)); + } + b'^' => { + if let Some(input) = eat(input, "^=") { + return (input, Some(Token::BitXorEq)); + } + return (&input[1..], Some(Token::BitXor)); + } + b'~' => return (&input[1..], Some(Token::BitNot)), + b'%' => { + if let Some(input) = eat(input, "%=") { + return (input, Some(Token::ModEq)); + } + return (&input[1..], Some(Token::Mod)); + } + _ => (), + } + if let Some((ident, input)) = eat_identifier(input) { + let ident = String::from_utf8_lossy(ident).to_string(); + return ( + input, + Some(match &*ident { + x if x.starts_with("aleo1") + && x.chars().skip(5).all(|x| x.is_ascii_lowercase() || x.is_ascii_digit()) => + { + Token::AddressLit(x.to_string()) + } + "address" => Token::Address, + "as" => Token::As, + "bool" => Token::Bool, + "circuit" => Token::Circuit, + "const" => Token::Const, + "else" => Token::Else, + "false" => Token::False, + "field" => Token::Field, + "for" => Token::For, + "function" => Token::Function, + "group" => Token::Group, + "i128" => Token::I128, + "i64" => Token::I64, + "i32" => Token::I32, + "i16" => Token::I16, + "i8" => Token::I8, + "if" => Token::If, + "import" => Token::Import, + "in" => Token::In, + "input" => Token::Input, + "let" => Token::Let, + "mut" => Token::Mut, + "return" => Token::Return, + "static" => Token::Static, + "string" => Token::Str, + "true" => Token::True, + "u128" => Token::U128, + "u64" => Token::U64, + "u32" => Token::U32, + "u16" => Token::U16, + "u8" => Token::U8, + "Self" => Token::BigSelf, + "self" => Token::LittleSelf, + "console" => Token::Console, + _ => Token::Ident(ident), + }), + ); + } + + (input, None) + } +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct SpannedToken { + pub token: Token, + pub span: Span, +} + +impl fmt::Display for SpannedToken { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "'{}' @ ", self.token.to_string().trim())?; + self.span.fmt(f) + } +} + +impl fmt::Debug for SpannedToken { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ::fmt(self, f) + } +} + +/// +/// Returns true if the given string looks like Aleo address. +/// This method DOES NOT check if the address is valid on-chain. +/// +pub(crate) fn check_address(address: &str) -> bool { + // "aleo1" (LOWERCASE_LETTER | ASCII_DIGIT){58} + if !address.starts_with("aleo1") || address.len() != 63 { + return false; + } + address + .chars() + .skip(5) + .all(|x| x.is_ascii_lowercase() || x.is_ascii_digit()) +} diff --git a/parser/src/tokenizer/mod.rs b/parser/src/tokenizer/mod.rs new file mode 100644 index 0000000000..7cfe52175f --- /dev/null +++ b/parser/src/tokenizer/mod.rs @@ -0,0 +1,258 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +//! The tokenizer to convert Leo code text into tokens. +//! +//! This module contains the [`tokenize()`] method which breaks down string text into tokens, +//! separated by whitespace. + +pub(crate) mod token; +pub(crate) use self::token::*; + +pub(crate) mod lexer; +pub(crate) use self::lexer::*; + +use crate::TokenError; +use leo_ast::Span; + +use std::rc::Rc; + +/// Creates a new vector of spanned tokens from a given file path and source code text. +pub(crate) fn tokenize(path: &str, source: &str) -> Result, TokenError> { + let path = Rc::new(path.to_string()); + let mut input = source.as_bytes(); + let mut tokens = vec![]; + let mut index = 0usize; + let mut line_no = 1usize; + let mut line_start = 0usize; + while !input.is_empty() { + match Token::gobble(input) { + (output, Some(token)) => { + let mut span = Span { + line_start: line_no, + line_stop: line_no, + col_start: index - line_start + 1, + col_stop: index - line_start + (input.len() - output.len()) + 1, + path: path.clone(), + }; + match &token { + Token::CommentLine(_) => { + line_no += 1; + line_start = index + (input.len() - output.len()); + } + Token::CommentBlock(block) => { + let line_ct = block.chars().filter(|x| *x == '\n').count(); + line_no += line_ct; + if line_ct > 0 { + let last_line_index = block.rfind('\n').unwrap(); + line_start = index + last_line_index + 1; + span.col_stop = index + (input.len() - output.len()) - line_start + 1; + } + span.line_stop = line_no; + } + Token::AddressLit(address) => { + if !check_address(address) { + return Err(TokenError::invalid_address_lit(address, &span)); + } + } + _ => (), + } + tokens.push(SpannedToken { token, span }); + index += input.len() - output.len(); + input = output; + } + (output, None) => { + if output.is_empty() { + break; + } else if output.len() == input.len() { + return Err(TokenError::unexpected_token( + &String::from_utf8_lossy(&[input[0]]), + &Span { + line_start: line_no, + line_stop: line_no, + col_start: index - line_start + 1, + col_stop: index - line_start + 2, + path, + }, + )); + } + index += input.len() - output.len(); + if input[0] == b'\n' { + line_no += 1; + line_start = index; + } + input = output; + } + } + } + Ok(tokens) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_tokenizer() { + let tokens = tokenize( + "test_path", + r#" + "test" + "test{}test" + "test{}" + "{}test" + "test{" + "test}" + "test{test" + "test}test" + "te{{}}" + aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8 + test_ident + 12345 + address + as + bool + circuit + const + else + false + field + for + function + group + i128 + i64 + i32 + i16 + i8 + if + import + in + input + let + mut + return + static + string + test + true + u128 + u64 + u32 + u16 + u8 + self + Self + console + ! + != + && + ( + ) + * + ** + **= + *= + + + += + , + - + -= + -> + . + .. + ... + / + /= + : + :: + ; + < + <= + = + == + > + >= + @ + [ + ] + {{ + }} + || + & + &= + | + |= + ^ + ^= + ~ + << + <<= + >> + >>= + >>> + >>>= + % + %= + ||= + &&= + ? + // test + /* test */ + //"#, + ) + .unwrap(); + let mut output = String::new(); + for SpannedToken { token, .. } in tokens.iter() { + output += &format!("{} ", &token.to_string()); + } + assert_eq!( + output, + r#""test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8 test_ident 12345 address as bool circuit const else false field for function group i128 i64 i32 i16 i8 if import in input let mut return static string test true u128 u64 u32 u16 u8 self Self console ! != && ( ) * ** **= *= + += , - -= -> . .. ... / /= : :: ; < <= = == > >= @ [ ] { { } } || & &= | |= ^ ^= ~ << <<= >> >>= >>> >>>= % %= ||= &&= ? // test + /* test */ // + "# + ); + } + + #[test] + fn test_spans() { + let raw = r#" + test + // test + test + /* test */ + test + /* test + test */ + test + "#; + let tokens = tokenize("test_path", raw).unwrap(); + let mut line_indicies = vec![0]; + for (i, c) in raw.chars().enumerate() { + if c == '\n' { + line_indicies.push(i + 1); + } + } + for token in tokens.iter() { + let token_raw = token.token.to_string(); + let start = line_indicies.get(token.span.line_start - 1).unwrap(); + let stop = line_indicies.get(token.span.line_stop - 1).unwrap(); + let original = &raw[*start + token.span.col_start - 1..*stop + token.span.col_stop - 1]; + assert_eq!(original, &token_raw); + } + println!("{}", serde_json::to_string_pretty(&tokens).unwrap()); + } +} diff --git a/parser/src/tokenizer/token.rs b/parser/src/tokenizer/token.rs new file mode 100644 index 0000000000..18604d64db --- /dev/null +++ b/parser/src/tokenizer/token.rs @@ -0,0 +1,287 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// Parts of a formatted string for logging to the console. +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum FormattedStringPart { + Const(String), + Container, +} + +impl fmt::Display for FormattedStringPart { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + FormattedStringPart::Const(c) => write!(f, "{}", c), + FormattedStringPart::Container => write!(f, "{{}}"), + } + } +} + +/// Represents all valid Leo syntax tokens. +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum Token { + FormattedString(Vec), + AddressLit(String), + Ident(String), + Int(String), + CommentLine(String), + CommentBlock(String), + Not, + NotEq, + And, + LeftParen, + RightParen, + Mul, + Exp, + ExpEq, + MulEq, + Add, + AddEq, + Comma, + Minus, + MinusEq, + Arrow, + Dot, + DotDot, + DotDotDot, + Div, + DivEq, + Colon, + DoubleColon, + Semicolon, + Lt, + LtEq, + Assign, + Eq, + Gt, + GtEq, + At, + LeftSquare, + RightSquare, + Address, + As, + Bool, + Circuit, + Const, + Else, + False, + Field, + For, + Function, + Group, + I128, + I64, + I32, + I16, + I8, + If, + Import, + In, + Input, + Let, + Mut, + Return, + Static, + Str, + True, + U128, + U64, + U32, + U16, + U8, + BigSelf, + LittleSelf, + Console, + LeftCurly, + RightCurly, + Or, + BitAnd, + BitAndEq, + BitOr, + BitOrEq, + BitXor, + BitXorEq, + BitNot, + Shl, + ShlEq, + Shr, + ShrEq, + ShrSigned, + ShrSignedEq, + Mod, + ModEq, + OrEq, + AndEq, + Question, +} + +/// Represents all valid Leo keyword tokens. +pub const KEYWORD_TOKENS: &[Token] = &[ + Token::Address, + Token::As, + Token::Bool, + Token::Circuit, + Token::Const, + Token::Else, + Token::False, + Token::Field, + Token::For, + Token::Function, + Token::Group, + Token::I128, + Token::I64, + Token::I32, + Token::I16, + Token::I8, + Token::If, + Token::Import, + Token::In, + Token::Input, + Token::Let, + Token::Mut, + Token::Return, + Token::Static, + Token::Str, + Token::True, + Token::U128, + Token::U64, + Token::U32, + Token::U16, + Token::U8, + Token::BigSelf, + Token::LittleSelf, + Token::Console, +]; + +impl Token { + /// + /// Returns `true` if the `self` token equals a Leo keyword. + /// + pub fn is_keyword(&self) -> bool { + KEYWORD_TOKENS.iter().any(|x| x == self) + } +} + +impl fmt::Display for Token { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use Token::*; + match self { + FormattedString(parts) => { + // todo escapes + write!(f, "\"")?; + for part in parts.iter() { + part.fmt(f)?; + } + write!(f, "\"") + } + AddressLit(s) => write!(f, "{}", s), + Ident(s) => write!(f, "{}", s), + Int(s) => write!(f, "{}", s), + CommentLine(s) => writeln!(f, "{}", s), + CommentBlock(s) => write!(f, "{}", s), + Not => write!(f, "!"), + NotEq => write!(f, "!="), + And => write!(f, "&&"), + LeftParen => write!(f, "("), + RightParen => write!(f, ")"), + Mul => write!(f, "*"), + Exp => write!(f, "**"), + ExpEq => write!(f, "**="), + MulEq => write!(f, "*="), + Add => write!(f, "+"), + AddEq => write!(f, "+="), + Comma => write!(f, ","), + Minus => write!(f, "-"), + MinusEq => write!(f, "-="), + Arrow => write!(f, "->"), + Dot => write!(f, "."), + DotDot => write!(f, ".."), + DotDotDot => write!(f, "..."), + Div => write!(f, "/"), + DivEq => write!(f, "/="), + Colon => write!(f, ":"), + DoubleColon => write!(f, "::"), + Semicolon => write!(f, ";"), + Lt => write!(f, "<"), + LtEq => write!(f, "<="), + Assign => write!(f, "="), + Eq => write!(f, "=="), + Gt => write!(f, ">"), + GtEq => write!(f, ">="), + At => write!(f, "@"), + LeftSquare => write!(f, "["), + RightSquare => write!(f, "]"), + Address => write!(f, "address"), + As => write!(f, "as"), + Bool => write!(f, "bool"), + Circuit => write!(f, "circuit"), + Const => write!(f, "const"), + Else => write!(f, "else"), + False => write!(f, "false"), + Field => write!(f, "field"), + For => write!(f, "for"), + Function => write!(f, "function"), + Group => write!(f, "group"), + I128 => write!(f, "i128"), + I64 => write!(f, "i64"), + I32 => write!(f, "i32"), + I16 => write!(f, "i16"), + I8 => write!(f, "i8"), + If => write!(f, "if"), + Import => write!(f, "import"), + In => write!(f, "in"), + Input => write!(f, "input"), + Let => write!(f, "let"), + Mut => write!(f, "mut"), + Return => write!(f, "return"), + Static => write!(f, "static"), + Str => write!(f, "string"), + True => write!(f, "true"), + U128 => write!(f, "u128"), + U64 => write!(f, "u64"), + U32 => write!(f, "u32"), + U16 => write!(f, "u16"), + U8 => write!(f, "u8"), + BigSelf => write!(f, "Self"), + LittleSelf => write!(f, "self"), + Console => write!(f, "console"), + LeftCurly => write!(f, "{{"), + RightCurly => write!(f, "}}"), + Or => write!(f, "||"), + BitAnd => write!(f, "&"), + BitAndEq => write!(f, "&="), + BitOr => write!(f, "|"), + BitOrEq => write!(f, "|="), + BitXor => write!(f, "^"), + BitXorEq => write!(f, "^="), + BitNot => write!(f, "~"), + Shl => write!(f, "<<"), + ShlEq => write!(f, "<<="), + Shr => write!(f, ">>"), + ShrEq => write!(f, ">>="), + ShrSigned => write!(f, ">>>"), + ShrSignedEq => write!(f, ">>>="), + Mod => write!(f, "%"), + ModEq => write!(f, "%="), + OrEq => write!(f, "||="), + AndEq => write!(f, "&&="), + Question => write!(f, "?"), + } + } +} diff --git a/ast/tests/mod.rs b/parser/tests/mod.rs similarity index 100% rename from ast/tests/mod.rs rename to parser/tests/mod.rs diff --git a/ast/tests/serialization/deprecated_error.leo b/parser/tests/serialization/deprecated_error.leo similarity index 100% rename from ast/tests/serialization/deprecated_error.leo rename to parser/tests/serialization/deprecated_error.leo diff --git a/parser/tests/serialization/expected_leo_ast.json b/parser/tests/serialization/expected_leo_ast.json new file mode 100644 index 0000000000..cedf6db8a0 --- /dev/null +++ b/parser/tests/serialization/expected_leo_ast.json @@ -0,0 +1,83 @@ +{ + "name": "", + "expected_input": [], + "imports": [], + "circuits": {}, + "functions": { + "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"test\\\"}\"}": { + "annotations": [], + "identifier": "{\"name\":\"main\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":10,\\\"col_stop\\\":14,\\\"path\\\":\\\"test\\\"}\"}", + "input": [], + "output": null, + "block": { + "statements": [ + { + "Return": { + "expression": { + "Binary": { + "left": { + "Value": { + "Implicit": [ + "1", + { + "line_start": 2, + "line_stop": 2, + "col_start": 12, + "col_stop": 13, + "path": "test" + } + ] + } + }, + "right": { + "Value": { + "Implicit": [ + "1", + { + "line_start": 2, + "line_stop": 2, + "col_start": 16, + "col_stop": 17, + "path": "test" + } + ] + } + }, + "op": "Add", + "span": { + "line_start": 2, + "line_stop": 2, + "col_start": 12, + "col_stop": 17, + "path": "test" + } + } + }, + "span": { + "line_start": 2, + "line_stop": 2, + "col_start": 5, + "col_stop": 17, + "path": "test" + } + } + } + ], + "span": { + "line_start": 1, + "line_stop": 3, + "col_start": 17, + "col_stop": 2, + "path": "test" + } + }, + "span": { + "line_start": 1, + "line_stop": 3, + "col_start": 1, + "col_stop": 2, + "path": "test" + } + } + } +} \ No newline at end of file diff --git a/ast/tests/serialization/json.rs b/parser/tests/serialization/json.rs similarity index 76% rename from ast/tests/serialization/json.rs rename to parser/tests/serialization/json.rs index 5a58ff12c5..9e62f65072 100644 --- a/ast/tests/serialization/json.rs +++ b/parser/tests/serialization/json.rs @@ -14,22 +14,18 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +use leo_ast::Ast; #[cfg(not(feature = "ci_skip"))] use leo_ast::Program; -use leo_ast::{Ast, AstError}; -use leo_grammar::{Grammar, ParserError}; +use leo_parser::SyntaxError; use std::path::{Path, PathBuf}; -fn to_ast(program_filepath: &Path) -> Result { - // Loads the Leo code as a string from the given file path. - let program_string = Grammar::load_file(program_filepath)?; +fn to_ast(program_filepath: &Path) -> Result { + let program_string = std::fs::read_to_string(program_filepath).expect("failed to open test"); - // Parses the Leo file and constructs a grammar ast. - let ast = Grammar::new(&program_filepath, &program_string)?; - - // Parses the pest ast and constructs a Leo ast. - Ast::new("leo_tree", &ast) + // Parses the Leo file and constructs a leo ast. + leo_parser::parse_ast("test", &program_string) } #[test] @@ -92,19 +88,6 @@ fn test_serialize_deserialize_serialize() { assert_eq!(serialized_ast, reserialized_ast); } -#[test] -fn test_file_read_error() { - let error_result = { - let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - program_filepath.push("tests/serialization/dne.leo"); - - to_ast(&program_filepath) - } - .map_err(|err| matches!(err, AstError::ParserError(x) if matches!(x, ParserError::FileReadError(_)))); - - assert!(error_result.err().unwrap()); -} - #[test] fn test_generic_parser_error() { let error_result = { @@ -113,7 +96,7 @@ fn test_generic_parser_error() { to_ast(&program_filepath) } - .map_err(|err| matches!(err, AstError::ParserError(_))); + .map_err(|err| matches!(err, SyntaxError::Error(_))); assert!(error_result.err().unwrap()); } diff --git a/ast/tests/serialization/main.leo b/parser/tests/serialization/main.leo similarity index 100% rename from ast/tests/serialization/main.leo rename to parser/tests/serialization/main.leo diff --git a/ast/tests/serialization/mod.rs b/parser/tests/serialization/mod.rs similarity index 100% rename from ast/tests/serialization/mod.rs rename to parser/tests/serialization/mod.rs diff --git a/ast/tests/serialization/parser_error.leo b/parser/tests/serialization/parser_error.leo similarity index 100% rename from ast/tests/serialization/parser_error.leo rename to parser/tests/serialization/parser_error.leo diff --git a/tests/fail/parse/address/empty.leo b/tests/fail/parse/address/empty.leo new file mode 100644 index 0000000000..e5c06d0def --- /dev/null +++ b/tests/fail/parse/address/empty.leo @@ -0,0 +1,3 @@ +function main() { + let owner = address(); +} \ No newline at end of file diff --git a/tests/fail/parse/address/invalid_length.leo b/tests/fail/parse/address/invalid_length.leo new file mode 100644 index 0000000000..c1b7f719be --- /dev/null +++ b/tests/fail/parse/address/invalid_length.leo @@ -0,0 +1,3 @@ +function main() { + let public_key_string = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j88); +} \ No newline at end of file diff --git a/tests/fail/parse/address/invalid_prefix.leo b/tests/fail/parse/address/invalid_prefix.leo new file mode 100644 index 0000000000..81959d2fa6 --- /dev/null +++ b/tests/fail/parse/address/invalid_prefix.leo @@ -0,0 +1,3 @@ +function main() { + let public_key_string = address(zleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8); +} \ No newline at end of file diff --git a/tests/fail/parse/array/initializer_fail.leo b/tests/fail/parse/array/initializer_fail.leo new file mode 100644 index 0000000000..3b2e7785cc --- /dev/null +++ b/tests/fail/parse/array/initializer_fail.leo @@ -0,0 +1,3 @@ +function main(a: [u8; 3]) { + console.assert(a == [1u8; -3]); +} \ No newline at end of file diff --git a/tests/fail/parse/array/type_fail.leo b/tests/fail/parse/array/type_fail.leo new file mode 100644 index 0000000000..1402ceba4c --- /dev/null +++ b/tests/fail/parse/array/type_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: [u8; -2] = [0u32; 2]; +} \ No newline at end of file diff --git a/tests/fail/parse/circuits/self_circuit.leo b/tests/fail/parse/circuits/self_circuit.leo new file mode 100644 index 0000000000..5a1d6c63be --- /dev/null +++ b/tests/fail/parse/circuits/self_circuit.leo @@ -0,0 +1,9 @@ +circuit Foo { + static function new() -> Self { + return Self { } + } +} + +function main() { + let a = Foo::new(); +} \ No newline at end of file diff --git a/tests/fail/parse/console/log_fail.leo b/tests/fail/parse/console/log_fail.leo new file mode 100644 index 0000000000..dafa6bea8e --- /dev/null +++ b/tests/fail/parse/console/log_fail.leo @@ -0,0 +1,3 @@ +function main() { + console.log( hello ); +} \ No newline at end of file diff --git a/tests/fail/parse/import/names_a_dash.leo b/tests/fail/parse/import/names_a_dash.leo new file mode 100644 index 0000000000..ec136176b2 --- /dev/null +++ b/tests/fail/parse/import/names_a_dash.leo @@ -0,0 +1,3 @@ +import a-.foo; + +function main() {} \ No newline at end of file diff --git a/tests/fail/parse/import/names_dash_a.leo b/tests/fail/parse/import/names_dash_a.leo new file mode 100644 index 0000000000..95ccb7e4a5 --- /dev/null +++ b/tests/fail/parse/import/names_dash_a.leo @@ -0,0 +1,3 @@ +import -a.foo; + +function main() {} \ No newline at end of file diff --git a/tests/fail/parse/import/names_dollar.leo b/tests/fail/parse/import/names_dollar.leo new file mode 100644 index 0000000000..e4eaec3719 --- /dev/null +++ b/tests/fail/parse/import/names_dollar.leo @@ -0,0 +1,3 @@ +import money$.foo; + +function main() {} \ No newline at end of file diff --git a/tests/fail/parse/syntax/address_fail.leo b/tests/fail/parse/syntax/address_fail.leo new file mode 100644 index 0000000000..4eb12c7743 --- /dev/null +++ b/tests/fail/parse/syntax/address_fail.leo @@ -0,0 +1,3 @@ +function main() { + let address = 0u32; +} \ No newline at end of file diff --git a/tests/fail/parse/syntax/console_fail.leo b/tests/fail/parse/syntax/console_fail.leo new file mode 100644 index 0000000000..6ee932a66b --- /dev/null +++ b/tests/fail/parse/syntax/console_fail.leo @@ -0,0 +1,3 @@ +function main() { + let console = 0u32; +} \ No newline at end of file diff --git a/tests/fail/parse/syntax/field_fail.leo b/tests/fail/parse/syntax/field_fail.leo new file mode 100644 index 0000000000..a1f85dc6ea --- /dev/null +++ b/tests/fail/parse/syntax/field_fail.leo @@ -0,0 +1,3 @@ +function main() { + let field = 0u32; +} \ No newline at end of file diff --git a/tests/fail/parse/syntax/group_fail.leo b/tests/fail/parse/syntax/group_fail.leo new file mode 100644 index 0000000000..322997ea50 --- /dev/null +++ b/tests/fail/parse/syntax/group_fail.leo @@ -0,0 +1,3 @@ +function main() { + let group = 0u32; +} \ No newline at end of file diff --git a/tests/fail/parse/syntax/i8_fail.leo b/tests/fail/parse/syntax/i8_fail.leo new file mode 100644 index 0000000000..596a9056ab --- /dev/null +++ b/tests/fail/parse/syntax/i8_fail.leo @@ -0,0 +1,3 @@ +function main() { + let i8 = 0u32; +} \ No newline at end of file diff --git a/tests/fail/parse/syntax/input_fail.leo b/tests/fail/parse/syntax/input_fail.leo new file mode 100644 index 0000000000..e1b466d6d4 --- /dev/null +++ b/tests/fail/parse/syntax/input_fail.leo @@ -0,0 +1,3 @@ +function main() { + let input = 0u32; +} \ No newline at end of file diff --git a/tests/fail/parse/syntax/self_keyword_fail.leo b/tests/fail/parse/syntax/self_keyword_fail.leo new file mode 100644 index 0000000000..28b899ccd4 --- /dev/null +++ b/tests/fail/parse/syntax/self_keyword_fail.leo @@ -0,0 +1,3 @@ +function main() { + let Self = 0u32; +} \ No newline at end of file diff --git a/tests/fail/parse/syntax/self_type_fail.leo b/tests/fail/parse/syntax/self_type_fail.leo new file mode 100644 index 0000000000..28b899ccd4 --- /dev/null +++ b/tests/fail/parse/syntax/self_type_fail.leo @@ -0,0 +1,3 @@ +function main() { + let Self = 0u32; +} \ No newline at end of file diff --git a/tests/fail/parse/syntax/semicolon.leo b/tests/fail/parse/syntax/semicolon.leo new file mode 100644 index 0000000000..68cfa7cbe0 --- /dev/null +++ b/tests/fail/parse/syntax/semicolon.leo @@ -0,0 +1,3 @@ +function main() { + let a = 0 +} \ No newline at end of file diff --git a/tests/fail/parse/syntax/true_fail.leo b/tests/fail/parse/syntax/true_fail.leo new file mode 100644 index 0000000000..4eb12c7743 --- /dev/null +++ b/tests/fail/parse/syntax/true_fail.leo @@ -0,0 +1,3 @@ +function main() { + let address = 0u32; +} \ No newline at end of file diff --git a/tests/fail/parse/syntax/u8_fail.leo b/tests/fail/parse/syntax/u8_fail.leo new file mode 100644 index 0000000000..77687f5ff2 --- /dev/null +++ b/tests/fail/parse/syntax/u8_fail.leo @@ -0,0 +1,3 @@ +function main() { + let u8 = 0u32; +} \ No newline at end of file diff --git a/tests/pass/parse/address/console_assert_fail.leo b/tests/pass/parse/address/console_assert_fail.leo new file mode 100644 index 0000000000..3e7a5f106d --- /dev/null +++ b/tests/pass/parse/address/console_assert_fail.leo @@ -0,0 +1,6 @@ +function main() { + let address_1 = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8); + let address_2 = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j9); + + console.assert(address_1 == address_2); +} \ No newline at end of file diff --git a/tests/pass/parse/address/console_assert_pass.leo b/tests/pass/parse/address/console_assert_pass.leo new file mode 100644 index 0000000000..60ea4a79cd --- /dev/null +++ b/tests/pass/parse/address/console_assert_pass.leo @@ -0,0 +1,6 @@ +function main() { + let address_1 = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8); + let address_2 = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8); + + console.assert(address_1 == address_2); +} \ No newline at end of file diff --git a/tests/pass/parse/address/equal.leo b/tests/pass/parse/address/equal.leo new file mode 100644 index 0000000000..9012a8c49d --- /dev/null +++ b/tests/pass/parse/address/equal.leo @@ -0,0 +1,3 @@ +function main(a: address, b: address, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/address/implicit_invalid.leo b/tests/pass/parse/address/implicit_invalid.leo new file mode 100644 index 0000000000..6f8eba5114 --- /dev/null +++ b/tests/pass/parse/address/implicit_invalid.leo @@ -0,0 +1,3 @@ +function main() { + let public_key_string: address = zleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8; +} \ No newline at end of file diff --git a/tests/pass/parse/address/implicit_valid.leo b/tests/pass/parse/address/implicit_valid.leo new file mode 100644 index 0000000000..df6ebf497d --- /dev/null +++ b/tests/pass/parse/address/implicit_valid.leo @@ -0,0 +1,3 @@ +function main() { + let public_key_string: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8; +} \ No newline at end of file diff --git a/tests/pass/parse/address/input.leo b/tests/pass/parse/address/input.leo new file mode 100644 index 0000000000..795deac98b --- /dev/null +++ b/tests/pass/parse/address/input.leo @@ -0,0 +1,5 @@ +function main(owner: address) { + let sender = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8); + + console.assert(owner == sender); +} \ No newline at end of file diff --git a/tests/pass/parse/address/ternary.leo b/tests/pass/parse/address/ternary.leo new file mode 100644 index 0000000000..bdd88b9d92 --- /dev/null +++ b/tests/pass/parse/address/ternary.leo @@ -0,0 +1,8 @@ +function main(s: bool, c: address) { + let a = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8); + let b = address(aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r); + + let r = s? a: b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/address/valid.leo b/tests/pass/parse/address/valid.leo new file mode 100644 index 0000000000..f06aefdaa6 --- /dev/null +++ b/tests/pass/parse/address/valid.leo @@ -0,0 +1,3 @@ +function main() { + let public_key_string = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8); +} \ No newline at end of file diff --git a/tests/pass/parse/array/initializer.leo b/tests/pass/parse/array/initializer.leo new file mode 100644 index 0000000000..51ac19f68f --- /dev/null +++ b/tests/pass/parse/array/initializer.leo @@ -0,0 +1,3 @@ +function main(a: [u8; 3]) { + console.assert(a == [1u8; 3]); +} \ No newline at end of file diff --git a/tests/pass/parse/array/initializer_input.leo b/tests/pass/parse/array/initializer_input.leo new file mode 100644 index 0000000000..4b886159dc --- /dev/null +++ b/tests/pass/parse/array/initializer_input.leo @@ -0,0 +1,3 @@ +function main(a: [u8; (3, 2)]) { + console.assert(a == [0u8; (3, 2)]); +} \ No newline at end of file diff --git a/tests/pass/parse/array/inline.leo b/tests/pass/parse/array/inline.leo new file mode 100644 index 0000000000..8c5c98ae50 --- /dev/null +++ b/tests/pass/parse/array/inline.leo @@ -0,0 +1,3 @@ +function main(a: [u8; 3]) { + console.assert(a == [1u8, 1u8, 1u8]); +} \ No newline at end of file diff --git a/tests/pass/parse/array/input_nested_3x2.leo b/tests/pass/parse/array/input_nested_3x2.leo new file mode 100644 index 0000000000..b7e59a5dc0 --- /dev/null +++ b/tests/pass/parse/array/input_nested_3x2.leo @@ -0,0 +1,3 @@ +function main(a: [u8; (3, 2)]) { + console.assert(a == [[0u8; 2]; 3]); +} diff --git a/tests/pass/parse/array/input_tuple_3x2.leo b/tests/pass/parse/array/input_tuple_3x2.leo new file mode 100644 index 0000000000..4c3c001f41 --- /dev/null +++ b/tests/pass/parse/array/input_tuple_3x2.leo @@ -0,0 +1,3 @@ +function main(a: [u8; (3, 2)]) { + console.assert(a == [0u8; (3, 2)]); +} diff --git a/tests/pass/parse/array/input_tuple_3x2_fail.leo b/tests/pass/parse/array/input_tuple_3x2_fail.leo new file mode 100644 index 0000000000..4c3c001f41 --- /dev/null +++ b/tests/pass/parse/array/input_tuple_3x2_fail.leo @@ -0,0 +1,3 @@ +function main(a: [u8; (3, 2)]) { + console.assert(a == [0u8; (3, 2)]); +} diff --git a/tests/pass/parse/array/multi_fail_initializer.leo b/tests/pass/parse/array/multi_fail_initializer.leo new file mode 100644 index 0000000000..258750b327 --- /dev/null +++ b/tests/pass/parse/array/multi_fail_initializer.leo @@ -0,0 +1,3 @@ +function main() { + let arr: [u8; (2, 2)] = [[1u8; 2]; 1]; // incorrect dimensions +} \ No newline at end of file diff --git a/tests/pass/parse/array/multi_fail_inline.leo b/tests/pass/parse/array/multi_fail_inline.leo new file mode 100644 index 0000000000..50a06c09b2 --- /dev/null +++ b/tests/pass/parse/array/multi_fail_inline.leo @@ -0,0 +1,4 @@ +function main() { + let arr: [u8; (2, 2)] = [[1u8, 1u8], + [1u8]]; // incorrect dimensions +} \ No newline at end of file diff --git a/tests/pass/parse/array/multi_initializer.leo b/tests/pass/parse/array/multi_initializer.leo new file mode 100644 index 0000000000..7257999ddf --- /dev/null +++ b/tests/pass/parse/array/multi_initializer.leo @@ -0,0 +1,7 @@ +function main() { + let a: [u8; (2, 2, 2)] = [1u8; (2, 2, 2)]; + + let b: [u8; (2, 2, 2)] = [[[1u8; 2]; 2]; 2]; + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/multi_initializer_fail.leo b/tests/pass/parse/array/multi_initializer_fail.leo new file mode 100644 index 0000000000..0bd76acffa --- /dev/null +++ b/tests/pass/parse/array/multi_initializer_fail.leo @@ -0,0 +1,3 @@ +function main() { + let arr: [u8; (2, 2)] = [1u8; (2, 1)]; // incorrect dimensions +} \ No newline at end of file diff --git a/tests/pass/parse/array/nested.leo b/tests/pass/parse/array/nested.leo new file mode 100644 index 0000000000..c557758b05 --- /dev/null +++ b/tests/pass/parse/array/nested.leo @@ -0,0 +1,4 @@ +function main () { + let x = [false; (2, 2)]; + let y: bool = x[0][0]; +} diff --git a/tests/pass/parse/array/nested_3x2_value.leo b/tests/pass/parse/array/nested_3x2_value.leo new file mode 100644 index 0000000000..b69ddffb89 --- /dev/null +++ b/tests/pass/parse/array/nested_3x2_value.leo @@ -0,0 +1,8 @@ +// Multidimensional array syntax in leo +function main() { + let a = [[0u32, 0u32], [0u32, 0u32], [0u32, 0u32]]; // inline + + let b: [u32; (3, 2)] = [[0; 2]; 3]; // initializer + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/nested_3x2_value_fail.leo b/tests/pass/parse/array/nested_3x2_value_fail.leo new file mode 100644 index 0000000000..35c8478cd1 --- /dev/null +++ b/tests/pass/parse/array/nested_3x2_value_fail.leo @@ -0,0 +1,4 @@ +// Multidimensional array syntax in leo +function main() { + let a: [u32; (3, 2)] = [[0; 3]; 2]; // initializer (incorrectly reversed ordering) +} diff --git a/tests/pass/parse/array/registers.leo b/tests/pass/parse/array/registers.leo new file mode 100644 index 0000000000..fb8980868e --- /dev/null +++ b/tests/pass/parse/array/registers.leo @@ -0,0 +1,3 @@ +function main(input) -> [u8; 3] { + return input.registers.r +} \ No newline at end of file diff --git a/tests/pass/parse/array/slice.leo b/tests/pass/parse/array/slice.leo new file mode 100644 index 0000000000..296f5bd050 --- /dev/null +++ b/tests/pass/parse/array/slice.leo @@ -0,0 +1,6 @@ +// `{from}..{to}` copies the elements of one array into another exclusively +function main(a: [u8; 3]) { + let b = [1u8; 4]; + + console.assert(a == b[0..3]); +} diff --git a/tests/pass/parse/array/slice_lower.leo b/tests/pass/parse/array/slice_lower.leo new file mode 100644 index 0000000000..dd669830ea --- /dev/null +++ b/tests/pass/parse/array/slice_lower.leo @@ -0,0 +1,8 @@ +function main() { + let arr: [u32; 9] = [0, 1, 2, 3, 4, 5, 6, 7, 8]; + let expected: [u32; 2] = [0, 1]; + + let actual = arr[..2]; // Should produce [0, 1] + + console.assert(expected == actual); +} \ No newline at end of file diff --git a/tests/pass/parse/array/spread.leo b/tests/pass/parse/array/spread.leo new file mode 100644 index 0000000000..962e92c923 --- /dev/null +++ b/tests/pass/parse/array/spread.leo @@ -0,0 +1,7 @@ +// A spread operator `...` copies the elements of one array into another +function main(a: [u8; 3]) { + let b = [1u8, 1u8]; + let c = [1u8, ...b]; + + console.assert(a == c); +} \ No newline at end of file diff --git a/tests/pass/parse/array/tuple_3x2_value.leo b/tests/pass/parse/array/tuple_3x2_value.leo new file mode 100644 index 0000000000..dc9128c51e --- /dev/null +++ b/tests/pass/parse/array/tuple_3x2_value.leo @@ -0,0 +1,8 @@ +// Multidimensional array syntax in leo +function main() { + let a = [[0u32, 0u32], [0u32, 0u32], [0u32, 0u32]]; // inline + + let b: [u32; (3, 2)] = [0; (3, 2)]; // initializer + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/tuple_3x2_value_fail.leo b/tests/pass/parse/array/tuple_3x2_value_fail.leo new file mode 100644 index 0000000000..42e6f61500 --- /dev/null +++ b/tests/pass/parse/array/tuple_3x2_value_fail.leo @@ -0,0 +1,4 @@ +// Multidimensional array syntax in leo +function main() { + let a: [u32; (3, 2)] = [0; (2, 3)]; // initializer (incorrectly reversed ordering) +} diff --git a/tests/pass/parse/array/type_input_3x2.leo b/tests/pass/parse/array/type_input_3x2.leo new file mode 100644 index 0000000000..40781415c1 --- /dev/null +++ b/tests/pass/parse/array/type_input_3x2.leo @@ -0,0 +1,5 @@ +function main(a: [[u8; 2]; 3]) { + let b = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_input_4x3x2.leo b/tests/pass/parse/array/type_input_4x3x2.leo new file mode 100644 index 0000000000..bd75514904 --- /dev/null +++ b/tests/pass/parse/array/type_input_4x3x2.leo @@ -0,0 +1,8 @@ +function main(a: [[[u8; 2]; 3]; 4]) { + let b = [[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]]; // inline + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_nested_value_nested_3x2.leo b/tests/pass/parse/array/type_nested_value_nested_3x2.leo new file mode 100644 index 0000000000..341b9ead9c --- /dev/null +++ b/tests/pass/parse/array/type_nested_value_nested_3x2.leo @@ -0,0 +1,7 @@ +function main() { + let a = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline + + let b: [[u8; 2]; 3] = [[0; 2]; 3]; // initializer + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_nested_value_nested_3x2_fail.leo b/tests/pass/parse/array/type_nested_value_nested_3x2_fail.leo new file mode 100644 index 0000000000..4bd07f85db --- /dev/null +++ b/tests/pass/parse/array/type_nested_value_nested_3x2_fail.leo @@ -0,0 +1,3 @@ +function main() { + let b: [[u8; 2]; 3] = [[0; 3]; 2]; // initializer (incorrectly reversed ordering) +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_nested_value_nested_4x3x2.leo b/tests/pass/parse/array/type_nested_value_nested_4x3x2.leo new file mode 100644 index 0000000000..5ba24a381b --- /dev/null +++ b/tests/pass/parse/array/type_nested_value_nested_4x3x2.leo @@ -0,0 +1,10 @@ +function main() { + let a = [[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]]; // inline + + let b: [[[u8; 2]; 3]; 4] = [[[0; 2]; 3]; 4]; // initializer + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_nested_value_nested_4x3x2_fail.leo b/tests/pass/parse/array/type_nested_value_nested_4x3x2_fail.leo new file mode 100644 index 0000000000..6479004d68 --- /dev/null +++ b/tests/pass/parse/array/type_nested_value_nested_4x3x2_fail.leo @@ -0,0 +1,3 @@ +function main() { + let b: [[[u8; 2]; 3]; 4] = [[[0; 4]; 3]; 2]; // initializer (incorrectly reversed ordering) +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_nested_value_tuple_3x2.leo b/tests/pass/parse/array/type_nested_value_tuple_3x2.leo new file mode 100644 index 0000000000..c6fac9ec64 --- /dev/null +++ b/tests/pass/parse/array/type_nested_value_tuple_3x2.leo @@ -0,0 +1,7 @@ +function main() { + let a = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline + + let b: [[u8; 2]; 3] = [0; (3, 2)]; // initializer + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_nested_value_tuple_3x2_fail.leo b/tests/pass/parse/array/type_nested_value_tuple_3x2_fail.leo new file mode 100644 index 0000000000..ba99b070c7 --- /dev/null +++ b/tests/pass/parse/array/type_nested_value_tuple_3x2_fail.leo @@ -0,0 +1,3 @@ +function main() { + let b: [[u8; 2]; 3] = [0; (2, 3)]; // initializer (incorrectly reversed ordering) +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_nested_value_tuple_4x3x2.leo b/tests/pass/parse/array/type_nested_value_tuple_4x3x2.leo new file mode 100644 index 0000000000..9be45de408 --- /dev/null +++ b/tests/pass/parse/array/type_nested_value_tuple_4x3x2.leo @@ -0,0 +1,10 @@ +function main() { + let a = [[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]]; // inline + + let b: [[[u8; 2]; 3]; 4] = [0; (4, 3, 2)]; // initializer + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_nested_value_tuple_4x3x2_fail.leo b/tests/pass/parse/array/type_nested_value_tuple_4x3x2_fail.leo new file mode 100644 index 0000000000..95172bf329 --- /dev/null +++ b/tests/pass/parse/array/type_nested_value_tuple_4x3x2_fail.leo @@ -0,0 +1,3 @@ +function main() { + let b: [[[u8; 2]; 3]; 4] = [0; (2, 3, 4)]; // initializer (incorrectly reversed ordering) +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_tuple_value_nested_3x2.leo b/tests/pass/parse/array/type_tuple_value_nested_3x2.leo new file mode 100644 index 0000000000..4e061c4309 --- /dev/null +++ b/tests/pass/parse/array/type_tuple_value_nested_3x2.leo @@ -0,0 +1,7 @@ +function main() { + let a = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline + + let b: [u8; (3, 2)] = [[0; 2]; 3]; // initializer + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_tuple_value_nested_3x2_fail.leo b/tests/pass/parse/array/type_tuple_value_nested_3x2_fail.leo new file mode 100644 index 0000000000..9732cf26ef --- /dev/null +++ b/tests/pass/parse/array/type_tuple_value_nested_3x2_fail.leo @@ -0,0 +1,3 @@ +function main() { + let b: [u8; (2, 3)] = [[0; 2]; 3]; // initializer (incorrectly reversed ordering) +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_tuple_value_nested_4x3x2.leo b/tests/pass/parse/array/type_tuple_value_nested_4x3x2.leo new file mode 100644 index 0000000000..d9dc698784 --- /dev/null +++ b/tests/pass/parse/array/type_tuple_value_nested_4x3x2.leo @@ -0,0 +1,10 @@ +function main() { + let a = [[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]]; // inline + + let b: [u8; (4, 3, 2)] = [[[0; 2]; 3]; 4]; // initializer + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_tuple_value_nested_4x3x2_fail.leo b/tests/pass/parse/array/type_tuple_value_nested_4x3x2_fail.leo new file mode 100644 index 0000000000..b820c4d088 --- /dev/null +++ b/tests/pass/parse/array/type_tuple_value_nested_4x3x2_fail.leo @@ -0,0 +1,3 @@ +function main() { + let b: [u8; (4, 3, 2)] = [[[0; 4]; 3]; 2]; // initializer (incorrectly reversed ordering) +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_tuple_value_tuple_3x2.leo b/tests/pass/parse/array/type_tuple_value_tuple_3x2.leo new file mode 100644 index 0000000000..b0693f7667 --- /dev/null +++ b/tests/pass/parse/array/type_tuple_value_tuple_3x2.leo @@ -0,0 +1,7 @@ +function main() { + let a = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline + + let b: [u8; (3, 2)] = [0; (3, 2)]; // initializer + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_tuple_value_tuple_3x2_fail.leo b/tests/pass/parse/array/type_tuple_value_tuple_3x2_fail.leo new file mode 100644 index 0000000000..99487ccb7a --- /dev/null +++ b/tests/pass/parse/array/type_tuple_value_tuple_3x2_fail.leo @@ -0,0 +1,3 @@ +function main() { + let b: [u8; (2, 3)] = [0; (3, 2)]; // initializer (incorrectly reversed ordering) +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_tuple_value_tuple_4x3x2.leo b/tests/pass/parse/array/type_tuple_value_tuple_4x3x2.leo new file mode 100644 index 0000000000..cdc1bc961e --- /dev/null +++ b/tests/pass/parse/array/type_tuple_value_tuple_4x3x2.leo @@ -0,0 +1,10 @@ +function main() { + let a = [[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]], + [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]]; // inline + + let b: [u8; (4, 3, 2)] = [0; (4, 3, 2)]; // initializer + + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/array/type_tuple_value_tuple_4x3x2_fail.leo b/tests/pass/parse/array/type_tuple_value_tuple_4x3x2_fail.leo new file mode 100644 index 0000000000..824fd90bc6 --- /dev/null +++ b/tests/pass/parse/array/type_tuple_value_tuple_4x3x2_fail.leo @@ -0,0 +1,3 @@ +function main() { + let b: [u8; (4, 3, 2)] = [0; (2, 3, 4)]; // initializer (incorrectly reversed order) +} \ No newline at end of file diff --git a/tests/pass/parse/array/variable_slice_fail.leo b/tests/pass/parse/array/variable_slice_fail.leo new file mode 100644 index 0000000000..edb04caacf --- /dev/null +++ b/tests/pass/parse/array/variable_slice_fail.leo @@ -0,0 +1,7 @@ +function main() { + let a = [1u8; 10]; + for i in 0..10 { + let x = a[i..10]; + console.debug("{}", x); + } +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/all.leo b/tests/pass/parse/boolean/all.leo new file mode 100644 index 0000000000..29a3815881 --- /dev/null +++ b/tests/pass/parse/boolean/all.leo @@ -0,0 +1,8 @@ +// !(true && (false || true)) +function main() { + let a = true; + let b = false || a; + let c = !(true && b); + + console.assert(c == false); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/assert_eq_input.leo b/tests/pass/parse/boolean/assert_eq_input.leo new file mode 100644 index 0000000000..8a796e5bbd --- /dev/null +++ b/tests/pass/parse/boolean/assert_eq_input.leo @@ -0,0 +1,3 @@ +function main(a: bool, b: bool) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/conditional_mut.leo b/tests/pass/parse/boolean/conditional_mut.leo new file mode 100644 index 0000000000..e6716cb05a --- /dev/null +++ b/tests/pass/parse/boolean/conditional_mut.leo @@ -0,0 +1,6 @@ +function main () { + let mut x = true; + if x { + let y = 0u8; + } +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/false_and_false.leo b/tests/pass/parse/boolean/false_and_false.leo new file mode 100644 index 0000000000..70e4b0797b --- /dev/null +++ b/tests/pass/parse/boolean/false_and_false.leo @@ -0,0 +1,5 @@ +function main() { + let a = false && false; + + console.assert(a == false); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/false_or_false.leo b/tests/pass/parse/boolean/false_or_false.leo new file mode 100644 index 0000000000..4ae820254e --- /dev/null +++ b/tests/pass/parse/boolean/false_or_false.leo @@ -0,0 +1,5 @@ +function main() { + let a = false || false; + + console.assert(a == false); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/not_false.leo b/tests/pass/parse/boolean/not_false.leo new file mode 100644 index 0000000000..796b616871 --- /dev/null +++ b/tests/pass/parse/boolean/not_false.leo @@ -0,0 +1,3 @@ +function main() { + console.assert(!false == true); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/not_mutable.leo b/tests/pass/parse/boolean/not_mutable.leo new file mode 100644 index 0000000000..91a6e5ff37 --- /dev/null +++ b/tests/pass/parse/boolean/not_mutable.leo @@ -0,0 +1,4 @@ +function main () { + let mut b = false; + let a = !b; +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/not_true.leo b/tests/pass/parse/boolean/not_true.leo new file mode 100644 index 0000000000..8c87dffabb --- /dev/null +++ b/tests/pass/parse/boolean/not_true.leo @@ -0,0 +1,3 @@ +function main() { + console.assert(!true == false); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/not_u32.leo b/tests/pass/parse/boolean/not_u32.leo new file mode 100644 index 0000000000..44491d785b --- /dev/null +++ b/tests/pass/parse/boolean/not_u32.leo @@ -0,0 +1,3 @@ +function main() -> bool { + console.assert(!1u32 == 0u32); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/output_register.leo b/tests/pass/parse/boolean/output_register.leo new file mode 100644 index 0000000000..fb01d41dbe --- /dev/null +++ b/tests/pass/parse/boolean/output_register.leo @@ -0,0 +1,3 @@ +function main(input) -> bool { + return input.registers.r +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/true_and_false.leo b/tests/pass/parse/boolean/true_and_false.leo new file mode 100644 index 0000000000..3c7c484603 --- /dev/null +++ b/tests/pass/parse/boolean/true_and_false.leo @@ -0,0 +1,5 @@ +function main() { + let a = true && false; + + console.assert(a == false); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/true_and_true.leo b/tests/pass/parse/boolean/true_and_true.leo new file mode 100644 index 0000000000..c378e50024 --- /dev/null +++ b/tests/pass/parse/boolean/true_and_true.leo @@ -0,0 +1,5 @@ +function main() { + let a = true && true; + + console.assert(a == true); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/true_and_u32.leo b/tests/pass/parse/boolean/true_and_u32.leo new file mode 100644 index 0000000000..e5b3a8c001 --- /dev/null +++ b/tests/pass/parse/boolean/true_and_u32.leo @@ -0,0 +1,3 @@ +function main() { + let a = true && 1u32; +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/true_or_false.leo b/tests/pass/parse/boolean/true_or_false.leo new file mode 100644 index 0000000000..d643a96aa1 --- /dev/null +++ b/tests/pass/parse/boolean/true_or_false.leo @@ -0,0 +1,5 @@ +function main() { + let a = true || false; + + console.assert(a == true); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/true_or_true.leo b/tests/pass/parse/boolean/true_or_true.leo new file mode 100644 index 0000000000..b8eaa91ff1 --- /dev/null +++ b/tests/pass/parse/boolean/true_or_true.leo @@ -0,0 +1,5 @@ +function main() { + let a = true || true; + + console.assert(a == true); +} \ No newline at end of file diff --git a/tests/pass/parse/boolean/true_or_u32.leo b/tests/pass/parse/boolean/true_or_u32.leo new file mode 100644 index 0000000000..500b5f7bf4 --- /dev/null +++ b/tests/pass/parse/boolean/true_or_u32.leo @@ -0,0 +1,3 @@ +function main() { + let a = true || 1u32; +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/define_circuit_inside_circuit_function.leo b/tests/pass/parse/circuits/define_circuit_inside_circuit_function.leo new file mode 100644 index 0000000000..8c25c1e9d9 --- /dev/null +++ b/tests/pass/parse/circuits/define_circuit_inside_circuit_function.leo @@ -0,0 +1,13 @@ +circuit Foo { + a: u32, +} + +circuit Bar { + function bar() { + let f = Foo { a: 0u32 }; + } +} + +function main() { + let b = Bar::bar(); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/duplicate_name_context.leo b/tests/pass/parse/circuits/duplicate_name_context.leo new file mode 100644 index 0000000000..98ff42d8f0 --- /dev/null +++ b/tests/pass/parse/circuits/duplicate_name_context.leo @@ -0,0 +1,13 @@ +circuit Bar { + b2: u32 + + function add_five(z:u32) -> u32 { + return z+5u32 + } +} + +function main () { + let Bar = 66u32; + let k1 = Bar{ b2: 30u32 }; + let k2 = Bar::add_five(55u32); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/inline.leo b/tests/pass/parse/circuits/inline.leo new file mode 100644 index 0000000000..8e214c729a --- /dev/null +++ b/tests/pass/parse/circuits/inline.leo @@ -0,0 +1,7 @@ +circuit Foo { + x: u32 +} + +function main() { + let a = Foo { x: 1u32 }; +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/inline_fail.leo b/tests/pass/parse/circuits/inline_fail.leo new file mode 100644 index 0000000000..52792a07e0 --- /dev/null +++ b/tests/pass/parse/circuits/inline_fail.leo @@ -0,0 +1,7 @@ +circuit Foo { + x: u32 +} + +function main() { + let a = Foo { y: 0u32 }; +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/inline_member_fail.leo b/tests/pass/parse/circuits/inline_member_fail.leo new file mode 100644 index 0000000000..7f0b8f7889 --- /dev/null +++ b/tests/pass/parse/circuits/inline_member_fail.leo @@ -0,0 +1,8 @@ +circuit Foo { + x: u8 +} + +function main() { + let y: u8 = 1; + let a = Foo { y }; +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/inline_member_pass.leo b/tests/pass/parse/circuits/inline_member_pass.leo new file mode 100644 index 0000000000..5541a65638 --- /dev/null +++ b/tests/pass/parse/circuits/inline_member_pass.leo @@ -0,0 +1,13 @@ +circuit Foo { + x: u8 + + function new(x: u8) -> Self { + return Self { x } + } +} + +function main() { + let x: u8 = 1; + let a = Foo { x }; + let b = Foo::new(x); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/inline_undefined.leo b/tests/pass/parse/circuits/inline_undefined.leo new file mode 100644 index 0000000000..af070e01e9 --- /dev/null +++ b/tests/pass/parse/circuits/inline_undefined.leo @@ -0,0 +1,3 @@ +function main() { + let a = Foo { }; +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/member_function.leo b/tests/pass/parse/circuits/member_function.leo new file mode 100644 index 0000000000..e40603dffb --- /dev/null +++ b/tests/pass/parse/circuits/member_function.leo @@ -0,0 +1,13 @@ +circuit Foo { + x: u32, + + function echo(self) -> u32 { + return self.x + } +} + +function main() { + let a = Foo { x: 1u32 }; + + console.assert(a.echo() == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/member_function_fail.leo b/tests/pass/parse/circuits/member_function_fail.leo new file mode 100644 index 0000000000..224b79cbf4 --- /dev/null +++ b/tests/pass/parse/circuits/member_function_fail.leo @@ -0,0 +1,10 @@ +circuit Foo { + function echo(x: u32) -> u32 { + return x + } +} + +function main() { + let a = Foo { }; + let err = a.echoed(1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/member_function_invalid.leo b/tests/pass/parse/circuits/member_function_invalid.leo new file mode 100644 index 0000000000..bb834e9562 --- /dev/null +++ b/tests/pass/parse/circuits/member_function_invalid.leo @@ -0,0 +1,10 @@ +circuit Foo { + function echo(x: u32) -> u32 { + return x + } +} + +function main() { + let a = Foo { }; + let err = a.echo(1u32); // echo is a static function and must be accessed using `::` +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/member_function_nested.leo b/tests/pass/parse/circuits/member_function_nested.leo new file mode 100644 index 0000000000..9e07cc9acf --- /dev/null +++ b/tests/pass/parse/circuits/member_function_nested.leo @@ -0,0 +1,18 @@ +circuit Foo { + x: u32, + + function add_x(self, y: u32) -> u32 { + return self.x + y + } + + function call_add_x(self, y: u32) -> u32 { + return self.add_x(y) + } +} + +function main() { + let a = Foo { x: 1u32 }; + let b = a.add_x(1u32); + + console.assert(b == 2u32); +} diff --git a/tests/pass/parse/circuits/member_static_function.leo b/tests/pass/parse/circuits/member_static_function.leo new file mode 100644 index 0000000000..4bf51190f0 --- /dev/null +++ b/tests/pass/parse/circuits/member_static_function.leo @@ -0,0 +1,11 @@ +circuit Foo { + function echo(x: u32) -> u32 { + return x + } +} + +function main() { + let a = Foo::echo(1u32); + + console.assert(a == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/member_static_function_invalid.leo b/tests/pass/parse/circuits/member_static_function_invalid.leo new file mode 100644 index 0000000000..09fec386d9 --- /dev/null +++ b/tests/pass/parse/circuits/member_static_function_invalid.leo @@ -0,0 +1,9 @@ +circuit Foo { + function echo(x: u32) -> u32 { + return x + } +} + +function main() { + let err = Foo.echo(1u32); // Invalid, echo is a static function and must be accessed using `::` +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/member_static_function_nested.leo b/tests/pass/parse/circuits/member_static_function_nested.leo new file mode 100644 index 0000000000..ef536e3f6e --- /dev/null +++ b/tests/pass/parse/circuits/member_static_function_nested.leo @@ -0,0 +1,15 @@ +circuit Foo { + function qux() {} + + function bar() { + Self::qux(); + } + + function baz() { + Self::bar(); + } +} + +function main() { + Foo::baz(); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/member_static_function_undefined.leo b/tests/pass/parse/circuits/member_static_function_undefined.leo new file mode 100644 index 0000000000..cf9f98c7b4 --- /dev/null +++ b/tests/pass/parse/circuits/member_static_function_undefined.leo @@ -0,0 +1,9 @@ +circuit Foo { + function echo(x: u32) -> u32 { + return x + } +} + +function main() { + let err = Foo::echoed(1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/member_variable.leo b/tests/pass/parse/circuits/member_variable.leo new file mode 100644 index 0000000000..0dd35f2aec --- /dev/null +++ b/tests/pass/parse/circuits/member_variable.leo @@ -0,0 +1,9 @@ +circuit Foo { + x: u32, +} + +function main() { + let a = Foo { x: 1u32 }; + + console.assert(a.x == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/member_variable_and_function.leo b/tests/pass/parse/circuits/member_variable_and_function.leo new file mode 100644 index 0000000000..074feab7b8 --- /dev/null +++ b/tests/pass/parse/circuits/member_variable_and_function.leo @@ -0,0 +1,15 @@ +circuit Foo { + foo: u32, + + function bar() -> u32 { + return 1u32 + } +} + +function main() { + let a = Foo { foo: 1 }; + + let b = a.foo + Foo::bar(); + + console.assert(b == 2u32); +} diff --git a/tests/pass/parse/circuits/member_variable_fail.leo b/tests/pass/parse/circuits/member_variable_fail.leo new file mode 100644 index 0000000000..5780704ea2 --- /dev/null +++ b/tests/pass/parse/circuits/member_variable_fail.leo @@ -0,0 +1,9 @@ +circuit Foo { + x: u32 +} + +function main() { + let a = Foo { x: 1u32 }; + + let err = a.y; +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/mut_function_fail.leo b/tests/pass/parse/circuits/mut_function_fail.leo new file mode 100644 index 0000000000..3469f97627 --- /dev/null +++ b/tests/pass/parse/circuits/mut_function_fail.leo @@ -0,0 +1,11 @@ +circuit Foo { + a: u8, + + function bar() {} +} + +function main() { + let mut f = Foo { a: 0u8 }; + + f.bar = 1u8; +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/mut_self_function_fail.leo b/tests/pass/parse/circuits/mut_self_function_fail.leo new file mode 100644 index 0000000000..8c9b99f6ae --- /dev/null +++ b/tests/pass/parse/circuits/mut_self_function_fail.leo @@ -0,0 +1,15 @@ +circuit Foo { + a: u8, + + function bar() {} + + function set_a(mut self, new: u8) { + self.bar = new; + } +} + +function main() { + let mut f = Foo { a: 0u8 }; + + f.set_a(1u8); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/mut_self_static_function_fail.leo b/tests/pass/parse/circuits/mut_self_static_function_fail.leo new file mode 100644 index 0000000000..8c9b99f6ae --- /dev/null +++ b/tests/pass/parse/circuits/mut_self_static_function_fail.leo @@ -0,0 +1,15 @@ +circuit Foo { + a: u8, + + function bar() {} + + function set_a(mut self, new: u8) { + self.bar = new; + } +} + +function main() { + let mut f = Foo { a: 0u8 }; + + f.set_a(1u8); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/mut_self_variable.leo b/tests/pass/parse/circuits/mut_self_variable.leo new file mode 100644 index 0000000000..f5a35ec754 --- /dev/null +++ b/tests/pass/parse/circuits/mut_self_variable.leo @@ -0,0 +1,22 @@ +circuit Foo { + a: u8, + + function set_a(mut self, new: u8) { + self.a = new; + console.assert(self.a == new); + } +} + +function main() { + let mut f = Foo { a: 0u8 }; + + console.assert(f.a == 0u8); + + f.set_a(1u8); + + console.assert(f.a == 1u8); + + f.set_a(2u8); + + console.assert(f.a == 2u8); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/mut_self_variable_branch.leo b/tests/pass/parse/circuits/mut_self_variable_branch.leo new file mode 100644 index 0000000000..e47f9b85df --- /dev/null +++ b/tests/pass/parse/circuits/mut_self_variable_branch.leo @@ -0,0 +1,32 @@ +circuit Foo { + a: u8, + + function set_a(mut self, condition: bool, new: u8) { + if condition { + self.a = new; + console.assert(self.a == new); + } + } +} + +function main() { + let mut f = Foo { a: 0u8 }; + + console.assert(f.a == 0u8); + + f.set_a(false, 1u8); + + console.assert(f.a == 0u8); + + f.set_a(true, 1u8); + + console.assert(f.a == 1u8); + + f.set_a(false, 2u8); + + console.assert(f.a == 1u8); + + f.set_a(true, 2u8); + + console.assert(f.a == 2u8); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/mut_self_variable_conditional.leo b/tests/pass/parse/circuits/mut_self_variable_conditional.leo new file mode 100644 index 0000000000..74345afcb4 --- /dev/null +++ b/tests/pass/parse/circuits/mut_self_variable_conditional.leo @@ -0,0 +1,15 @@ +function main() { + let mut f = Foo { a: 0u32 }; + + f.bar(); +} + +circuit Foo { + a: u32 + + function bar(mut self) { + if true { + self.a = 5u32; // Mutating a variable inside a conditional statement should work. + } + } +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/mut_self_variable_fail.leo b/tests/pass/parse/circuits/mut_self_variable_fail.leo new file mode 100644 index 0000000000..fdbb556bca --- /dev/null +++ b/tests/pass/parse/circuits/mut_self_variable_fail.leo @@ -0,0 +1,13 @@ +circuit Foo { + a: u8, + + function set_a(self, new: u8) { + self.a = new; + } +} + +function main() { + let mut f = Foo { a: 0u8 }; + + f.set_a(1u8); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/mut_static_function_fail.leo b/tests/pass/parse/circuits/mut_static_function_fail.leo new file mode 100644 index 0000000000..ed3092c656 --- /dev/null +++ b/tests/pass/parse/circuits/mut_static_function_fail.leo @@ -0,0 +1,9 @@ +circuit Foo { + function bar() {} +} + +function main() { + let mut f = Foo { a: 0u8 }; + + f.bar = 1u8; +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/mut_variable.leo b/tests/pass/parse/circuits/mut_variable.leo new file mode 100644 index 0000000000..243d7a2cf2 --- /dev/null +++ b/tests/pass/parse/circuits/mut_variable.leo @@ -0,0 +1,17 @@ +circuit Foo { + a: u8, +} + +function main() { + let mut f = Foo { a: 0u8 }; + + console.assert(f.a == 0u8); + + f.a = 1u8; + + console.assert(f.a == 1u8); + + f.a = 2u8; + + console.assert(f.a == 2u8); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/mut_variable_fail.leo b/tests/pass/parse/circuits/mut_variable_fail.leo new file mode 100644 index 0000000000..4d58150c95 --- /dev/null +++ b/tests/pass/parse/circuits/mut_variable_fail.leo @@ -0,0 +1,9 @@ +circuit Foo { + a: u8, +} + +function main() { + let f = Foo { a: 0u8 }; + + f.a = 1u8; +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/pedersen_mock.leo b/tests/pass/parse/circuits/pedersen_mock.leo new file mode 100644 index 0000000000..559ebb7614 --- /dev/null +++ b/tests/pass/parse/circuits/pedersen_mock.leo @@ -0,0 +1,27 @@ +circuit PedersenHash { + parameters: [u32; 512] + + function new(parameters: [u32; 512]) -> Self { + return Self { parameters: parameters } + } + + function hash(self, bits: [bool; 512]) -> u32 { + let mut digest: u32 = 0; + for i in 0..512 { + let base = bits[i] ? self.parameters[i] : 0u32; + digest += base; + } + return digest + } +} + +// The 'pedersen_hash' main function. +function main() { + let parameters = [0u32; 512]; + let pedersen = PedersenHash::new(parameters); + let hash_input: [bool; 512] = [true; 512]; + + let res = pedersen.hash(hash_input); + + console.assert(res == 0u32); +} diff --git a/tests/pass/parse/circuits/self_fail.leo b/tests/pass/parse/circuits/self_fail.leo new file mode 100644 index 0000000000..e4e878dc89 --- /dev/null +++ b/tests/pass/parse/circuits/self_fail.leo @@ -0,0 +1,3 @@ +function main() { + Self::main(); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/self_member.leo b/tests/pass/parse/circuits/self_member.leo new file mode 100644 index 0000000000..1bd978433d --- /dev/null +++ b/tests/pass/parse/circuits/self_member.leo @@ -0,0 +1,14 @@ +circuit Foo { + f: u32, + + function bar(self) -> u32 { + return self.f + } +} + +function main() { + let a = Foo { f: 1u32 }; + let b = a.bar(); + + console.assert(b == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/self_member_invalid.leo b/tests/pass/parse/circuits/self_member_invalid.leo new file mode 100644 index 0000000000..2e8b14f66c --- /dev/null +++ b/tests/pass/parse/circuits/self_member_invalid.leo @@ -0,0 +1,12 @@ +circuit Foo { + f: u32, + + function bar() -> u32 { + return f + } +} + +function main() -> u32 { + let foo = Foo { f: 1u32 }; + let err = foo.bar(); +} \ No newline at end of file diff --git a/tests/pass/parse/circuits/self_member_undefined.leo b/tests/pass/parse/circuits/self_member_undefined.leo new file mode 100644 index 0000000000..471ffb973c --- /dev/null +++ b/tests/pass/parse/circuits/self_member_undefined.leo @@ -0,0 +1,10 @@ +circuit Foo { + function bar() -> u32 { + return self.f + } +} + +function main() { + let foo = Foo { }; + let err = foo.bar(); +} \ No newline at end of file diff --git a/tests/pass/parse/compiler/main.leo b/tests/pass/parse/compiler/main.leo new file mode 100644 index 0000000000..f5ddfb4e7f --- /dev/null +++ b/tests/pass/parse/compiler/main.leo @@ -0,0 +1,3 @@ +function main() { + let a: u32 = 1 + 2; +} \ No newline at end of file diff --git a/tests/pass/parse/console/assert.leo b/tests/pass/parse/console/assert.leo new file mode 100644 index 0000000000..ba6be77256 --- /dev/null +++ b/tests/pass/parse/console/assert.leo @@ -0,0 +1,3 @@ +function main(a: bool) { + console.assert(a == true); +} \ No newline at end of file diff --git a/tests/pass/parse/console/conditional_assert.leo b/tests/pass/parse/console/conditional_assert.leo new file mode 100644 index 0000000000..f2c1591e9c --- /dev/null +++ b/tests/pass/parse/console/conditional_assert.leo @@ -0,0 +1,7 @@ +function main(a: bool) { + if a { + console.assert(a == true); + } else { + console.assert(a == false); + } +} \ No newline at end of file diff --git a/tests/pass/parse/console/debug.leo b/tests/pass/parse/console/debug.leo new file mode 100644 index 0000000000..54e6eb539f --- /dev/null +++ b/tests/pass/parse/console/debug.leo @@ -0,0 +1,3 @@ +function main() { + console.debug("hello debug"); +} \ No newline at end of file diff --git a/tests/pass/parse/console/error.leo b/tests/pass/parse/console/error.leo new file mode 100644 index 0000000000..86d13f8cee --- /dev/null +++ b/tests/pass/parse/console/error.leo @@ -0,0 +1,3 @@ +function main() { + console.error("hello error"); +} \ No newline at end of file diff --git a/tests/pass/parse/console/log.leo b/tests/pass/parse/console/log.leo new file mode 100644 index 0000000000..a190ca4ba9 --- /dev/null +++ b/tests/pass/parse/console/log.leo @@ -0,0 +1,3 @@ +function main() { + console.log("hello world"); +} \ No newline at end of file diff --git a/tests/pass/parse/console/log_conditional.leo b/tests/pass/parse/console/log_conditional.leo new file mode 100644 index 0000000000..a9fdb6e698 --- /dev/null +++ b/tests/pass/parse/console/log_conditional.leo @@ -0,0 +1,6 @@ +// Conditionally add two u32 integers and log the result to the console. +function main(a: u32, b: u32) { + if a == b { + console.log("{}=={}",a,b); // This line should not fail. + } +} \ No newline at end of file diff --git a/tests/pass/parse/console/log_input.leo b/tests/pass/parse/console/log_input.leo new file mode 100644 index 0000000000..c4fd0a8b12 --- /dev/null +++ b/tests/pass/parse/console/log_input.leo @@ -0,0 +1,3 @@ +function main(a: bool) { + console.log("a = {}", a); +} \ No newline at end of file diff --git a/tests/pass/parse/console/log_parameter.leo b/tests/pass/parse/console/log_parameter.leo new file mode 100644 index 0000000000..ebcb931a2b --- /dev/null +++ b/tests/pass/parse/console/log_parameter.leo @@ -0,0 +1,3 @@ +function main() { + console.log("{}", 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/console/log_parameter_fail_empty.leo b/tests/pass/parse/console/log_parameter_fail_empty.leo new file mode 100644 index 0000000000..81b42c0919 --- /dev/null +++ b/tests/pass/parse/console/log_parameter_fail_empty.leo @@ -0,0 +1,3 @@ +function main() { + console.log("{}"); +} \ No newline at end of file diff --git a/tests/pass/parse/console/log_parameter_fail_none.leo b/tests/pass/parse/console/log_parameter_fail_none.leo new file mode 100644 index 0000000000..c92fdfbb2d --- /dev/null +++ b/tests/pass/parse/console/log_parameter_fail_none.leo @@ -0,0 +1,3 @@ +function main() { + console.log("", 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/console/log_parameter_fail_unknown.leo b/tests/pass/parse/console/log_parameter_fail_unknown.leo new file mode 100644 index 0000000000..757f4c27c3 --- /dev/null +++ b/tests/pass/parse/console/log_parameter_fail_unknown.leo @@ -0,0 +1,3 @@ +function main() { + console.log("{}", a); +} \ No newline at end of file diff --git a/tests/pass/parse/console/log_parameter_many.leo b/tests/pass/parse/console/log_parameter_many.leo new file mode 100644 index 0000000000..60455ebbb0 --- /dev/null +++ b/tests/pass/parse/console/log_parameter_many.leo @@ -0,0 +1,3 @@ +function main() { + console.log("{} {}", 1u32, true); +} \ No newline at end of file diff --git a/tests/pass/parse/core/arguments_length_fail.leo b/tests/pass/parse/core/arguments_length_fail.leo new file mode 100644 index 0000000000..ccdd4c5af9 --- /dev/null +++ b/tests/pass/parse/core/arguments_length_fail.leo @@ -0,0 +1,9 @@ +import core.unstable.blake2s.Blake2s; + +function main() { + let seed: [u8; 32] = [0; 32]; + + let result = Blake2s::hash(seed); // function `hash` takes 2 arguments + + console.log("Result: {}", result); +} diff --git a/tests/pass/parse/core/arguments_type_fail.leo b/tests/pass/parse/core/arguments_type_fail.leo new file mode 100644 index 0000000000..13c7e9735e --- /dev/null +++ b/tests/pass/parse/core/arguments_type_fail.leo @@ -0,0 +1,10 @@ +import core.unstable.blake2s.Blake2s; + +function main() { + let seed: [u8; 32] = [0; 32]; + let message: [u16; 32] = [0; 32]; // message should be type [u8; 32] + + let result = Blake2s::hash(seed, message); + + console.log("Result: {}", result); +} diff --git a/tests/pass/parse/core/blake2s_input.leo b/tests/pass/parse/core/blake2s_input.leo new file mode 100644 index 0000000000..6044795c3d --- /dev/null +++ b/tests/pass/parse/core/blake2s_input.leo @@ -0,0 +1,5 @@ +import core.unstable.blake2s.Blake2s; + +function main(seed: [u8; 32], message: [u8; 32]) -> [u8; 32] { + return Blake2s::hash(seed, message) +} diff --git a/tests/pass/parse/core/blake2s_random.leo b/tests/pass/parse/core/blake2s_random.leo new file mode 100644 index 0000000000..72aef44932 --- /dev/null +++ b/tests/pass/parse/core/blake2s_random.leo @@ -0,0 +1,7 @@ +import core.unstable.blake2s.Blake2s; + +function main(seed: [u8; 32], message: [u8; 32], expected: [u8; 32]) { + let actual = Blake2s::hash(seed, message); + + console.assert(expected == actual); +} diff --git a/tests/pass/parse/core/core_circuit_invalid.leo b/tests/pass/parse/core/core_circuit_invalid.leo new file mode 100644 index 0000000000..4a42bda032 --- /dev/null +++ b/tests/pass/parse/core/core_circuit_invalid.leo @@ -0,0 +1,3 @@ +import core.unstable.blake2s.BadCircuit; // `BadCircuit` is not included in the blake2s package + +function main() {} diff --git a/tests/pass/parse/core/core_circuit_star_fail.leo b/tests/pass/parse/core/core_circuit_star_fail.leo new file mode 100644 index 0000000000..14b54b0d69 --- /dev/null +++ b/tests/pass/parse/core/core_circuit_star_fail.leo @@ -0,0 +1,3 @@ +import core.*; // You cannot import all dependencies from core at once + +function main() {} diff --git a/tests/pass/parse/core/core_package_invalid.leo b/tests/pass/parse/core/core_package_invalid.leo new file mode 100644 index 0000000000..7cbcf93ecc --- /dev/null +++ b/tests/pass/parse/core/core_package_invalid.leo @@ -0,0 +1,3 @@ +import core.bad_circuit; // `bad_circuit` is not a core package + +function main() {} diff --git a/tests/pass/parse/core/core_unstable_package_invalid.leo b/tests/pass/parse/core/core_unstable_package_invalid.leo new file mode 100644 index 0000000000..35e6c0d1ba --- /dev/null +++ b/tests/pass/parse/core/core_unstable_package_invalid.leo @@ -0,0 +1,3 @@ +import core.unstable.bad_circuit; // `bad_circuit` is not a core unstable package + +function main() {} diff --git a/tests/pass/parse/core/unstable_blake2s.leo b/tests/pass/parse/core/unstable_blake2s.leo new file mode 100644 index 0000000000..ca7db13892 --- /dev/null +++ b/tests/pass/parse/core/unstable_blake2s.leo @@ -0,0 +1,10 @@ +import core.unstable.blake2s.Blake2s; + +function main() { + let seed: [u8; 32] = [0; 32]; + let message: [u8; 32] = [0; 32]; + + let result = Blake2s::hash(seed, message); + + console.log("Result: {}", result); +} diff --git a/tests/pass/parse/definition/out_of_order.leo b/tests/pass/parse/definition/out_of_order.leo new file mode 100644 index 0000000000..69d46d0e74 --- /dev/null +++ b/tests/pass/parse/definition/out_of_order.leo @@ -0,0 +1,6 @@ +@test +function fake_test() {} + +function main() {} + +circuit Foo {} \ No newline at end of file diff --git a/tests/pass/parse/definition/out_of_order_with_import.leo b/tests/pass/parse/definition/out_of_order_with_import.leo new file mode 100644 index 0000000000..daf92fdecb --- /dev/null +++ b/tests/pass/parse/definition/out_of_order_with_import.leo @@ -0,0 +1,7 @@ +@test function fake_test() {} + +function main() {} + +import test_import.foo; + +circuit Foo {} \ No newline at end of file diff --git a/tests/pass/parse/field/add.leo b/tests/pass/parse/field/add.leo new file mode 100644 index 0000000000..8dc2c7df4e --- /dev/null +++ b/tests/pass/parse/field/add.leo @@ -0,0 +1,3 @@ +function main(a: field, b: field, c: field) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/field/console_assert.leo b/tests/pass/parse/field/console_assert.leo new file mode 100644 index 0000000000..c7224bcea5 --- /dev/null +++ b/tests/pass/parse/field/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: field, b: field) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/field/div.leo b/tests/pass/parse/field/div.leo new file mode 100644 index 0000000000..028b06fad2 --- /dev/null +++ b/tests/pass/parse/field/div.leo @@ -0,0 +1,3 @@ +function main(a: field, b: field, c: field) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/field/eq.leo b/tests/pass/parse/field/eq.leo new file mode 100644 index 0000000000..e64307d8de --- /dev/null +++ b/tests/pass/parse/field/eq.leo @@ -0,0 +1,3 @@ +function main(a: field, b: field, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/field/field.leo b/tests/pass/parse/field/field.leo new file mode 100644 index 0000000000..3f109881ad --- /dev/null +++ b/tests/pass/parse/field/field.leo @@ -0,0 +1,4 @@ +function main() { + let negOneField: field = -1field; + let oneField = 1field; +} \ No newline at end of file diff --git a/tests/pass/parse/field/mul.leo b/tests/pass/parse/field/mul.leo new file mode 100644 index 0000000000..7df7c83830 --- /dev/null +++ b/tests/pass/parse/field/mul.leo @@ -0,0 +1,3 @@ +function main(a: field, b: field, c: field) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/field/negate.leo b/tests/pass/parse/field/negate.leo new file mode 100644 index 0000000000..94c730207a --- /dev/null +++ b/tests/pass/parse/field/negate.leo @@ -0,0 +1,3 @@ +function main(a: field, b: field) { + console.assert(-a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/field/sub.leo b/tests/pass/parse/field/sub.leo new file mode 100644 index 0000000000..2c84b24647 --- /dev/null +++ b/tests/pass/parse/field/sub.leo @@ -0,0 +1,3 @@ +function main(a: field, b: field, c: field) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/field/ternary.leo b/tests/pass/parse/field/ternary.leo new file mode 100644 index 0000000000..f193ad82a3 --- /dev/null +++ b/tests/pass/parse/field/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: field, b: field, c: field) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/function/array_input.leo b/tests/pass/parse/function/array_input.leo new file mode 100644 index 0000000000..a70483cae7 --- /dev/null +++ b/tests/pass/parse/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/tests/pass/parse/function/array_params_direct_call.leo b/tests/pass/parse/function/array_params_direct_call.leo new file mode 100644 index 0000000000..9305b0958d --- /dev/null +++ b/tests/pass/parse/function/array_params_direct_call.leo @@ -0,0 +1,9 @@ +function do_nothing(arr: [u32; 2]) {} + +function main() { + let arr: [u32; 2] = [0; 2]; + + do_nothing(arr); + do_nothing([...arr]); + do_nothing(arr[1u32..]); +} \ No newline at end of file diff --git a/tests/pass/parse/function/conditional_return.leo b/tests/pass/parse/function/conditional_return.leo new file mode 100644 index 0000000000..7ecd0e625c --- /dev/null +++ b/tests/pass/parse/function/conditional_return.leo @@ -0,0 +1,7 @@ +function main(x: u8) -> u8 { + if x == 2u8 { + return 3u8 + } else { + return 4u8 + } +} \ No newline at end of file diff --git a/tests/pass/parse/function/empty.leo b/tests/pass/parse/function/empty.leo new file mode 100644 index 0000000000..f06c976158 --- /dev/null +++ b/tests/pass/parse/function/empty.leo @@ -0,0 +1,5 @@ +function empty() { } + +function main() { + empty(); +} \ No newline at end of file diff --git a/tests/pass/parse/function/iteration.leo b/tests/pass/parse/function/iteration.leo new file mode 100644 index 0000000000..19af4dd9cf --- /dev/null +++ b/tests/pass/parse/function/iteration.leo @@ -0,0 +1,13 @@ +function one() -> u32 { + return 1u32 +} + +function main() { + let mut a = 0u32; + + for i in 0..10 { + a += one(); + } + + console.assert(a == 10u32); +} \ No newline at end of file diff --git a/tests/pass/parse/function/iteration_repeated.leo b/tests/pass/parse/function/iteration_repeated.leo new file mode 100644 index 0000000000..3694b3594a --- /dev/null +++ b/tests/pass/parse/function/iteration_repeated.leo @@ -0,0 +1,15 @@ +function iteration() -> u32 { + let mut a = 0u32; + + for i in 0..10 { + a += 1; + } + + return a +} + +function main() { + let total = iteration() + iteration(); + + console.assert(total == 20); +} \ No newline at end of file diff --git a/tests/pass/parse/function/multiple_returns.leo b/tests/pass/parse/function/multiple_returns.leo new file mode 100644 index 0000000000..ef00a4ef47 --- /dev/null +++ b/tests/pass/parse/function/multiple_returns.leo @@ -0,0 +1,10 @@ +function tuple() -> (bool, bool) { + return (true, false) +} + +function main() { + let (a, b) = tuple(); + + console.assert(a == true); + console.assert(b == false); +} \ No newline at end of file diff --git a/tests/pass/parse/function/multiple_returns_fail.leo b/tests/pass/parse/function/multiple_returns_fail.leo new file mode 100644 index 0000000000..d4a8b36eac --- /dev/null +++ b/tests/pass/parse/function/multiple_returns_fail.leo @@ -0,0 +1,7 @@ +function main () -> i8 { + if true { + return 1i8 //ignored + } + return 2i8 //ignored + return 3i8 //returns +} \ No newline at end of file diff --git a/tests/pass/parse/function/multiple_returns_fail_conditional.leo b/tests/pass/parse/function/multiple_returns_fail_conditional.leo new file mode 100644 index 0000000000..04ebb9e306 --- /dev/null +++ b/tests/pass/parse/function/multiple_returns_fail_conditional.leo @@ -0,0 +1,9 @@ +function main () -> u16 { + if false { + let a = 1u16; + let b = a + 1u16; + return b + } else if false { + return 0u16 + } +} \ No newline at end of file diff --git a/tests/pass/parse/function/multiple_returns_main.leo b/tests/pass/parse/function/multiple_returns_main.leo new file mode 100644 index 0000000000..0bc82e1e4b --- /dev/null +++ b/tests/pass/parse/function/multiple_returns_main.leo @@ -0,0 +1,3 @@ +function main(input) -> (bool, bool) { + return (input.registers.a, input.registers.b) +} \ No newline at end of file diff --git a/tests/pass/parse/function/newlines.leo b/tests/pass/parse/function/newlines.leo new file mode 100644 index 0000000000..8c703f81d3 --- /dev/null +++ b/tests/pass/parse/function/newlines.leo @@ -0,0 +1,9 @@ +function main( + a: u32, + b: u32, +) -> ( + u32, + u32, +) { + return (a, b) +} \ No newline at end of file diff --git a/tests/pass/parse/function/repeated.leo b/tests/pass/parse/function/repeated.leo new file mode 100644 index 0000000000..a2d04d55f9 --- /dev/null +++ b/tests/pass/parse/function/repeated.leo @@ -0,0 +1,9 @@ +function one() -> bool { + return true +} + +function main() { + let a = one() && one(); + + console.assert(a == true); +} \ No newline at end of file diff --git a/tests/pass/parse/function/return.leo b/tests/pass/parse/function/return.leo new file mode 100644 index 0000000000..10c7138977 --- /dev/null +++ b/tests/pass/parse/function/return.leo @@ -0,0 +1,7 @@ +function one() -> u32 { + return 1u32 +} + +function main() { + console.assert(one() == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/function/return_array_nested_fail.leo b/tests/pass/parse/function/return_array_nested_fail.leo new file mode 100644 index 0000000000..dca001d9cc --- /dev/null +++ b/tests/pass/parse/function/return_array_nested_fail.leo @@ -0,0 +1,7 @@ +function array_3x2_tuple() -> [[u8; 2]; 3] { + return [0u8; (2, 3)] // The correct 3x2 array tuple is `[0u8; (3, 2)]` +} + +function main() { + let b = array_3x2_tuple(); +} \ No newline at end of file diff --git a/tests/pass/parse/function/return_array_nested_pass.leo b/tests/pass/parse/function/return_array_nested_pass.leo new file mode 100644 index 0000000000..dda5b4342b --- /dev/null +++ b/tests/pass/parse/function/return_array_nested_pass.leo @@ -0,0 +1,12 @@ +function array_3x2_nested() -> [[u8; 2]; 3] { + return [[0u8; 2]; 3] +} + +function array_3x2_tuple() -> [[u8; 2]; 3] { + return [0u8; (3, 2)] +} + +function main() { + let a = array_3x2_nested(); + let b = array_3x2_tuple(); +} \ No newline at end of file diff --git a/tests/pass/parse/function/return_array_tuple_fail.leo b/tests/pass/parse/function/return_array_tuple_fail.leo new file mode 100644 index 0000000000..4b7377e327 --- /dev/null +++ b/tests/pass/parse/function/return_array_tuple_fail.leo @@ -0,0 +1,7 @@ +function array_3x2_nested() -> [u8; (3, 2)] { + return [[0u8; 3]; 2] // The correct 3x2 nested array is `[0u8; 2]; 3]` +} + +function main() { + let a = array_3x2_nested(); +} \ No newline at end of file diff --git a/tests/pass/parse/function/return_array_tuple_pass.leo b/tests/pass/parse/function/return_array_tuple_pass.leo new file mode 100644 index 0000000000..a700bcabad --- /dev/null +++ b/tests/pass/parse/function/return_array_tuple_pass.leo @@ -0,0 +1,12 @@ +function array_3x2_nested() -> [u8; (3, 2)] { + return [[0u8; 2]; 3] +} + +function array_3x2_tuple() -> [u8; (3, 2)] { + return [0u8; (3, 2)] +} + +function main() { + let a = array_3x2_nested(); + let b = array_3x2_tuple(); +} \ No newline at end of file diff --git a/tests/pass/parse/function/return_tuple.leo b/tests/pass/parse/function/return_tuple.leo new file mode 100644 index 0000000000..c459740a47 --- /dev/null +++ b/tests/pass/parse/function/return_tuple.leo @@ -0,0 +1,11 @@ +// Returns a tuple of tuples. +function tuples() -> ((u8, u8), u32) { + let a: (u8, u8) = (1, 2); + let b: u32 = 3; + + return (a, b) +} + +function main() { + let t = tuples(); +} \ No newline at end of file diff --git a/tests/pass/parse/function/return_tuple_conditional.leo b/tests/pass/parse/function/return_tuple_conditional.leo new file mode 100644 index 0000000000..c63967f548 --- /dev/null +++ b/tests/pass/parse/function/return_tuple_conditional.leo @@ -0,0 +1,15 @@ +// Returns a tuple using a conditional "if" statement. +function tuple_conditional () -> ( + i64, + i64 +) { + if true { + return (1, 1) + } else { + return (2, 2) + } +} + +function main() { + let t = tuple_conditional(); +} \ No newline at end of file diff --git a/tests/pass/parse/function/scope_fail.leo b/tests/pass/parse/function/scope_fail.leo new file mode 100644 index 0000000000..773c2479d7 --- /dev/null +++ b/tests/pass/parse/function/scope_fail.leo @@ -0,0 +1,8 @@ +function foo() -> field { + return myGlobal +} + +function main() { + let myGlobal = 42field; + let err = foo(); +} \ No newline at end of file diff --git a/tests/pass/parse/function/undefined.leo b/tests/pass/parse/function/undefined.leo new file mode 100644 index 0000000000..e1db3b9f09 --- /dev/null +++ b/tests/pass/parse/function/undefined.leo @@ -0,0 +1,3 @@ +function main() { + my_function(); +} \ No newline at end of file diff --git a/tests/pass/parse/function/value_unchanged.leo b/tests/pass/parse/function/value_unchanged.leo new file mode 100644 index 0000000000..32dcfa62d6 --- /dev/null +++ b/tests/pass/parse/function/value_unchanged.leo @@ -0,0 +1,19 @@ +// Functions input in leo are pass-by-value. +// +// Program execution: +// line 15: variable `a` is defined with value `1`. +// line 16: value `1` is copied and passed into function `bad_mutate()`. +// line 10: variable `x` is defined with value `1`. +// line 11: variable `x` is set to value `0`. +// line 18: program returns the value of `a`. + +function bad_mutate(mut x: u32) { + x = 0; // <- does not change `a` +} + +function main() { + let a = 1u32; + bad_mutate(a); + + console.assert(a == 1u32); // <- value `a` is still `1u32` +} \ No newline at end of file diff --git a/tests/pass/parse/group/add.leo b/tests/pass/parse/group/add.leo new file mode 100644 index 0000000000..bb84df2d6c --- /dev/null +++ b/tests/pass/parse/group/add.leo @@ -0,0 +1,3 @@ +function main(a: group, b: group, c: group) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/group/assert_eq.leo b/tests/pass/parse/group/assert_eq.leo new file mode 100644 index 0000000000..3886a07bbf --- /dev/null +++ b/tests/pass/parse/group/assert_eq.leo @@ -0,0 +1,3 @@ +function main(a: group, b: group) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/group/both_sign_high.leo b/tests/pass/parse/group/both_sign_high.leo new file mode 100644 index 0000000000..a8217d6d40 --- /dev/null +++ b/tests/pass/parse/group/both_sign_high.leo @@ -0,0 +1,3 @@ +function main() { + let element = (+, +)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/both_sign_inferred.leo b/tests/pass/parse/group/both_sign_inferred.leo new file mode 100644 index 0000000000..b3b8b512c3 --- /dev/null +++ b/tests/pass/parse/group/both_sign_inferred.leo @@ -0,0 +1,3 @@ +function main() { + let element = (_, _)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/both_sign_low.leo b/tests/pass/parse/group/both_sign_low.leo new file mode 100644 index 0000000000..0519c6d17d --- /dev/null +++ b/tests/pass/parse/group/both_sign_low.leo @@ -0,0 +1,3 @@ +function main() { + let element = (-, -)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/eq.leo b/tests/pass/parse/group/eq.leo new file mode 100644 index 0000000000..89701d9c99 --- /dev/null +++ b/tests/pass/parse/group/eq.leo @@ -0,0 +1,3 @@ +function main(a: group, b: group, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/group/input.leo b/tests/pass/parse/group/input.leo new file mode 100644 index 0000000000..3886a07bbf --- /dev/null +++ b/tests/pass/parse/group/input.leo @@ -0,0 +1,3 @@ +function main(a: group, b: group) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/group/negate.leo b/tests/pass/parse/group/negate.leo new file mode 100644 index 0000000000..506d8d73ce --- /dev/null +++ b/tests/pass/parse/group/negate.leo @@ -0,0 +1,3 @@ +function main(a: group, b: group) { + console.assert(-a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/group/one.leo b/tests/pass/parse/group/one.leo new file mode 100644 index 0000000000..7be0cbbc2c --- /dev/null +++ b/tests/pass/parse/group/one.leo @@ -0,0 +1,3 @@ +function main() { + let element = 1group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/point.leo b/tests/pass/parse/group/point.leo new file mode 100644 index 0000000000..85eeb53b7b --- /dev/null +++ b/tests/pass/parse/group/point.leo @@ -0,0 +1,3 @@ +function main() { + let point = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/point_input.leo b/tests/pass/parse/group/point_input.leo new file mode 100644 index 0000000000..68d8c458a3 --- /dev/null +++ b/tests/pass/parse/group/point_input.leo @@ -0,0 +1,3 @@ +function main(a: group) { + let b = a; +} \ No newline at end of file diff --git a/tests/pass/parse/group/positive_and_negative.leo b/tests/pass/parse/group/positive_and_negative.leo new file mode 100644 index 0000000000..fdf9b892be --- /dev/null +++ b/tests/pass/parse/group/positive_and_negative.leo @@ -0,0 +1,10 @@ +function main() { + let pos_element = 1group; + let neg_element = -1group; + + let pair_x_pos = (1, _)group; + let pair_x_neg = (-1, _)group; + + let pair_y_pos = (_, 1)group; + let pair_y_neg = (_, -1)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/sub.leo b/tests/pass/parse/group/sub.leo new file mode 100644 index 0000000000..dfe82d8e31 --- /dev/null +++ b/tests/pass/parse/group/sub.leo @@ -0,0 +1,3 @@ +function main(a: group, b: group, c: group) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/group/ternary.leo b/tests/pass/parse/group/ternary.leo new file mode 100644 index 0000000000..fb69b74521 --- /dev/null +++ b/tests/pass/parse/group/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: group, b: group, c: group) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/group/x_and_y.leo b/tests/pass/parse/group/x_and_y.leo new file mode 100644 index 0000000000..1b64702db1 --- /dev/null +++ b/tests/pass/parse/group/x_and_y.leo @@ -0,0 +1,3 @@ +function main(element: group) { + let b = element; +} \ No newline at end of file diff --git a/tests/pass/parse/group/x_sign_high.leo b/tests/pass/parse/group/x_sign_high.leo new file mode 100644 index 0000000000..1b8d397d02 --- /dev/null +++ b/tests/pass/parse/group/x_sign_high.leo @@ -0,0 +1,3 @@ +function main() { + let element = (0, +)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/x_sign_inferred.leo b/tests/pass/parse/group/x_sign_inferred.leo new file mode 100644 index 0000000000..9e9622a4a4 --- /dev/null +++ b/tests/pass/parse/group/x_sign_inferred.leo @@ -0,0 +1,3 @@ +function main() { + let element = (0, _)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/x_sign_low.leo b/tests/pass/parse/group/x_sign_low.leo new file mode 100644 index 0000000000..a5058bda52 --- /dev/null +++ b/tests/pass/parse/group/x_sign_low.leo @@ -0,0 +1,3 @@ +function main() { + let element = (0, -)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/y_sign_high.leo b/tests/pass/parse/group/y_sign_high.leo new file mode 100644 index 0000000000..fe16883b39 --- /dev/null +++ b/tests/pass/parse/group/y_sign_high.leo @@ -0,0 +1,3 @@ +function main() { + let element = (+, 1)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/y_sign_inferred.leo b/tests/pass/parse/group/y_sign_inferred.leo new file mode 100644 index 0000000000..003c373cf2 --- /dev/null +++ b/tests/pass/parse/group/y_sign_inferred.leo @@ -0,0 +1,3 @@ +function main() { + let element = (_, 1)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/y_sign_low.leo b/tests/pass/parse/group/y_sign_low.leo new file mode 100644 index 0000000000..9e61bfd2bb --- /dev/null +++ b/tests/pass/parse/group/y_sign_low.leo @@ -0,0 +1,3 @@ +function main() { + let element = (-, 1)group; +} \ No newline at end of file diff --git a/tests/pass/parse/group/zero.leo b/tests/pass/parse/group/zero.leo new file mode 100644 index 0000000000..e2c0283c21 --- /dev/null +++ b/tests/pass/parse/group/zero.leo @@ -0,0 +1,3 @@ +function main() { + let element = 0group; +} \ No newline at end of file diff --git a/tests/pass/parse/import/a-9.leo b/tests/pass/parse/import/a-9.leo new file mode 100644 index 0000000000..8cd9f87f14 --- /dev/null +++ b/tests/pass/parse/import/a-9.leo @@ -0,0 +1 @@ +function bar() {} \ No newline at end of file diff --git a/tests/pass/parse/import/a0-f.leo b/tests/pass/parse/import/a0-f.leo new file mode 100644 index 0000000000..c99ad3b713 --- /dev/null +++ b/tests/pass/parse/import/a0-f.leo @@ -0,0 +1 @@ +function foo() {} \ No newline at end of file diff --git a/tests/pass/parse/import/alias.leo b/tests/pass/parse/import/alias.leo new file mode 100644 index 0000000000..f153b5a128 --- /dev/null +++ b/tests/pass/parse/import/alias.leo @@ -0,0 +1,5 @@ +import test-import.foo as bar; + +function main() { + console.assert(bar() == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/import/basic.leo b/tests/pass/parse/import/basic.leo new file mode 100644 index 0000000000..53d243efaa --- /dev/null +++ b/tests/pass/parse/import/basic.leo @@ -0,0 +1,5 @@ +import test-import.foo; + +function main() { + console.assert(foo() == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/import/bat.leo b/tests/pass/parse/import/bat.leo new file mode 100755 index 0000000000..a7d2fc83d4 --- /dev/null +++ b/tests/pass/parse/import/bat.leo @@ -0,0 +1,3 @@ +circuit Bat { + t: u32 +} \ No newline at end of file diff --git a/tests/pass/parse/import/baz.leo b/tests/pass/parse/import/baz.leo new file mode 100755 index 0000000000..1bb268a84c --- /dev/null +++ b/tests/pass/parse/import/baz.leo @@ -0,0 +1,7 @@ +circuit Baz { + z: u32 +} + +circuit Bazzar { + a: u32 +} \ No newline at end of file diff --git a/tests/pass/parse/import/hello-world.leo b/tests/pass/parse/import/hello-world.leo new file mode 100644 index 0000000000..2d96e74c4c --- /dev/null +++ b/tests/pass/parse/import/hello-world.leo @@ -0,0 +1 @@ +function hello() {} \ No newline at end of file diff --git a/tests/pass/parse/import/lib.leo b/tests/pass/parse/import/lib.leo new file mode 100755 index 0000000000..c169f5935e --- /dev/null +++ b/tests/pass/parse/import/lib.leo @@ -0,0 +1,3 @@ +circuit Bar { + r: u32 +} \ No newline at end of file diff --git a/tests/pass/parse/import/many_import.leo b/tests/pass/parse/import/many_import.leo new file mode 100644 index 0000000000..5e85f19778 --- /dev/null +++ b/tests/pass/parse/import/many_import.leo @@ -0,0 +1,26 @@ +import test-import.( // local import + Point, + foo, +); + +import bar.( // imports directory import + Bar, + baz.(Baz, Bazzar), + bat.bat.Bat, +); + +import car.Car; // imports directory import + +function main() { + let point = Point { x: 1u32, y: 1u32 }; + let foo = foo(); + + let bar = Bar { r: 1u32 }; + let baz = Baz { z: 1u32 }; + let bazzar = Bazzar { a: 1u32 }; + let bat = Bat { t: 1u32 }; + + let car = Car { c: 1u32 }; + + console.assert(car.c == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/import/many_import_star.leo b/tests/pass/parse/import/many_import_star.leo new file mode 100644 index 0000000000..5145d0d05d --- /dev/null +++ b/tests/pass/parse/import/many_import_star.leo @@ -0,0 +1,19 @@ +import test-import.*; // local import + +import bar.*; // imports directory import +import bar.baz.*; // imports directory import +import bar.bat.bat.*; // imports directory import +import car.*; // imports directory import + +function main() { + let point = Point { x: 1u32, y: 1u32 }; + let foo = foo(); + + let bar = Bar { r: 1u32 }; + let bat = Bat { t: 1u32 }; + let baz = Baz { z: 1u32 }; + + let car = Car { c: 1u32 }; + + console.assert(car.c == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/import/multiple.leo b/tests/pass/parse/import/multiple.leo new file mode 100644 index 0000000000..5c89aaee0c --- /dev/null +++ b/tests/pass/parse/import/multiple.leo @@ -0,0 +1,10 @@ +import test-import.( + Point, + foo +); + +function main() { + let a = Point { x: 1u32, y: 0u32 }; + + console.assert(a.x == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/import/names.leo b/tests/pass/parse/import/names.leo new file mode 100644 index 0000000000..d3ce50829a --- /dev/null +++ b/tests/pass/parse/import/names.leo @@ -0,0 +1,5 @@ +import a0-f.foo; +import a-9.bar; +import hello-world.hello; + +function main() {} \ No newline at end of file diff --git a/tests/pass/parse/import/names_underscore.leo b/tests/pass/parse/import/names_underscore.leo new file mode 100644 index 0000000000..c5822ebadd --- /dev/null +++ b/tests/pass/parse/import/names_underscore.leo @@ -0,0 +1,3 @@ +import hello_world.foo; + +function main() {} \ No newline at end of file diff --git a/tests/pass/parse/import/star.leo b/tests/pass/parse/import/star.leo new file mode 100644 index 0000000000..9cd817686f --- /dev/null +++ b/tests/pass/parse/import/star.leo @@ -0,0 +1,7 @@ +import test-import.*; + +function main() { + let a = Point { x: 1u32, y: 0u32 }; + + console.assert(foo() == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/import/star_fail.leo b/tests/pass/parse/import/star_fail.leo new file mode 100644 index 0000000000..47f2efeda7 --- /dev/null +++ b/tests/pass/parse/import/star_fail.leo @@ -0,0 +1,4 @@ +// importing `*` from a directory is illegal +import bar.bat.*; + +function main() {} \ No newline at end of file diff --git a/tests/pass/parse/import/test-import.leo b/tests/pass/parse/import/test-import.leo new file mode 100644 index 0000000000..6dd3e2c88a --- /dev/null +++ b/tests/pass/parse/import/test-import.leo @@ -0,0 +1,8 @@ +circuit Point { + x: u32 + y: u32 +} + +function foo() -> u32 { + return 1u32 +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/add.leo b/tests/pass/parse/integers/i128/add.leo new file mode 100644 index 0000000000..e35648f545 --- /dev/null +++ b/tests/pass/parse/integers/i128/add.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: i128) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/console_assert.leo b/tests/pass/parse/integers/i128/console_assert.leo new file mode 100644 index 0000000000..c89021f609 --- /dev/null +++ b/tests/pass/parse/integers/i128/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/div.leo b/tests/pass/parse/integers/i128/div.leo new file mode 100644 index 0000000000..ffaeae19a8 --- /dev/null +++ b/tests/pass/parse/integers/i128/div.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: i128) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/eq.leo b/tests/pass/parse/integers/i128/eq.leo new file mode 100644 index 0000000000..f4beddc8fc --- /dev/null +++ b/tests/pass/parse/integers/i128/eq.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/ge.leo b/tests/pass/parse/integers/i128/ge.leo new file mode 100644 index 0000000000..1fbbd68073 --- /dev/null +++ b/tests/pass/parse/integers/i128/ge.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: bool) { + console.assert(a >= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/gt.leo b/tests/pass/parse/integers/i128/gt.leo new file mode 100644 index 0000000000..27849afbe8 --- /dev/null +++ b/tests/pass/parse/integers/i128/gt.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: bool) { + console.assert(a > b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/input.leo b/tests/pass/parse/integers/i128/input.leo new file mode 100644 index 0000000000..c89021f609 --- /dev/null +++ b/tests/pass/parse/integers/i128/input.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/le.leo b/tests/pass/parse/integers/i128/le.leo new file mode 100644 index 0000000000..ea0c3c9e1d --- /dev/null +++ b/tests/pass/parse/integers/i128/le.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: bool) { + console.assert(a <= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/lt.leo b/tests/pass/parse/integers/i128/lt.leo new file mode 100644 index 0000000000..bde4def85c --- /dev/null +++ b/tests/pass/parse/integers/i128/lt.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: bool) { + console.assert(a < b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/max.leo b/tests/pass/parse/integers/i128/max.leo new file mode 100644 index 0000000000..46c0a32599 --- /dev/null +++ b/tests/pass/parse/integers/i128/max.leo @@ -0,0 +1,3 @@ +function main() { + let a: i128 = 170141183460469231731687303715884105727; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/max_fail.leo b/tests/pass/parse/integers/i128/max_fail.leo new file mode 100644 index 0000000000..820eda8759 --- /dev/null +++ b/tests/pass/parse/integers/i128/max_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: i128 = 170141183460469231731687303715884105728; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/min.leo b/tests/pass/parse/integers/i128/min.leo new file mode 100644 index 0000000000..5f32e5add5 --- /dev/null +++ b/tests/pass/parse/integers/i128/min.leo @@ -0,0 +1,3 @@ +function main() { + let a: i128 = -170141183460469231731687303715884105728; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/min_fail.leo b/tests/pass/parse/integers/i128/min_fail.leo new file mode 100644 index 0000000000..9035444fa9 --- /dev/null +++ b/tests/pass/parse/integers/i128/min_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: i128 = -170141183460469231731687303715884105729; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/mod.rs b/tests/pass/parse/integers/i128/mod.rs new file mode 100644 index 0000000000..e62e07260e --- /dev/null +++ b/tests/pass/parse/integers/i128/mod.rs @@ -0,0 +1,134 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{ + assert_satisfied, + expect_asg_error, + expect_compiler_error, + generate_main_input, + integers::{expect_computation_error, IntegerTester}, + parse_program, +}; +use leo_ast::InputValue; +use leo_input::types::{I128Type, IntegerType, SignedIntegerType}; + +test_int!( + TestI128, + i128, + IntegerType::Signed(SignedIntegerType::I128Type(I128Type {})), + Int128 +); + +#[test] +fn test_i128_min() { + TestI128::test_min(); +} + +#[test] +fn test_i128_min_fail() { + TestI128::test_min_fail(); +} + +#[test] +fn test_i128_max() { + TestI128::test_max(); +} + +#[test] +fn test_i128_max_fail() { + TestI128::test_max_fail(); +} + +#[test] +fn test_i128_neg() { + TestI128::test_negate(); +} + +#[test] +fn test_i128_neg_max_fail() { + TestI128::test_negate_min_fail(); +} + +#[test] +fn test_i128_neg_zero() { + TestI128::test_negate_zero(); +} + +#[test] +fn test_i128_add() { + TestI128::test_add(); +} + +#[test] +fn test_i128_sub() { + TestI128::test_sub(); +} + +#[test] +fn test_i128_mul() { + TestI128::test_mul(); +} + +#[test] +#[ignore] // takes several minutes +fn test_i128_div() { + TestI128::test_div(); +} + +#[test] +fn test_i128_pow() { + TestI128::test_pow(); +} + +#[test] +fn test_i128_eq() { + TestI128::test_eq(); +} + +#[test] +fn test_i128_ne() { + TestI128::test_ne(); +} + +#[test] +fn test_i128_ge() { + TestI128::test_ge(); +} + +#[test] +fn test_i128_gt() { + TestI128::test_gt(); +} + +#[test] +fn test_i128_le() { + TestI128::test_le(); +} + +#[test] +fn test_i128_lt() { + TestI128::test_lt(); +} + +#[test] +fn test_i128_assert_eq() { + TestI128::test_console_assert(); +} + +#[test] +fn test_i128_ternary() { + TestI128::test_ternary(); +} diff --git a/tests/pass/parse/integers/i128/mul.leo b/tests/pass/parse/integers/i128/mul.leo new file mode 100644 index 0000000000..25b902d53c --- /dev/null +++ b/tests/pass/parse/integers/i128/mul.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: i128) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/ne.leo b/tests/pass/parse/integers/i128/ne.leo new file mode 100644 index 0000000000..dae148b49c --- /dev/null +++ b/tests/pass/parse/integers/i128/ne.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: bool) { + console.assert(a != b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/negate.leo b/tests/pass/parse/integers/i128/negate.leo new file mode 100644 index 0000000000..437ee06390 --- /dev/null +++ b/tests/pass/parse/integers/i128/negate.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128) { + console.assert(-a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/negate_min.leo b/tests/pass/parse/integers/i128/negate_min.leo new file mode 100644 index 0000000000..cfbd308362 --- /dev/null +++ b/tests/pass/parse/integers/i128/negate_min.leo @@ -0,0 +1,4 @@ +function main() { + let a: i128 = -170141183460469231731687303715884105728; + let b = -a; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/negate_zero.leo b/tests/pass/parse/integers/i128/negate_zero.leo new file mode 100644 index 0000000000..9fb0c11afe --- /dev/null +++ b/tests/pass/parse/integers/i128/negate_zero.leo @@ -0,0 +1,5 @@ +function main() { + let a = 0i128; + + console.assert(-a == 0i128); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/pow.leo b/tests/pass/parse/integers/i128/pow.leo new file mode 100644 index 0000000000..05536aad51 --- /dev/null +++ b/tests/pass/parse/integers/i128/pow.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: i128) { + console.assert(a ** b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/sub.leo b/tests/pass/parse/integers/i128/sub.leo new file mode 100644 index 0000000000..3a723eec49 --- /dev/null +++ b/tests/pass/parse/integers/i128/sub.leo @@ -0,0 +1,3 @@ +function main(a: i128, b: i128, c: i128) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i128/ternary.leo b/tests/pass/parse/integers/i128/ternary.leo new file mode 100644 index 0000000000..a923c428e6 --- /dev/null +++ b/tests/pass/parse/integers/i128/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: i128, b: i128, c: i128) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/add.leo b/tests/pass/parse/integers/i16/add.leo new file mode 100644 index 0000000000..556ae65c3a --- /dev/null +++ b/tests/pass/parse/integers/i16/add.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: i16) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/console_assert.leo b/tests/pass/parse/integers/i16/console_assert.leo new file mode 100644 index 0000000000..3afb25b207 --- /dev/null +++ b/tests/pass/parse/integers/i16/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/div.leo b/tests/pass/parse/integers/i16/div.leo new file mode 100644 index 0000000000..6d0c8f4614 --- /dev/null +++ b/tests/pass/parse/integers/i16/div.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: i16) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/eq.leo b/tests/pass/parse/integers/i16/eq.leo new file mode 100644 index 0000000000..338e3e50f6 --- /dev/null +++ b/tests/pass/parse/integers/i16/eq.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/ge.leo b/tests/pass/parse/integers/i16/ge.leo new file mode 100644 index 0000000000..68a4d40bf8 --- /dev/null +++ b/tests/pass/parse/integers/i16/ge.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: bool) { + console.assert(a >= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/gt.leo b/tests/pass/parse/integers/i16/gt.leo new file mode 100644 index 0000000000..75d9bfb612 --- /dev/null +++ b/tests/pass/parse/integers/i16/gt.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: bool) { + console.assert(a > b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/input.leo b/tests/pass/parse/integers/i16/input.leo new file mode 100644 index 0000000000..3afb25b207 --- /dev/null +++ b/tests/pass/parse/integers/i16/input.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/le.leo b/tests/pass/parse/integers/i16/le.leo new file mode 100644 index 0000000000..ff112c7fbc --- /dev/null +++ b/tests/pass/parse/integers/i16/le.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: bool) { + console.assert(a <= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/lt.leo b/tests/pass/parse/integers/i16/lt.leo new file mode 100644 index 0000000000..46c57aabe6 --- /dev/null +++ b/tests/pass/parse/integers/i16/lt.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: bool) { + console.assert(a < b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/max.leo b/tests/pass/parse/integers/i16/max.leo new file mode 100644 index 0000000000..084fe4969a --- /dev/null +++ b/tests/pass/parse/integers/i16/max.leo @@ -0,0 +1,3 @@ +function main() { + let a: i16 = 32767; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/max_fail.leo b/tests/pass/parse/integers/i16/max_fail.leo new file mode 100644 index 0000000000..8dd2b7f50a --- /dev/null +++ b/tests/pass/parse/integers/i16/max_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: i16 = 32768; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/min.leo b/tests/pass/parse/integers/i16/min.leo new file mode 100644 index 0000000000..3331281fcf --- /dev/null +++ b/tests/pass/parse/integers/i16/min.leo @@ -0,0 +1,3 @@ +function main() { + let a: i16 = -32768; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/min_fail.leo b/tests/pass/parse/integers/i16/min_fail.leo new file mode 100644 index 0000000000..380848381a --- /dev/null +++ b/tests/pass/parse/integers/i16/min_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: i16 = -32769; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/mod.rs b/tests/pass/parse/integers/i16/mod.rs new file mode 100644 index 0000000000..49b45f5b3e --- /dev/null +++ b/tests/pass/parse/integers/i16/mod.rs @@ -0,0 +1,133 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{ + assert_satisfied, + expect_asg_error, + expect_compiler_error, + generate_main_input, + integers::{expect_computation_error, IntegerTester}, + parse_program, +}; +use leo_ast::InputValue; +use leo_input::types::{I16Type, IntegerType, SignedIntegerType}; + +test_int!( + TestI16, + i16, + IntegerType::Signed(SignedIntegerType::I16Type(I16Type {})), + Int16 +); + +#[test] +fn test_i16_min() { + TestI16::test_min(); +} + +#[test] +fn test_i16_min_fail() { + TestI16::test_min_fail(); +} + +#[test] +fn test_i16_max() { + TestI16::test_max(); +} + +#[test] +fn test_i16_max_fail() { + TestI16::test_max_fail(); +} + +#[test] +fn test_i16_neg() { + TestI16::test_negate(); +} + +#[test] +fn test_i16_neg_max_fail() { + TestI16::test_negate_min_fail(); +} + +#[test] +fn test_i16_neg_zero() { + TestI16::test_negate_zero(); +} + +#[test] +fn test_i16_add() { + TestI16::test_add(); +} + +#[test] +fn test_i16_sub() { + TestI16::test_sub(); +} + +#[test] +fn test_i16_mul() { + TestI16::test_mul(); +} + +#[test] +fn test_i16_div() { + TestI16::test_div(); +} + +#[test] +fn test_i16_pow() { + TestI16::test_pow(); +} + +#[test] +fn test_i16_eq() { + TestI16::test_eq(); +} + +#[test] +fn test_i16_ne() { + TestI16::test_ne(); +} + +#[test] +fn test_i16_ge() { + TestI16::test_ge(); +} + +#[test] +fn test_i16_gt() { + TestI16::test_gt(); +} + +#[test] +fn test_i16_le() { + TestI16::test_le(); +} + +#[test] +fn test_i16_lt() { + TestI16::test_lt(); +} + +#[test] +fn test_i16_console_assert() { + TestI16::test_console_assert(); +} + +#[test] +fn test_i16_ternary() { + TestI16::test_ternary(); +} diff --git a/tests/pass/parse/integers/i16/mul.leo b/tests/pass/parse/integers/i16/mul.leo new file mode 100644 index 0000000000..6fd19b703a --- /dev/null +++ b/tests/pass/parse/integers/i16/mul.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: i16) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/ne.leo b/tests/pass/parse/integers/i16/ne.leo new file mode 100644 index 0000000000..f0a9472678 --- /dev/null +++ b/tests/pass/parse/integers/i16/ne.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: bool) { + console.assert(a != b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/negate.leo b/tests/pass/parse/integers/i16/negate.leo new file mode 100644 index 0000000000..1d2644dce7 --- /dev/null +++ b/tests/pass/parse/integers/i16/negate.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16) { + console.assert(-a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/negate_min.leo b/tests/pass/parse/integers/i16/negate_min.leo new file mode 100644 index 0000000000..2622f8d2a3 --- /dev/null +++ b/tests/pass/parse/integers/i16/negate_min.leo @@ -0,0 +1,4 @@ +function main() { + let a = -32768i16; + let b = -a; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/negate_zero.leo b/tests/pass/parse/integers/i16/negate_zero.leo new file mode 100644 index 0000000000..46340c3dc5 --- /dev/null +++ b/tests/pass/parse/integers/i16/negate_zero.leo @@ -0,0 +1,5 @@ +function main() { + let a = 0i16; + + console.assert(-a == 0i16); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/pow.leo b/tests/pass/parse/integers/i16/pow.leo new file mode 100644 index 0000000000..769d2d2fbb --- /dev/null +++ b/tests/pass/parse/integers/i16/pow.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: i16) { + console.assert(a ** b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/sub.leo b/tests/pass/parse/integers/i16/sub.leo new file mode 100644 index 0000000000..e935935187 --- /dev/null +++ b/tests/pass/parse/integers/i16/sub.leo @@ -0,0 +1,3 @@ +function main(a: i16, b: i16, c: i16) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i16/ternary.leo b/tests/pass/parse/integers/i16/ternary.leo new file mode 100644 index 0000000000..4586b87bb4 --- /dev/null +++ b/tests/pass/parse/integers/i16/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: i16, b: i16, c: i16) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/add.leo b/tests/pass/parse/integers/i32/add.leo new file mode 100644 index 0000000000..3d8fb1b1d2 --- /dev/null +++ b/tests/pass/parse/integers/i32/add.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: i32) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/console_assert.leo b/tests/pass/parse/integers/i32/console_assert.leo new file mode 100644 index 0000000000..a2d6980e9a --- /dev/null +++ b/tests/pass/parse/integers/i32/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/div.leo b/tests/pass/parse/integers/i32/div.leo new file mode 100644 index 0000000000..3189a354f0 --- /dev/null +++ b/tests/pass/parse/integers/i32/div.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: i32) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/eq.leo b/tests/pass/parse/integers/i32/eq.leo new file mode 100644 index 0000000000..bac7af0be0 --- /dev/null +++ b/tests/pass/parse/integers/i32/eq.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/ge.leo b/tests/pass/parse/integers/i32/ge.leo new file mode 100644 index 0000000000..362521fc82 --- /dev/null +++ b/tests/pass/parse/integers/i32/ge.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: bool) { + console.assert(a >= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/gt.leo b/tests/pass/parse/integers/i32/gt.leo new file mode 100644 index 0000000000..63ddcaa85c --- /dev/null +++ b/tests/pass/parse/integers/i32/gt.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: bool) { + console.assert(a > b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/input.leo b/tests/pass/parse/integers/i32/input.leo new file mode 100644 index 0000000000..a2d6980e9a --- /dev/null +++ b/tests/pass/parse/integers/i32/input.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/le.leo b/tests/pass/parse/integers/i32/le.leo new file mode 100644 index 0000000000..948c66b1fc --- /dev/null +++ b/tests/pass/parse/integers/i32/le.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: bool) { + console.assert(a <= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/lt.leo b/tests/pass/parse/integers/i32/lt.leo new file mode 100644 index 0000000000..72a8fb0d53 --- /dev/null +++ b/tests/pass/parse/integers/i32/lt.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: bool) { + console.assert(a < b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/max.leo b/tests/pass/parse/integers/i32/max.leo new file mode 100644 index 0000000000..a9c707eb7f --- /dev/null +++ b/tests/pass/parse/integers/i32/max.leo @@ -0,0 +1,3 @@ +function main() { + let a: i32 = 2147483647; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/max_fail.leo b/tests/pass/parse/integers/i32/max_fail.leo new file mode 100644 index 0000000000..f3fd81815f --- /dev/null +++ b/tests/pass/parse/integers/i32/max_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: i32 = 2147483648; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/min.leo b/tests/pass/parse/integers/i32/min.leo new file mode 100644 index 0000000000..a29d591029 --- /dev/null +++ b/tests/pass/parse/integers/i32/min.leo @@ -0,0 +1,3 @@ +function main() { + let a: i32 = -2147483648; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/min_fail.leo b/tests/pass/parse/integers/i32/min_fail.leo new file mode 100644 index 0000000000..1462d207e9 --- /dev/null +++ b/tests/pass/parse/integers/i32/min_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: i32 = -2147483649; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/mod.rs b/tests/pass/parse/integers/i32/mod.rs new file mode 100644 index 0000000000..ee9e25701a --- /dev/null +++ b/tests/pass/parse/integers/i32/mod.rs @@ -0,0 +1,133 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{ + assert_satisfied, + expect_asg_error, + expect_compiler_error, + generate_main_input, + integers::{expect_computation_error, IntegerTester}, + parse_program, +}; +use leo_ast::InputValue; +use leo_input::types::{I32Type, IntegerType, SignedIntegerType}; + +test_int!( + TestI32, + i32, + IntegerType::Signed(SignedIntegerType::I32Type(I32Type {})), + Int32 +); + +#[test] +fn test_i32_min() { + TestI32::test_min(); +} + +#[test] +fn test_i32_min_fail() { + TestI32::test_min_fail(); +} + +#[test] +fn test_i32_max() { + TestI32::test_max(); +} + +#[test] +fn test_i32_max_fail() { + TestI32::test_max_fail(); +} + +#[test] +fn test_i32_neg() { + TestI32::test_negate(); +} + +#[test] +fn test_i32_neg_max_fail() { + TestI32::test_negate_min_fail(); +} + +#[test] +fn test_i32_neg_zero() { + TestI32::test_negate_zero(); +} + +#[test] +fn test_i32_add() { + TestI32::test_add(); +} + +#[test] +fn test_i32_sub() { + TestI32::test_sub(); +} + +#[test] +fn test_i32_mul() { + TestI32::test_mul(); +} + +#[test] +fn test_i32_div() { + TestI32::test_div(); +} + +#[test] +fn test_i32_pow() { + TestI32::test_pow(); +} + +#[test] +fn test_i32_eq() { + TestI32::test_eq(); +} + +#[test] +fn test_i32_ne() { + TestI32::test_ne(); +} + +#[test] +fn test_i32_ge() { + TestI32::test_ge(); +} + +#[test] +fn test_i32_gt() { + TestI32::test_gt(); +} + +#[test] +fn test_i32_le() { + TestI32::test_le(); +} + +#[test] +fn test_i32_lt() { + TestI32::test_lt(); +} + +#[test] +fn test_i32_console_assert() { + TestI32::test_console_assert(); +} + +#[test] +fn test_i32_ternary() { + TestI32::test_ternary(); +} diff --git a/tests/pass/parse/integers/i32/mul.leo b/tests/pass/parse/integers/i32/mul.leo new file mode 100644 index 0000000000..50ba5b4128 --- /dev/null +++ b/tests/pass/parse/integers/i32/mul.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: i32) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/ne.leo b/tests/pass/parse/integers/i32/ne.leo new file mode 100644 index 0000000000..dcc1a185d1 --- /dev/null +++ b/tests/pass/parse/integers/i32/ne.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: bool) { + console.assert(a != b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/negate.leo b/tests/pass/parse/integers/i32/negate.leo new file mode 100644 index 0000000000..eef94c934f --- /dev/null +++ b/tests/pass/parse/integers/i32/negate.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32) { + console.assert(-a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/negate_min.leo b/tests/pass/parse/integers/i32/negate_min.leo new file mode 100644 index 0000000000..b3c10064e1 --- /dev/null +++ b/tests/pass/parse/integers/i32/negate_min.leo @@ -0,0 +1,4 @@ +function main() { + let a = -2147483648i32; + let b = -a; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/negate_zero.leo b/tests/pass/parse/integers/i32/negate_zero.leo new file mode 100644 index 0000000000..5533f575a6 --- /dev/null +++ b/tests/pass/parse/integers/i32/negate_zero.leo @@ -0,0 +1,5 @@ +function main() { + let a = 0i32; + + console.assert(-a == 0i32); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/pow.leo b/tests/pass/parse/integers/i32/pow.leo new file mode 100644 index 0000000000..ebb131e30b --- /dev/null +++ b/tests/pass/parse/integers/i32/pow.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: i32) { + console.assert(a ** b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/sub.leo b/tests/pass/parse/integers/i32/sub.leo new file mode 100644 index 0000000000..1f054a5ddf --- /dev/null +++ b/tests/pass/parse/integers/i32/sub.leo @@ -0,0 +1,3 @@ +function main(a: i32, b: i32, c: i32) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i32/ternary.leo b/tests/pass/parse/integers/i32/ternary.leo new file mode 100644 index 0000000000..7927c2998b --- /dev/null +++ b/tests/pass/parse/integers/i32/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: i32, b: i32, c: i32) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/add.leo b/tests/pass/parse/integers/i64/add.leo new file mode 100644 index 0000000000..aefdbb178f --- /dev/null +++ b/tests/pass/parse/integers/i64/add.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: i64) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/console_assert.leo b/tests/pass/parse/integers/i64/console_assert.leo new file mode 100644 index 0000000000..ab9a5d6e91 --- /dev/null +++ b/tests/pass/parse/integers/i64/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/div.leo b/tests/pass/parse/integers/i64/div.leo new file mode 100644 index 0000000000..142e4ab801 --- /dev/null +++ b/tests/pass/parse/integers/i64/div.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: i64) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/eq.leo b/tests/pass/parse/integers/i64/eq.leo new file mode 100644 index 0000000000..86a234c834 --- /dev/null +++ b/tests/pass/parse/integers/i64/eq.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/ge.leo b/tests/pass/parse/integers/i64/ge.leo new file mode 100644 index 0000000000..e7b453c5dc --- /dev/null +++ b/tests/pass/parse/integers/i64/ge.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: bool) { + console.assert(a >= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/gt.leo b/tests/pass/parse/integers/i64/gt.leo new file mode 100644 index 0000000000..9709bad012 --- /dev/null +++ b/tests/pass/parse/integers/i64/gt.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: bool) { + console.assert(a > b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/input.leo b/tests/pass/parse/integers/i64/input.leo new file mode 100644 index 0000000000..ab9a5d6e91 --- /dev/null +++ b/tests/pass/parse/integers/i64/input.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/le.leo b/tests/pass/parse/integers/i64/le.leo new file mode 100644 index 0000000000..3e2cfcb711 --- /dev/null +++ b/tests/pass/parse/integers/i64/le.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: bool) { + console.assert(a <= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/lt.leo b/tests/pass/parse/integers/i64/lt.leo new file mode 100644 index 0000000000..ef4e38eb76 --- /dev/null +++ b/tests/pass/parse/integers/i64/lt.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: bool) { + console.assert(a < b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/max.leo b/tests/pass/parse/integers/i64/max.leo new file mode 100644 index 0000000000..e0d19881e6 --- /dev/null +++ b/tests/pass/parse/integers/i64/max.leo @@ -0,0 +1,3 @@ +function main() { + let a: i64 = 9223372036854775807; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/max_fail.leo b/tests/pass/parse/integers/i64/max_fail.leo new file mode 100644 index 0000000000..3e6603e4be --- /dev/null +++ b/tests/pass/parse/integers/i64/max_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: i64 = 9223372036854775808; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/min.leo b/tests/pass/parse/integers/i64/min.leo new file mode 100644 index 0000000000..d7e99a87f8 --- /dev/null +++ b/tests/pass/parse/integers/i64/min.leo @@ -0,0 +1,3 @@ +function main() { + let a: i64 = -9223372036854775808; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/min_fail.leo b/tests/pass/parse/integers/i64/min_fail.leo new file mode 100644 index 0000000000..11e43646b0 --- /dev/null +++ b/tests/pass/parse/integers/i64/min_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: i64 = -9223372036854775809; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/mod.rs b/tests/pass/parse/integers/i64/mod.rs new file mode 100644 index 0000000000..066ac9956f --- /dev/null +++ b/tests/pass/parse/integers/i64/mod.rs @@ -0,0 +1,134 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{ + assert_satisfied, + expect_asg_error, + expect_compiler_error, + generate_main_input, + integers::{expect_computation_error, IntegerTester}, + parse_program, +}; +use leo_ast::InputValue; +use leo_input::types::{I64Type, IntegerType, SignedIntegerType}; + +test_int!( + TestI64, + i64, + IntegerType::Signed(SignedIntegerType::I64Type(I64Type {})), + Int64 +); + +#[test] +fn test_i64_min() { + TestI64::test_min(); +} + +#[test] +fn test_i64_min_fail() { + TestI64::test_min_fail(); +} + +#[test] +fn test_i64_max() { + TestI64::test_max(); +} + +#[test] +fn test_i64_max_fail() { + TestI64::test_max_fail(); +} + +#[test] +fn test_i64_neg() { + TestI64::test_negate(); +} + +#[test] +fn test_i64_neg_max_fail() { + TestI64::test_negate_min_fail(); +} + +#[test] +fn test_i64_neg_zero() { + TestI64::test_negate_zero(); +} + +#[test] +fn test_i64_add() { + TestI64::test_add(); +} + +#[test] +fn test_i64_sub() { + TestI64::test_sub(); +} + +#[test] +fn test_i64_mul() { + TestI64::test_mul(); +} + +#[test] +#[ignore] // takes 2 minutes +fn test_i64_div() { + TestI64::test_div(); +} + +#[test] +fn test_i64_pow() { + TestI64::test_pow(); +} + +#[test] +fn test_i64_eq() { + TestI64::test_eq(); +} + +#[test] +fn test_i64_ne() { + TestI64::test_ne(); +} + +#[test] +fn test_i64_ge() { + TestI64::test_ge(); +} + +#[test] +fn test_i64_gt() { + TestI64::test_gt(); +} + +#[test] +fn test_i64_le() { + TestI64::test_le(); +} + +#[test] +fn test_i64_lt() { + TestI64::test_lt(); +} + +#[test] +fn test_i64_console_assert() { + TestI64::test_console_assert(); +} + +#[test] +fn test_i64_ternary() { + TestI64::test_ternary(); +} diff --git a/tests/pass/parse/integers/i64/mul.leo b/tests/pass/parse/integers/i64/mul.leo new file mode 100644 index 0000000000..a3b8bd1da5 --- /dev/null +++ b/tests/pass/parse/integers/i64/mul.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: i64) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/ne.leo b/tests/pass/parse/integers/i64/ne.leo new file mode 100644 index 0000000000..a2642bb479 --- /dev/null +++ b/tests/pass/parse/integers/i64/ne.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: bool) { + console.assert(a != b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/negate.leo b/tests/pass/parse/integers/i64/negate.leo new file mode 100644 index 0000000000..fe0cdc4d97 --- /dev/null +++ b/tests/pass/parse/integers/i64/negate.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64) { + console.assert(-a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/negate_min.leo b/tests/pass/parse/integers/i64/negate_min.leo new file mode 100644 index 0000000000..4dd27778d0 --- /dev/null +++ b/tests/pass/parse/integers/i64/negate_min.leo @@ -0,0 +1,4 @@ +function main() { + let a: i64 = -9223372036854775808; + let b = -a; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/negate_zero.leo b/tests/pass/parse/integers/i64/negate_zero.leo new file mode 100644 index 0000000000..6badfe4dc7 --- /dev/null +++ b/tests/pass/parse/integers/i64/negate_zero.leo @@ -0,0 +1,5 @@ +function main() { + let a = 0i64; + + console.assert(-a == 0i64); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/pow.leo b/tests/pass/parse/integers/i64/pow.leo new file mode 100644 index 0000000000..dca2dace74 --- /dev/null +++ b/tests/pass/parse/integers/i64/pow.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: i64) { + console.assert(a ** b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/sub.leo b/tests/pass/parse/integers/i64/sub.leo new file mode 100644 index 0000000000..4d335e504b --- /dev/null +++ b/tests/pass/parse/integers/i64/sub.leo @@ -0,0 +1,3 @@ +function main(a: i64, b: i64, c: i64) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i64/ternary.leo b/tests/pass/parse/integers/i64/ternary.leo new file mode 100644 index 0000000000..1a2d03a77f --- /dev/null +++ b/tests/pass/parse/integers/i64/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: i64, b: i64, c: i64) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/add.leo b/tests/pass/parse/integers/i8/add.leo new file mode 100644 index 0000000000..dd71bc7f53 --- /dev/null +++ b/tests/pass/parse/integers/i8/add.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: i8) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/console_assert.leo b/tests/pass/parse/integers/i8/console_assert.leo new file mode 100644 index 0000000000..1fc09cb57d --- /dev/null +++ b/tests/pass/parse/integers/i8/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/div.leo b/tests/pass/parse/integers/i8/div.leo new file mode 100644 index 0000000000..a80d8e6319 --- /dev/null +++ b/tests/pass/parse/integers/i8/div.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: i8) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/eq.leo b/tests/pass/parse/integers/i8/eq.leo new file mode 100644 index 0000000000..130cc64b89 --- /dev/null +++ b/tests/pass/parse/integers/i8/eq.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/ge.leo b/tests/pass/parse/integers/i8/ge.leo new file mode 100644 index 0000000000..3084692c0c --- /dev/null +++ b/tests/pass/parse/integers/i8/ge.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: bool) { + console.assert(a >= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/gt.leo b/tests/pass/parse/integers/i8/gt.leo new file mode 100644 index 0000000000..d3913b8b24 --- /dev/null +++ b/tests/pass/parse/integers/i8/gt.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: bool) { + console.assert(a > b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/input.leo b/tests/pass/parse/integers/i8/input.leo new file mode 100644 index 0000000000..1fc09cb57d --- /dev/null +++ b/tests/pass/parse/integers/i8/input.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/le.leo b/tests/pass/parse/integers/i8/le.leo new file mode 100644 index 0000000000..92e011f206 --- /dev/null +++ b/tests/pass/parse/integers/i8/le.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: bool) { + console.assert(a <= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/lt.leo b/tests/pass/parse/integers/i8/lt.leo new file mode 100644 index 0000000000..eb34b7148e --- /dev/null +++ b/tests/pass/parse/integers/i8/lt.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: bool) { + console.assert(a < b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/max.leo b/tests/pass/parse/integers/i8/max.leo new file mode 100644 index 0000000000..b51126da59 --- /dev/null +++ b/tests/pass/parse/integers/i8/max.leo @@ -0,0 +1,3 @@ +function main() { + let a: i8 = 127; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/max_fail.leo b/tests/pass/parse/integers/i8/max_fail.leo new file mode 100644 index 0000000000..4892505915 --- /dev/null +++ b/tests/pass/parse/integers/i8/max_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: i8 = 128; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/min.leo b/tests/pass/parse/integers/i8/min.leo new file mode 100644 index 0000000000..d3c1bff5e4 --- /dev/null +++ b/tests/pass/parse/integers/i8/min.leo @@ -0,0 +1,3 @@ +function main() { + let a: i8 = -128; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/min_fail.leo b/tests/pass/parse/integers/i8/min_fail.leo new file mode 100644 index 0000000000..051468ea70 --- /dev/null +++ b/tests/pass/parse/integers/i8/min_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: i8 = -129; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/mod.rs b/tests/pass/parse/integers/i8/mod.rs new file mode 100644 index 0000000000..9133a72248 --- /dev/null +++ b/tests/pass/parse/integers/i8/mod.rs @@ -0,0 +1,133 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{ + assert_satisfied, + expect_asg_error, + expect_compiler_error, + generate_main_input, + integers::{expect_computation_error, IntegerTester}, + parse_program, +}; +use leo_ast::InputValue; +use leo_input::types::{I8Type, IntegerType, SignedIntegerType}; + +test_int!( + TestI8, + i8, + IntegerType::Signed(SignedIntegerType::I8Type(I8Type {})), + Int8 +); + +#[test] +fn test_i8_min() { + TestI8::test_min(); +} + +#[test] +fn test_i8_min_fail() { + TestI8::test_min_fail(); +} + +#[test] +fn test_i8_max() { + TestI8::test_max(); +} + +#[test] +fn test_i8_max_fail() { + TestI8::test_max_fail(); +} + +#[test] +fn test_i8_neg() { + TestI8::test_negate(); +} + +#[test] +fn test_i8_neg_max_fail() { + TestI8::test_negate_min_fail(); +} + +#[test] +fn test_i8_neg_zero() { + TestI8::test_negate_zero(); +} + +#[test] +fn test_i8_add() { + TestI8::test_add(); +} + +#[test] +fn test_i8_sub() { + TestI8::test_sub(); +} + +#[test] +fn test_i8_mul() { + TestI8::test_mul(); +} + +#[test] +fn test_i8_div() { + TestI8::test_div(); +} + +#[test] +fn test_i8_pow() { + TestI8::test_pow(); +} + +#[test] +fn test_i8_eq() { + TestI8::test_eq(); +} + +#[test] +fn test_i8_ne() { + TestI8::test_ne(); +} + +#[test] +fn test_i8_ge() { + TestI8::test_ge(); +} + +#[test] +fn test_i8_gt() { + TestI8::test_gt(); +} + +#[test] +fn test_i8_le() { + TestI8::test_le(); +} + +#[test] +fn test_i8_lt() { + TestI8::test_lt(); +} + +#[test] +fn test_i8_console_assert() { + TestI8::test_console_assert(); +} + +#[test] +fn test_i8_ternary() { + TestI8::test_ternary(); +} diff --git a/tests/pass/parse/integers/i8/mul.leo b/tests/pass/parse/integers/i8/mul.leo new file mode 100644 index 0000000000..34726fff92 --- /dev/null +++ b/tests/pass/parse/integers/i8/mul.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: i8) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/ne.leo b/tests/pass/parse/integers/i8/ne.leo new file mode 100644 index 0000000000..e5028d404a --- /dev/null +++ b/tests/pass/parse/integers/i8/ne.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: bool) { + console.assert(a != b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/negate.leo b/tests/pass/parse/integers/i8/negate.leo new file mode 100644 index 0000000000..2a2266bc56 --- /dev/null +++ b/tests/pass/parse/integers/i8/negate.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8) { + console.assert(-a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/negate_min.leo b/tests/pass/parse/integers/i8/negate_min.leo new file mode 100644 index 0000000000..3959da615e --- /dev/null +++ b/tests/pass/parse/integers/i8/negate_min.leo @@ -0,0 +1,4 @@ +function main() { + let a = -128i8; + let b = -a; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/negate_zero.leo b/tests/pass/parse/integers/i8/negate_zero.leo new file mode 100644 index 0000000000..21fbbab675 --- /dev/null +++ b/tests/pass/parse/integers/i8/negate_zero.leo @@ -0,0 +1,5 @@ +function main() { + let a = 0i8; + + console.assert(-a == 0i8); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/pow.leo b/tests/pass/parse/integers/i8/pow.leo new file mode 100644 index 0000000000..18aeb44b46 --- /dev/null +++ b/tests/pass/parse/integers/i8/pow.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: i8) { + console.assert(a ** b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/sub.leo b/tests/pass/parse/integers/i8/sub.leo new file mode 100644 index 0000000000..a795bed153 --- /dev/null +++ b/tests/pass/parse/integers/i8/sub.leo @@ -0,0 +1,3 @@ +function main(a: i8, b: i8, c: i8) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/i8/ternary.leo b/tests/pass/parse/integers/i8/ternary.leo new file mode 100644 index 0000000000..e1ec1943c9 --- /dev/null +++ b/tests/pass/parse/integers/i8/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: i8, b: i8, c: i8) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/add.leo b/tests/pass/parse/integers/u128/add.leo new file mode 100644 index 0000000000..6b32042fd5 --- /dev/null +++ b/tests/pass/parse/integers/u128/add.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: u128) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/console_assert.leo b/tests/pass/parse/integers/u128/console_assert.leo new file mode 100644 index 0000000000..adab295385 --- /dev/null +++ b/tests/pass/parse/integers/u128/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/div.leo b/tests/pass/parse/integers/u128/div.leo new file mode 100644 index 0000000000..0d62054eca --- /dev/null +++ b/tests/pass/parse/integers/u128/div.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: u128) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/eq.leo b/tests/pass/parse/integers/u128/eq.leo new file mode 100644 index 0000000000..2c2acd923a --- /dev/null +++ b/tests/pass/parse/integers/u128/eq.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/ge.leo b/tests/pass/parse/integers/u128/ge.leo new file mode 100644 index 0000000000..bff7cd321b --- /dev/null +++ b/tests/pass/parse/integers/u128/ge.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: bool) { + console.assert(a >= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/gt.leo b/tests/pass/parse/integers/u128/gt.leo new file mode 100644 index 0000000000..e8aec0faf2 --- /dev/null +++ b/tests/pass/parse/integers/u128/gt.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: bool) { + console.assert(a > b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/input.leo b/tests/pass/parse/integers/u128/input.leo new file mode 100644 index 0000000000..adab295385 --- /dev/null +++ b/tests/pass/parse/integers/u128/input.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/le.leo b/tests/pass/parse/integers/u128/le.leo new file mode 100644 index 0000000000..c9e4609136 --- /dev/null +++ b/tests/pass/parse/integers/u128/le.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: bool) { + console.assert(a <= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/lt.leo b/tests/pass/parse/integers/u128/lt.leo new file mode 100644 index 0000000000..b37057c895 --- /dev/null +++ b/tests/pass/parse/integers/u128/lt.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: bool) { + console.assert(a < b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/max.leo b/tests/pass/parse/integers/u128/max.leo new file mode 100644 index 0000000000..6da59dd058 --- /dev/null +++ b/tests/pass/parse/integers/u128/max.leo @@ -0,0 +1,3 @@ +function main() { + let a: u128 = 340282366920938463463374607431768211455; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/max_fail.leo b/tests/pass/parse/integers/u128/max_fail.leo new file mode 100644 index 0000000000..40cdf7d2bb --- /dev/null +++ b/tests/pass/parse/integers/u128/max_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: u128 = 340282366920938463463374607431768211456; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/min.leo b/tests/pass/parse/integers/u128/min.leo new file mode 100644 index 0000000000..044bda9e1c --- /dev/null +++ b/tests/pass/parse/integers/u128/min.leo @@ -0,0 +1,3 @@ +function main() { + let a: u128 = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/min_fail.leo b/tests/pass/parse/integers/u128/min_fail.leo new file mode 100644 index 0000000000..df2390c576 --- /dev/null +++ b/tests/pass/parse/integers/u128/min_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: u128 = -1; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/mod.rs b/tests/pass/parse/integers/u128/mod.rs new file mode 100644 index 0000000000..2c110af0a5 --- /dev/null +++ b/tests/pass/parse/integers/u128/mod.rs @@ -0,0 +1,118 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{ + assert_satisfied, + expect_asg_error, + expect_compiler_error, + generate_main_input, + integers::IntegerTester, + parse_program, +}; +use leo_ast::InputValue; +use leo_input::types::{IntegerType, U128Type, UnsignedIntegerType}; + +test_uint!( + TestU128, + u128, + IntegerType::Unsigned(UnsignedIntegerType::U128Type(U128Type {})), + UInt128 +); + +#[test] +fn test_u128_min() { + TestU128::test_min(); +} + +#[test] +fn test_u128_min_fail() { + TestU128::test_min_fail(); +} + +#[test] +fn test_u128_max() { + TestU128::test_max(); +} + +#[test] +fn test_u128_max_fail() { + TestU128::test_max_fail(); +} + +#[test] +fn test_u128_add() { + TestU128::test_add(); +} + +#[test] +fn test_u128_sub() { + TestU128::test_sub(); +} + +#[test] +fn test_u128_mul() { + TestU128::test_mul(); +} + +#[test] +fn test_u128_div() { + TestU128::test_div(); +} + +#[test] +fn test_u128_pow() { + TestU128::test_pow(); +} + +#[test] +fn test_u128_eq() { + TestU128::test_eq(); +} + +#[test] +fn test_u128_ne() { + TestU128::test_ne(); +} + +#[test] +fn test_u128_ge() { + TestU128::test_ge(); +} + +#[test] +fn test_u128_gt() { + TestU128::test_gt(); +} + +#[test] +fn test_u128_le() { + TestU128::test_le(); +} + +#[test] +fn test_u128_lt() { + TestU128::test_lt(); +} + +#[test] +fn test_u128_console_assert() { + TestU128::test_console_assert(); +} + +#[test] +fn test_u128_ternary() { + TestU128::test_ternary(); +} diff --git a/tests/pass/parse/integers/u128/mul.leo b/tests/pass/parse/integers/u128/mul.leo new file mode 100644 index 0000000000..c7fdc1530c --- /dev/null +++ b/tests/pass/parse/integers/u128/mul.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: u128) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/ne.leo b/tests/pass/parse/integers/u128/ne.leo new file mode 100644 index 0000000000..da3467d01e --- /dev/null +++ b/tests/pass/parse/integers/u128/ne.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: bool) { + console.assert(a != b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/pow.leo b/tests/pass/parse/integers/u128/pow.leo new file mode 100644 index 0000000000..27614bfa56 --- /dev/null +++ b/tests/pass/parse/integers/u128/pow.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: u128) { + console.assert(a ** b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/sub.leo b/tests/pass/parse/integers/u128/sub.leo new file mode 100644 index 0000000000..2374413505 --- /dev/null +++ b/tests/pass/parse/integers/u128/sub.leo @@ -0,0 +1,3 @@ +function main(a: u128, b: u128, c: u128) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u128/ternary.leo b/tests/pass/parse/integers/u128/ternary.leo new file mode 100644 index 0000000000..22e2e67058 --- /dev/null +++ b/tests/pass/parse/integers/u128/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: u128, b: u128, c: u128) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/add.leo b/tests/pass/parse/integers/u16/add.leo new file mode 100644 index 0000000000..f00701181b --- /dev/null +++ b/tests/pass/parse/integers/u16/add.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: u16) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/console_assert.leo b/tests/pass/parse/integers/u16/console_assert.leo new file mode 100644 index 0000000000..761f0639d0 --- /dev/null +++ b/tests/pass/parse/integers/u16/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/div.leo b/tests/pass/parse/integers/u16/div.leo new file mode 100644 index 0000000000..f1dd3fa463 --- /dev/null +++ b/tests/pass/parse/integers/u16/div.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: u16) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/eq.leo b/tests/pass/parse/integers/u16/eq.leo new file mode 100644 index 0000000000..a4b4e78b49 --- /dev/null +++ b/tests/pass/parse/integers/u16/eq.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/ge.leo b/tests/pass/parse/integers/u16/ge.leo new file mode 100644 index 0000000000..4b1da1b27b --- /dev/null +++ b/tests/pass/parse/integers/u16/ge.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: bool) { + console.assert(a >= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/gt.leo b/tests/pass/parse/integers/u16/gt.leo new file mode 100644 index 0000000000..2c5ffbe8eb --- /dev/null +++ b/tests/pass/parse/integers/u16/gt.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: bool) { + console.assert(a > b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/input.leo b/tests/pass/parse/integers/u16/input.leo new file mode 100644 index 0000000000..761f0639d0 --- /dev/null +++ b/tests/pass/parse/integers/u16/input.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/le.leo b/tests/pass/parse/integers/u16/le.leo new file mode 100644 index 0000000000..49713482d0 --- /dev/null +++ b/tests/pass/parse/integers/u16/le.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: bool) { + console.assert(a <= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/lt.leo b/tests/pass/parse/integers/u16/lt.leo new file mode 100644 index 0000000000..dae1951231 --- /dev/null +++ b/tests/pass/parse/integers/u16/lt.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: bool) { + console.assert(a < b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/max.leo b/tests/pass/parse/integers/u16/max.leo new file mode 100644 index 0000000000..a707df9af8 --- /dev/null +++ b/tests/pass/parse/integers/u16/max.leo @@ -0,0 +1,3 @@ +function main() { + let a: u16 = 65535; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/max_fail.leo b/tests/pass/parse/integers/u16/max_fail.leo new file mode 100644 index 0000000000..68ff0481e0 --- /dev/null +++ b/tests/pass/parse/integers/u16/max_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: u16 = 65536; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/min.leo b/tests/pass/parse/integers/u16/min.leo new file mode 100644 index 0000000000..ab1bd7db48 --- /dev/null +++ b/tests/pass/parse/integers/u16/min.leo @@ -0,0 +1,3 @@ +function main() { + let a: u16 = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/min_fail.leo b/tests/pass/parse/integers/u16/min_fail.leo new file mode 100644 index 0000000000..99b7310362 --- /dev/null +++ b/tests/pass/parse/integers/u16/min_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: u16 = -1; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/mod.rs b/tests/pass/parse/integers/u16/mod.rs new file mode 100644 index 0000000000..b4b202b9da --- /dev/null +++ b/tests/pass/parse/integers/u16/mod.rs @@ -0,0 +1,118 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{ + assert_satisfied, + expect_asg_error, + expect_compiler_error, + generate_main_input, + integers::IntegerTester, + parse_program, +}; +use leo_ast::InputValue; +use leo_input::types::{IntegerType, U16Type, UnsignedIntegerType}; + +test_uint!( + TestU16, + u16, + IntegerType::Unsigned(UnsignedIntegerType::U16Type(U16Type {})), + UInt16 +); + +#[test] +fn test_u16_min() { + TestU16::test_min(); +} + +#[test] +fn test_u16_min_fail() { + TestU16::test_min_fail(); +} + +#[test] +fn test_u16_max() { + TestU16::test_max(); +} + +#[test] +fn test_u16_max_fail() { + TestU16::test_max_fail(); +} + +#[test] +fn test_u16_add() { + TestU16::test_add(); +} + +#[test] +fn test_u16_sub() { + TestU16::test_sub(); +} + +#[test] +fn test_u16_mul() { + TestU16::test_mul(); +} + +#[test] +fn test_u16_div() { + TestU16::test_div(); +} + +#[test] +fn test_u16_pow() { + TestU16::test_pow(); +} + +#[test] +fn test_u16_eq() { + TestU16::test_eq(); +} + +#[test] +fn test_u16_ne() { + TestU16::test_ne(); +} + +#[test] +fn test_u16_ge() { + TestU16::test_ge(); +} + +#[test] +fn test_u16_gt() { + TestU16::test_gt(); +} + +#[test] +fn test_u16_le() { + TestU16::test_le(); +} + +#[test] +fn test_u16_lt() { + TestU16::test_lt(); +} + +#[test] +fn test_u16_console_assert() { + TestU16::test_console_assert(); +} + +#[test] +fn test_u16_ternary() { + TestU16::test_ternary(); +} diff --git a/tests/pass/parse/integers/u16/mul.leo b/tests/pass/parse/integers/u16/mul.leo new file mode 100644 index 0000000000..f2c6f0aac8 --- /dev/null +++ b/tests/pass/parse/integers/u16/mul.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: u16) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/ne.leo b/tests/pass/parse/integers/u16/ne.leo new file mode 100644 index 0000000000..e90a304cfe --- /dev/null +++ b/tests/pass/parse/integers/u16/ne.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: bool) { + console.assert(a != b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/pow.leo b/tests/pass/parse/integers/u16/pow.leo new file mode 100644 index 0000000000..564c1c51fe --- /dev/null +++ b/tests/pass/parse/integers/u16/pow.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: u16) { + console.assert(a ** b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/sub.leo b/tests/pass/parse/integers/u16/sub.leo new file mode 100644 index 0000000000..92aae9ac2c --- /dev/null +++ b/tests/pass/parse/integers/u16/sub.leo @@ -0,0 +1,3 @@ +function main(a: u16, b: u16, c: u16) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u16/ternary.leo b/tests/pass/parse/integers/u16/ternary.leo new file mode 100644 index 0000000000..11d836570d --- /dev/null +++ b/tests/pass/parse/integers/u16/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: u16, b: u16, c: u16) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/add.leo b/tests/pass/parse/integers/u32/add.leo new file mode 100644 index 0000000000..6f6a2454b4 --- /dev/null +++ b/tests/pass/parse/integers/u32/add.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: u32) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/console_assert.leo b/tests/pass/parse/integers/u32/console_assert.leo new file mode 100644 index 0000000000..32604eb3b8 --- /dev/null +++ b/tests/pass/parse/integers/u32/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/div.leo b/tests/pass/parse/integers/u32/div.leo new file mode 100644 index 0000000000..ed689bd408 --- /dev/null +++ b/tests/pass/parse/integers/u32/div.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: u32) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/eq.leo b/tests/pass/parse/integers/u32/eq.leo new file mode 100644 index 0000000000..ca427b3c42 --- /dev/null +++ b/tests/pass/parse/integers/u32/eq.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/ge.leo b/tests/pass/parse/integers/u32/ge.leo new file mode 100644 index 0000000000..35c1c71829 --- /dev/null +++ b/tests/pass/parse/integers/u32/ge.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: bool) { + console.assert(a >= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/gt.leo b/tests/pass/parse/integers/u32/gt.leo new file mode 100644 index 0000000000..f76df415c4 --- /dev/null +++ b/tests/pass/parse/integers/u32/gt.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: bool) { + console.assert(a > b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/input.leo b/tests/pass/parse/integers/u32/input.leo new file mode 100644 index 0000000000..32604eb3b8 --- /dev/null +++ b/tests/pass/parse/integers/u32/input.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/le.leo b/tests/pass/parse/integers/u32/le.leo new file mode 100644 index 0000000000..9a802f896d --- /dev/null +++ b/tests/pass/parse/integers/u32/le.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: bool) { + console.assert(a <= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/lt.leo b/tests/pass/parse/integers/u32/lt.leo new file mode 100644 index 0000000000..73e5654470 --- /dev/null +++ b/tests/pass/parse/integers/u32/lt.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: bool) { + console.assert(a < b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/max.leo b/tests/pass/parse/integers/u32/max.leo new file mode 100644 index 0000000000..2950164a08 --- /dev/null +++ b/tests/pass/parse/integers/u32/max.leo @@ -0,0 +1,3 @@ +function main() { + let a: u32 = 4294967295; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/max_fail.leo b/tests/pass/parse/integers/u32/max_fail.leo new file mode 100644 index 0000000000..96c7e01657 --- /dev/null +++ b/tests/pass/parse/integers/u32/max_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: u32 = 4294967296; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/min.leo b/tests/pass/parse/integers/u32/min.leo new file mode 100644 index 0000000000..0f1c080938 --- /dev/null +++ b/tests/pass/parse/integers/u32/min.leo @@ -0,0 +1,3 @@ +function main() { + let a: u32 = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/min_fail.leo b/tests/pass/parse/integers/u32/min_fail.leo new file mode 100644 index 0000000000..a8d41c475a --- /dev/null +++ b/tests/pass/parse/integers/u32/min_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: u32 = -1; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/mod.rs b/tests/pass/parse/integers/u32/mod.rs new file mode 100644 index 0000000000..920fc6ed5b --- /dev/null +++ b/tests/pass/parse/integers/u32/mod.rs @@ -0,0 +1,118 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{ + assert_satisfied, + expect_asg_error, + expect_compiler_error, + generate_main_input, + integers::IntegerTester, + parse_program, +}; +use leo_ast::InputValue; +use leo_input::types::{IntegerType, U32Type, UnsignedIntegerType}; + +test_uint!( + TestU32, + u32, + IntegerType::Unsigned(UnsignedIntegerType::U32Type(U32Type {})), + UInt32 +); + +#[test] +fn test_u32_min() { + TestU32::test_min(); +} + +#[test] +fn test_u32_min_fail() { + TestU32::test_min_fail(); +} + +#[test] +fn test_u32_max() { + TestU32::test_max(); +} + +#[test] +fn test_u32_max_fail() { + TestU32::test_max_fail(); +} + +#[test] +fn test_u32_add() { + TestU32::test_add(); +} + +#[test] +fn test_u32_sub() { + TestU32::test_sub(); +} + +#[test] +fn test_u32_mul() { + TestU32::test_mul(); +} + +#[test] +fn test_u32_div() { + TestU32::test_div(); +} + +#[test] +fn test_u32_pow() { + TestU32::test_pow(); +} + +#[test] +fn test_u32_eq() { + TestU32::test_eq(); +} + +#[test] +fn test_u32_ne() { + TestU32::test_ne(); +} + +#[test] +fn test_u32_ge() { + TestU32::test_ge(); +} + +#[test] +fn test_u32_gt() { + TestU32::test_gt(); +} + +#[test] +fn test_u32_le() { + TestU32::test_le(); +} + +#[test] +fn test_u32_lt() { + TestU32::test_lt(); +} + +#[test] +fn test_u32_console_assert() { + TestU32::test_console_assert(); +} + +#[test] +fn test_u32_ternary() { + TestU32::test_ternary(); +} diff --git a/tests/pass/parse/integers/u32/mul.leo b/tests/pass/parse/integers/u32/mul.leo new file mode 100644 index 0000000000..a77a85477b --- /dev/null +++ b/tests/pass/parse/integers/u32/mul.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: u32) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/ne.leo b/tests/pass/parse/integers/u32/ne.leo new file mode 100644 index 0000000000..00ee1a9989 --- /dev/null +++ b/tests/pass/parse/integers/u32/ne.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: bool) { + console.assert(a != b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/pow.leo b/tests/pass/parse/integers/u32/pow.leo new file mode 100644 index 0000000000..b82496ff77 --- /dev/null +++ b/tests/pass/parse/integers/u32/pow.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: u32) { + console.assert(a ** b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/sub.leo b/tests/pass/parse/integers/u32/sub.leo new file mode 100644 index 0000000000..54480bd4bc --- /dev/null +++ b/tests/pass/parse/integers/u32/sub.leo @@ -0,0 +1,3 @@ +function main(a: u32, b: u32, c: u32) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u32/ternary.leo b/tests/pass/parse/integers/u32/ternary.leo new file mode 100644 index 0000000000..3c96a7236c --- /dev/null +++ b/tests/pass/parse/integers/u32/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: u32, b: u32, c: u32) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/add.leo b/tests/pass/parse/integers/u64/add.leo new file mode 100644 index 0000000000..28abe51201 --- /dev/null +++ b/tests/pass/parse/integers/u64/add.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: u64) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/console_assert.leo b/tests/pass/parse/integers/u64/console_assert.leo new file mode 100644 index 0000000000..ac1d6d40c3 --- /dev/null +++ b/tests/pass/parse/integers/u64/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/div.leo b/tests/pass/parse/integers/u64/div.leo new file mode 100644 index 0000000000..059da236bb --- /dev/null +++ b/tests/pass/parse/integers/u64/div.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: u64) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/eq.leo b/tests/pass/parse/integers/u64/eq.leo new file mode 100644 index 0000000000..990b2dad2d --- /dev/null +++ b/tests/pass/parse/integers/u64/eq.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/ge.leo b/tests/pass/parse/integers/u64/ge.leo new file mode 100644 index 0000000000..46ba36ceff --- /dev/null +++ b/tests/pass/parse/integers/u64/ge.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: bool) { + console.assert(a >= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/gt.leo b/tests/pass/parse/integers/u64/gt.leo new file mode 100644 index 0000000000..7d3032c7f5 --- /dev/null +++ b/tests/pass/parse/integers/u64/gt.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: bool) { + console.assert(a > b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/input.leo b/tests/pass/parse/integers/u64/input.leo new file mode 100644 index 0000000000..ac1d6d40c3 --- /dev/null +++ b/tests/pass/parse/integers/u64/input.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/le.leo b/tests/pass/parse/integers/u64/le.leo new file mode 100644 index 0000000000..625b38d2d9 --- /dev/null +++ b/tests/pass/parse/integers/u64/le.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: bool) { + console.assert(a <= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/lt.leo b/tests/pass/parse/integers/u64/lt.leo new file mode 100644 index 0000000000..ed379f7341 --- /dev/null +++ b/tests/pass/parse/integers/u64/lt.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: bool) { + console.assert(a < b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/max.leo b/tests/pass/parse/integers/u64/max.leo new file mode 100644 index 0000000000..985897c006 --- /dev/null +++ b/tests/pass/parse/integers/u64/max.leo @@ -0,0 +1,3 @@ +function main() { + let a: u64 = 18446744073709551615; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/max_fail.leo b/tests/pass/parse/integers/u64/max_fail.leo new file mode 100644 index 0000000000..0ca3f13895 --- /dev/null +++ b/tests/pass/parse/integers/u64/max_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: u64 = 18446744073709551616; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/min.leo b/tests/pass/parse/integers/u64/min.leo new file mode 100644 index 0000000000..aa9b72fc8a --- /dev/null +++ b/tests/pass/parse/integers/u64/min.leo @@ -0,0 +1,3 @@ +function main() { + let a: u64 = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/min_fail.leo b/tests/pass/parse/integers/u64/min_fail.leo new file mode 100644 index 0000000000..81b90cc74a --- /dev/null +++ b/tests/pass/parse/integers/u64/min_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: u64 = -1; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/mod.rs b/tests/pass/parse/integers/u64/mod.rs new file mode 100644 index 0000000000..ec86c868f1 --- /dev/null +++ b/tests/pass/parse/integers/u64/mod.rs @@ -0,0 +1,118 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{ + assert_satisfied, + expect_asg_error, + expect_compiler_error, + generate_main_input, + integers::IntegerTester, + parse_program, +}; +use leo_ast::InputValue; +use leo_input::types::{IntegerType, U64Type, UnsignedIntegerType}; + +test_uint!( + TestU64, + u64, + IntegerType::Unsigned(UnsignedIntegerType::U64Type(U64Type {})), + UInt64 +); + +#[test] +fn test_u64_min() { + TestU64::test_min(); +} + +#[test] +fn test_u64_min_fail() { + TestU64::test_min_fail(); +} + +#[test] +fn test_u64_max() { + TestU64::test_max(); +} + +#[test] +fn test_u64_max_fail() { + TestU64::test_max_fail(); +} + +#[test] +fn test_u64_add() { + TestU64::test_add(); +} + +#[test] +fn test_u64_sub() { + TestU64::test_sub(); +} + +#[test] +fn test_u64_mul() { + TestU64::test_mul(); +} + +#[test] +fn test_u64_div() { + TestU64::test_div(); +} + +#[test] +fn test_u64_pow() { + TestU64::test_pow(); +} + +#[test] +fn test_u64_eq() { + TestU64::test_eq(); +} + +#[test] +fn test_u64_ne() { + TestU64::test_ne(); +} + +#[test] +fn test_u64_ge() { + TestU64::test_ge(); +} + +#[test] +fn test_u64_gt() { + TestU64::test_gt(); +} + +#[test] +fn test_u64_le() { + TestU64::test_le(); +} + +#[test] +fn test_u64_lt() { + TestU64::test_lt(); +} + +#[test] +fn test_u64_console_assert() { + TestU64::test_console_assert(); +} + +#[test] +fn test_u64_ternary() { + TestU64::test_ternary(); +} diff --git a/tests/pass/parse/integers/u64/mul.leo b/tests/pass/parse/integers/u64/mul.leo new file mode 100644 index 0000000000..2633e6780c --- /dev/null +++ b/tests/pass/parse/integers/u64/mul.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: u64) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/ne.leo b/tests/pass/parse/integers/u64/ne.leo new file mode 100644 index 0000000000..e47acbb1de --- /dev/null +++ b/tests/pass/parse/integers/u64/ne.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: bool) { + console.assert(a != b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/pow.leo b/tests/pass/parse/integers/u64/pow.leo new file mode 100644 index 0000000000..64f0694ed1 --- /dev/null +++ b/tests/pass/parse/integers/u64/pow.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: u64) { + console.assert(a ** b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/sub.leo b/tests/pass/parse/integers/u64/sub.leo new file mode 100644 index 0000000000..9961f0f7b7 --- /dev/null +++ b/tests/pass/parse/integers/u64/sub.leo @@ -0,0 +1,3 @@ +function main(a: u64, b: u64, c: u64) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u64/ternary.leo b/tests/pass/parse/integers/u64/ternary.leo new file mode 100644 index 0000000000..4c4ddd8e0c --- /dev/null +++ b/tests/pass/parse/integers/u64/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: u64, b: u64, c: u64) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/add.leo b/tests/pass/parse/integers/u8/add.leo new file mode 100644 index 0000000000..1b40e304d2 --- /dev/null +++ b/tests/pass/parse/integers/u8/add.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: u8) { + console.assert(a + b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/console_assert.leo b/tests/pass/parse/integers/u8/console_assert.leo new file mode 100644 index 0000000000..4d99dc106c --- /dev/null +++ b/tests/pass/parse/integers/u8/console_assert.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/div.leo b/tests/pass/parse/integers/u8/div.leo new file mode 100644 index 0000000000..945aa94c30 --- /dev/null +++ b/tests/pass/parse/integers/u8/div.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: u8) { + console.assert(a / b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/eq.leo b/tests/pass/parse/integers/u8/eq.leo new file mode 100644 index 0000000000..c2a487b0e7 --- /dev/null +++ b/tests/pass/parse/integers/u8/eq.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: bool) { + console.assert(a == b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/ge.leo b/tests/pass/parse/integers/u8/ge.leo new file mode 100644 index 0000000000..d819422276 --- /dev/null +++ b/tests/pass/parse/integers/u8/ge.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: bool) { + console.assert(a >= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/gt.leo b/tests/pass/parse/integers/u8/gt.leo new file mode 100644 index 0000000000..87843f575f --- /dev/null +++ b/tests/pass/parse/integers/u8/gt.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: bool) { + console.assert(a > b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/input.leo b/tests/pass/parse/integers/u8/input.leo new file mode 100644 index 0000000000..4d99dc106c --- /dev/null +++ b/tests/pass/parse/integers/u8/input.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8) { + console.assert(a == b); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/le.leo b/tests/pass/parse/integers/u8/le.leo new file mode 100644 index 0000000000..2607b7f3d1 --- /dev/null +++ b/tests/pass/parse/integers/u8/le.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: bool) { + console.assert(a <= b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/lt.leo b/tests/pass/parse/integers/u8/lt.leo new file mode 100644 index 0000000000..7495d0fe37 --- /dev/null +++ b/tests/pass/parse/integers/u8/lt.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: bool) { + console.assert(a < b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/max.leo b/tests/pass/parse/integers/u8/max.leo new file mode 100644 index 0000000000..684bdfba10 --- /dev/null +++ b/tests/pass/parse/integers/u8/max.leo @@ -0,0 +1,3 @@ +function main() { + let a: u8 = 255; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/max_fail.leo b/tests/pass/parse/integers/u8/max_fail.leo new file mode 100644 index 0000000000..f2b870096d --- /dev/null +++ b/tests/pass/parse/integers/u8/max_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: u8 = 256; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/min.leo b/tests/pass/parse/integers/u8/min.leo new file mode 100644 index 0000000000..a88e33c5a6 --- /dev/null +++ b/tests/pass/parse/integers/u8/min.leo @@ -0,0 +1,3 @@ +function main() { + let a: u8 = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/min_fail.leo b/tests/pass/parse/integers/u8/min_fail.leo new file mode 100644 index 0000000000..7b91dc6e1a --- /dev/null +++ b/tests/pass/parse/integers/u8/min_fail.leo @@ -0,0 +1,3 @@ +function main() { + let a: u8 = -1; +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/mod.rs b/tests/pass/parse/integers/u8/mod.rs new file mode 100644 index 0000000000..a61e28246d --- /dev/null +++ b/tests/pass/parse/integers/u8/mod.rs @@ -0,0 +1,118 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{ + assert_satisfied, + expect_asg_error, + expect_compiler_error, + generate_main_input, + integers::IntegerTester, + parse_program, +}; +use leo_ast::InputValue; +use leo_input::types::{IntegerType, U8Type, UnsignedIntegerType}; + +test_uint!( + TestU8, + u8, + IntegerType::Unsigned(UnsignedIntegerType::U8Type(U8Type {})), + UInt8 +); + +#[test] +fn test_u8_min() { + TestU8::test_min(); +} + +#[test] +fn test_u8_min_fail() { + TestU8::test_min_fail(); +} + +#[test] +fn test_u8_max() { + TestU8::test_max(); +} + +#[test] +fn test_u8_max_fail() { + TestU8::test_max_fail(); +} + +#[test] +fn test_u8_add() { + TestU8::test_add(); +} + +#[test] +fn test_u8_sub() { + TestU8::test_sub(); +} + +#[test] +fn test_u8_mul() { + TestU8::test_mul(); +} + +#[test] +fn test_u8_div() { + TestU8::test_div(); +} + +#[test] +fn test_u8_pow() { + TestU8::test_pow(); +} + +#[test] +fn test_u8_eq() { + TestU8::test_eq(); +} + +#[test] +fn test_u8_ne() { + TestU8::test_ne(); +} + +#[test] +fn test_u8_ge() { + TestU8::test_ge(); +} + +#[test] +fn test_u8_gt() { + TestU8::test_gt(); +} + +#[test] +fn test_u8_le() { + TestU8::test_le(); +} + +#[test] +fn test_u8_lt() { + TestU8::test_lt(); +} + +#[test] +fn test_u8_console_assert() { + TestU8::test_console_assert(); +} + +#[test] +fn test_u8_ternary() { + TestU8::test_ternary(); +} diff --git a/tests/pass/parse/integers/u8/mul.leo b/tests/pass/parse/integers/u8/mul.leo new file mode 100644 index 0000000000..11acf4688b --- /dev/null +++ b/tests/pass/parse/integers/u8/mul.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: u8) { + console.assert(a * b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/ne.leo b/tests/pass/parse/integers/u8/ne.leo new file mode 100644 index 0000000000..e75194a2f2 --- /dev/null +++ b/tests/pass/parse/integers/u8/ne.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: bool) { + console.assert(a != b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/pow.leo b/tests/pass/parse/integers/u8/pow.leo new file mode 100644 index 0000000000..928ab73b0d --- /dev/null +++ b/tests/pass/parse/integers/u8/pow.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: u8) { + console.assert(a ** b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/sub.leo b/tests/pass/parse/integers/u8/sub.leo new file mode 100644 index 0000000000..1335409c29 --- /dev/null +++ b/tests/pass/parse/integers/u8/sub.leo @@ -0,0 +1,3 @@ +function main(a: u8, b: u8, c: u8) { + console.assert(a - b == c); +} \ No newline at end of file diff --git a/tests/pass/parse/integers/u8/ternary.leo b/tests/pass/parse/integers/u8/ternary.leo new file mode 100644 index 0000000000..1b436aa054 --- /dev/null +++ b/tests/pass/parse/integers/u8/ternary.leo @@ -0,0 +1,5 @@ +function main(s: bool, a: u8, b: u8, c: u8) { + let r = s ? a : b; + + console.assert(r == c); +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/array.leo b/tests/pass/parse/mutability/array.leo new file mode 100644 index 0000000000..1d51c15271 --- /dev/null +++ b/tests/pass/parse/mutability/array.leo @@ -0,0 +1,5 @@ +// Arrays are immutable by default. +function main() { + let a = [1u32]; + a[0] = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/array_mut.leo b/tests/pass/parse/mutability/array_mut.leo new file mode 100644 index 0000000000..1b86bac80f --- /dev/null +++ b/tests/pass/parse/mutability/array_mut.leo @@ -0,0 +1,7 @@ +// Adding the `mut` keyword makes an array variable mutable. +function main() { + let mut a = [1u32]; + a[0] = 0; + + console.assert(a[0] == 0u32); +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/array_splice_mut.leo b/tests/pass/parse/mutability/array_splice_mut.leo new file mode 100644 index 0000000000..57cc67e872 --- /dev/null +++ b/tests/pass/parse/mutability/array_splice_mut.leo @@ -0,0 +1,9 @@ +// Adding the `mut` keyword makes an array variable mutable. +function main() { + let mut a = [1u32, 2u32, 3u32]; + a[0u32..2u32] = [4u32, 5u32]; + + console.assert(a[0] == 4u32); + console.assert(a[1] == 5u32); + console.assert(a[2] == 3u32); +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/array_tuple_mut.leo b/tests/pass/parse/mutability/array_tuple_mut.leo new file mode 100644 index 0000000000..e0096bd7ac --- /dev/null +++ b/tests/pass/parse/mutability/array_tuple_mut.leo @@ -0,0 +1,8 @@ +// Adding the `mut` keyword makes an array variable mutable. +function main() { + let mut a = [(1u32, 2u32)]; + a[0u32].1 = 3u32; + + console.assert(a[0u32].0 == 1u32); + console.assert(a[0u32].1 == 3u32); +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/circuit.leo b/tests/pass/parse/mutability/circuit.leo new file mode 100644 index 0000000000..be1c568836 --- /dev/null +++ b/tests/pass/parse/mutability/circuit.leo @@ -0,0 +1,9 @@ +// Circuits are immutable by default. +circuit Foo { + x: u32 +} + +function main() { + let a = Foo { x: 1 }; + a.x = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/circuit_function_mut.leo b/tests/pass/parse/mutability/circuit_function_mut.leo new file mode 100644 index 0000000000..eba1d02c0e --- /dev/null +++ b/tests/pass/parse/mutability/circuit_function_mut.leo @@ -0,0 +1,9 @@ +// Adding the `mut` keyword makes a circuit variable mutable. +circuit Foo { + function bar() {} +} + +function main() { + let mut a = Foo { x: 1 }; + a.bar = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/circuit_mut.leo b/tests/pass/parse/mutability/circuit_mut.leo new file mode 100644 index 0000000000..27bd6109b2 --- /dev/null +++ b/tests/pass/parse/mutability/circuit_mut.leo @@ -0,0 +1,11 @@ +// Adding the `mut` keyword makes a circuit variable mutable. +circuit Foo { + x: u32 +} + +function main() { + let mut a = Foo { x: 1 }; + a.x = 0; + + console.assert(a.x == 0u32); +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/circuit_static_function_mut.leo b/tests/pass/parse/mutability/circuit_static_function_mut.leo new file mode 100644 index 0000000000..eba1d02c0e --- /dev/null +++ b/tests/pass/parse/mutability/circuit_static_function_mut.leo @@ -0,0 +1,9 @@ +// Adding the `mut` keyword makes a circuit variable mutable. +circuit Foo { + function bar() {} +} + +function main() { + let mut a = Foo { x: 1 }; + a.bar = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/circuit_variable_mut.leo b/tests/pass/parse/mutability/circuit_variable_mut.leo new file mode 100644 index 0000000000..27bd6109b2 --- /dev/null +++ b/tests/pass/parse/mutability/circuit_variable_mut.leo @@ -0,0 +1,11 @@ +// Adding the `mut` keyword makes a circuit variable mutable. +circuit Foo { + x: u32 +} + +function main() { + let mut a = Foo { x: 1 }; + a.x = 0; + + console.assert(a.x == 0u32); +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/const.leo b/tests/pass/parse/mutability/const.leo new file mode 100644 index 0000000000..d2a3a6ac2b --- /dev/null +++ b/tests/pass/parse/mutability/const.leo @@ -0,0 +1,5 @@ +// Let variables are immutable by default. +function main() { + let a = 1u32; + a = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/function_input.leo b/tests/pass/parse/mutability/function_input.leo new file mode 100644 index 0000000000..1ef3ce1f02 --- /dev/null +++ b/tests/pass/parse/mutability/function_input.leo @@ -0,0 +1,4 @@ +// Function input are immutable by default. +function main(a: bool) { + a = false; +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/function_input_mut.leo b/tests/pass/parse/mutability/function_input_mut.leo new file mode 100644 index 0000000000..2df24b227c --- /dev/null +++ b/tests/pass/parse/mutability/function_input_mut.leo @@ -0,0 +1,6 @@ +// Adding the `mut` keyword makes a function variable mutable. +function main(mut a: bool) { + a = true; + + console.assert(a == true); +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/let.leo b/tests/pass/parse/mutability/let.leo new file mode 100644 index 0000000000..477e6b35f5 --- /dev/null +++ b/tests/pass/parse/mutability/let.leo @@ -0,0 +1,5 @@ +// Variables are immutable by default. +function main() { + let a = 1u32; + a = 0; +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/let_mut.leo b/tests/pass/parse/mutability/let_mut.leo new file mode 100644 index 0000000000..5766d144d3 --- /dev/null +++ b/tests/pass/parse/mutability/let_mut.leo @@ -0,0 +1,7 @@ +// Adding the `mut` keyword makes a variable mutable. +function main() { + let mut a = 1u32; + a = 0; + + console.assert(a == 0u32); +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/let_mut_nested.leo b/tests/pass/parse/mutability/let_mut_nested.leo new file mode 100644 index 0000000000..27121f6e48 --- /dev/null +++ b/tests/pass/parse/mutability/let_mut_nested.leo @@ -0,0 +1,5 @@ +function main () { + let mut x = 2u8; + let mut y = x; + let z = y / 2u8; +} \ No newline at end of file diff --git a/tests/pass/parse/mutability/swap.leo b/tests/pass/parse/mutability/swap.leo new file mode 100644 index 0000000000..0a209149ee --- /dev/null +++ b/tests/pass/parse/mutability/swap.leo @@ -0,0 +1,20 @@ +// Swap two elements of an array. +function swap(mut a: [u32; 2], const i: u32, const j: u32) -> [u32; 2] { + let t = a[i]; + a[i] = a[j]; + a[j] = t; + return a +} + +function main() { + let mut arr: [u32; 2] = [0, 1]; + let expected: [u32; 2] = [1, 0]; + + // Do swap. + let actual = swap(arr, 0, 1); + + // Check result. + for i in 0..2 { + console.assert(expected[i] == actual[i]); + } +} \ No newline at end of file diff --git a/tests/pass/parse/statements/assert.leo b/tests/pass/parse/statements/assert.leo new file mode 100644 index 0000000000..f3d20b461d --- /dev/null +++ b/tests/pass/parse/statements/assert.leo @@ -0,0 +1,7 @@ +function main(a: u32) { + if a == 1 { + console.assert(a == 1); + } else { + console.assert(a == 0); + } +} diff --git a/tests/pass/parse/statements/block.leo b/tests/pass/parse/statements/block.leo new file mode 100644 index 0000000000..8650808041 --- /dev/null +++ b/tests/pass/parse/statements/block.leo @@ -0,0 +1,9 @@ +function main() { + let mut x = 4u32; + + { + x = 5u32; + } + + console.assert(x == 5u32); +} \ No newline at end of file diff --git a/tests/pass/parse/statements/chain.leo b/tests/pass/parse/statements/chain.leo new file mode 100644 index 0000000000..dbc0e1f38c --- /dev/null +++ b/tests/pass/parse/statements/chain.leo @@ -0,0 +1,13 @@ +function main(a: u32, b: u32) { + let mut c = 0u32; + + if a == 1 { + c = 1; + } else if a == 2 { + c = 2; + } else { + c = 3; + } + + console.assert(c == b); +} \ No newline at end of file diff --git a/tests/pass/parse/statements/for_loop.leo b/tests/pass/parse/statements/for_loop.leo new file mode 100644 index 0000000000..2dca076858 --- /dev/null +++ b/tests/pass/parse/statements/for_loop.leo @@ -0,0 +1,13 @@ +function main(a: bool) { + let mut b = 0u32; + + if a { + for i in 0..4 { + b += i; + } + } + + let r: u32 = a ? 6 : 0; + + console.assert(r == b); +} diff --git a/tests/pass/parse/statements/iteration_basic.leo b/tests/pass/parse/statements/iteration_basic.leo new file mode 100644 index 0000000000..103c9abb9e --- /dev/null +++ b/tests/pass/parse/statements/iteration_basic.leo @@ -0,0 +1,8 @@ +function main() { + let mut x = 4u32; + for i in 0..3 { + x -= 1; + } + + console.assert(x == 1u32); +} \ No newline at end of file diff --git a/tests/pass/parse/statements/multiple_returns.leo b/tests/pass/parse/statements/multiple_returns.leo new file mode 100644 index 0000000000..b8dd869b47 --- /dev/null +++ b/tests/pass/parse/statements/multiple_returns.leo @@ -0,0 +1,7 @@ +function main(input) -> u32 { + if input.registers.a == 0u32 { + return 0u32 + } else { + return 1u32 + } +} \ No newline at end of file diff --git a/tests/pass/parse/statements/mutate.leo b/tests/pass/parse/statements/mutate.leo new file mode 100644 index 0000000000..458d3d0d60 --- /dev/null +++ b/tests/pass/parse/statements/mutate.leo @@ -0,0 +1,15 @@ +function main(a: u32) { + let mut b = 5u32; + + if a == 1 { + b = 1; + } else { + b = 0; + } + + if a == 1 { + console.assert(b == 1); + } else { + console.assert(b == 0); + } +} diff --git a/tests/pass/parse/statements/nested.leo b/tests/pass/parse/statements/nested.leo new file mode 100644 index 0000000000..3596f889d1 --- /dev/null +++ b/tests/pass/parse/statements/nested.leo @@ -0,0 +1,12 @@ +function main(a: bool, b: bool, c: u32) { + let mut d = 0u32; + + if a { + d += 1; + if b { + d += 2; + } + } + + console.assert(d == c); +} \ No newline at end of file diff --git a/tests/pass/parse/statements/num_returns_fail.leo b/tests/pass/parse/statements/num_returns_fail.leo new file mode 100644 index 0000000000..14b2fe6ad0 --- /dev/null +++ b/tests/pass/parse/statements/num_returns_fail.leo @@ -0,0 +1,3 @@ +function main() -> (bool, bool) { + return true +} \ No newline at end of file diff --git a/tests/pass/parse/statements/ternary_basic.leo b/tests/pass/parse/statements/ternary_basic.leo new file mode 100644 index 0000000000..675b681fa9 --- /dev/null +++ b/tests/pass/parse/statements/ternary_basic.leo @@ -0,0 +1,5 @@ +function main(a: bool, b: bool) { + let c = a ? true : false; + + let d = c == b; +} \ No newline at end of file diff --git a/tests/pass/parse/syntax/compare_mismatched_types.leo b/tests/pass/parse/syntax/compare_mismatched_types.leo new file mode 100644 index 0000000000..8cf6327cb3 --- /dev/null +++ b/tests/pass/parse/syntax/compare_mismatched_types.leo @@ -0,0 +1,3 @@ +function main() { + let a = -5i8 > 342u32; +} \ No newline at end of file diff --git a/tests/pass/parse/syntax/undefined.leo b/tests/pass/parse/syntax/undefined.leo new file mode 100644 index 0000000000..856b07589a --- /dev/null +++ b/tests/pass/parse/syntax/undefined.leo @@ -0,0 +1,3 @@ +function main() -> bool { + return a +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/access.leo b/tests/pass/parse/tuples/access.leo new file mode 100644 index 0000000000..196e9d058c --- /dev/null +++ b/tests/pass/parse/tuples/access.leo @@ -0,0 +1,6 @@ +function main() { + let a = (true, false); + + console.assert(a.0 == true); + console.assert(a.1 == false); +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/basic.leo b/tests/pass/parse/tuples/basic.leo new file mode 100644 index 0000000000..37c728611c --- /dev/null +++ b/tests/pass/parse/tuples/basic.leo @@ -0,0 +1,3 @@ +function main() { + let a = (true, false); +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/function.leo b/tests/pass/parse/tuples/function.leo new file mode 100644 index 0000000000..b318348813 --- /dev/null +++ b/tests/pass/parse/tuples/function.leo @@ -0,0 +1,10 @@ +function foo() -> (bool, bool) { + return (true, false) +} + +function main() { + let a = foo(); + + console.assert(a.0 == true); + console.assert(a.1 == false); +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/function_multiple.leo b/tests/pass/parse/tuples/function_multiple.leo new file mode 100644 index 0000000000..39848377c6 --- /dev/null +++ b/tests/pass/parse/tuples/function_multiple.leo @@ -0,0 +1,10 @@ +function foo() -> (bool, bool) { + return (true, false) +} + +function main() { + let (a, b) = foo(); + + console.assert(a == true); + console.assert(b == false); +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/function_typed.leo b/tests/pass/parse/tuples/function_typed.leo new file mode 100644 index 0000000000..8af2c907ca --- /dev/null +++ b/tests/pass/parse/tuples/function_typed.leo @@ -0,0 +1,10 @@ +function foo() -> (bool, bool) { + return (true, false) +} + +function main() { + let a: (bool, bool) = foo(); + + console.assert(a.0 == true); + console.assert(a.1 == false); +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/input.leo b/tests/pass/parse/tuples/input.leo new file mode 100644 index 0000000000..f7672a3b03 --- /dev/null +++ b/tests/pass/parse/tuples/input.leo @@ -0,0 +1,3 @@ +function main(a: (bool, bool)) { + +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/multiple.leo b/tests/pass/parse/tuples/multiple.leo new file mode 100644 index 0000000000..b7627dad2a --- /dev/null +++ b/tests/pass/parse/tuples/multiple.leo @@ -0,0 +1,6 @@ +function main() { + let (a, b) = (true, false); + + console.assert(a == true); + console.assert(b == false); +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/multiple_typed.leo b/tests/pass/parse/tuples/multiple_typed.leo new file mode 100644 index 0000000000..29fc7ef877 --- /dev/null +++ b/tests/pass/parse/tuples/multiple_typed.leo @@ -0,0 +1,6 @@ +function main() { + let (a, b): (bool, bool) = (true, false); + + console.assert(a == true); + console.assert(b == false); +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/nested.leo b/tests/pass/parse/tuples/nested.leo new file mode 100644 index 0000000000..a9599b360c --- /dev/null +++ b/tests/pass/parse/tuples/nested.leo @@ -0,0 +1,4 @@ +function main() { + let a = (true, false); + let b = (true, a); +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/nested_access.leo b/tests/pass/parse/tuples/nested_access.leo new file mode 100644 index 0000000000..5edba64e24 --- /dev/null +++ b/tests/pass/parse/tuples/nested_access.leo @@ -0,0 +1,8 @@ +function main() { + let a = (true, false); + let b = (true, a); + + console.assert(b.0 == true); + console.assert(b.1.0 == true); + console.assert(b.1.1 == false); +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/nested_typed.leo b/tests/pass/parse/tuples/nested_typed.leo new file mode 100644 index 0000000000..2e68117a2b --- /dev/null +++ b/tests/pass/parse/tuples/nested_typed.leo @@ -0,0 +1,4 @@ +function main() { + let a = (true, false); + let b: (bool, (bool, bool)) = (true, a); +} \ No newline at end of file diff --git a/tests/pass/parse/tuples/typed.leo b/tests/pass/parse/tuples/typed.leo new file mode 100644 index 0000000000..8cd2ed79db --- /dev/null +++ b/tests/pass/parse/tuples/typed.leo @@ -0,0 +1,3 @@ +function main() { + let a: (bool, bool) = (true, false); +} \ No newline at end of file