mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-23 23:23:50 +03:00
Merge branch 'master' of github.com:AleoHQ/leo into fix/prefer-index-map
This commit is contained in:
commit
00dac3709a
@ -1,5 +1,5 @@
|
||||
[hooks]
|
||||
pre-commit = "cargo +nightly fmt --all -- --check"
|
||||
pre-commit = "cargo +nightly clippy && cargo +nightly fmt --all -- --check"
|
||||
|
||||
[logging]
|
||||
verbose = false
|
||||
|
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -2485,9 +2485,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.59"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95"
|
||||
checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -15,10 +15,9 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Function, Identifier, Type};
|
||||
use leo_grammar::circuits::{
|
||||
CircuitFunction as GrammarCircuitFunction,
|
||||
CircuitMember as GrammarCircuitMember,
|
||||
CircuitVariableDefinition as GrammarCircuitVariableDefinition,
|
||||
use leo_grammar::{
|
||||
circuits::{CircuitMember as GrammarCircuitMember, CircuitVariableDefinition as GrammarCircuitVariableDefinition},
|
||||
functions::Function as GrammarFunction,
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -26,28 +25,24 @@ use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum CircuitMember {
|
||||
// (is_mutable, variable_name, variable_type)
|
||||
CircuitVariable(bool, Identifier, Type),
|
||||
// (is_static, function)
|
||||
CircuitFunction(bool, Function),
|
||||
// (variable_name, variable_type)
|
||||
CircuitVariable(Identifier, Type),
|
||||
// (function)
|
||||
CircuitFunction(Function),
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarCircuitVariableDefinition<'ast>> for CircuitMember {
|
||||
fn from(circuit_value: GrammarCircuitVariableDefinition<'ast>) -> Self {
|
||||
CircuitMember::CircuitVariable(
|
||||
circuit_value.mutable.is_some(),
|
||||
Identifier::from(circuit_value.identifier),
|
||||
Type::from(circuit_value.type_),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarCircuitFunction<'ast>> for CircuitMember {
|
||||
fn from(circuit_function: GrammarCircuitFunction<'ast>) -> Self {
|
||||
CircuitMember::CircuitFunction(
|
||||
circuit_function._static.is_some(),
|
||||
Function::from(circuit_function.function),
|
||||
)
|
||||
impl<'ast> From<GrammarFunction<'ast>> for CircuitMember {
|
||||
fn from(circuit_function: GrammarFunction<'ast>) -> Self {
|
||||
CircuitMember::CircuitFunction(Function::from(circuit_function))
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,16 +58,10 @@ impl<'ast> From<GrammarCircuitMember<'ast>> for CircuitMember {
|
||||
impl fmt::Display for CircuitMember {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
CircuitMember::CircuitVariable(ref mutable, ref identifier, ref type_) => {
|
||||
if *mutable {
|
||||
write!(f, "mut ")?;
|
||||
}
|
||||
CircuitMember::CircuitVariable(ref identifier, ref type_) => {
|
||||
write!(f, "{}: {}", identifier, type_)
|
||||
}
|
||||
CircuitMember::CircuitFunction(ref static_, ref function) => {
|
||||
if *static_ {
|
||||
write!(f, "static ")?;
|
||||
}
|
||||
CircuitMember::CircuitFunction(ref function) => {
|
||||
write!(f, "{}", function)
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,18 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::Span;
|
||||
use crate::{InputKeyword, MutSelfKeyword, SelfKeyword, Span};
|
||||
use leo_grammar::{
|
||||
annotations::AnnotationArgument,
|
||||
common::{Identifier as GrammarIdentifier, KeywordOrIdentifier, SelfKeyword, SelfKeywordOrIdentifier},
|
||||
common::{
|
||||
Identifier as GrammarIdentifier,
|
||||
KeywordOrIdentifier,
|
||||
MutSelfKeyword as GrammarMutSelfKeyword,
|
||||
SelfKeyword as GrammarSelfKeyword,
|
||||
SelfKeywordOrIdentifier,
|
||||
},
|
||||
expressions::CircuitName,
|
||||
functions::InputKeyword,
|
||||
functions::InputKeyword as GrammarInputKeyword,
|
||||
imports::PackageName as GrammarPackageName,
|
||||
types::SelfType,
|
||||
};
|
||||
@ -128,20 +134,56 @@ impl<'ast> From<SelfKeywordOrIdentifier<'ast>> for Identifier {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<SelfKeyword<'ast>> for Identifier {
|
||||
fn from(self_: SelfKeyword<'ast>) -> Self {
|
||||
impl<'ast> From<GrammarSelfKeyword<'ast>> for Identifier {
|
||||
fn from(grammar: GrammarSelfKeyword<'ast>) -> Self {
|
||||
Self {
|
||||
name: self_.keyword,
|
||||
span: Span::from(self_.span),
|
||||
name: grammar.keyword,
|
||||
span: Span::from(grammar.span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<InputKeyword<'ast>> for Identifier {
|
||||
fn from(input: InputKeyword<'ast>) -> Self {
|
||||
impl From<SelfKeyword> for Identifier {
|
||||
fn from(keyword: SelfKeyword) -> Self {
|
||||
Self {
|
||||
name: input.keyword,
|
||||
span: Span::from(input.span),
|
||||
name: keyword.to_string(),
|
||||
span: keyword.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarMutSelfKeyword<'ast>> for Identifier {
|
||||
fn from(grammar: GrammarMutSelfKeyword<'ast>) -> Self {
|
||||
Self {
|
||||
name: grammar.to_string(),
|
||||
span: Span::from(grammar.span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MutSelfKeyword> for Identifier {
|
||||
fn from(keyword: MutSelfKeyword) -> Self {
|
||||
Self {
|
||||
name: keyword.to_string(),
|
||||
span: keyword.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarInputKeyword<'ast>> for Identifier {
|
||||
fn from(grammar: GrammarInputKeyword<'ast>) -> Self {
|
||||
Self {
|
||||
name: grammar.keyword,
|
||||
span: Span::from(grammar.span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InputKeyword> for Identifier {
|
||||
fn from(keyword: InputKeyword) -> Self {
|
||||
Self {
|
||||
name: keyword.to_string(),
|
||||
span: keyword.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
42
ast/src/common/input_keyword.rs
Normal file
42
ast/src/common/input_keyword.rs
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::Span;
|
||||
use leo_grammar::functions::InputKeyword as GrammarInputKeyword;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// The `input` keyword can view program register, record, and state values.
|
||||
/// Values cannot be modified. The `input` keyword cannot be made mutable.
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct InputKeyword {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarInputKeyword<'ast>> 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")
|
||||
}
|
||||
}
|
@ -26,12 +26,21 @@ pub use declare::*;
|
||||
pub mod identifier;
|
||||
pub use identifier::*;
|
||||
|
||||
pub mod input_keyword;
|
||||
pub use input_keyword::*;
|
||||
|
||||
pub mod mut_self_keyword;
|
||||
pub use mut_self_keyword::*;
|
||||
|
||||
pub mod positive_number;
|
||||
pub use positive_number::*;
|
||||
|
||||
pub mod range_or_expression;
|
||||
pub use range_or_expression::*;
|
||||
|
||||
pub mod self_keyword;
|
||||
pub use self_keyword::*;
|
||||
|
||||
pub mod span;
|
||||
pub use span::*;
|
||||
|
||||
|
41
ast/src/common/mut_self_keyword.rs
Normal file
41
ast/src/common/mut_self_keyword.rs
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::Span;
|
||||
use leo_grammar::common::MutSelfKeyword as GrammarMutSelfKeyword;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// The `mut self` keyword can view and modify circuit values inside of a circuit function.
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct MutSelfKeyword {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarMutSelfKeyword<'ast>> 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")
|
||||
}
|
||||
}
|
42
ast/src/common/self_keyword.rs
Normal file
42
ast/src/common/self_keyword.rs
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::Span;
|
||||
use leo_grammar::common::SelfKeyword as GrammarSelfKeyword;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// The `self` keyword can view circuit values inside of a circuit function.
|
||||
/// Circuit values cannot be modified. To modify values use the `mut self` [MutSelfKeyword].
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct SelfKeyword {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarSelfKeyword<'ast>> 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")
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{FunctionInput, Identifier, Span, Statement, Type};
|
||||
use crate::{Block, FunctionInput, Identifier, Span, Type};
|
||||
use leo_grammar::functions::Function as GrammarFunction;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -25,7 +25,7 @@ pub struct Function {
|
||||
pub identifier: Identifier,
|
||||
pub input: Vec<FunctionInput>,
|
||||
pub output: Option<Type>,
|
||||
pub statements: Vec<Statement>,
|
||||
pub block: Block,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
@ -43,13 +43,13 @@ impl<'ast> From<GrammarFunction<'ast>> for Function {
|
||||
|
||||
let parameters = function.parameters.into_iter().map(FunctionInput::from).collect();
|
||||
let returns = function.returns.map(Type::from);
|
||||
let statements = function.statements.into_iter().map(Statement::from).collect();
|
||||
let block = Block::from(function.block);
|
||||
|
||||
Function {
|
||||
identifier: function_name,
|
||||
input: parameters,
|
||||
output: returns,
|
||||
statements,
|
||||
block,
|
||||
span: Span::from(function.span),
|
||||
}
|
||||
}
|
||||
@ -60,21 +60,38 @@ impl Function {
|
||||
&self.identifier.name
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns `true` if the function has input `self` or `mut self`.
|
||||
/// Returns `false` otherwise.
|
||||
///
|
||||
pub fn contains_self(&self) -> bool {
|
||||
self.input.iter().any(|param| param.is_self())
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns `true` if the function has input `mut self`.
|
||||
/// Returns `false` otherwise.
|
||||
///
|
||||
pub fn contains_mut_self(&self) -> bool {
|
||||
self.input.iter().any(|param| param.is_mut_self())
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns an iterator of [&FunctionInput] removing `self` and `mut self` inputs.
|
||||
///
|
||||
pub fn filter_self_inputs(&self) -> impl Iterator<Item = &FunctionInput> {
|
||||
self.input.iter().filter(|input| !input.is_self())
|
||||
}
|
||||
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "function {}", self.identifier)?;
|
||||
|
||||
let parameters = self.input.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
|
||||
let returns = self.output.as_ref().map(|type_| type_.to_string());
|
||||
let statements = self
|
||||
.statements
|
||||
.iter()
|
||||
.map(|s| format!("\t{}\n", s))
|
||||
.collect::<Vec<_>>()
|
||||
.join("");
|
||||
if returns.is_none() {
|
||||
write!(f, "({}) {{\n{}}}", parameters, statements,)
|
||||
write!(f, "({}) {}", parameters, self.block)
|
||||
} else {
|
||||
write!(f, "({}) -> {} {{\n{}}}", parameters, returns.unwrap(), statements,)
|
||||
write!(f, "({}) -> {} {}", parameters, returns.unwrap(), self.block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,29 +14,27 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{FunctionInputVariable, Identifier, Span};
|
||||
use crate::{FunctionInputVariable, InputKeyword, MutSelfKeyword, SelfKeyword};
|
||||
use leo_grammar::functions::input::Input as GrammarInput;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
/// Enumerates the possible inputs to a function.
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub enum FunctionInput {
|
||||
InputKeyword(Identifier),
|
||||
InputKeyword(InputKeyword),
|
||||
SelfKeyword(SelfKeyword),
|
||||
MutSelfKeyword(MutSelfKeyword),
|
||||
Variable(FunctionInputVariable),
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarInput<'ast>> for FunctionInput {
|
||||
fn from(input: GrammarInput<'ast>) -> Self {
|
||||
match input {
|
||||
GrammarInput::InputKeyword(input_keyword) => {
|
||||
let id = Identifier {
|
||||
name: input_keyword.keyword,
|
||||
span: Span::from(input_keyword.span),
|
||||
};
|
||||
|
||||
FunctionInput::InputKeyword(id)
|
||||
}
|
||||
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))
|
||||
}
|
||||
@ -45,9 +43,37 @@ impl<'ast> From<GrammarInput<'ast>> for FunctionInput {
|
||||
}
|
||||
|
||||
impl FunctionInput {
|
||||
///
|
||||
/// Returns `true` if the function input is the `self` or `mut self` keyword.
|
||||
/// Returns `false` otherwise.
|
||||
///
|
||||
pub fn is_self(&self) -> bool {
|
||||
match self {
|
||||
FunctionInput::InputKeyword(_) => false,
|
||||
FunctionInput::SelfKeyword(_) => true,
|
||||
FunctionInput::MutSelfKeyword(_) => true,
|
||||
FunctionInput::Variable(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns `true` if the function input is the `mut self` keyword.
|
||||
/// Returns `false` otherwise.
|
||||
///
|
||||
pub fn is_mut_self(&self) -> bool {
|
||||
match self {
|
||||
FunctionInput::InputKeyword(_) => false,
|
||||
FunctionInput::SelfKeyword(_) => false,
|
||||
FunctionInput::MutSelfKeyword(_) => true,
|
||||
FunctionInput::Variable(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
FunctionInput::InputKeyword(id) => write!(f, "{}", id),
|
||||
FunctionInput::InputKeyword(keyword) => write!(f, "{}", keyword),
|
||||
FunctionInput::SelfKeyword(keyword) => write!(f, "{}", keyword),
|
||||
FunctionInput::MutSelfKeyword(keyword) => write!(f, "{}", keyword),
|
||||
FunctionInput::Variable(function_input) => write!(f, "{}", function_input),
|
||||
}
|
||||
}
|
||||
@ -64,3 +90,18 @@ impl fmt::Debug for FunctionInput {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for FunctionInput {
|
||||
/// Returns true if `self == other`. Does not compare spans.
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(FunctionInput::InputKeyword(_), FunctionInput::InputKeyword(_)) => true,
|
||||
(FunctionInput::SelfKeyword(_), FunctionInput::SelfKeyword(_)) => true,
|
||||
(FunctionInput::MutSelfKeyword(_), FunctionInput::MutSelfKeyword(_)) => true,
|
||||
(FunctionInput::Variable(left), FunctionInput::Variable(right)) => left.eq(right),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for FunctionInput {}
|
||||
|
48
ast/src/statements/block.rs
Normal file
48
ast/src/statements/block.rs
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::Statement;
|
||||
use leo_grammar::statements::Block as GrammarBlock;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Block {
|
||||
pub statements: Vec<Statement>,
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarBlock<'ast>> for Block {
|
||||
fn from(block: GrammarBlock<'ast>) -> Self {
|
||||
Block {
|
||||
statements: block.statements.into_iter().map(Statement::from).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Block {
|
||||
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, "}}")
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ConditionalStatement, Statement};
|
||||
use crate::{Block, ConditionalStatement};
|
||||
use leo_grammar::statements::ConditionalNestedOrEndStatement as GrammarConditionalNestedOrEndStatement;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -23,7 +23,7 @@ use std::fmt;
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum ConditionalNestedOrEndStatement {
|
||||
Nested(Box<ConditionalStatement>),
|
||||
End(Vec<Statement>),
|
||||
End(Block),
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarConditionalNestedOrEndStatement<'ast>> for ConditionalNestedOrEndStatement {
|
||||
@ -32,8 +32,8 @@ impl<'ast> From<GrammarConditionalNestedOrEndStatement<'ast>> for ConditionalNes
|
||||
GrammarConditionalNestedOrEndStatement::Nested(nested) => {
|
||||
ConditionalNestedOrEndStatement::Nested(Box::new(ConditionalStatement::from(*nested)))
|
||||
}
|
||||
GrammarConditionalNestedOrEndStatement::End(statements) => {
|
||||
ConditionalNestedOrEndStatement::End(statements.into_iter().map(Statement::from).collect())
|
||||
GrammarConditionalNestedOrEndStatement::End(block) => {
|
||||
ConditionalNestedOrEndStatement::End(Block::from(block))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -43,13 +43,7 @@ impl fmt::Display for ConditionalNestedOrEndStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ConditionalNestedOrEndStatement::Nested(ref nested) => write!(f, "else {}", nested),
|
||||
ConditionalNestedOrEndStatement::End(ref statements) => {
|
||||
writeln!(f, "else {{")?;
|
||||
for statement in statements.iter() {
|
||||
writeln!(f, "\t\t{}", statement)?;
|
||||
}
|
||||
write!(f, "\t}}")
|
||||
}
|
||||
ConditionalNestedOrEndStatement::End(ref block) => write!(f, "else {}", block),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ConditionalNestedOrEndStatement, Expression, Statement};
|
||||
use crate::{Block, ConditionalNestedOrEndStatement, Expression};
|
||||
use leo_grammar::statements::ConditionalStatement as GrammarConditionalStatement;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -23,7 +23,7 @@ use std::fmt;
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ConditionalStatement {
|
||||
pub condition: Expression,
|
||||
pub statements: Vec<Statement>,
|
||||
pub block: Block,
|
||||
pub next: Option<ConditionalNestedOrEndStatement>,
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ impl<'ast> From<GrammarConditionalStatement<'ast>> for ConditionalStatement {
|
||||
fn from(statement: GrammarConditionalStatement<'ast>) -> Self {
|
||||
ConditionalStatement {
|
||||
condition: Expression::from(statement.condition),
|
||||
statements: statement.statements.into_iter().map(Statement::from).collect(),
|
||||
block: Block::from(statement.block),
|
||||
next: statement
|
||||
.next
|
||||
.map(|n_or_e| Some(ConditionalNestedOrEndStatement::from(n_or_e)))
|
||||
@ -42,13 +42,10 @@ impl<'ast> From<GrammarConditionalStatement<'ast>> for ConditionalStatement {
|
||||
|
||||
impl fmt::Display for ConditionalStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "if ({}) {{", self.condition)?;
|
||||
for statement in self.statements.iter() {
|
||||
writeln!(f, "\t\t{}", statement)?;
|
||||
}
|
||||
write!(f, "if ({}) {}", self.condition, self.block)?;
|
||||
match self.next.clone() {
|
||||
Some(n_or_e) => write!(f, "\t}} {}", n_or_e),
|
||||
None => write!(f, "\t}}"),
|
||||
Some(n_or_e) => write!(f, " {}", n_or_e),
|
||||
None => write!(f, ""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,3 +22,6 @@ pub use conditional_statement::*;
|
||||
|
||||
pub mod statement;
|
||||
pub use statement::*;
|
||||
|
||||
pub mod block;
|
||||
pub use block::*;
|
||||
|
@ -14,7 +14,17 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Assignee, ConditionalStatement, ConsoleFunctionCall, Declare, Expression, Identifier, Span, Variables};
|
||||
use crate::{
|
||||
Assignee,
|
||||
Block,
|
||||
ConditionalStatement,
|
||||
ConsoleFunctionCall,
|
||||
Declare,
|
||||
Expression,
|
||||
Identifier,
|
||||
Span,
|
||||
Variables,
|
||||
};
|
||||
use leo_grammar::{
|
||||
console::ConsoleFunctionCall as GrammarConsoleFunctionCall,
|
||||
operations::AssignOperation,
|
||||
@ -38,7 +48,7 @@ pub enum Statement {
|
||||
Definition(Declare, Variables, Expression, Span),
|
||||
Assign(Assignee, Expression, Span),
|
||||
Conditional(ConditionalStatement, Span),
|
||||
Iteration(Identifier, Box<(Expression, Expression)>, Vec<Statement>, Span),
|
||||
Iteration(Identifier, Box<(Expression, Expression)>, Block, Span),
|
||||
Console(ConsoleFunctionCall),
|
||||
Expression(Expression, Span),
|
||||
}
|
||||
@ -127,7 +137,7 @@ impl<'ast> From<ForStatement<'ast>> for Statement {
|
||||
Statement::Iteration(
|
||||
Identifier::from(statement.index),
|
||||
Box::new((Expression::from(statement.start), Expression::from(statement.stop))),
|
||||
statement.statements.into_iter().map(Statement::from).collect(),
|
||||
Block::from(statement.block),
|
||||
Span::from(statement.span),
|
||||
)
|
||||
}
|
||||
@ -176,12 +186,8 @@ impl fmt::Display for Statement {
|
||||
}
|
||||
Statement::Assign(ref variable, ref statement, ref _span) => write!(f, "{} = {};", variable, statement),
|
||||
Statement::Conditional(ref statement, ref _span) => write!(f, "{}", statement),
|
||||
Statement::Iteration(ref var, ref start_stop, ref list, ref _span) => {
|
||||
writeln!(f, "for {} in {}..{} {{", var, start_stop.0, start_stop.1)?;
|
||||
for l in list {
|
||||
writeln!(f, "\t\t{}", l)?;
|
||||
}
|
||||
write!(f, "\t}}")
|
||||
Statement::Iteration(ref var, ref start_stop, ref block, ref _span) => {
|
||||
write!(f, "for {} in {}..{} {}", var, start_stop.0, start_stop.1, block)
|
||||
}
|
||||
Statement::Console(ref console) => write!(f, "{}", console),
|
||||
Statement::Expression(ref expression, ref _span) => write!(f, "{};", expression),
|
||||
|
@ -8,6 +8,7 @@
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"text\\\":\\\" function main() {\\\",\\\"line\\\":1,\\\"start\\\":10,\\\"end\\\":14}\"}",
|
||||
"input": [],
|
||||
"output": null,
|
||||
"block" : {
|
||||
"statements": [
|
||||
{
|
||||
"Return": [
|
||||
@ -51,7 +52,8 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
]
|
||||
},
|
||||
"span": {
|
||||
"text": " function main() {",
|
||||
"line": 1,
|
||||
|
@ -16,7 +16,13 @@
|
||||
|
||||
//! Enforces an assert equals statement in a compiled Leo program.
|
||||
|
||||
use crate::{errors::ConsoleError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use crate::{
|
||||
errors::ConsoleError,
|
||||
get_indicator_value,
|
||||
program::ConstrainedProgram,
|
||||
value::ConstrainedValue,
|
||||
GroupType,
|
||||
};
|
||||
use leo_ast::{Expression, Span, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
@ -30,7 +36,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
cs: &mut CS,
|
||||
file_scope: &str,
|
||||
function_scope: &str,
|
||||
indicator: Option<Boolean>,
|
||||
indicator: &Boolean,
|
||||
expression: Expression,
|
||||
span: &Span,
|
||||
) -> Result<(), ConsoleError> {
|
||||
@ -42,12 +48,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
// If the indicator bit is false, do not evaluate the assertion
|
||||
// This is okay since we are not enforcing any constraints
|
||||
let false_boolean = Boolean::Constant(false);
|
||||
|
||||
if let Some(indicator_bool) = indicator {
|
||||
if indicator_bool.eq(&false_boolean) {
|
||||
return Ok(()); // continue execution
|
||||
}
|
||||
if !get_indicator_value(indicator) {
|
||||
return Ok(()); // Continue execution.
|
||||
}
|
||||
|
||||
// Unwrap assertion value and handle errors
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
//! Evaluates a macro in a compiled Leo program.
|
||||
|
||||
use crate::{errors::ConsoleError, program::ConstrainedProgram, GroupType};
|
||||
use crate::{errors::ConsoleError, program::ConstrainedProgram, statement::get_indicator_value, GroupType};
|
||||
use leo_ast::{ConsoleFunction, ConsoleFunctionCall};
|
||||
|
||||
use snarkos_models::{
|
||||
@ -30,7 +30,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
cs: &mut CS,
|
||||
file_scope: &str,
|
||||
function_scope: &str,
|
||||
indicator: Option<Boolean>,
|
||||
indicator: &Boolean,
|
||||
console: ConsoleFunctionCall,
|
||||
) -> Result<(), ConsoleError> {
|
||||
match console.function {
|
||||
@ -40,21 +40,21 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
ConsoleFunction::Debug(string) => {
|
||||
let string = self.format(cs, file_scope, function_scope, string)?;
|
||||
|
||||
if unwrap_indicator_value(indicator) {
|
||||
if get_indicator_value(indicator) {
|
||||
tracing::debug!("{}", string);
|
||||
}
|
||||
}
|
||||
ConsoleFunction::Error(string) => {
|
||||
let string = self.format(cs, file_scope, function_scope, string)?;
|
||||
|
||||
if unwrap_indicator_value(indicator) {
|
||||
if get_indicator_value(indicator) {
|
||||
tracing::error!("{}", string);
|
||||
}
|
||||
}
|
||||
ConsoleFunction::Log(string) => {
|
||||
let string = self.format(cs, file_scope, function_scope, string)?;
|
||||
|
||||
if unwrap_indicator_value(indicator) {
|
||||
if get_indicator_value(indicator) {
|
||||
tracing::info!("{}", string);
|
||||
}
|
||||
}
|
||||
@ -63,16 +63,3 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Return the indicator boolean gadget value or true if it is None
|
||||
// This is okay since we are not enforcing any constraints
|
||||
fn unwrap_indicator_value(indicator: Option<Boolean>) -> bool {
|
||||
let false_boolean = Boolean::constant(false);
|
||||
|
||||
if let Some(indicator_bool) = indicator {
|
||||
if indicator_bool.eq(&false_boolean) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ impl ExpressionError {
|
||||
}
|
||||
|
||||
pub fn undefined_identifier(identifier: Identifier) -> Self {
|
||||
let message = format!("cannot find value `{}` in this scope", identifier.name);
|
||||
let message = format!("Cannot find value `{}` in this scope", identifier.name);
|
||||
|
||||
Self::new_from_span(message, identifier.span)
|
||||
}
|
||||
|
@ -82,12 +82,6 @@ impl FunctionError {
|
||||
FunctionError::Error(FormattedError::new_from_span(message, span))
|
||||
}
|
||||
|
||||
pub fn arguments_length(expected: usize, actual: usize, span: Span) -> Self {
|
||||
let message = format!("function expected {} input variables, found {}", expected, actual);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_array(actual: String, span: Span) -> Self {
|
||||
let message = format!("Expected function input array, found `{}`", actual);
|
||||
|
||||
|
@ -135,6 +135,22 @@ impl StatementError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
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 {
|
||||
let message = format!(
|
||||
"function expected `{}` return type but no valid branches returned a result",
|
||||
expected
|
||||
);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn select_fail(first: String, second: String, span: Span) -> Self {
|
||||
let message = format!(
|
||||
"Conditional select gadget failed to select between `{}` or `{}`",
|
||||
|
@ -67,7 +67,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
match matched_member {
|
||||
Some(member) => {
|
||||
match &member.1 {
|
||||
ConstrainedValue::Function(ref _circuit_identifier, ref _function) => {
|
||||
ConstrainedValue::Function(ref _circuit_identifier, ref function) => {
|
||||
// Check for function input `self` or `mut self`.
|
||||
if function.contains_self() {
|
||||
// Pass circuit members into function call by value
|
||||
for stored_member in members {
|
||||
let circuit_scope = new_scope(&file_scope, &circuit_name.name);
|
||||
@ -77,6 +79,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
self.store(variable, stored_member.1.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
ConstrainedValue::Static(value) => {
|
||||
return Err(ExpressionError::invalid_static_access(value.to_string(), span));
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
for member in circuit.members.into_iter() {
|
||||
match member {
|
||||
CircuitMember::CircuitVariable(is_mutable, identifier, type_) => {
|
||||
CircuitMember::CircuitVariable(identifier, type_) => {
|
||||
let matched_variable = members
|
||||
.clone()
|
||||
.into_iter()
|
||||
@ -66,7 +66,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
match matched_variable {
|
||||
Some(variable) => {
|
||||
// Resolve and enforce circuit variable
|
||||
let mut variable_value = self.enforce_expression(
|
||||
let variable_value = self.enforce_expression(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
@ -74,25 +74,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
variable.expression,
|
||||
)?;
|
||||
|
||||
// Add mutability to circuit variable
|
||||
if is_mutable {
|
||||
variable_value = ConstrainedValue::Mutable(Box::new(variable_value))
|
||||
}
|
||||
|
||||
resolved_members.push(ConstrainedCircuitMember(identifier, variable_value))
|
||||
}
|
||||
None => return Err(ExpressionError::expected_circuit_member(identifier.to_string(), span)),
|
||||
}
|
||||
}
|
||||
CircuitMember::CircuitFunction(_static, function) => {
|
||||
CircuitMember::CircuitFunction(function) => {
|
||||
let identifier = function.identifier.clone();
|
||||
let mut constrained_function_value =
|
||||
let constrained_function_value =
|
||||
ConstrainedValue::Function(Some(circuit_identifier.clone()), function);
|
||||
|
||||
if _static {
|
||||
constrained_function_value = ConstrainedValue::Static(Box::new(constrained_function_value));
|
||||
}
|
||||
|
||||
resolved_members.push(ConstrainedCircuitMember(identifier, constrained_function_value));
|
||||
}
|
||||
};
|
||||
|
@ -56,22 +56,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
// Find static circuit function
|
||||
let matched_function = circuit.members.into_iter().find(|member| match member {
|
||||
CircuitMember::CircuitFunction(_static, function) => function.identifier == circuit_member,
|
||||
CircuitMember::CircuitFunction(function) => function.identifier == circuit_member,
|
||||
_ => false,
|
||||
});
|
||||
|
||||
// Return errors if no static function exists
|
||||
let function = match matched_function {
|
||||
Some(CircuitMember::CircuitFunction(_static, function)) => {
|
||||
if _static {
|
||||
function
|
||||
} else {
|
||||
return Err(ExpressionError::invalid_member_access(
|
||||
function.identifier.to_string(),
|
||||
span,
|
||||
));
|
||||
}
|
||||
}
|
||||
Some(CircuitMember::CircuitFunction(function)) => function,
|
||||
_ => {
|
||||
return Err(ExpressionError::undefined_member_access(
|
||||
circuit.circuit_name.to_string(),
|
||||
|
@ -23,22 +23,13 @@ use crate::{
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use leo_ast::{Expression, Function, FunctionInput, Span, Type};
|
||||
use leo_ast::{Expression, Function, FunctionInput};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
|
||||
};
|
||||
|
||||
pub fn check_arguments_length(expected: usize, actual: usize, span: &Span) -> Result<(), FunctionError> {
|
||||
// Make sure we are given the correct number of arguments
|
||||
if expected != actual {
|
||||
Err(FunctionError::arguments_length(expected, actual, span.to_owned()))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub(crate) fn enforce_function<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
@ -51,17 +42,29 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let function_name = new_scope(scope, function.get_name());
|
||||
|
||||
// Make sure we are given the correct number of input variables
|
||||
check_arguments_length(function.input.len(), input.len(), &function.span)?;
|
||||
// Store if function contains input `mut self`.
|
||||
let mut_self = function.contains_mut_self();
|
||||
|
||||
// Store input values as new variables in resolved program
|
||||
for (input_model, input_expression) in function.input.iter().zip(input.into_iter()) {
|
||||
for (input_model, input_expression) in function.filter_self_inputs().zip(input.into_iter()) {
|
||||
let (name, value) = match input_model {
|
||||
FunctionInput::InputKeyword(identifier) => {
|
||||
let input_value =
|
||||
FunctionInput::InputKeyword(keyword) => {
|
||||
let value =
|
||||
self.enforce_function_input(cs, scope, caller_scope, &function_name, None, input_expression)?;
|
||||
|
||||
(&identifier.name, input_value)
|
||||
(keyword.to_string(), value)
|
||||
}
|
||||
FunctionInput::SelfKeyword(keyword) => {
|
||||
let value =
|
||||
self.enforce_function_input(cs, scope, caller_scope, &function_name, None, input_expression)?;
|
||||
|
||||
(keyword.to_string(), value)
|
||||
}
|
||||
FunctionInput::MutSelfKeyword(keyword) => {
|
||||
let value =
|
||||
self.enforce_function_input(cs, scope, caller_scope, &function_name, None, input_expression)?;
|
||||
|
||||
(keyword.to_string(), value)
|
||||
}
|
||||
FunctionInput::Variable(input_model) => {
|
||||
// First evaluate input expression
|
||||
@ -78,7 +81,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
input_value = ConstrainedValue::Mutable(Box::new(input_value))
|
||||
}
|
||||
|
||||
(&input_model.identifier.name, input_value)
|
||||
(input_model.identifier.name.clone(), input_value)
|
||||
}
|
||||
};
|
||||
|
||||
@ -89,42 +92,25 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
// Evaluate every statement in the function and save all potential results
|
||||
let mut results = vec![];
|
||||
let indicator = Boolean::constant(true);
|
||||
|
||||
for statement in function.statements.iter() {
|
||||
for statement in function.block.statements.iter() {
|
||||
let mut result = self.enforce_statement(
|
||||
cs,
|
||||
scope,
|
||||
&function_name,
|
||||
None,
|
||||
&indicator,
|
||||
statement.clone(),
|
||||
function.output.clone(),
|
||||
declared_circuit_reference,
|
||||
mut_self,
|
||||
)?;
|
||||
|
||||
results.append(&mut result);
|
||||
}
|
||||
|
||||
// Conditionally select a result based on returned indicators
|
||||
let mut return_values = ConstrainedValue::Tuple(vec![]);
|
||||
|
||||
Self::conditionally_select_result(cs, &mut return_values, results, &function.span)?;
|
||||
|
||||
if let ConstrainedValue::Tuple(ref returns) = return_values {
|
||||
let return_types = match function.output {
|
||||
Some(Type::Tuple(types)) => types.len(),
|
||||
Some(_) => 1usize,
|
||||
None => 0usize,
|
||||
};
|
||||
|
||||
if return_types != returns.len() {
|
||||
return Err(FunctionError::return_arguments_length(
|
||||
return_types,
|
||||
returns.len(),
|
||||
function.span.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(return_values)
|
||||
Self::conditionally_select_result(cs, function.output, results, &function.span)
|
||||
.map_err(FunctionError::StatementError)
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{errors::FunctionError, ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType};
|
||||
use leo_ast::{Identifier, Input};
|
||||
use leo_ast::{Identifier, Input, InputKeyword};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
@ -31,26 +31,26 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn allocate_input_keyword<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
identifier: Identifier,
|
||||
keyword: InputKeyword,
|
||||
input: &Input,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
// Create an identifier for each input variable
|
||||
|
||||
let registers_name = Identifier {
|
||||
name: REGISTERS_VARIABLE_NAME.to_string(),
|
||||
span: identifier.span.clone(),
|
||||
span: keyword.span.clone(),
|
||||
};
|
||||
let record_name = Identifier {
|
||||
name: RECORD_VARIABLE_NAME.to_string(),
|
||||
span: identifier.span.clone(),
|
||||
span: keyword.span.clone(),
|
||||
};
|
||||
let state_name = Identifier {
|
||||
name: STATE_VARIABLE_NAME.to_string(),
|
||||
span: identifier.span.clone(),
|
||||
span: keyword.span.clone(),
|
||||
};
|
||||
let state_leaf_name = Identifier {
|
||||
name: STATE_LEAF_VARIABLE_NAME.to_string(),
|
||||
span: identifier.span.clone(),
|
||||
span: keyword.span.clone(),
|
||||
};
|
||||
|
||||
// Fetch each input variable's definitions
|
||||
@ -82,6 +82,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
// Return input variable keyword as circuit expression
|
||||
|
||||
Ok(ConstrainedValue::CircuitExpression(identifier, members))
|
||||
Ok(ConstrainedValue::CircuitExpression(Identifier::from(keyword), members))
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ use crate::{
|
||||
OutputBytes,
|
||||
};
|
||||
|
||||
use leo_ast::{Expression, Function, FunctionInput, Input};
|
||||
use leo_ast::{Expression, Function, FunctionInput, Identifier, Input};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
@ -44,11 +44,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
// Iterate over main function input variables and allocate new values
|
||||
let mut input_variables = Vec::with_capacity(function.input.len());
|
||||
for input_model in function.input.clone().into_iter() {
|
||||
let (identifier, value) = match input_model {
|
||||
FunctionInput::InputKeyword(identifier) => {
|
||||
let value = self.allocate_input_keyword(cs, identifier.clone(), &input)?;
|
||||
let (input_id, value) = match input_model {
|
||||
FunctionInput::InputKeyword(keyword) => {
|
||||
let input_id = Identifier::new_with_span(&keyword.to_string(), &keyword.span);
|
||||
let value = self.allocate_input_keyword(cs, keyword, &input)?;
|
||||
|
||||
(identifier, value)
|
||||
(input_id, value)
|
||||
}
|
||||
FunctionInput::SelfKeyword(_) => unimplemented!("cannot access self keyword in main function"),
|
||||
FunctionInput::MutSelfKeyword(_) => {
|
||||
unimplemented!("cannot access mut self keyword in main function")
|
||||
}
|
||||
FunctionInput::Variable(input_model) => {
|
||||
let name = input_model.identifier.name.clone();
|
||||
@ -63,12 +68,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
};
|
||||
|
||||
// Store input as variable with {function_name}_{identifier_name}
|
||||
let input_name = new_scope(&function_name, &identifier.name);
|
||||
let input_name = new_scope(&function_name, &input_id.to_string());
|
||||
|
||||
// Store a new variable for every allocated main function input
|
||||
self.store(input_name, value);
|
||||
|
||||
input_variables.push(Expression::Identifier(identifier));
|
||||
input_variables.push(Expression::Identifier(input_id));
|
||||
}
|
||||
|
||||
let span = function.span.clone();
|
||||
|
@ -16,9 +16,16 @@
|
||||
|
||||
//! Enforces that one return value is produced in a compiled Leo program.
|
||||
|
||||
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use crate::{
|
||||
check_return_type,
|
||||
errors::StatementError,
|
||||
get_indicator_value,
|
||||
program::ConstrainedProgram,
|
||||
value::ConstrainedValue,
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use leo_ast::Span;
|
||||
use leo_ast::{Span, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
@ -29,49 +36,82 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
/// iterates through a vector of results and selects one based off of indicators
|
||||
///
|
||||
/// Returns a conditionally selected result from the given possible function returns and
|
||||
/// given function return type.
|
||||
///
|
||||
pub fn conditionally_select_result<CS: ConstraintSystem<F>>(
|
||||
cs: &mut CS,
|
||||
return_value: &mut ConstrainedValue<F, G>,
|
||||
results: Vec<(Option<Boolean>, ConstrainedValue<F, G>)>,
|
||||
expected_return: Option<Type>,
|
||||
results: Vec<(Boolean, ConstrainedValue<F, G>)>,
|
||||
span: &Span,
|
||||
) -> Result<(), StatementError> {
|
||||
// if there are no results, continue
|
||||
) -> Result<ConstrainedValue<F, G>, StatementError> {
|
||||
// Initialize empty return value.
|
||||
let mut return_value = ConstrainedValue::Tuple(vec![]);
|
||||
|
||||
// If the function does not expect a return type, then make sure there are no returned results.
|
||||
let return_type = match expected_return {
|
||||
Some(return_type) => return_type,
|
||||
None => {
|
||||
if results.is_empty() {
|
||||
return Ok(());
|
||||
// If the function has no returns, then return an empty tuple.
|
||||
return Ok(return_value);
|
||||
} else {
|
||||
return Err(StatementError::invalid_number_of_returns(
|
||||
0,
|
||||
results.len(),
|
||||
span.to_owned(),
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Error if the function or one of its branches does not return.
|
||||
if results
|
||||
.iter()
|
||||
.find(|(indicator, _res)| get_indicator_value(indicator))
|
||||
.is_none()
|
||||
{
|
||||
return Err(StatementError::no_returns(return_type, span.to_owned()));
|
||||
}
|
||||
|
||||
// If all indicators are none, then there are no branch conditions in the function.
|
||||
// We simply return the last result.
|
||||
// Find the return value
|
||||
let mut ignored = vec![];
|
||||
let mut found_return = false;
|
||||
for (indicator, result) in results.into_iter() {
|
||||
// Error if a statement returned a result with an incorrect type
|
||||
let result_type = result.to_type(span)?;
|
||||
check_return_type(&return_type, &result_type, span)?;
|
||||
|
||||
if results.iter().all(|(indicator, _res)| indicator.is_none()) {
|
||||
let result = &results[results.len() - 1].1;
|
||||
|
||||
*return_value = result.clone();
|
||||
|
||||
return Ok(());
|
||||
if get_indicator_value(&indicator) {
|
||||
// Error if we already have a return value.
|
||||
if found_return {
|
||||
return Err(StatementError::multiple_returns(span.to_owned()));
|
||||
} else {
|
||||
// Set the function return value.
|
||||
return_value = result;
|
||||
found_return = true;
|
||||
}
|
||||
} else {
|
||||
// Ignore a possible function return value.
|
||||
ignored.push((indicator, result))
|
||||
}
|
||||
}
|
||||
|
||||
// Conditionally select out the ignored results in the circuit.
|
||||
//
|
||||
// If there are branches in the function we need to use the `ConditionalSelectGadget` to parse through and select the correct one.
|
||||
// This can be thought of as de-multiplexing all previous wires that may have returned results into one.
|
||||
for (i, (indicator, result)) in results.into_iter().enumerate() {
|
||||
// Set the first value as the starting point
|
||||
if i == 0 {
|
||||
*return_value = result.clone();
|
||||
}
|
||||
|
||||
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
||||
let selected_value = ConstrainedValue::conditionally_select(
|
||||
cs.ns(|| format!("select {} {}:{}", result, span.line, span.start)),
|
||||
&condition,
|
||||
for (i, (indicator, result)) in ignored.into_iter().enumerate() {
|
||||
return_value = ConstrainedValue::conditionally_select(
|
||||
cs.ns(|| format!("select result {} {}:{}", i, span.line, span.start)),
|
||||
&indicator,
|
||||
&result,
|
||||
return_value,
|
||||
&return_value,
|
||||
)
|
||||
.map_err(|_| StatementError::select_fail(result.to_string(), return_value.to_string(), span.to_owned()))?;
|
||||
|
||||
*return_value = selected_value;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(return_value)
|
||||
}
|
||||
}
|
||||
|
@ -34,14 +34,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
cs: &mut CS,
|
||||
file_scope: &str,
|
||||
function_scope: &str,
|
||||
indicator: Option<Boolean>,
|
||||
indicator: &Boolean,
|
||||
name: &str,
|
||||
range_or_expression: RangeOrExpression,
|
||||
mut new_value: ConstrainedValue<F, G>,
|
||||
span: &Span,
|
||||
) -> Result<(), StatementError> {
|
||||
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
||||
|
||||
// Resolve index so we know if we are assigning to a single value or a range of values
|
||||
match range_or_expression {
|
||||
RangeOrExpression::Expression(index) => {
|
||||
@ -54,7 +52,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
let selected_value = ConstrainedValue::conditionally_select(
|
||||
cs.ns(|| format!("select {} {}:{}", new_value, span.line, span.start)),
|
||||
&condition,
|
||||
indicator,
|
||||
&new_value,
|
||||
&old[index],
|
||||
)
|
||||
@ -90,7 +88,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
};
|
||||
let selected_array = ConstrainedValue::conditionally_select(
|
||||
cs.ns(|| format!("select {} {}:{}", new_array, span.line, span.start)),
|
||||
&condition,
|
||||
indicator,
|
||||
&new_array,
|
||||
old_array,
|
||||
)
|
||||
|
@ -42,7 +42,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
file_scope: &str,
|
||||
function_scope: &str,
|
||||
declared_circuit_reference: &str,
|
||||
indicator: Option<Boolean>,
|
||||
indicator: &Boolean,
|
||||
mut_self: bool,
|
||||
assignee: Assignee,
|
||||
expression: Expression,
|
||||
span: &Span,
|
||||
@ -55,14 +56,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
// Mutate the old value into the new value
|
||||
if assignee.accesses.is_empty() {
|
||||
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
||||
let old_value = self.get_mutable_assignee(&variable_name, span)?;
|
||||
|
||||
new_value.resolve_type(Some(old_value.to_type(&span)?), span)?;
|
||||
|
||||
let selected_value = ConstrainedValue::conditionally_select(
|
||||
cs.ns(|| format!("select {} {}:{}", new_value, span.line, span.start)),
|
||||
&condition,
|
||||
indicator,
|
||||
&new_value,
|
||||
old_value,
|
||||
)
|
||||
@ -88,7 +88,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
}
|
||||
AssigneeAccess::Member(identifier) => {
|
||||
// Mutate a circuit variable using the self keyword.
|
||||
if assignee.identifier.is_self() {
|
||||
if assignee.identifier.is_self() && mut_self {
|
||||
let self_circuit_variable_name = new_scope(&assignee.identifier.name, &identifier.name);
|
||||
let self_variable_name = new_scope(file_scope, &self_circuit_variable_name);
|
||||
let value = self.mutate_circuit_variable(
|
||||
|
@ -31,14 +31,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn mutate_circuit_variable<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
indicator: Option<Boolean>,
|
||||
indicator: &Boolean,
|
||||
circuit_name: &str,
|
||||
variable_name: Identifier,
|
||||
mut new_value: ConstrainedValue<F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<F, G>, StatementError> {
|
||||
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
||||
|
||||
// Get the mutable circuit by name
|
||||
match self.get_mutable_assignee(circuit_name, span)? {
|
||||
ConstrainedValue::CircuitExpression(_variable, members) => {
|
||||
@ -61,16 +59,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
span.to_owned(),
|
||||
))
|
||||
}
|
||||
ConstrainedValue::Mutable(value) => {
|
||||
// Mutate the circuit variable's value in place
|
||||
|
||||
value => {
|
||||
// Check that the new value type == old value type
|
||||
new_value.resolve_type(Some(value.to_type(span)?), span)?;
|
||||
|
||||
// Conditionally select the value if this branch is executed.
|
||||
let mut selected_value = ConstrainedValue::conditionally_select(
|
||||
cs.ns(|| format!("select {} {}:{}", new_value, span.line, span.start)),
|
||||
&condition,
|
||||
indicator,
|
||||
&new_value,
|
||||
&member.1,
|
||||
)
|
||||
@ -89,13 +85,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
Ok(selected_value)
|
||||
}
|
||||
_ => {
|
||||
// Throw an error if we try to mutate an immutable circuit variable
|
||||
Err(StatementError::immutable_circuit_variable(
|
||||
variable_name.name,
|
||||
span.to_owned(),
|
||||
))
|
||||
}
|
||||
},
|
||||
None => {
|
||||
// Throw an error if the circuit variable does not exist in the circuit
|
||||
|
@ -31,15 +31,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn assign_tuple<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
indicator: Option<Boolean>,
|
||||
indicator: &Boolean,
|
||||
name: &str,
|
||||
index: PositiveNumber,
|
||||
mut new_value: ConstrainedValue<F, G>,
|
||||
span: &Span,
|
||||
) -> Result<(), StatementError> {
|
||||
// Get the indicator value.
|
||||
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
||||
|
||||
// Parse the index.
|
||||
let index_usize = parse_index(&index, &span)?;
|
||||
|
||||
@ -50,7 +47,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
let selected_value = ConstrainedValue::conditionally_select(
|
||||
cs.ns(|| format!("select {} {}:{}", new_value, span.line, span.start)),
|
||||
&condition,
|
||||
indicator,
|
||||
&new_value,
|
||||
&old[index_usize],
|
||||
)
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a branch of a conditional or iteration statement in a compiled Leo program.
|
||||
|
||||
use crate::{program::ConstrainedProgram, GroupType, IndicatorAndConstrainedValue, StatementResult};
|
||||
use leo_ast::{Statement, Type};
|
||||
use leo_ast::{Block, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
@ -25,18 +25,22 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn evaluate_branch<CS: ConstraintSystem<F>>(
|
||||
/// Evaluates a branch of one or more statements and returns a result in
|
||||
/// the given scope.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn evaluate_block<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: &str,
|
||||
function_scope: &str,
|
||||
indicator: Option<Boolean>,
|
||||
statements: Vec<Statement>,
|
||||
indicator: &Boolean,
|
||||
block: Block,
|
||||
return_type: Option<Type>,
|
||||
mut_self: bool,
|
||||
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||
let mut results = Vec::with_capacity(statements.len());
|
||||
let mut results = Vec::with_capacity(block.statements.len());
|
||||
// Evaluate statements. Only allow a single return argument to be returned.
|
||||
for statement in statements.into_iter() {
|
||||
for statement in block.statements.into_iter() {
|
||||
let mut value = self.enforce_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
@ -45,6 +49,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
statement,
|
||||
return_type.clone(),
|
||||
"",
|
||||
mut_self,
|
||||
)?;
|
||||
|
||||
results.append(&mut value);
|
@ -17,5 +17,5 @@
|
||||
//! Methods to enforce constraints on a branch of a conditional or iteration statement
|
||||
//! in a compiled Leo program.
|
||||
|
||||
pub mod branch;
|
||||
pub use self::branch::*;
|
||||
pub mod block;
|
||||
pub use self::block::*;
|
@ -49,15 +49,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
cs: &mut CS,
|
||||
file_scope: &str,
|
||||
function_scope: &str,
|
||||
indicator: Option<Boolean>,
|
||||
indicator: &Boolean,
|
||||
statement: ConditionalStatement,
|
||||
return_type: Option<Type>,
|
||||
mut_self: bool,
|
||||
span: &Span,
|
||||
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||
let statement_string = statement.to_string();
|
||||
|
||||
// Inherit the indicator from a previous conditional statement or assume that we are the outer parent
|
||||
let outer_indicator = indicator.unwrap_or(Boolean::Constant(true));
|
||||
// Inherit an indicator from a previous statement.
|
||||
let outer_indicator = indicator;
|
||||
|
||||
// Evaluate the conditional boolean as the inner indicator
|
||||
let inner_indicator = match self.enforce_expression(
|
||||
@ -72,7 +73,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
};
|
||||
|
||||
// If outer_indicator && inner_indicator, then select branch 1
|
||||
let outer_indicator_string = indicator_to_string(&outer_indicator);
|
||||
let outer_indicator_string = indicator_to_string(outer_indicator);
|
||||
let inner_indicator_string = indicator_to_string(&inner_indicator);
|
||||
let branch_1_name = format!(
|
||||
"branch indicator 1 {} && {}",
|
||||
@ -80,7 +81,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
);
|
||||
let branch_1_indicator = Boolean::and(
|
||||
&mut cs.ns(|| format!("branch 1 {} {}:{}", statement_string, span.line, span.start)),
|
||||
&outer_indicator,
|
||||
outer_indicator,
|
||||
&inner_indicator,
|
||||
)
|
||||
.map_err(|_| StatementError::indicator_calculation(branch_1_name, span.to_owned()))?;
|
||||
@ -88,13 +89,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
let mut results = vec![];
|
||||
|
||||
// Evaluate branch 1
|
||||
let mut branch_1_result = self.evaluate_branch(
|
||||
let mut branch_1_result = self.evaluate_block(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
Some(branch_1_indicator),
|
||||
statement.statements,
|
||||
&branch_1_indicator,
|
||||
statement.block,
|
||||
return_type.clone(),
|
||||
mut_self,
|
||||
)?;
|
||||
|
||||
results.append(&mut branch_1_result);
|
||||
@ -120,18 +122,20 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
Some(branch_2_indicator),
|
||||
&branch_2_indicator,
|
||||
*nested,
|
||||
return_type,
|
||||
mut_self,
|
||||
span,
|
||||
)?,
|
||||
ConditionalNestedOrEndStatement::End(statements) => self.evaluate_branch(
|
||||
ConditionalNestedOrEndStatement::End(block) => self.evaluate_block(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
Some(branch_2_indicator),
|
||||
statements,
|
||||
&branch_2_indicator,
|
||||
block,
|
||||
return_type,
|
||||
mut_self,
|
||||
)?,
|
||||
},
|
||||
None => vec![],
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||
Integer,
|
||||
StatementResult,
|
||||
};
|
||||
use leo_ast::{Expression, Identifier, Span, Statement, Type};
|
||||
use leo_ast::{Block, Expression, Identifier, Span, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
@ -42,12 +42,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
cs: &mut CS,
|
||||
file_scope: &str,
|
||||
function_scope: &str,
|
||||
indicator: Option<Boolean>,
|
||||
indicator: &Boolean,
|
||||
index: Identifier,
|
||||
start: Expression,
|
||||
stop: Expression,
|
||||
statements: Vec<Statement>,
|
||||
block: Block,
|
||||
return_type: Option<Type>,
|
||||
mut_self: bool,
|
||||
span: &Span,
|
||||
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||
let mut results = vec![];
|
||||
@ -67,13 +68,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
);
|
||||
|
||||
// Evaluate statements and possibly return early
|
||||
let mut result = self.evaluate_branch(
|
||||
let mut result = self.evaluate_block(
|
||||
&mut cs.ns(|| format!("for loop iteration {} {}:{}", i, span.line, span.start)),
|
||||
file_scope,
|
||||
function_scope,
|
||||
indicator,
|
||||
statements.clone(),
|
||||
block.clone(),
|
||||
return_type.clone(),
|
||||
mut_self,
|
||||
)?;
|
||||
|
||||
results.append(&mut result);
|
||||
|
@ -19,8 +19,8 @@
|
||||
pub mod assign;
|
||||
pub use self::assign::*;
|
||||
|
||||
pub mod branch;
|
||||
pub use self::branch::*;
|
||||
pub mod block;
|
||||
pub use self::block::*;
|
||||
|
||||
pub mod conditional;
|
||||
pub use self::conditional::*;
|
||||
|
@ -24,21 +24,18 @@ use snarkos_models::{
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
fn check_return_type(expected: Option<Type>, actual: Type, span: &Span) -> Result<(), StatementError> {
|
||||
match expected {
|
||||
Some(expected) => {
|
||||
/// Returns `Ok` if the expected type == actual type, returns `Err` otherwise.
|
||||
pub fn check_return_type(expected: &Type, actual: &Type, span: &Span) -> Result<(), StatementError> {
|
||||
if expected.ne(&actual) {
|
||||
if (expected.is_self() && actual.is_circuit()) || expected.eq_flat(&actual) {
|
||||
return Ok(());
|
||||
// If the return type is `SelfType` returning the circuit type is okay.
|
||||
return if (expected.is_self() && actual.is_circuit()) || expected.eq_flat(&actual) {
|
||||
Ok(())
|
||||
} else {
|
||||
return Err(StatementError::arguments_type(&expected, &actual, span.to_owned()));
|
||||
}
|
||||
Err(StatementError::arguments_type(&expected, &actual, span.to_owned()))
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn enforce_return_statement<CS: ConstraintSystem<F>>(
|
||||
@ -53,7 +50,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
let result = self.enforce_operand(cs, file_scope, function_scope, return_type.clone(), expression, span)?;
|
||||
|
||||
// Make sure we return the correct type.
|
||||
check_return_type(return_type, result.to_type(&span)?, span)?;
|
||||
if let Some(expected) = return_type {
|
||||
check_return_type(&expected, &result.to_type(span)?, span)?;
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
pub type StatementResult<T> = Result<T, StatementError>;
|
||||
pub type IndicatorAndConstrainedValue<T, U> = (Option<Boolean>, ConstrainedValue<T, U>);
|
||||
pub type IndicatorAndConstrainedValue<T, U> = (Boolean, ConstrainedValue<T, U>);
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
///
|
||||
@ -41,17 +41,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
cs: &mut CS,
|
||||
file_scope: &str,
|
||||
function_scope: &str,
|
||||
indicator: Option<Boolean>,
|
||||
indicator: &Boolean,
|
||||
statement: Statement,
|
||||
return_type: Option<Type>,
|
||||
declared_circuit_reference: &str,
|
||||
mut_self: bool,
|
||||
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||
let mut results = vec![];
|
||||
|
||||
match statement {
|
||||
Statement::Return(expression, span) => {
|
||||
let return_value = (
|
||||
indicator,
|
||||
indicator.to_owned(),
|
||||
self.enforce_return_statement(cs, file_scope, function_scope, expression, return_type, &span)?,
|
||||
);
|
||||
|
||||
@ -75,6 +76,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
function_scope,
|
||||
declared_circuit_reference,
|
||||
indicator,
|
||||
mut_self,
|
||||
variable,
|
||||
expression,
|
||||
&span,
|
||||
@ -88,12 +90,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
indicator,
|
||||
statement,
|
||||
return_type,
|
||||
mut_self,
|
||||
&span,
|
||||
)?;
|
||||
|
||||
results.append(&mut result);
|
||||
}
|
||||
Statement::Iteration(index, start_stop, statements, span) => {
|
||||
Statement::Iteration(index, start_stop, block, span) => {
|
||||
let mut result = self.enforce_iteration_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
@ -102,8 +105,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
index,
|
||||
start_stop.0,
|
||||
start_stop.1,
|
||||
statements,
|
||||
block,
|
||||
return_type,
|
||||
mut_self,
|
||||
&span,
|
||||
)?;
|
||||
|
||||
@ -116,22 +120,25 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
let expression_string = expression.to_string();
|
||||
let value = self.enforce_expression(cs, file_scope, function_scope, None, expression)?;
|
||||
|
||||
// handle empty return value cases
|
||||
// Handle empty return value cases.
|
||||
match &value {
|
||||
ConstrainedValue::Tuple(values) => {
|
||||
if !values.is_empty() {
|
||||
return Err(StatementError::unassigned(expression_string, span));
|
||||
results.push((*indicator, value));
|
||||
}
|
||||
}
|
||||
_ => return Err(StatementError::unassigned(expression_string, span)),
|
||||
}
|
||||
|
||||
let result = (indicator, value);
|
||||
|
||||
results.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the indicator boolean gadget value.
|
||||
/// We can directly compare a boolean constant to the indicator since we are not enforcing any
|
||||
/// constraints
|
||||
pub fn get_indicator_value(indicator: &Boolean) -> bool {
|
||||
indicator.eq(&Boolean::constant(true))
|
||||
}
|
||||
|
@ -229,8 +229,15 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Modifies the `self` [ConstrainedValue] so there are no `mut` keywords wrapping the `self` value.
|
||||
///
|
||||
pub(crate) fn get_inner_mut(&mut self) {
|
||||
if let ConstrainedValue::Mutable(inner) = self {
|
||||
// Recursively remove `mut` keywords.
|
||||
inner.get_inner_mut();
|
||||
|
||||
// Modify the value.
|
||||
*self = *inner.clone()
|
||||
}
|
||||
}
|
||||
|
@ -22,72 +22,72 @@ static TEST_ADDRESS_2: &str = "aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams
|
||||
|
||||
#[test]
|
||||
fn test_valid() {
|
||||
let bytes = include_bytes!("valid.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("valid.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_prefix() {
|
||||
let bytes = include_bytes!("invalid_prefix.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("invalid_prefix.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_length() {
|
||||
let bytes = include_bytes!("invalid_length.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("invalid_length.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty() {
|
||||
let bytes = include_bytes!("empty.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("empty.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_implicit_valid() {
|
||||
let bytes = include_bytes!("implicit_valid.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("implicit_valid.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_implicit_invalid() {
|
||||
let bytes = include_bytes!("implicit_invalid.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("implicit_invalid.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _output = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_console_assert_pass() {
|
||||
let bytes = include_bytes!("console_assert_pass.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("console_assert_pass.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_console_assert_fail() {
|
||||
let bytes = include_bytes!("console_assert_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("console_assert_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _output = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ternary() {
|
||||
let bytes = include_bytes!("ternary.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("ternary.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("s", Some(InputValue::Boolean(true))),
|
||||
@ -98,7 +98,7 @@ fn test_ternary() {
|
||||
|
||||
assert_satisfied(program);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("s", Some(InputValue::Boolean(false))),
|
||||
@ -112,8 +112,8 @@ fn test_ternary() {
|
||||
|
||||
#[test]
|
||||
fn test_equal() {
|
||||
let bytes = include_bytes!("equal.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("equal.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Address(TEST_ADDRESS_1.to_string()))),
|
||||
@ -125,7 +125,7 @@ fn test_equal() {
|
||||
|
||||
assert_satisfied(program);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Address(TEST_ADDRESS_1.to_string()))),
|
||||
|
@ -41,17 +41,17 @@ pub fn output_zeros(program: EdwardsTestCompiler) {
|
||||
|
||||
#[test]
|
||||
fn test_registers() {
|
||||
let program_bytes = include_bytes!("registers.leo");
|
||||
let ones_input_bytes = include_bytes!("input/registers_ones.in");
|
||||
let zeros_input_bytes = include_bytes!("input/registers_zeros.in");
|
||||
let program_string = include_str!("registers.leo");
|
||||
let ones_input_string = include_str!("input/registers_ones.in");
|
||||
let zeros_input_string = include_str!("input/registers_zeros.in");
|
||||
|
||||
// test ones input register => ones output register
|
||||
let program = parse_program_with_input(program_bytes, ones_input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, ones_input_string).unwrap();
|
||||
|
||||
output_ones(program);
|
||||
|
||||
// test zeros input register => zeros output register
|
||||
let program = parse_program_with_input(program_bytes, zeros_input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, zeros_input_string).unwrap();
|
||||
|
||||
output_zeros(program);
|
||||
}
|
||||
@ -60,171 +60,171 @@ fn test_registers() {
|
||||
|
||||
#[test]
|
||||
fn test_inline() {
|
||||
let program_bytes = include_bytes!("inline.leo");
|
||||
let input_bytes = include_bytes!("input/three_ones.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("inline.leo");
|
||||
let input_string = include_str!("input/three_ones.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inline_fail() {
|
||||
let program_bytes = include_bytes!("inline.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("inline.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_initializer() {
|
||||
let program_bytes = include_bytes!("initializer.leo");
|
||||
let input_bytes = include_bytes!("input/three_ones.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("initializer.leo");
|
||||
let input_string = include_str!("input/three_ones.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_initializer_fail() {
|
||||
let program_bytes = include_bytes!("initializer_fail.leo");
|
||||
let input_bytes = include_bytes!("input/three_ones.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("initializer_fail.leo");
|
||||
let input_string = include_str!("input/three_ones.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_initializer_input() {
|
||||
let program_bytes = include_bytes!("initializer_input.leo");
|
||||
let input_bytes = include_bytes!("input/six_zeros.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("initializer_input.leo");
|
||||
let input_string = include_str!("input/six_zeros.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_initializer_input_fail() {
|
||||
let program_bytes = include_bytes!("initializer_input.leo");
|
||||
let input_bytes = include_bytes!("input/initializer_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("initializer_input.leo");
|
||||
let input_string = include_str!("input/initializer_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_nested_3x2() {
|
||||
let program_bytes = include_bytes!("input_nested_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/input_nested_3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("input_nested_3x2.leo");
|
||||
let input_string = include_str!("input/input_nested_3x2.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_nested_3x2_fail() {
|
||||
let program_bytes = include_bytes!("input_nested_3x2_fail.leo");
|
||||
let input_bytes = include_bytes!("input/input_nested_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("input_nested_3x2_fail.leo");
|
||||
let input_string = include_str!("input/input_nested_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_tuple_3x2() {
|
||||
let program_bytes = include_bytes!("input_tuple_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/input_tuple_3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("input_tuple_3x2.leo");
|
||||
let input_string = include_str!("input/input_tuple_3x2.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_tuple_3x2_fail() {
|
||||
let program_bytes = include_bytes!("input_tuple_3x2_fail.leo");
|
||||
let input_bytes = include_bytes!("input/input_tuple_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("input_tuple_3x2_fail.leo");
|
||||
let input_string = include_str!("input/input_tuple_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_fail_initializer() {
|
||||
let program_bytes = include_bytes!("multi_fail_initializer.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("multi_fail_initializer.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_inline_fail() {
|
||||
let program_bytes = include_bytes!("multi_fail_inline.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("multi_fail_inline.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_initializer() {
|
||||
let program_bytes = include_bytes!("multi_initializer.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("multi_initializer.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_initializer_fail() {
|
||||
let program_bytes = include_bytes!("multi_initializer_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("multi_initializer_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_3x2_value() {
|
||||
let program_bytes = include_bytes!("nested_3x2_value.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("nested_3x2_value.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_3x2_value_fail() {
|
||||
let program_bytes = include_bytes!("nested_3x2_value_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("nested_3x2_value_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tuple_3x2_value() {
|
||||
let program_bytes = include_bytes!("tuple_3x2_value.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("tuple_3x2_value.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tuple_3x2_value_fail() {
|
||||
let program_bytes = include_bytes!("tuple_3x2_value_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("tuple_3x2_value_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_spread() {
|
||||
let program_bytes = include_bytes!("spread.leo");
|
||||
let input_bytes = include_bytes!("input/three_ones.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("spread.leo");
|
||||
let input_string = include_str!("input/three_ones.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_slice() {
|
||||
let program_bytes = include_bytes!("slice.leo");
|
||||
let input_bytes = include_bytes!("input/three_ones.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("slice.leo");
|
||||
let input_string = include_str!("input/three_ones.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -233,136 +233,136 @@ fn test_slice() {
|
||||
|
||||
#[test]
|
||||
fn test_type_fail() {
|
||||
let program_bytes = include_bytes!("type_fail.leo");
|
||||
let syntax_error = parse_program(program_bytes).is_err();
|
||||
let program_string = include_str!("type_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_nested_value_nested_3x2() {
|
||||
let program_bytes = include_bytes!("type_nested_value_nested_3x2.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_nested_value_nested_3x2.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_nested_value_nested_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_nested_value_nested_3x2_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_nested_value_nested_3x2_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_nested_value_nested_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_nested_value_nested_4x3x2.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_nested_value_nested_4x3x2.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_nested_value_nested_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_nested_value_nested_4x3x2_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_nested_value_nested_4x3x2_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_nested_value_tuple_3x2() {
|
||||
let program_bytes = include_bytes!("type_nested_value_tuple_3x2.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_nested_value_tuple_3x2.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_nested_value_tuple_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_nested_value_tuple_3x2_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_nested_value_tuple_3x2_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_nested_value_tuple_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_nested_value_tuple_4x3x2.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_nested_value_tuple_4x3x2.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_nested_value_tuple_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_nested_value_tuple_4x3x2_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_nested_value_tuple_4x3x2_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_tuple_value_nested_3x2() {
|
||||
let program_bytes = include_bytes!("type_tuple_value_nested_3x2.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_tuple_value_nested_3x2.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_tuple_value_nested_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_tuple_value_nested_3x2_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_tuple_value_nested_3x2_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_tuple_value_nested_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_tuple_value_nested_4x3x2.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_tuple_value_nested_4x3x2.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_tuple_value_nested_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_tuple_value_nested_4x3x2_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_tuple_value_nested_4x3x2_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_tuple_value_tuple_3x2() {
|
||||
let program_bytes = include_bytes!("type_tuple_value_tuple_3x2.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_tuple_value_tuple_3x2.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_tuple_value_tuple_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_tuple_value_tuple_3x2_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_tuple_value_tuple_3x2_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_tuple_value_tuple_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_tuple_value_tuple_4x3x2.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_tuple_value_tuple_4x3x2.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_tuple_value_tuple_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_tuple_value_tuple_4x3x2_fail.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("type_tuple_value_tuple_4x3x2_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
@ -371,72 +371,72 @@ fn test_type_tuple_value_tuple_4x3x2_fail() {
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_nested_3x2() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_nested_3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("type_input_3x2.leo");
|
||||
let input_string = include_str!("input/type_nested_value_nested_3x2.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_nested_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_nested_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("type_input_3x2.leo");
|
||||
let input_string = include_str!("input/type_nested_value_nested_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_nested_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_nested_4x3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("type_input_4x3x2.leo");
|
||||
let input_string = include_str!("input/type_nested_value_nested_4x3x2.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_nested_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_nested_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("type_input_4x3x2.leo");
|
||||
let input_string = include_str!("input/type_nested_value_nested_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_tuple_3x2() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_tuple_3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("type_input_3x2.leo");
|
||||
let input_string = include_str!("input/type_nested_value_tuple_3x2.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_tuple_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_tuple_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("type_input_3x2.leo");
|
||||
let input_string = include_str!("input/type_nested_value_tuple_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_tuple_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_tuple_4x3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("type_input_4x3x2.leo");
|
||||
let input_string = include_str!("input/type_nested_value_tuple_4x3x2.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_tuple_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_tuple_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("type_input_4x3x2.leo");
|
||||
let input_string = include_str!("input/type_nested_value_tuple_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
@ -445,72 +445,72 @@ fn test_input_type_nested_value_tuple_4x3x2_fail() {
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_nested_3x2() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_nested_3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("type_input_3x2.leo");
|
||||
let input_string = include_str!("input/type_tuple_value_nested_3x2.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_nested_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_nested_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("type_input_3x2.leo");
|
||||
let input_string = include_str!("input/type_tuple_value_nested_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_nested_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_nested_4x3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("type_input_4x3x2.leo");
|
||||
let input_string = include_str!("input/type_tuple_value_nested_4x3x2.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_nested_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_nested_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("type_input_4x3x2.leo");
|
||||
let input_string = include_str!("input/type_tuple_value_nested_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_tuple_3x2() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_tuple_3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("type_input_3x2.leo");
|
||||
let input_string = include_str!("input/type_tuple_value_tuple_3x2.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_tuple_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_tuple_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("type_input_3x2.leo");
|
||||
let input_string = include_str!("input/type_tuple_value_tuple_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_tuple_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_tuple_4x3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program_string = include_str!("type_input_4x3x2.leo");
|
||||
let input_string = include_str!("input/type_tuple_value_tuple_4x3x2.in");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_tuple_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_tuple_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
let program_string = include_str!("type_input_4x3x2.leo");
|
||||
let input_string = include_str!("input/type_tuple_value_tuple_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_string, input_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
@ -40,37 +40,37 @@ pub fn output_false(program: EdwardsTestCompiler) {
|
||||
|
||||
#[test]
|
||||
fn test_input_pass() {
|
||||
let program_bytes = include_bytes!("assert_eq_input.leo");
|
||||
let input_bytes = include_bytes!("input/true_true.in");
|
||||
let program_string = include_str!("assert_eq_input.leo");
|
||||
let input_string = include_str!("input/true_true.in");
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_fail() {
|
||||
let program_bytes = include_bytes!("assert_eq_input.leo");
|
||||
let input_bytes = include_bytes!("input/true_false.in");
|
||||
let program_string = include_str!("assert_eq_input.leo");
|
||||
let input_string = include_str!("input/true_false.in");
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_registers() {
|
||||
let program_bytes = include_bytes!("output_register.leo");
|
||||
let true_input_bytes = include_bytes!("input/registers_true.in");
|
||||
let false_input_bytes = include_bytes!("input/registers_false.in");
|
||||
let program_string = include_str!("output_register.leo");
|
||||
let true_input_string = include_str!("input/registers_true.in");
|
||||
let false_input_string = include_str!("input/registers_false.in");
|
||||
|
||||
// test true input register => true output register
|
||||
let program = parse_program_with_input(program_bytes, true_input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, true_input_string).unwrap();
|
||||
|
||||
output_true(program);
|
||||
|
||||
// test false input register => false output register
|
||||
let program = parse_program_with_input(program_bytes, false_input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, false_input_string).unwrap();
|
||||
|
||||
output_false(program);
|
||||
}
|
||||
@ -79,32 +79,32 @@ fn test_registers() {
|
||||
|
||||
#[test]
|
||||
fn test_not_true() {
|
||||
let bytes = include_bytes!("not_true.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("not_true.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_not_false() {
|
||||
let bytes = include_bytes!("not_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("not_false.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_not_mutable() {
|
||||
let bytes = include_bytes!("not_mutable.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("not_mutable.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_not_u32() {
|
||||
let bytes = include_bytes!("not_u32.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("not_u32.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
@ -113,32 +113,32 @@ fn test_not_u32() {
|
||||
|
||||
#[test]
|
||||
fn test_true_or_true() {
|
||||
let bytes = include_bytes!("true_or_true.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("true_or_true.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_true_or_false() {
|
||||
let bytes = include_bytes!("true_or_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("true_or_false.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_false_or_false() {
|
||||
let bytes = include_bytes!("false_or_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("false_or_false.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_true_or_u32() {
|
||||
let bytes = include_bytes!("true_or_u32.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("true_or_u32.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
@ -147,32 +147,32 @@ fn test_true_or_u32() {
|
||||
|
||||
#[test]
|
||||
fn test_true_and_true() {
|
||||
let bytes = include_bytes!("true_and_true.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("true_and_true.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_true_and_false() {
|
||||
let bytes = include_bytes!("true_and_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("true_and_false.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_false_and_false() {
|
||||
let bytes = include_bytes!("false_and_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("false_and_false.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_true_and_u32() {
|
||||
let bytes = include_bytes!("true_and_u32.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("true_and_u32.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
@ -181,8 +181,8 @@ fn test_true_and_u32() {
|
||||
|
||||
#[test]
|
||||
fn test_all() {
|
||||
let bytes = include_bytes!("all.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("all.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ circuit Foo {
|
||||
}
|
||||
|
||||
circuit Bar {
|
||||
static function bar() {
|
||||
function bar() {
|
||||
let f = Foo { a: 0u32 };
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
circuit Foo {
|
||||
static function echo(x: u32) -> u32 {
|
||||
function echo(x: u32) -> u32 {
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
circuit Foo {
|
||||
x: u32,
|
||||
|
||||
function add_x(y: u32) -> u32 {
|
||||
function add_x(self, y: u32) -> u32 {
|
||||
return self.x + y
|
||||
}
|
||||
|
||||
function call_add_x(y: u32) -> u32 {
|
||||
function call_add_x(self, y: u32) -> u32 {
|
||||
return self.add_x(y)
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
let a = Foo { x: 1u32 };
|
||||
let b = a.call_add_x(1u32);
|
||||
let b = a.add_x(1u32);
|
||||
|
||||
console.assert(b == 2u32);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
circuit Foo {
|
||||
static function echo(x: u32) -> u32 {
|
||||
function echo(x: u32) -> u32 {
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
@ -5,5 +5,5 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let err = Foo::echo(1u32); // echo is a non-static function and must be accessed using `.`
|
||||
let err = Foo.echo(1u32); // Invalid, echo is a static function and must be accessed using `::`
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
circuit Foo {
|
||||
static function qux() {}
|
||||
function qux() {}
|
||||
|
||||
static function bar() {
|
||||
function bar() {
|
||||
Self::qux();
|
||||
}
|
||||
|
||||
static function baz() {
|
||||
function baz() {
|
||||
Self::bar();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
circuit Foo {
|
||||
static function echo(x: u32) -> u32 {
|
||||
function echo(x: u32) -> u32 {
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
circuit Foo {
|
||||
foo: u32,
|
||||
|
||||
static function bar() -> u32 {
|
||||
function bar() -> u32 {
|
||||
return 1u32
|
||||
}
|
||||
}
|
||||
|
@ -20,24 +20,24 @@ use crate::{assert_satisfied, expect_compiler_error, expect_type_inference_error
|
||||
|
||||
#[test]
|
||||
fn test_inline() {
|
||||
let bytes = include_bytes!("inline.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("inline.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inline_fail() {
|
||||
let bytes = include_bytes!("inline_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("inline_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inline_undefined() {
|
||||
let bytes = include_bytes!("inline_undefined.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("inline_undefined.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
@ -46,88 +46,88 @@ fn test_inline_undefined() {
|
||||
|
||||
#[test]
|
||||
fn test_member_variable() {
|
||||
let bytes = include_bytes!("member_variable.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("member_variable.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_variable_fail() {
|
||||
let bytes = include_bytes!("member_variable_fail.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("member_variable_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_variable_and_function() {
|
||||
let bytes = include_bytes!("member_variable_and_function.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("member_variable_and_function.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_function() {
|
||||
let bytes = include_bytes!("member_function.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("member_function.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_function_fail() {
|
||||
let bytes = include_bytes!("member_function_fail.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("member_function_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_function_invalid() {
|
||||
let bytes = include_bytes!("member_function_invalid.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("member_function_invalid.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_function_nested() {
|
||||
let bytes = include_bytes!("member_function_nested.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("member_function_nested.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_static_function() {
|
||||
let bytes = include_bytes!("member_static_function.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("member_static_function.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_static_function_nested() {
|
||||
let bytes = include_bytes!("member_static_function_nested.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("member_static_function_nested.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_static_function_invalid() {
|
||||
let bytes = include_bytes!("member_static_function_invalid.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("member_static_function_invalid.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_static_function_undefined() {
|
||||
let bytes = include_bytes!("member_static_function_undefined.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("member_static_function_undefined.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error)
|
||||
}
|
||||
@ -136,64 +136,64 @@ fn test_member_static_function_undefined() {
|
||||
|
||||
#[test]
|
||||
fn test_mutate_function_fail() {
|
||||
let bytes = include_bytes!("mut_function_fail.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("mut_function_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutate_self_variable() {
|
||||
let bytes = include_bytes!("mut_self_variable.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("mut_self_variable.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutate_self_variable_fail() {
|
||||
let bytes = include_bytes!("mut_self_variable_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("mut_self_variable_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutate_self_function_fail() {
|
||||
let bytes = include_bytes!("mut_self_function_fail.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("mut_self_function_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutate_self_static_function_fail() {
|
||||
let bytes = include_bytes!("mut_self_static_function_fail.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("mut_self_static_function_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutate_static_function_fail() {
|
||||
let bytes = include_bytes!("mut_static_function_fail.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("mut_static_function_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutate_variable() {
|
||||
let bytes = include_bytes!("mut_variable.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("mut_variable.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutate_variable_fail() {
|
||||
let bytes = include_bytes!("mut_variable_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("mut_variable_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
@ -202,32 +202,32 @@ fn test_mutate_variable_fail() {
|
||||
|
||||
#[test]
|
||||
fn test_self_fail() {
|
||||
let bytes = include_bytes!("self_fail.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("self_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_self_member_pass() {
|
||||
let bytes = include_bytes!("self_member.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("self_member.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_self_member_invalid() {
|
||||
let bytes = include_bytes!("self_member_invalid.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("self_member_invalid.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_self_member_undefined() {
|
||||
let bytes = include_bytes!("self_member_undefined.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("self_member_undefined.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
@ -236,16 +236,16 @@ fn test_self_member_undefined() {
|
||||
|
||||
#[test]
|
||||
fn test_pedersen_mock() {
|
||||
let bytes = include_bytes!("pedersen_mock.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("pedersen_mock.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_define_circuit_inside_circuit_function() {
|
||||
let bytes = include_bytes!("define_circuit_inside_circuit_function.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("define_circuit_inside_circuit_function.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ circuit Foo {
|
||||
|
||||
function bar() {}
|
||||
|
||||
function set_a(new: u8) {
|
||||
function set_a(mut self, new: u8) {
|
||||
self.bar = new;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
circuit Foo {
|
||||
a: u8,
|
||||
|
||||
static function bar() {}
|
||||
function bar() {}
|
||||
|
||||
function set_a(new: u8) {
|
||||
function set_a(mut self, new: u8) {
|
||||
self.bar = new;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
circuit Foo {
|
||||
mut a: u8,
|
||||
a: u8,
|
||||
|
||||
function set_a(new: u8) {
|
||||
function set_a(mut self, new: u8) {
|
||||
self.a = new;
|
||||
console.assert(self.a == new);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
circuit Foo {
|
||||
a: u8,
|
||||
|
||||
function set_a(new: u8) {
|
||||
function set_a(self, new: u8) {
|
||||
self.a = new;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
circuit Foo {
|
||||
static function bar() {}
|
||||
function bar() {}
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
circuit Foo {
|
||||
mut a: u8,
|
||||
a: u8,
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
@ -3,7 +3,7 @@ circuit Foo {
|
||||
}
|
||||
|
||||
function main() {
|
||||
let mut f = Foo { a: 0u8 };
|
||||
let f = Foo { a: 0u8 };
|
||||
|
||||
f.a = 1u8;
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
circuit PedersenHash {
|
||||
parameters: [u32; 512]
|
||||
|
||||
static function new(parameters: [u32; 512]) -> Self {
|
||||
function new(parameters: [u32; 512]) -> Self {
|
||||
return Self { parameters: parameters }
|
||||
}
|
||||
|
||||
function hash(bits: [bool; 512]) -> u32 {
|
||||
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;
|
||||
|
@ -1,7 +1,7 @@
|
||||
circuit Foo {
|
||||
f: u32,
|
||||
|
||||
function bar() -> u32 {
|
||||
function bar(self) -> u32 {
|
||||
return self.f
|
||||
}
|
||||
}
|
||||
|
@ -19,63 +19,63 @@ use leo_ast::InputValue;
|
||||
|
||||
#[test]
|
||||
fn test_log() {
|
||||
let bytes = include_bytes!("log.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("log.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_log_fail() {
|
||||
let bytes = include_bytes!("log_fail.leo");
|
||||
let program_string = include_str!("log_fail.leo");
|
||||
|
||||
assert!(parse_program(bytes).is_err());
|
||||
assert!(parse_program(program_string).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_log_parameter() {
|
||||
let bytes = include_bytes!("log_parameter.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("log_parameter.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_log_parameter_many() {
|
||||
let bytes = include_bytes!("log_parameter_many.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("log_parameter_many.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_log_parameter_fail_unknown() {
|
||||
let bytes = include_bytes!("log_parameter_fail_unknown.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("log_parameter_fail_unknown.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_log_parameter_fail_empty() {
|
||||
let bytes = include_bytes!("log_parameter_fail_empty.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("log_parameter_fail_empty.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_log_parameter_fail_none() {
|
||||
let bytes = include_bytes!("log_parameter_fail_empty.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("log_parameter_fail_empty.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_log_input() {
|
||||
let bytes = include_bytes!("log_input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("log_input.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![("a", Some(InputValue::Boolean(true)))]);
|
||||
|
||||
@ -88,8 +88,8 @@ fn test_log_input() {
|
||||
|
||||
#[test]
|
||||
fn test_debug() {
|
||||
let bytes = include_bytes!("debug.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("debug.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -98,8 +98,8 @@ fn test_debug() {
|
||||
|
||||
#[test]
|
||||
fn test_error() {
|
||||
let bytes = include_bytes!("error.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("error.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -108,8 +108,8 @@ fn test_error() {
|
||||
|
||||
#[test]
|
||||
fn test_assert() {
|
||||
let bytes = include_bytes!("assert.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("assert.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![("a", Some(InputValue::Boolean(true)))]);
|
||||
|
||||
@ -117,7 +117,7 @@ fn test_assert() {
|
||||
|
||||
assert_satisfied(program);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![("a", Some(InputValue::Boolean(false)))]);
|
||||
|
||||
@ -128,15 +128,15 @@ fn test_assert() {
|
||||
|
||||
#[test]
|
||||
fn test_conditional_assert() {
|
||||
let bytes = include_bytes!("conditional_assert.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("conditional_assert.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![("a", Some(InputValue::Boolean(true)))]);
|
||||
program.set_main_input(main_input);
|
||||
|
||||
assert_satisfied(program);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![("a", Some(InputValue::Boolean(false)))]);
|
||||
|
||||
|
@ -20,40 +20,40 @@ use crate::{assert_satisfied, expect_symbol_table_error, parse_program};
|
||||
|
||||
#[test]
|
||||
fn test_core_circuit_invalid() {
|
||||
let program_bytes = include_bytes!("core_package_invalid.leo");
|
||||
let program = parse_program(program_bytes).err().unwrap();
|
||||
let program_string = include_str!("core_package_invalid.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_symbol_table_error(program);
|
||||
expect_symbol_table_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_core_circuit_star_fail() {
|
||||
let program_bytes = include_bytes!("core_circuit_star_fail.leo");
|
||||
let error = parse_program(program_bytes).err().unwrap();
|
||||
let program_string = include_str!("core_circuit_star_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_symbol_table_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_core_package_invalid() {
|
||||
let program_bytes = include_bytes!("core_package_invalid.leo");
|
||||
let error = parse_program(program_bytes).err().unwrap();
|
||||
let program_string = include_str!("core_package_invalid.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_symbol_table_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_core_unstable_package_invalid() {
|
||||
let program_bytes = include_bytes!("core_unstable_package_invalid.leo");
|
||||
let error = parse_program(program_bytes).err().unwrap();
|
||||
let program_string = include_str!("core_unstable_package_invalid.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_symbol_table_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unstable_blake2s_sanity() {
|
||||
let program_bytes = include_bytes!("unstable_blake2s.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program_string = include_str!("unstable_blake2s.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
@ -32,33 +32,32 @@ use snarkos_models::algorithms::PRF;
|
||||
|
||||
#[test]
|
||||
fn test_arguments_length_fail() {
|
||||
let program_bytes = include_bytes!("arguments_length_fail.leo");
|
||||
let error = parse_program(program_bytes).err().unwrap();
|
||||
let program_string = include_str!("arguments_length_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_arguments_type_fail() {
|
||||
let program_bytes = include_bytes!("arguments_type_fail.leo");
|
||||
let error = parse_program(program_bytes).err().unwrap();
|
||||
let program_string = include_str!("arguments_type_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_blake2s_input() {
|
||||
let input_bytes = include_bytes!("inputs/valid_input.in");
|
||||
let program_bytes = include_bytes!("blake2s_input.leo");
|
||||
let expected_bytes = include_bytes!("outputs/valid_output.out");
|
||||
let input_string = include_str!("inputs/valid_input.in");
|
||||
let program_string = include_str!("blake2s_input.leo");
|
||||
let expected_string = include_str!("outputs/valid_output.out");
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
let expected = std::str::from_utf8(expected_bytes).unwrap();
|
||||
let actual_bytes = get_output(program);
|
||||
let actual = std::str::from_utf8(actual_bytes.bytes().as_slice()).unwrap();
|
||||
let actual_string = std::str::from_utf8(actual_bytes.bytes().as_slice()).unwrap();
|
||||
|
||||
assert_eq!(expected, actual)
|
||||
assert_eq!(expected_string, actual_string)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -81,7 +80,7 @@ fn test_blake2s_random() {
|
||||
|
||||
// The `blake2s_random.leo` program will compute a blake2s hash digest and compare it against
|
||||
// the expected value
|
||||
let bytes = include_bytes!("blake2s_random.leo");
|
||||
let bytes = include_str!("blake2s_random.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
|
@ -18,9 +18,9 @@ use crate::{assert_satisfied, import::set_local_dir, parse_program};
|
||||
|
||||
#[test]
|
||||
fn test_out_of_order() {
|
||||
let program_bytes = include_bytes!("out_of_order.leo");
|
||||
let program_string = include_str!("out_of_order.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -30,9 +30,9 @@ fn test_out_of_order() {
|
||||
fn test_out_of_order_with_import() {
|
||||
set_local_dir();
|
||||
|
||||
let program_bytes = include_bytes!("out_of_order_with_import.leo");
|
||||
let program_string = include_str!("out_of_order_with_import.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ fn test_negate() {
|
||||
let a_string = field_to_decimal_string(a);
|
||||
let b_string = field_to_decimal_string(b);
|
||||
|
||||
let bytes = include_bytes!("negate.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("negate.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Field(a_string))),
|
||||
@ -81,8 +81,8 @@ fn test_add() {
|
||||
let b_string = field_to_decimal_string(b);
|
||||
let c_string = field_to_decimal_string(c);
|
||||
|
||||
let bytes = include_bytes!("add.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("add.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Field(a_string))),
|
||||
@ -111,8 +111,8 @@ fn test_sub() {
|
||||
let b_string = field_to_decimal_string(b);
|
||||
let c_string = field_to_decimal_string(c);
|
||||
|
||||
let bytes = include_bytes!("sub.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("sub.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Field(a_string))),
|
||||
@ -140,8 +140,8 @@ fn test_div() {
|
||||
let b_string = field_to_decimal_string(b);
|
||||
let c_string = field_to_decimal_string(c);
|
||||
|
||||
let bytes = include_bytes!("div.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("div.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Field(a_string))),
|
||||
@ -169,8 +169,8 @@ fn test_mul() {
|
||||
let b_string = field_to_decimal_string(b);
|
||||
let c_string = field_to_decimal_string(c);
|
||||
|
||||
let bytes = include_bytes!("mul.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("mul.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Field(a_string))),
|
||||
@ -197,8 +197,8 @@ fn test_eq() {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("eq.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Field(a_string.clone()))),
|
||||
@ -214,7 +214,7 @@ fn test_eq() {
|
||||
|
||||
let c = a.eq(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Field(a_string))),
|
||||
@ -237,8 +237,8 @@ fn test_console_assert_pass() {
|
||||
|
||||
let a_string = field_to_decimal_string(a);
|
||||
|
||||
let bytes = include_bytes!("console_assert.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("console_assert.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Field(a_string.clone()))),
|
||||
@ -266,8 +266,8 @@ fn test_console_assert_fail() {
|
||||
let a_string = field_to_decimal_string(a);
|
||||
let b_string = field_to_decimal_string(b);
|
||||
|
||||
let bytes = include_bytes!("console_assert.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("console_assert.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Field(a_string))),
|
||||
@ -290,8 +290,8 @@ fn test_ternary() {
|
||||
let a_string = field_to_decimal_string(a);
|
||||
let b_string = field_to_decimal_string(b);
|
||||
|
||||
let bytes = include_bytes!("ternary.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("ternary.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
// true -> field a
|
||||
let main_input = generate_main_input(vec![
|
||||
@ -305,7 +305,7 @@ fn test_ternary() {
|
||||
|
||||
assert_satisfied(program);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
// false -> field b
|
||||
let main_input = generate_main_input(vec![
|
||||
@ -322,24 +322,24 @@ fn test_ternary() {
|
||||
|
||||
//
|
||||
// pub fn output_one(program: EdwardsTestCompiler) {
|
||||
// let expected = include_bytes!("output_/register_one.out");
|
||||
// let expected = include_str!("output_/register_one.out");
|
||||
// let actual = get_output(program);
|
||||
//
|
||||
// assert_eq!(expected, actual.bytes().as_slice());
|
||||
// assert_eq!(expected, actual.program_string().as_slice());
|
||||
// }
|
||||
//
|
||||
// pub fn output_zero(program: EdwardsTestCompiler) {
|
||||
// let expected = include_bytes!("output_/register_zero.out");
|
||||
// let expected = include_str!("output_/register_zero.out");
|
||||
// let actual = get_output(program);
|
||||
//
|
||||
// assert_eq!(expected, actual.bytes().as_slice());
|
||||
// assert_eq!(expected, actual.program_string().as_slice());
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn test_registers() {
|
||||
// let program_bytes = include_bytes!("output_register.leo");
|
||||
// let one_input_bytes = include_bytes!("input/register_one.in");
|
||||
// let zero_input_bytes = include_bytes!("input/register_zero.in");
|
||||
// let program_bytes = include_str!("output_register.leo");
|
||||
// let one_input_bytes = include_str!("input/register_one.in");
|
||||
// let zero_input_bytes = include_str!("input/register_zero.in");
|
||||
//
|
||||
// // test 1field input register => 1field output register
|
||||
// let program = parse_program_with_input(program_bytes, one_input_bytes).unwrap();
|
||||
|
@ -26,85 +26,99 @@ use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, Statem
|
||||
|
||||
#[test]
|
||||
fn test_empty() {
|
||||
let bytes = include_bytes!("empty.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("empty.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iteration() {
|
||||
let bytes = include_bytes!("iteration.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("iteration.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iteration_repeated() {
|
||||
let bytes = include_bytes!("iteration_repeated.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("iteration_repeated.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_newlines() {
|
||||
let input_bytes = include_bytes!("input/newlines.in");
|
||||
let program_bytes = include_bytes!("newlines.leo");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let input_string = include_str!("input/newlines.in");
|
||||
let program_string = include_str!("newlines.leo");
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
let expected_bytes = include_bytes!("output/newlines.out");
|
||||
let expected = std::str::from_utf8(expected_bytes).unwrap();
|
||||
let expected_string = include_str!("output/newlines.out");
|
||||
let actual_bytes = get_output(program);
|
||||
let actual = std::str::from_utf8(actual_bytes.bytes().as_slice()).unwrap();
|
||||
let actual_string = std::str::from_utf8(actual_bytes.bytes().as_slice()).unwrap();
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
assert_eq!(expected_string, actual_string);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_returns() {
|
||||
let bytes = include_bytes!("multiple.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("multiple_returns.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_returns_fail() {
|
||||
let program_string = include_str!("multiple_returns_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_returns_fail_conditional() {
|
||||
let program_string = include_str!("multiple_returns_fail_conditional.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_returns_main() {
|
||||
let program_bytes = include_bytes!("multiple_main.leo");
|
||||
let input_bytes = include_bytes!("input/registers.in");
|
||||
let program_string = include_str!("multiple_returns_main.leo");
|
||||
let input_string = include_str!("input/registers.in");
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
let expected_bytes = include_bytes!("output/registers.out");
|
||||
let expected = std::str::from_utf8(expected_bytes).unwrap();
|
||||
let expected_string = include_str!("output/registers.out");
|
||||
let actual_bytes = get_output(program);
|
||||
let actual = std::str::from_utf8(actual_bytes.bytes().as_slice()).unwrap();
|
||||
let actual_string = std::str::from_utf8(actual_bytes.bytes().as_slice()).unwrap();
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
assert_eq!(expected_string, actual_string);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeated_function_call() {
|
||||
let bytes = include_bytes!("repeated.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("repeated.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_return() {
|
||||
let bytes = include_bytes!("return.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("return.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scope_fail() {
|
||||
let bytes = include_bytes!("scope_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("scope_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
match expect_compiler_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
@ -119,24 +133,24 @@ fn test_scope_fail() {
|
||||
|
||||
#[test]
|
||||
fn test_undefined() {
|
||||
let bytes = include_bytes!("undefined.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("undefined.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_value_unchanged() {
|
||||
let bytes = include_bytes!("value_unchanged.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("value_unchanged.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_input() {
|
||||
let bytes = include_bytes!("array_input.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("array_input.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error)
|
||||
}
|
||||
@ -145,32 +159,32 @@ fn test_array_input() {
|
||||
|
||||
#[test]
|
||||
fn test_return_array_nested_fail() {
|
||||
let bytes = include_bytes!("return_array_nested_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("return_array_nested_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_return_array_nested_pass() {
|
||||
let bytes = include_bytes!("return_array_nested_pass.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("return_array_nested_pass.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_return_array_tuple_fail() {
|
||||
let bytes = include_bytes!("return_array_tuple_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("return_array_tuple_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let _err = expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_return_array_tuple_pass() {
|
||||
let bytes = include_bytes!("return_array_tuple_pass.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("return_array_tuple_pass.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -179,16 +193,16 @@ fn test_return_array_tuple_pass() {
|
||||
|
||||
#[test]
|
||||
fn test_return_tuple() {
|
||||
let bytes = include_bytes!("return_tuple.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("return_tuple.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_return_tuple_conditional() {
|
||||
let bytes = include_bytes!("return_tuple_conditional.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("return_tuple_conditional.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
7
compiler/tests/function/multiple_returns_fail.leo
Normal file
7
compiler/tests/function/multiple_returns_fail.leo
Normal file
@ -0,0 +1,7 @@
|
||||
function main () -> i8 {
|
||||
if true {
|
||||
return 1i8 //ignored
|
||||
}
|
||||
return 2i8 //ignored
|
||||
return 3i8 //returns
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
function main () -> u16 {
|
||||
if false {
|
||||
let a = 1u16;
|
||||
let b = a + 1u16;
|
||||
return b
|
||||
} else if false {
|
||||
return 0u16
|
||||
}
|
||||
}
|
@ -15,8 +15,13 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{
|
||||
assert_satisfied, expect_compiler_error, expect_synthesis_error, field::field_to_decimal_string,
|
||||
generate_main_input, parse_program, parse_program_with_input,
|
||||
assert_satisfied,
|
||||
expect_compiler_error,
|
||||
expect_synthesis_error,
|
||||
field::field_to_decimal_string,
|
||||
generate_main_input,
|
||||
parse_program,
|
||||
parse_program_with_input,
|
||||
};
|
||||
use leo_ast::{GroupCoordinate, GroupTuple, GroupValue, InputValue, Span};
|
||||
|
||||
@ -47,124 +52,124 @@ pub fn group_element_to_input_value(g: EdwardsAffine) -> GroupValue {
|
||||
|
||||
#[test]
|
||||
fn test_one() {
|
||||
let bytes = include_bytes!("one.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("one.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero() {
|
||||
let bytes = include_bytes!("zero.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("zero.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_point() {
|
||||
let bytes = include_bytes!("point.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("point.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_x_sign_high() {
|
||||
let bytes = include_bytes!("x_sign_high.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("x_sign_high.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_x_sign_low() {
|
||||
let bytes = include_bytes!("x_sign_low.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("x_sign_low.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_x_sign_inferred() {
|
||||
let bytes = include_bytes!("x_sign_inferred.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("x_sign_inferred.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_y_sign_high() {
|
||||
let bytes = include_bytes!("y_sign_high.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("y_sign_high.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_y_sign_low() {
|
||||
let bytes = include_bytes!("y_sign_low.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("y_sign_low.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_y_sign_inferred() {
|
||||
let bytes = include_bytes!("y_sign_inferred.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("y_sign_inferred.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_both_sign_high() {
|
||||
let bytes = include_bytes!("both_sign_high.leo");
|
||||
let program_string = include_str!("both_sign_high.leo");
|
||||
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_both_sign_low() {
|
||||
let bytes = include_bytes!("both_sign_low.leo");
|
||||
let program_string = include_str!("both_sign_low.leo");
|
||||
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_both_sign_inferred() {
|
||||
let bytes = include_bytes!("both_sign_inferred.leo");
|
||||
let program_string = include_str!("both_sign_inferred.leo");
|
||||
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_point_input() {
|
||||
let program_bytes = include_bytes!("point_input.leo");
|
||||
let input_bytes = include_bytes!("input/point.in");
|
||||
let program_string = include_str!("point_input.leo");
|
||||
let input_bytes = include_str!("input/point.in");
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input() {
|
||||
let program_bytes = include_bytes!("input.leo");
|
||||
let input_bytes_pass = include_bytes!("input/valid.in");
|
||||
let input_bytes_fail = include_bytes!("input/invalid.in");
|
||||
let program_string = include_str!("input.leo");
|
||||
let input_string_pass = include_str!("input/valid.in");
|
||||
let input_string_fail = include_str!("input/invalid.in");
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes_pass).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_string_pass).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes_fail).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_string_fail).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
@ -182,8 +187,8 @@ fn test_negate() {
|
||||
let a_element = group_element_to_input_value(a);
|
||||
let b_element = group_element_to_input_value(b);
|
||||
|
||||
let bytes = include_bytes!("negate.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("negate.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Group(a_element))),
|
||||
@ -210,8 +215,8 @@ fn test_add() {
|
||||
let b_element = group_element_to_input_value(b);
|
||||
let c_element = group_element_to_input_value(c);
|
||||
|
||||
let bytes = include_bytes!("add.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("add.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Group(a_element))),
|
||||
@ -239,8 +244,8 @@ fn test_sub() {
|
||||
let b_element = group_element_to_input_value(b);
|
||||
let c_element = group_element_to_input_value(c);
|
||||
|
||||
let bytes = include_bytes!("sub.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("sub.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Group(a_element))),
|
||||
@ -262,8 +267,8 @@ fn test_console_assert_pass() {
|
||||
|
||||
let a_element = group_element_to_input_value(a);
|
||||
|
||||
let bytes = include_bytes!("assert_eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("assert_eq.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Group(a_element.clone()))),
|
||||
@ -291,8 +296,8 @@ fn test_console_assert_fail() {
|
||||
let a_element = group_element_to_input_value(a);
|
||||
let b_element = group_element_to_input_value(b);
|
||||
|
||||
let bytes = include_bytes!("assert_eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("assert_eq.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Group(a_element))),
|
||||
@ -318,8 +323,8 @@ fn test_eq() {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("eq.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Group(a_element.clone()))),
|
||||
@ -335,7 +340,7 @@ fn test_eq() {
|
||||
|
||||
let c = a.eq(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Group(a_element))),
|
||||
@ -359,8 +364,8 @@ fn test_ternary() {
|
||||
let a_element = group_element_to_input_value(a);
|
||||
let b_element = group_element_to_input_value(b);
|
||||
|
||||
let bytes = include_bytes!("ternary.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("ternary.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
// true -> field a
|
||||
let main_input = generate_main_input(vec![
|
||||
@ -374,7 +379,7 @@ fn test_ternary() {
|
||||
|
||||
assert_satisfied(program);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
// false -> field b
|
||||
let main_input = generate_main_input(vec![
|
||||
|
@ -34,8 +34,8 @@ pub fn set_local_dir() {
|
||||
fn test_basic() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("basic.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("basic.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -45,8 +45,8 @@ fn test_basic() {
|
||||
fn test_multiple() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("multiple.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("multiple.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -56,8 +56,8 @@ fn test_multiple() {
|
||||
fn test_star() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("star.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("star.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -67,8 +67,8 @@ fn test_star() {
|
||||
fn test_star_fail() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("star_fail.leo");
|
||||
assert!(parse_program(bytes).is_err());
|
||||
let program_string = include_str!("star_fail.leo");
|
||||
assert!(parse_program(program_string).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -76,8 +76,8 @@ fn test_star_fail() {
|
||||
fn test_alias() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("alias.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("alias.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -88,8 +88,8 @@ fn test_alias() {
|
||||
fn test_names_pass() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("names.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("names.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -99,8 +99,8 @@ fn test_names_pass() {
|
||||
fn test_names_fail_1() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("names_dash_a.leo");
|
||||
assert!(parse_program(bytes).is_err());
|
||||
let program_string = include_str!("names_dash_a.leo");
|
||||
assert!(parse_program(program_string).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -108,8 +108,8 @@ fn test_names_fail_1() {
|
||||
fn test_names_fail_2() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("names_a_dash.leo");
|
||||
assert!(parse_program(bytes).is_err());
|
||||
let program_string = include_str!("names_a_dash.leo");
|
||||
assert!(parse_program(program_string).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -117,8 +117,8 @@ fn test_names_fail_2() {
|
||||
fn test_names_fail_3() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("names_underscore.leo");
|
||||
assert!(parse_program(bytes).is_err());
|
||||
let program_string = include_str!("names_underscore.leo");
|
||||
assert!(parse_program(program_string).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -126,8 +126,8 @@ fn test_names_fail_3() {
|
||||
fn test_names_fail_4() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("names_dollar.leo");
|
||||
assert!(parse_program(bytes).is_err());
|
||||
let program_string = include_str!("names_dollar.leo");
|
||||
assert!(parse_program(program_string).is_err());
|
||||
}
|
||||
|
||||
// more complex tests
|
||||
@ -136,8 +136,8 @@ fn test_names_fail_4() {
|
||||
fn test_many_import() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("many_import.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("many_import.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -147,8 +147,8 @@ fn test_many_import() {
|
||||
fn test_many_import_star() {
|
||||
set_local_dir();
|
||||
|
||||
let bytes = include_bytes!("many_import_star.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("many_import_star.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
@ -26,40 +26,40 @@ fn expect_fail(program: EdwardsTestCompiler) {
|
||||
|
||||
#[test]
|
||||
fn test_input_pass() {
|
||||
let program_bytes = include_bytes!("main.leo");
|
||||
let input_bytes = include_bytes!("input/main.in");
|
||||
let program_string = include_str!("main.leo");
|
||||
let input_string = include_str!("input/main.in");
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_fail_name() {
|
||||
let program_bytes = include_bytes!("main.leo");
|
||||
let input_bytes = include_bytes!("input/main_fail_name.in");
|
||||
let program_string = include_str!("main.leo");
|
||||
let input_string = include_str!("input/main_fail_name.in");
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
expect_fail(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_fail_type() {
|
||||
let program_bytes = include_bytes!("main.leo");
|
||||
let input_bytes = include_bytes!("input/main_fail_type.in");
|
||||
let program_string = include_str!("main.leo");
|
||||
let input_string = include_str!("input/main_fail_type.in");
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
expect_fail(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_multiple() {
|
||||
let program_bytes = include_bytes!("main_multiple.leo");
|
||||
let input_bytes = include_bytes!("input/main_multiple.in");
|
||||
let program_string = include_str!("main_multiple.leo");
|
||||
let input_string = include_str!("input/main_multiple.in");
|
||||
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
@ -18,27 +18,27 @@ use crate::{assert_satisfied, parse_input_and_state, parse_program_with_input_an
|
||||
|
||||
#[test]
|
||||
fn test_basic() {
|
||||
let input_bytes = include_bytes!("input/basic.in");
|
||||
let state_bytes = include_bytes!("input/basic.state");
|
||||
let input_string = include_str!("input/basic.in");
|
||||
let state_string = include_str!("input/basic.state");
|
||||
|
||||
parse_input_and_state(input_bytes, state_bytes).unwrap();
|
||||
parse_input_and_state(input_string, state_string).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_full() {
|
||||
let input_bytes = include_bytes!("input/token_withdraw.in");
|
||||
let state_bytes = include_bytes!("input/token_withdraw.state");
|
||||
let input_string = include_str!("input/token_withdraw.in");
|
||||
let state_string = include_str!("input/token_withdraw.state");
|
||||
|
||||
parse_input_and_state(input_bytes, state_bytes).unwrap();
|
||||
parse_input_and_state(input_string, state_string).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_access() {
|
||||
let program_bytes = include_bytes!("access.leo");
|
||||
let input_bytes = include_bytes!("input/token_withdraw.in");
|
||||
let state_bytes = include_bytes!("input/token_withdraw.state");
|
||||
let program_string = include_str!("access.leo");
|
||||
let input_string = include_str!("input/token_withdraw.in");
|
||||
let state_string = include_str!("input/token_withdraw.state");
|
||||
|
||||
let program = parse_program_with_input_and_state(program_bytes, input_bytes, state_bytes).unwrap();
|
||||
let program = parse_program_with_input_and_state(program_string, input_string, state_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
@ -18,61 +18,61 @@ use crate::{assert_satisfied, parse_program_with_state, parse_state};
|
||||
|
||||
#[test]
|
||||
fn test_basic() {
|
||||
let bytes = include_bytes!("input/basic.state");
|
||||
let state_string = include_str!("input/basic.state");
|
||||
|
||||
parse_state(bytes).unwrap();
|
||||
parse_state(state_string).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_token_withdraw() {
|
||||
let bytes = include_bytes!("input/token_withdraw.state");
|
||||
let state_string = include_str!("input/token_withdraw.state");
|
||||
|
||||
parse_state(bytes).unwrap();
|
||||
parse_state(state_string).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_access_state() {
|
||||
let program_bytes = include_bytes!("access_state.leo");
|
||||
let state_bytes = include_bytes!("input/token_withdraw.state");
|
||||
let program_string = include_str!("access_state.leo");
|
||||
let state_string = include_str!("input/token_withdraw.state");
|
||||
|
||||
let program = parse_program_with_state(program_bytes, state_bytes).unwrap();
|
||||
let program = parse_program_with_state(program_string, state_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_access_all() {
|
||||
let program_bytes = include_bytes!("access_all.leo");
|
||||
let state_bytes = include_bytes!("input/token_withdraw.state");
|
||||
let program_string = include_str!("access_all.leo");
|
||||
let state_string = include_str!("input/token_withdraw.state");
|
||||
|
||||
let program = parse_program_with_state(program_bytes, state_bytes).unwrap();
|
||||
let program = parse_program_with_state(program_string, state_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_visibility_fail() {
|
||||
let state_bytes = include_bytes!("input/visibility_fail.state");
|
||||
let state_string = include_str!("input/visibility_fail.state");
|
||||
|
||||
let is_err = parse_state(state_bytes).is_err();
|
||||
let is_err = parse_state(state_string).is_err();
|
||||
|
||||
assert!(is_err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_section_undefined() {
|
||||
let state_bytes = include_bytes!("input/section_undefined.state");
|
||||
let state_string = include_str!("input/section_undefined.state");
|
||||
|
||||
let is_err = parse_state(state_bytes).is_err();
|
||||
let is_err = parse_state(state_string).is_err();
|
||||
|
||||
assert!(is_err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_section_invalid() {
|
||||
let state_bytes = include_bytes!("input/section_invalid.state");
|
||||
let state_string = include_str!("input/section_invalid.state");
|
||||
|
||||
let is_err = parse_state(state_bytes).is_err();
|
||||
let is_err = parse_state(state_string).is_err();
|
||||
|
||||
assert!(is_err);
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ macro_rules! test_int {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bytes = include_bytes!("negate.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("negate.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
("b", Some(InputValue::Integer($integer_type, b.to_string()))),
|
||||
@ -42,15 +42,15 @@ macro_rules! test_int {
|
||||
}
|
||||
|
||||
fn test_negate_min_fail() {
|
||||
let bytes = include_bytes!("negate_min.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("negate_min.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_computation_error(program);
|
||||
}
|
||||
|
||||
fn test_negate_zero() {
|
||||
let bytes = include_bytes!("negate_zero.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("negate_zero.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
@ -58,29 +58,29 @@ macro_rules! test_int {
|
||||
|
||||
impl IntegerTester for $name {
|
||||
fn test_min() {
|
||||
let bytes = include_bytes!("min.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("min.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
fn test_min_fail() {
|
||||
let bytes = include_bytes!("min_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("min_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_parsing_error(program);
|
||||
}
|
||||
|
||||
fn test_max() {
|
||||
let bytes = include_bytes!("max.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("max.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
fn test_max_fail() {
|
||||
let bytes = include_bytes!("max_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("max_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_parsing_error(program);
|
||||
}
|
||||
@ -95,8 +95,8 @@ macro_rules! test_int {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bytes = include_bytes!("add.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("add.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -124,8 +124,8 @@ macro_rules! test_int {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bytes = include_bytes!("sub.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("sub.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -149,8 +149,8 @@ macro_rules! test_int {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bytes = include_bytes!("mul.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("mul.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -176,8 +176,8 @@ macro_rules! test_int {
|
||||
continue;
|
||||
}
|
||||
|
||||
let bytes = include_bytes!("div.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("div.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
// expect an error when dividing by zero
|
||||
if b == 0 {
|
||||
@ -220,8 +220,8 @@ macro_rules! test_int {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bytes = include_bytes!("pow.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("pow.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -242,8 +242,8 @@ macro_rules! test_int {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("eq.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -259,7 +259,7 @@ macro_rules! test_int {
|
||||
|
||||
let c = a.eq(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -280,8 +280,8 @@ macro_rules! test_int {
|
||||
|
||||
// test a != a == false
|
||||
|
||||
let bytes = include_bytes!("ne.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("ne.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -297,7 +297,7 @@ macro_rules! test_int {
|
||||
|
||||
let c = a.ne(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -318,8 +318,8 @@ macro_rules! test_int {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("ge.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("ge.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -335,7 +335,7 @@ macro_rules! test_int {
|
||||
|
||||
let c = a.ge(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -356,8 +356,8 @@ macro_rules! test_int {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("gt.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("gt.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -373,7 +373,7 @@ macro_rules! test_int {
|
||||
|
||||
let c = a.gt(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -394,8 +394,8 @@ macro_rules! test_int {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("le.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("le.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -411,7 +411,7 @@ macro_rules! test_int {
|
||||
|
||||
let c = a.le(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -432,8 +432,8 @@ macro_rules! test_int {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("lt.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("lt.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -449,7 +449,7 @@ macro_rules! test_int {
|
||||
|
||||
let c = a.lt(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -468,8 +468,8 @@ macro_rules! test_int {
|
||||
let a: $type_ = rand::random();
|
||||
|
||||
// test equal
|
||||
let bytes = include_bytes!("console_assert.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("console_assert.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -487,7 +487,7 @@ macro_rules! test_int {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -504,8 +504,8 @@ macro_rules! test_int {
|
||||
let a: $type_ = rand::random();
|
||||
let b: $type_ = rand::random();
|
||||
|
||||
let bytes = include_bytes!("ternary.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("ternary.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
// true -> field 1
|
||||
let main_input = generate_main_input(vec![
|
||||
@ -520,7 +520,7 @@ macro_rules! test_int {
|
||||
assert_satisfied(program);
|
||||
|
||||
// false -> field 2
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("s", Some(InputValue::Boolean(false))),
|
||||
|
@ -20,29 +20,29 @@ macro_rules! test_uint {
|
||||
|
||||
impl IntegerTester for $name {
|
||||
fn test_min() {
|
||||
let bytes = include_bytes!("min.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("min.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
fn test_min_fail() {
|
||||
let bytes = include_bytes!("min_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("min_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_parsing_error(program);
|
||||
}
|
||||
|
||||
fn test_max() {
|
||||
let bytes = include_bytes!("max.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("max.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
fn test_max_fail() {
|
||||
let bytes = include_bytes!("max_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("max_fail.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_parsing_error(program);
|
||||
}
|
||||
@ -57,8 +57,8 @@ macro_rules! test_uint {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bytes = include_bytes!("add.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("add.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -82,8 +82,8 @@ macro_rules! test_uint {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bytes = include_bytes!("sub.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("sub.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -107,8 +107,8 @@ macro_rules! test_uint {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bytes = include_bytes!("mul.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("mul.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -132,8 +132,8 @@ macro_rules! test_uint {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bytes = include_bytes!("div.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("div.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -158,8 +158,8 @@ macro_rules! test_uint {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bytes = include_bytes!("pow.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("pow.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -180,8 +180,8 @@ macro_rules! test_uint {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("eq.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -197,7 +197,7 @@ macro_rules! test_uint {
|
||||
|
||||
let c = a.eq(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -218,8 +218,8 @@ macro_rules! test_uint {
|
||||
|
||||
// test a != a == false
|
||||
|
||||
let bytes = include_bytes!("ne.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("ne.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -235,7 +235,7 @@ macro_rules! test_uint {
|
||||
|
||||
let c = a.ne(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -256,8 +256,8 @@ macro_rules! test_uint {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("ge.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("ge.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -273,7 +273,7 @@ macro_rules! test_uint {
|
||||
|
||||
let c = a.ge(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -294,8 +294,8 @@ macro_rules! test_uint {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("gt.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("gt.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -311,7 +311,7 @@ macro_rules! test_uint {
|
||||
|
||||
let c = a.gt(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -332,8 +332,8 @@ macro_rules! test_uint {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("le.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("le.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -349,7 +349,7 @@ macro_rules! test_uint {
|
||||
|
||||
let c = a.le(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -370,8 +370,8 @@ macro_rules! test_uint {
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("lt.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("lt.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -387,7 +387,7 @@ macro_rules! test_uint {
|
||||
|
||||
let c = a.lt(&b);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -406,8 +406,8 @@ macro_rules! test_uint {
|
||||
let a: $type_ = rand::random();
|
||||
|
||||
// test equal
|
||||
let bytes = include_bytes!("console_assert.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("console_assert.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -425,7 +425,7 @@ macro_rules! test_uint {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Integer($integer_type, a.to_string()))),
|
||||
@ -442,8 +442,8 @@ macro_rules! test_uint {
|
||||
let a: $type_ = rand::random();
|
||||
let b: $type_ = rand::random();
|
||||
|
||||
let bytes = include_bytes!("ternary.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("ternary.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
// true -> field 1
|
||||
let main_input = generate_main_input(vec![
|
||||
@ -458,7 +458,7 @@ macro_rules! test_uint {
|
||||
assert_satisfied(program);
|
||||
|
||||
// false -> field 2
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("s", Some(InputValue::Boolean(false))),
|
||||
|
@ -64,94 +64,79 @@ fn new_compiler() -> EdwardsTestCompiler {
|
||||
EdwardsTestCompiler::new(program_name, path, output_dir)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_program(bytes: &[u8]) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
pub(crate) fn parse_program(program_string: &str) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
let mut compiler = new_compiler();
|
||||
let program_string = String::from_utf8_lossy(bytes);
|
||||
|
||||
compiler.parse_program_from_string(&program_string)?;
|
||||
compiler.parse_program_from_string(program_string)?;
|
||||
|
||||
Ok(compiler)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_input(bytes: &[u8]) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
pub(crate) fn parse_input(input_string: &str) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
let mut compiler = new_compiler();
|
||||
let input_string = String::from_utf8_lossy(bytes);
|
||||
let path = PathBuf::new();
|
||||
|
||||
compiler.parse_input(&input_string, &path, EMPTY_FILE, &path)?;
|
||||
compiler.parse_input(input_string, &path, EMPTY_FILE, &path)?;
|
||||
|
||||
Ok(compiler)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_state(bytes: &[u8]) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
pub(crate) fn parse_state(state_string: &str) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
let mut compiler = new_compiler();
|
||||
let state_string = String::from_utf8_lossy(bytes);
|
||||
let path = PathBuf::new();
|
||||
|
||||
compiler.parse_input(EMPTY_FILE, &path, &state_string, &path)?;
|
||||
compiler.parse_input(EMPTY_FILE, &path, state_string, &path)?;
|
||||
|
||||
Ok(compiler)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_input_and_state(
|
||||
input_bytes: &[u8],
|
||||
state_bytes: &[u8],
|
||||
input_string: &str,
|
||||
state_string: &str,
|
||||
) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
let mut compiler = new_compiler();
|
||||
let input_string = String::from_utf8_lossy(input_bytes);
|
||||
let state_string = String::from_utf8_lossy(state_bytes);
|
||||
let path = PathBuf::new();
|
||||
|
||||
compiler.parse_input(&input_string, &path, &state_string, &path)?;
|
||||
compiler.parse_input(input_string, &path, state_string, &path)?;
|
||||
|
||||
Ok(compiler)
|
||||
}
|
||||
|
||||
pub fn parse_program_with_input(
|
||||
program_bytes: &[u8],
|
||||
input_bytes: &[u8],
|
||||
program_string: &str,
|
||||
input_string: &str,
|
||||
) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
let mut compiler = new_compiler();
|
||||
|
||||
let program_string = String::from_utf8_lossy(program_bytes);
|
||||
let input_string = String::from_utf8_lossy(input_bytes);
|
||||
let path = PathBuf::new();
|
||||
|
||||
compiler.parse_input(&input_string, &path, EMPTY_FILE, &path)?;
|
||||
compiler.parse_program_from_string(&program_string)?;
|
||||
compiler.parse_input(input_string, &path, EMPTY_FILE, &path)?;
|
||||
compiler.parse_program_from_string(program_string)?;
|
||||
|
||||
Ok(compiler)
|
||||
}
|
||||
|
||||
pub fn parse_program_with_state(
|
||||
program_bytes: &[u8],
|
||||
state_bytes: &[u8],
|
||||
program_string: &str,
|
||||
state_string: &str,
|
||||
) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
let mut compiler = new_compiler();
|
||||
|
||||
let program_string = String::from_utf8_lossy(program_bytes);
|
||||
let state_string = String::from_utf8_lossy(state_bytes);
|
||||
let path = PathBuf::new();
|
||||
|
||||
compiler.parse_input(EMPTY_FILE, &path, &state_string, &path)?;
|
||||
compiler.parse_program_from_string(&program_string)?;
|
||||
compiler.parse_input(EMPTY_FILE, &path, state_string, &path)?;
|
||||
compiler.parse_program_from_string(program_string)?;
|
||||
|
||||
Ok(compiler)
|
||||
}
|
||||
|
||||
pub fn parse_program_with_input_and_state(
|
||||
program_bytes: &[u8],
|
||||
input_bytes: &[u8],
|
||||
state_bytes: &[u8],
|
||||
program_string: &str,
|
||||
input_string: &str,
|
||||
state_string: &str,
|
||||
) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
let mut compiler = new_compiler();
|
||||
|
||||
let program_string = String::from_utf8_lossy(program_bytes);
|
||||
let input_string = String::from_utf8_lossy(input_bytes);
|
||||
let state_string = String::from_utf8_lossy(state_bytes);
|
||||
let path = PathBuf::new();
|
||||
|
||||
compiler.parse_input(&input_string, &path, &state_string, &path)?;
|
||||
compiler.parse_input(input_string, &path, state_string, &path)?;
|
||||
compiler.parse_program_from_string(&program_string)?;
|
||||
|
||||
Ok(compiler)
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Adding the `mut` keyword makes a circuit variable mutable.
|
||||
circuit Foo {
|
||||
static function bar() {}
|
||||
function bar() {}
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Adding the `mut` keyword makes a circuit variable mutable.
|
||||
circuit Foo {
|
||||
mut x: u32
|
||||
x: u32
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
5
compiler/tests/mutability/let_mut_nested.leo
Normal file
5
compiler/tests/mutability/let_mut_nested.leo
Normal file
@ -0,0 +1,5 @@
|
||||
function main () {
|
||||
let mut x = 2u8;
|
||||
let mut y = x;
|
||||
let z = y / 2u8;
|
||||
}
|
@ -19,96 +19,104 @@ use leo_ast::InputValue;
|
||||
|
||||
#[test]
|
||||
fn test_let() {
|
||||
let bytes = include_bytes!("let.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("let.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_let_mut() {
|
||||
let bytes = include_bytes!("let_mut.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("let_mut.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_let_mut_nested() {
|
||||
let program_string = include_str!("let_mut_nested.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_const_fail() {
|
||||
let bytes = include_bytes!("const.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("const.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_const_mut_fail() {
|
||||
let bytes = include_bytes!("const_mut.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("const_mut.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array() {
|
||||
let bytes = include_bytes!("array.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("array.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_mut() {
|
||||
let bytes = include_bytes!("array_mut.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("array_mut.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit() {
|
||||
let bytes = include_bytes!("circuit.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("circuit.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_mut() {
|
||||
let bytes = include_bytes!("circuit_mut.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("circuit_mut.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
expect_compiler_error(program);
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_variable_mut() {
|
||||
let bytes = include_bytes!("circuit_variable_mut.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("circuit_variable_mut.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_function_mut() {
|
||||
let bytes = include_bytes!("circuit_function_mut.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("circuit_function_mut.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_static_function_mut() {
|
||||
let bytes = include_bytes!("circuit_static_function_mut.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("circuit_static_function_mut.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_input() {
|
||||
let bytes = include_bytes!("function_input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("function_input.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![("a", Some(InputValue::Boolean(true)))]);
|
||||
|
||||
@ -119,8 +127,8 @@ fn test_function_input() {
|
||||
|
||||
#[test]
|
||||
fn test_function_input_mut() {
|
||||
let bytes = include_bytes!("function_input_mut.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("function_input_mut.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![("a", Some(InputValue::Boolean(true)))]);
|
||||
|
||||
|
@ -28,8 +28,8 @@ use leo_ast::InputValue;
|
||||
|
||||
#[test]
|
||||
fn test_assert() {
|
||||
let bytes = include_bytes!("assert.leo");
|
||||
let mut program_1_pass = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("assert.leo");
|
||||
let mut program_1_pass = parse_program(program_string).unwrap();
|
||||
let mut program_0_pass = program_1_pass.clone();
|
||||
let mut program_2_fail = program_1_pass.clone();
|
||||
|
||||
@ -60,8 +60,8 @@ fn test_assert() {
|
||||
|
||||
#[test]
|
||||
fn test_mutate() {
|
||||
let bytes = include_bytes!("mutate.leo");
|
||||
let mut program_1_pass = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("mutate.leo");
|
||||
let mut program_1_pass = parse_program(program_string).unwrap();
|
||||
let mut program_0_pass = program_1_pass.clone();
|
||||
|
||||
// Check that an input value of 1 satisfies the constraint system
|
||||
@ -83,8 +83,8 @@ fn test_mutate() {
|
||||
|
||||
#[test]
|
||||
fn test_for_loop() {
|
||||
let bytes = include_bytes!("for_loop.leo");
|
||||
let mut program_true_6 = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("for_loop.leo");
|
||||
let mut program_true_6 = parse_program(program_string).unwrap();
|
||||
let mut program_false_0 = program_true_6.clone();
|
||||
|
||||
// Check that an input value of true satisfies the constraint system
|
||||
@ -106,8 +106,8 @@ fn test_for_loop() {
|
||||
|
||||
#[test]
|
||||
fn test_chain() {
|
||||
let bytes = include_bytes!("chain.leo");
|
||||
let mut program_1_1 = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("chain.leo");
|
||||
let mut program_1_1 = parse_program(program_string).unwrap();
|
||||
let mut program_2_2 = program_1_1.clone();
|
||||
let mut program_4_3 = program_1_1.clone();
|
||||
|
||||
@ -147,8 +147,8 @@ fn test_chain() {
|
||||
|
||||
#[test]
|
||||
fn test_nested() {
|
||||
let bytes = include_bytes!("nested.leo");
|
||||
let mut program_true_true_3 = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("nested.leo");
|
||||
let mut program_true_true_3 = parse_program(program_string).unwrap();
|
||||
let mut program_true_false_1 = program_true_true_3.clone();
|
||||
let mut program_false_false_0 = program_true_true_3.clone();
|
||||
|
||||
@ -205,19 +205,19 @@ fn output_zero(program: EdwardsTestCompiler) {
|
||||
|
||||
#[test]
|
||||
fn test_multiple_returns() {
|
||||
let program_bytes = include_bytes!("multiple_returns.leo");
|
||||
let program_string = include_str!("multiple_returns.leo");
|
||||
|
||||
// Check that an input value of 1 writes 1 to the output registers
|
||||
|
||||
let registers_one_bytes = include_bytes!("input/registers_one.in");
|
||||
let program = parse_program_with_input(program_bytes, registers_one_bytes).unwrap();
|
||||
let registers_one_string = include_str!("input/registers_one.in");
|
||||
let program = parse_program_with_input(program_string, registers_one_string).unwrap();
|
||||
|
||||
output_one(program);
|
||||
|
||||
// Check that an input value of 0 writes 0 to the output registers
|
||||
|
||||
let registers_zero_bytes = include_bytes!("input/registers_zero.in");
|
||||
let program = parse_program_with_input(program_bytes, registers_zero_bytes).unwrap();
|
||||
let registers_zero_string = include_str!("input/registers_zero.in");
|
||||
let program = parse_program_with_input(program_string, registers_zero_string).unwrap();
|
||||
|
||||
output_zero(program);
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ pub mod conditional;
|
||||
|
||||
#[test]
|
||||
fn test_ternary_basic() {
|
||||
let bytes = include_bytes!("ternary_basic.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("ternary_basic.leo");
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Boolean(true))),
|
||||
@ -35,7 +35,7 @@ fn test_ternary_basic() {
|
||||
|
||||
assert_satisfied(program);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
let mut program = parse_program(program_string).unwrap();
|
||||
|
||||
let main_input = generate_main_input(vec![
|
||||
("a", Some(InputValue::Boolean(false))),
|
||||
@ -51,16 +51,16 @@ fn test_ternary_basic() {
|
||||
|
||||
#[test]
|
||||
fn test_iteration_basic() {
|
||||
let bytes = include_bytes!("iteration_basic.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("iteration_basic.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_num_returns_fail() {
|
||||
let bytes = include_bytes!("num_returns_fail.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("num_returns_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_type_inference_error(error);
|
||||
}
|
||||
|
@ -18,80 +18,80 @@ use crate::parse_program;
|
||||
|
||||
#[test]
|
||||
fn test_address_name_fail() {
|
||||
let bytes = include_bytes!("address_fail.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("address_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_console_name_fail() {
|
||||
let bytes = include_bytes!("console_fail.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("console_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_field_name_fail() {
|
||||
let bytes = include_bytes!("field_fail.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("field_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_group_name_fail() {
|
||||
let bytes = include_bytes!("group_fail.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("group_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_i8_name_fail() {
|
||||
let bytes = include_bytes!("i8_fail.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("i8_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_name_fail() {
|
||||
let bytes = include_bytes!("input_fail.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("input_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_self_type_name_fail() {
|
||||
let bytes = include_bytes!("self_type_fail.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("self_type_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_self_keyword_name_fail() {
|
||||
let bytes = include_bytes!("self_keyword_fail.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("self_keyword_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_true_name_fail() {
|
||||
let bytes = include_bytes!("true_fail.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("true_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_u8_name_fail() {
|
||||
let bytes = include_bytes!("u8_fail.leo");
|
||||
let syntax_error = parse_program(bytes).is_err();
|
||||
let program_string = include_str!("u8_fail.leo");
|
||||
let syntax_error = parse_program(program_string).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ pub mod identifiers;
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_semicolon() {
|
||||
let bytes = include_bytes!("semicolon.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("semicolon.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
match error {
|
||||
CompilerError::ParserError(ParserError::SyntaxError(_)) => {}
|
||||
@ -36,8 +36,8 @@ fn test_semicolon() {
|
||||
|
||||
#[test]
|
||||
fn test_undefined() {
|
||||
let bytes = include_bytes!("undefined.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let program_string = include_str!("undefined.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
let error = expect_compiler_error(program);
|
||||
|
||||
@ -53,7 +53,7 @@ fn test_undefined() {
|
||||
" 2 | return a",
|
||||
" | ^",
|
||||
" |",
|
||||
" = cannot find value `a` in this scope",
|
||||
" = Cannot find value `a` in this scope",
|
||||
]
|
||||
.join("\n")
|
||||
);
|
||||
@ -63,10 +63,9 @@ fn test_undefined() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn input_syntax_error() {
|
||||
let bytes = include_bytes!("input_semicolon.leo");
|
||||
let error = parse_input(bytes).err().unwrap();
|
||||
let input_string = include_str!("input_semicolon.leo");
|
||||
let error = parse_input(input_string).err().unwrap();
|
||||
|
||||
// Expect an input parser error.
|
||||
match error {
|
||||
@ -77,8 +76,8 @@ fn input_syntax_error() {
|
||||
|
||||
#[test]
|
||||
fn test_compare_mismatched_types() {
|
||||
let bytes = include_bytes!("compare_mismatched_types.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
let program_string = include_str!("compare_mismatched_types.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
// Expect a type inference error.
|
||||
match error {
|
||||
|
@ -18,105 +18,105 @@ use crate::{assert_satisfied, parse_program};
|
||||
|
||||
#[test]
|
||||
fn test_tuple_basic() {
|
||||
let program_bytes = include_bytes!("basic.leo");
|
||||
let program_string = include_str!("basic.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tuple_access() {
|
||||
let program_bytes = include_bytes!("access.leo");
|
||||
let program_string = include_str!("access.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tuple_typed() {
|
||||
let program_bytes = include_bytes!("typed.leo");
|
||||
let program_string = include_str!("typed.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple() {
|
||||
let program_bytes = include_bytes!("multiple.leo");
|
||||
let program_string = include_str!("multiple.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_typed() {
|
||||
let program_bytes = include_bytes!("multiple_typed.leo");
|
||||
let program_string = include_str!("multiple_typed.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function() {
|
||||
let program_bytes = include_bytes!("function.leo");
|
||||
let program_string = include_str!("function.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_typed() {
|
||||
let program_bytes = include_bytes!("function_typed.leo");
|
||||
let program_string = include_str!("function_typed.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_multiple() {
|
||||
let progam_bytes = include_bytes!("function_multiple.leo");
|
||||
let progam_string = include_str!("function_multiple.leo");
|
||||
|
||||
let program = parse_program(progam_bytes).unwrap();
|
||||
let program = parse_program(progam_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested() {
|
||||
let program_bytes = include_bytes!("nested.leo");
|
||||
let program_string = include_str!("nested.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_access() {
|
||||
let program_bytes = include_bytes!("nested_access.leo");
|
||||
let program_string = include_str!("nested_access.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_typed() {
|
||||
let program_bytes = include_bytes!("nested_typed.leo");
|
||||
let program_string = include_str!("nested_typed.leo");
|
||||
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_input() {
|
||||
// let input_bytes = include_bytes!("inputs/input.in");
|
||||
// let program_bytes = include_bytes!("")
|
||||
// let input_string = include_str!("inputs/input.in");
|
||||
// let program_string = include_str!("")
|
||||
// }
|
||||
|
@ -18,6 +18,7 @@ use crate::{CoreCircuit, CoreCircuitError, Value};
|
||||
|
||||
use leo_ast::{
|
||||
ArrayDimensions,
|
||||
Block,
|
||||
Circuit,
|
||||
CircuitMember,
|
||||
Expression,
|
||||
@ -61,9 +62,7 @@ impl CoreCircuit for Blake2sCircuit {
|
||||
fn ast(circuit_name: Identifier, span: Span) -> Circuit {
|
||||
Circuit {
|
||||
circuit_name,
|
||||
members: vec![CircuitMember::CircuitFunction(
|
||||
true, // static function
|
||||
Function {
|
||||
members: vec![CircuitMember::CircuitFunction(Function {
|
||||
identifier: Identifier {
|
||||
name: "hash".to_owned(),
|
||||
span: span.clone(),
|
||||
@ -107,6 +106,7 @@ impl CoreCircuit for Blake2sCircuit {
|
||||
span: span.clone(),
|
||||
}]),
|
||||
)),
|
||||
block: Block {
|
||||
statements: vec![Statement::Return(
|
||||
Expression::CoreFunctionCall(
|
||||
Self::name(),
|
||||
@ -124,9 +124,9 @@ impl CoreCircuit for Blake2sCircuit {
|
||||
),
|
||||
span.clone(),
|
||||
)],
|
||||
span,
|
||||
},
|
||||
)],
|
||||
span,
|
||||
})],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
circuits::{CircuitFunction, CircuitVariableDefinition},
|
||||
};
|
||||
use crate::{ast::Rule, circuits::CircuitVariableDefinition, functions::Function};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use serde::Serialize;
|
||||
@ -26,5 +23,5 @@ use serde::Serialize;
|
||||
#[pest_ast(rule(Rule::circuit_member))]
|
||||
pub enum CircuitMember<'ast> {
|
||||
CircuitVariableDefinition(CircuitVariableDefinition<'ast>),
|
||||
CircuitFunction(CircuitFunction<'ast>),
|
||||
CircuitFunction(Function<'ast>),
|
||||
}
|
||||
|
@ -14,12 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
common::{Identifier, Mutable},
|
||||
types::Type,
|
||||
SpanDef,
|
||||
};
|
||||
use crate::{ast::Rule, common::Identifier, types::Type, SpanDef};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
@ -28,7 +23,6 @@ use serde::Serialize;
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||
#[pest_ast(rule(Rule::circuit_variable_definition))]
|
||||
pub struct CircuitVariableDefinition<'ast> {
|
||||
pub mutable: Option<Mutable>,
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub type_: Type<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
|
@ -23,8 +23,5 @@ pub use circuit_variable::*;
|
||||
pub mod circuit_variable_definition;
|
||||
pub use circuit_variable_definition::*;
|
||||
|
||||
pub mod circuit_function;
|
||||
pub use circuit_function::*;
|
||||
|
||||
pub mod circuit_member;
|
||||
pub use circuit_member::*;
|
||||
|
@ -35,6 +35,9 @@ 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::*;
|
||||
|
||||
|
@ -14,18 +14,29 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ast::Rule, common::Static, functions::Function, SpanDef};
|
||||
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::circuit_function))]
|
||||
pub struct CircuitFunction<'ast> {
|
||||
pub _static: Option<Static>,
|
||||
pub function: Function<'ast>,
|
||||
#[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)
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ast::Rule, common::Identifier, functions::input::Input, statements::Statement, types::Type, SpanDef};
|
||||
use crate::{ast::Rule, common::Identifier, functions::input::Input, statements::Block, types::Type, SpanDef};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
@ -26,7 +26,7 @@ pub struct Function<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub parameters: Vec<Input<'ast>>,
|
||||
pub returns: Option<Type<'ast>>,
|
||||
pub statements: Vec<Statement<'ast>>,
|
||||
pub block: Block<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
#[serde(with = "SpanDef")]
|
||||
pub span: Span<'ast>,
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
common::{MutSelfKeyword, SelfKeyword},
|
||||
functions::{FunctionInput, InputKeyword},
|
||||
};
|
||||
|
||||
@ -26,5 +27,7 @@ use serde::Serialize;
|
||||
#[pest_ast(rule(Rule::input))]
|
||||
pub enum Input<'ast> {
|
||||
InputKeyword(InputKeyword<'ast>),
|
||||
SelfKeyword(SelfKeyword<'ast>),
|
||||
MutSelfKeyword(MutSelfKeyword<'ast>),
|
||||
FunctionInput(FunctionInput<'ast>),
|
||||
}
|
||||
|
@ -47,6 +47,9 @@ protected_name = {
|
||||
// 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
|
||||
@ -319,13 +322,10 @@ circuit = { "circuit " ~ identifier ~ "{" ~ NEWLINE* ~ circuit_member* ~ NEWLINE
|
||||
circuit_variable = { identifier ~ ":" ~ expression }
|
||||
|
||||
// Declared in circuits/circuit_variable_definition.rs
|
||||
circuit_variable_definition = { mutable? ~ identifier ~ ":" ~ type_ ~ ","?}
|
||||
|
||||
// Declared in circuits/circuit_function.rs
|
||||
circuit_function = { static_? ~ function }
|
||||
circuit_variable_definition = { identifier ~ ":" ~ type_ ~ ","?}
|
||||
|
||||
// Declared in circuits/circuit_member.rs
|
||||
circuit_member = { circuit_function | circuit_variable_definition ~ NEWLINE*}
|
||||
circuit_member = { function | circuit_variable_definition ~ NEWLINE*}
|
||||
|
||||
/// Conditionals
|
||||
|
||||
@ -396,9 +396,11 @@ statement = {
|
||||
// Declared in statements/assign_statement.rs
|
||||
statement_assign = { assignee ~ operation_assign ~ expression ~ LINE_END }
|
||||
|
||||
block = { "{" ~ NEWLINE* ~ statement* ~ NEWLINE* ~ "}" }
|
||||
|
||||
// Declared in statements/conditional_statement.rs
|
||||
statement_conditional = {"if " ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}" ~ ("else " ~ conditional_nested_or_end_statement)?}
|
||||
conditional_nested_or_end_statement = { statement_conditional | "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
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}
|
||||
@ -407,7 +409,7 @@ statement_definition = { declare ~ variables ~ "=" ~ expression ~ LINE_END}
|
||||
statement_expression = { expression ~ LINE_END }
|
||||
|
||||
// Declared in statements/for_statement.rs
|
||||
statement_for = { "for " ~ identifier ~ "in " ~ expression ~ ".." ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
statement_for = { "for " ~ identifier ~ "in " ~ expression ~ ".." ~ expression ~ block }
|
||||
|
||||
// Declared in statements/return_statement.rs
|
||||
statement_return = { "return " ~ expression}
|
||||
@ -418,7 +420,7 @@ statement_return = { "return " ~ expression}
|
||||
test_function = { "test " ~ function }
|
||||
|
||||
// Declared in functions/function.rs
|
||||
function = { "function " ~ identifier ~ input_tuple ~ ("->" ~ type_)? ~ "{" ~ NEWLINE* ~ statement* ~ NEWLINE* ~ "}" ~ NEWLINE* }
|
||||
function = { "function " ~ identifier ~ input_tuple ~ ("->" ~ type_)? ~ block ~ NEWLINE* }
|
||||
|
||||
// Declared in functions/input/function_input.rs
|
||||
function_input = { mutable? ~ identifier ~ ":" ~ type_ }
|
||||
@ -429,6 +431,8 @@ input_keyword = { "input" }
|
||||
// Declared in functions/input/input.rs
|
||||
input = {
|
||||
input_keyword
|
||||
| self_keyword
|
||||
| mut_self_keyword
|
||||
| function_input
|
||||
}
|
||||
input_tuple = _{ "(" ~ NEWLINE* ~ (input ~ ("," ~ NEWLINE* ~ input)* ~ ","?)? ~ NEWLINE* ~ ")"}
|
||||
|
45
grammar/src/statements/block.rs
Normal file
45
grammar/src/statements/block.rs
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
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<Statement<'ast>>,
|
||||
#[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, "}}")
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
statements::{ConditionalStatement, Statement},
|
||||
statements::{Block, ConditionalStatement},
|
||||
};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
@ -27,14 +27,14 @@ use std::fmt;
|
||||
#[pest_ast(rule(Rule::conditional_nested_or_end_statement))]
|
||||
pub enum ConditionalNestedOrEndStatement<'ast> {
|
||||
Nested(Box<ConditionalStatement<'ast>>),
|
||||
End(Vec<Statement<'ast>>),
|
||||
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 statements) => write!(f, "else {{\n \t{:#?}\n }}", statements),
|
||||
ConditionalNestedOrEndStatement::End(ref block) => write!(f, "else {}", block),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
expressions::Expression,
|
||||
statements::{ConditionalNestedOrEndStatement, Statement},
|
||||
statements::{Block, ConditionalNestedOrEndStatement},
|
||||
SpanDef,
|
||||
};
|
||||
|
||||
@ -30,7 +30,7 @@ use std::fmt;
|
||||
#[pest_ast(rule(Rule::statement_conditional))]
|
||||
pub struct ConditionalStatement<'ast> {
|
||||
pub condition: Expression<'ast>,
|
||||
pub statements: Vec<Statement<'ast>>,
|
||||
pub block: Block<'ast>,
|
||||
pub next: Option<ConditionalNestedOrEndStatement<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
#[serde(with = "SpanDef")]
|
||||
@ -39,11 +39,10 @@ pub struct ConditionalStatement<'ast> {
|
||||
|
||||
impl<'ast> fmt::Display for ConditionalStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "if ({}) {{", self.condition)?;
|
||||
writeln!(f, "\t{:#?}", self.statements)?;
|
||||
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, "}}"))
|
||||
.map(|n_or_e| write!(f, " {}", n_or_e))
|
||||
.unwrap_or_else(|| write!(f, ""))
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user