Merge branch 'master' of https://github.com/AleoHQ/leo into feature/config-automatic

This commit is contained in:
raychu86 2020-09-03 00:21:33 -07:00
commit a3a121b42b
52 changed files with 616 additions and 91 deletions

View File

@ -14,7 +14,12 @@
// 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, types::Type, SpanDef};
use crate::{
ast::Rule,
common::{Identifier, Mutable},
types::Type,
SpanDef,
};
use pest::Span;
use pest_ast::FromPest;
@ -23,8 +28,9 @@ 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>,
pub type_: Type<'ast>,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,

View File

@ -38,6 +38,9 @@ pub use range::*;
pub mod range_or_expression;
pub use range_or_expression::*;
pub mod self_keyword;
pub use self_keyword::*;
pub mod spread;
pub use spread::*;

View File

@ -0,0 +1,34 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{
ast::{span_into_string, Rule},
SpanDef,
};
use pest::Span;
use pest_ast::FromPest;
use serde::Serialize;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::self_keyword))]
pub struct SelfKeyword<'ast> {
#[pest_ast(outer(with(span_into_string)))]
pub keyword: String,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,
}

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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, expressions::Expression, SpanDef};
use pest::Span;

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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, console::FormattedString, SpanDef};
use pest::Span;

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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,
console::{ConsoleAssert, ConsoleDebug, ConsoleError, ConsoleLog},

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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,
common::LineEnd,

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
pub mod console_assert;
pub use console_assert::*;

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{ast::Rule, circuits::CircuitVariable, common::Identifier, SpanDef};
use crate::{ast::Rule, circuits::CircuitVariable, common::Identifier, types::SelfType, SpanDef};
use pest::Span;
use pest_ast::FromPest;
@ -23,9 +23,16 @@ use serde::Serialize;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::expression_circuit_inline))]
pub struct CircuitInlineExpression<'ast> {
pub identifier: Identifier<'ast>,
pub name: CircuitName<'ast>,
pub members: Vec<CircuitVariable<'ast>>,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::circuit_name))]
pub enum CircuitName<'ast> {
SelfType(SelfType<'ast>),
Identifier(Identifier<'ast>),
}

View File

@ -14,7 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{access::Access, ast::Rule, common::Identifier, SpanDef};
use crate::{
access::Access,
ast::Rule,
common::{Identifier, SelfKeyword},
functions::InputKeyword,
SpanDef,
};
use pest::Span;
use pest_ast::FromPest;
@ -23,9 +29,17 @@ use serde::Serialize;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::expression_postfix))]
pub struct PostfixExpression<'ast> {
pub identifier: Identifier<'ast>,
pub name: KeywordOrIdentifier<'ast>,
pub accesses: Vec<Access<'ast>>,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::keyword_or_identifier))]
pub enum KeywordOrIdentifier<'ast> {
SelfKeyword(SelfKeyword<'ast>),
Input(InputKeyword<'ast>),
Identifier(Identifier<'ast>),
}

View File

@ -30,7 +30,7 @@ use serde::Serialize;
pub struct FunctionInput<'ast> {
pub mutable: Option<Mutable>,
pub identifier: Identifier<'ast>,
pub _type: Type<'ast>,
pub type_: Type<'ast>,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,

View File

@ -21,29 +21,32 @@ definition_annotated = { annotation ~ NEWLINE* ~ definition}
// Declared in common/identifier.rs
identifier = @{ ((!protected_name ~ ASCII_ALPHA) | (protected_name ~ (ASCII_ALPHANUMERIC | "_"))) ~ (ASCII_ALPHANUMERIC | "_")* }
protected_name = {
"address"
| "as"
"as"
| "circuit"
| "const"
| "console"
| "else"
| "false"
| "field"
| "for"
| "function"
| "group"
| "if"
| "import"
| input_keyword
| "in"
| "let"
| "mut"
| "return"
| self_keyword
| "static"
| "string"
| "test"
| "true"
| type_data
| type_self
| value_boolean
}
// Declared in common/self_keyword.rs
self_keyword = { "self" }
// Declared in common/line_end.rs
LINE_END = { ";" ~ NEWLINE* }
@ -311,7 +314,7 @@ circuit = { "circuit " ~ identifier ~ "{" ~ NEWLINE* ~ circuit_member* ~ NEWLINE
circuit_variable = { identifier ~ ":" ~ expression }
// Declared in circuits/circuit_variable_definition.rs
circuit_variable_definition = { identifier ~ ":" ~ type_ ~ ","?}
circuit_variable_definition = { mutable? ~ identifier ~ ":" ~ type_ ~ ","?}
// Declared in circuits/circuit_function.rs
circuit_function = { static_? ~ function }
@ -353,14 +356,29 @@ expression_array_inline = { "[" ~ NEWLINE* ~ inline_array_inner ~ NEWLINE* ~ "]"
inline_array_inner = _{(spread_or_expression ~ ("," ~ NEWLINE* ~ spread_or_expression)*)?}
// Declared in expressions/circuit_inline_expression.rs
expression_circuit_inline = { identifier ~ "{" ~ NEWLINE* ~ circuit_variable_list ~ NEWLINE* ~ "}" }
expression_circuit_inline = { circuit_name ~ "{" ~ NEWLINE* ~ circuit_variable_list ~ NEWLINE* ~ "}" }
// Declared in expressions/circuit_inline_expression.rs
circuit_name = {
type_self
| identifier
}
// Declared in expressions/circuit_inline_expression.rs
circuit_variable_list = _{ (circuit_variable ~ ("," ~ NEWLINE* ~ circuit_variable)*)? ~ ","? }
// Declared in expressions/unary_expression.rs
expression_unary = { operation_unary ~ expression_term }
// Declared in expressions/postfix_expression.rs
expression_postfix = ${ identifier ~ access+ }
expression_postfix = ${ keyword_or_identifier ~ access+ }
// Declared in expressions/postfix_expression.rs
keyword_or_identifier = {
input_keyword
| self_keyword
| identifier
}
/// Statements
@ -412,8 +430,8 @@ input_keyword = { "input" }
// Declared in functions/input/input.rs
input = {
function_input
| input_keyword
input_keyword
| function_input
}
input_tuple = _{ "(" ~ NEWLINE* ~ (input ~ ("," ~ NEWLINE* ~ input)* ~ ","?)? ~ NEWLINE* ~ ")"}

View File

@ -25,5 +25,5 @@ pub enum ArrayElement<'ast> {
Basic(DataType),
Tuple(TupleType<'ast>),
Circuit(CircuitType<'ast>),
SelfType(SelfType),
SelfType(SelfType<'ast>),
}

View File

@ -14,11 +14,21 @@
// 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;
use crate::{
ast::{span_into_string, Rule},
SpanDef,
};
use pest::Span;
use pest_ast::FromPest;
use serde::Serialize;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::type_self))]
pub struct SelfType {}
pub struct SelfType<'ast> {
#[pest_ast(outer(with(span_into_string)))]
pub keyword: String,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,
}

View File

@ -27,7 +27,7 @@ pub enum Type<'ast> {
Array(ArrayType<'ast>),
Tuple(TupleType<'ast>),
Circuit(CircuitType<'ast>),
SelfType(SelfType),
SelfType(SelfType<'ast>),
}
impl<'ast> fmt::Display for Type<'ast> {
@ -37,7 +37,7 @@ impl<'ast> fmt::Display for Type<'ast> {
Type::Array(ref _type) => write!(f, "array"),
Type::Tuple(ref _type) => write!(f, "tuple"),
Type::Circuit(ref _type) => write!(f, "struct"),
Type::SelfType(ref _type) => write!(f, "Self"),
Type::SelfType(ref type_) => write!(f, "{}", type_.keyword),
}
}
}

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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/>.
//! Enforces an assert equals statement in a compiled Leo program.
use crate::{errors::ConsoleError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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/>.
//! Evaluates a macro in a compiled Leo program.
use crate::{errors::ConsoleError, program::ConstrainedProgram, GroupType};

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
pub mod assert;
pub use assert::*;

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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::errors::ExpressionError;
use leo_typed::{Error as FormattedError, Span};

View File

@ -96,6 +96,12 @@ impl StatementError {
Self::new_from_span(message, span)
}
pub fn immutable_circuit_variable(name: String, span: Span) -> Self {
let message = format!("Circuit member variable `{}` is immutable", name);
Self::new_from_span(message, span)
}
pub fn indicator_calculation(name: String, span: Span) -> Self {
let message = format!(
"Constraint system failed to evaluate branch selection indicator `{}`",
@ -168,8 +174,8 @@ impl StatementError {
Self::new_from_span(message, span)
}
pub fn undefined_circuit_object(name: String, span: Span) -> Self {
let message = format!("Attempted to assign to unknown circuit object `{}`", name);
pub fn undefined_circuit_variable(name: String, span: Span) -> Self {
let message = format!("Attempted to assign to unknown circuit member variable `{}`", name);
Self::new_from_span(message, span)
}

View File

@ -77,9 +77,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
for stored_member in members {
let circuit_scope = new_scope(file_scope.clone(), circuit_name.to_string());
let self_keyword = new_scope(circuit_scope, SELF_KEYWORD.to_string());
let field = new_scope(self_keyword, stored_member.0.to_string());
let variable = new_scope(self_keyword, stored_member.0.to_string());
self.store(field, stored_member.1.clone());
self.store(variable, stored_member.1.clone());
}
}
ConstrainedValue::Static(value) => {

View File

@ -55,22 +55,27 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
for member in circuit.members.clone().into_iter() {
match member {
CircuitMember::CircuitVariable(identifier, _type) => {
CircuitMember::CircuitVariable(is_mutable, identifier, type_) => {
let matched_variable = members
.clone()
.into_iter()
.find(|variable| variable.identifier.eq(&identifier));
match matched_variable {
Some(variable) => {
// Resolve and enforce circuit object
let variable_value = self.enforce_expression(
// Resolve and enforce circuit variable
let mut variable_value = self.enforce_expression(
cs,
file_scope.clone(),
function_scope.clone(),
Some(_type.clone()),
Some(type_.clone()),
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)),

View File

@ -33,19 +33,20 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
cs: &mut CS,
indicator: Option<Boolean>,
circuit_name: String,
object_name: Identifier,
variable_name: Identifier,
mut new_value: ConstrainedValue<F, G>,
span: Span,
) -> Result<(), StatementError> {
let condition = indicator.unwrap_or(Boolean::Constant(true));
// Get the mutable circuit by name
match self.get_mutable_assignee(circuit_name, span.clone())? {
ConstrainedValue::CircuitExpression(_variable, members) => {
// Modify the circuit variable in place
let matched_variable = members.into_iter().find(|object| object.0 == object_name);
let matched_variable = members.into_iter().find(|member| member.0 == variable_name);
match matched_variable {
Some(object) => match &object.1 {
Some(member) => match &member.1 {
ConstrainedValue::Function(_circuit_identifier, function) => {
return Err(StatementError::immutable_circuit_function(
function.identifier.to_string(),
@ -55,27 +56,35 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
ConstrainedValue::Static(_value) => {
return Err(StatementError::immutable_circuit_function("static".into(), span));
}
_ => {
new_value.resolve_type(Some(object.1.to_type(span.clone())?), span.clone())?;
ConstrainedValue::Mutable(value) => {
new_value.resolve_type(Some(value.to_type(span.clone())?), span.clone())?;
let name_unique = format!("select {} {}:{}", new_value, span.line, span.start);
let selected_value = ConstrainedValue::conditionally_select(
cs.ns(|| name_unique),
&condition,
&new_value,
&object.1,
&member.1,
)
.map_err(|_| {
StatementError::select_fail(new_value.to_string(), object.1.to_string(), span)
StatementError::select_fail(new_value.to_string(), member.1.to_string(), span)
})?;
object.1 = selected_value.to_owned();
member.1 = selected_value.to_owned();
}
_ => {
return Err(StatementError::immutable_circuit_variable(variable_name.name, span));
}
},
None => return Err(StatementError::undefined_circuit_object(object_name.to_string(), span)),
None => {
return Err(StatementError::undefined_circuit_variable(
variable_name.to_string(),
span,
));
}
}
}
_ => return Err(StatementError::undefined_circuit(object_name.to_string(), span)),
_ => return Err(StatementError::undefined_circuit(variable_name.to_string(), span)),
}
Ok(())

View File

@ -132,6 +132,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
Type::Tuple(types)
}
ConstrainedValue::CircuitExpression(id, _members) => Type::Circuit(id.clone()),
ConstrainedValue::Mutable(value) => return value.to_type(span),
value => return Err(ValueError::implicit(value.to_string(), span)),
})
}

View File

@ -18,7 +18,6 @@ use crate::{
assert_satisfied,
expect_compiler_error,
get_output,
integers::{expect_computation_error, expect_parsing_error},
parse_program,
parse_program_with_input,
EdwardsTestCompiler,

View File

@ -19,9 +19,9 @@ circuit PedersenHash {
function main() {
let parameters = [0u32; 512];
let pedersen = PedersenHash::new(parameters);
let input: [bool; 512] = [true; 512];
let hash_input: [bool; 512] = [true; 512];
let res = pedersen.hash(input);
let res = pedersen.hash(hash_input);
console.assert(res == 0u32);
}

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program};
use leo_typed::InputValue;

View File

@ -0,0 +1,9 @@
// Adding the `mut` keyword makes a circuit variable mutable.
circuit Foo {
function bar() {}
}
function main() {
let mut a = Foo { x: 1 };
a.bar = 0;
}

View File

@ -0,0 +1,9 @@
// Adding the `mut` keyword makes a circuit variable mutable.
circuit Foo {
static function bar() {}
}
function main() {
let mut a = Foo { x: 1 };
a.bar = 0;
}

View File

@ -0,0 +1,11 @@
// Adding the `mut` keyword makes a circuit variable mutable.
circuit Foo {
mut x: u32
}
function main() {
let mut a = Foo { x: 1 };
a.x = 0;
console.assert(a.x == 0u32);
}

View File

@ -78,9 +78,33 @@ fn test_circuit_mut() {
let bytes = include_bytes!("circuit_mut.leo");
let program = parse_program(bytes).unwrap();
expect_compiler_error(program);
}
#[test]
fn test_circuit_variable_mut() {
let bytes = include_bytes!("circuit_variable_mut.leo");
let program = parse_program(bytes).unwrap();
assert_satisfied(program);
}
#[test]
fn test_circuit_function_mut() {
let bytes = include_bytes!("circuit_function_mut.leo");
let program = parse_program(bytes).unwrap();
expect_compiler_error(program);
}
#[test]
fn test_circuit_static_function_mut() {
let bytes = include_bytes!("circuit_static_function_mut.leo");
let program = parse_program(bytes).unwrap();
expect_compiler_error(program);
}
#[test]
fn test_function_input() {
let bytes = include_bytes!("function_input.leo");

View File

@ -0,0 +1,3 @@
function main() {
let address = 0u32;
}

View File

@ -0,0 +1,3 @@
function main() {
let console = 0u32;
}

View File

@ -0,0 +1,3 @@
function main() {
let field = 0u32;
}

View File

@ -0,0 +1,3 @@
function main() {
let group = 0u32;
}

View File

@ -0,0 +1,3 @@
function main() {
let i8 = 0u32;
}

View File

@ -0,0 +1,3 @@
function main() {
let input = 0u32;
}

View File

@ -0,0 +1,97 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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::parse_program;
#[test]
fn test_address_name_fail() {
let bytes = include_bytes!("address_fail.leo");
let syntax_error = parse_program(bytes).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();
assert!(syntax_error);
}
#[test]
fn test_field_name_fail() {
let bytes = include_bytes!("field_fail.leo");
let syntax_error = parse_program(bytes).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();
assert!(syntax_error);
}
#[test]
fn test_i8_name_fail() {
let bytes = include_bytes!("i8_fail.leo");
let syntax_error = parse_program(bytes).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();
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();
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();
assert!(syntax_error);
}
#[test]
fn test_true_name_fail() {
let bytes = include_bytes!("true_fail.leo");
let syntax_error = parse_program(bytes).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();
assert!(syntax_error);
}

View File

@ -0,0 +1,3 @@
function main() {
let Self = 0u32;
}

View File

@ -0,0 +1,3 @@
function main() {
let Self = 0u32;
}

View File

@ -0,0 +1,3 @@
function main() {
let address = 0u32;
}

View File

@ -0,0 +1,3 @@
function main() {
let u8 = 0u32;
}

View File

@ -19,6 +19,8 @@ use leo_ast::ParserError;
use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError};
use leo_input::InputParserError;
pub mod identifiers;
#[test]
#[ignore]
fn test_semicolon() {

View File

@ -21,6 +21,6 @@ circuit PedersenHash {
function main() -> group {
const parameters = [1group; 256];
const pedersen = PedersenHash::new(parameters);
let input: [bool; 256] = [true; 256];
return pedersen.hash(input)
let hash_input: [bool; 256] = [true; 256];
return pedersen.hash(hash_input)
}

View File

@ -26,15 +26,18 @@ use std::fmt;
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum CircuitMember {
CircuitVariable(Identifier, Type),
// (is_mutable, variable_name, variable_type)
CircuitVariable(bool, Identifier, Type),
// (is_static, function)
CircuitFunction(bool, Function),
}
impl<'ast> From<AstCircuitVariableDefinition<'ast>> for CircuitMember {
fn from(circuit_value: AstCircuitVariableDefinition<'ast>) -> Self {
CircuitMember::CircuitVariable(
circuit_value.mutable.is_some(),
Identifier::from(circuit_value.identifier),
Type::from(circuit_value._type),
Type::from(circuit_value.type_),
)
}
}
@ -60,9 +63,14 @@ impl<'ast> From<AstCircuitMember<'ast>> for CircuitMember {
impl fmt::Display for CircuitMember {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CircuitMember::CircuitVariable(ref identifier, ref _type) => write!(f, "{}: {}", identifier, _type),
CircuitMember::CircuitFunction(ref _static, ref function) => {
if *_static {
CircuitMember::CircuitVariable(ref mutable, ref identifier, ref type_) => {
if *mutable {
write!(f, "mut ")?;
}
write!(f, "{}: {}", identifier, type_)
}
CircuitMember::CircuitFunction(ref static_, ref function) => {
if *static_ {
write!(f, "static ")?;
}
write!(f, "{}", function)

View File

@ -22,6 +22,12 @@ use leo_ast::{
};
use leo_input::common::Identifier as InputAstIdentifier;
use leo_ast::{
common::SelfKeyword,
expressions::{CircuitName, KeywordOrIdentifier},
functions::InputKeyword,
types::SelfType,
};
use serde::{
de::{self, Visitor},
Deserialize,
@ -84,6 +90,52 @@ impl<'ast> From<AnnotationArgument<'ast>> for Identifier {
}
}
impl<'ast> From<KeywordOrIdentifier<'ast>> for Identifier {
fn from(name: KeywordOrIdentifier<'ast>) -> Self {
match name {
KeywordOrIdentifier::SelfKeyword(keyword) => Identifier::from(keyword),
KeywordOrIdentifier::Input(keyword) => Identifier::from(keyword),
KeywordOrIdentifier::Identifier(identifier) => Identifier::from(identifier),
}
}
}
impl<'ast> From<SelfKeyword<'ast>> for Identifier {
fn from(self_: SelfKeyword<'ast>) -> Self {
Self {
name: self_.keyword,
span: Span::from(self_.span),
}
}
}
impl<'ast> From<InputKeyword<'ast>> for Identifier {
fn from(input: InputKeyword<'ast>) -> Self {
Self {
name: input.keyword,
span: Span::from(input.span),
}
}
}
impl<'ast> From<CircuitName<'ast>> for Identifier {
fn from(name: CircuitName<'ast>) -> Self {
match name {
CircuitName::SelfType(self_type) => Identifier::from(self_type),
CircuitName::Identifier(identifier) => Identifier::from(identifier),
}
}
}
impl<'ast> From<SelfType<'ast>> for Identifier {
fn from(self_type: SelfType<'ast>) -> Self {
Self {
name: self_type.keyword,
span: Span::from(self_type.span),
}
}
}
impl fmt::Display for Identifier {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)

View File

@ -45,40 +45,3 @@ impl<'ast> From<AstSpan<'ast>> for Span {
}
}
}
pub fn find_line_start(pos: &Position) -> usize {
let input = pos.line_of();
if input.is_empty() {
return 0;
};
// Position's pos is always a UTF-8 border.
let start = input
.char_indices()
.rev()
.skip_while(|&(i, _)| i >= pos.pos())
.find(|&(_, c)| c == '\n');
match start {
Some((i, _)) => i,
None => 0,
}
}
pub fn find_line_end(pos: &Position) -> usize {
let input = pos.line_of();
if input.is_empty() {
0
} else if pos.pos() == input.len() - 1 {
input.len()
} else {
// Position's pos is always a UTF-8 border.
let end = input
.char_indices()
.skip_while(|&(i, _)| i < pos.pos())
.find(|&(_, c)| c == '\n');
match end {
Some((i, _)) => i,
None => input.len(),
}
}
}

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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::{Expression, FormattedString};
use leo_ast::console::{
ConsoleAssert as AstConsoleAssert,

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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::{ConsoleFunction, Span};
use leo_ast::console::ConsoleFunctionCall as AstConsoleFunctionCall;

View File

@ -1,3 +1,19 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
pub mod console_function;
pub use console_function::*;

View File

@ -275,7 +275,7 @@ impl<'ast> fmt::Display for Expression {
impl<'ast> From<CircuitInlineExpression<'ast>> for Expression {
fn from(expression: CircuitInlineExpression<'ast>) -> Self {
let circuit_name = Identifier::from(expression.identifier);
let circuit_name = Identifier::from(expression.name);
let members = expression
.members
.into_iter()
@ -288,7 +288,7 @@ impl<'ast> From<CircuitInlineExpression<'ast>> for Expression {
impl<'ast> From<PostfixExpression<'ast>> for Expression {
fn from(expression: PostfixExpression<'ast>) -> Self {
let variable = Expression::Identifier(Identifier::from(expression.identifier));
let variable = Expression::Identifier(Identifier::from(expression.name));
// ast::PostFixExpression contains an array of "accesses": `a(34)[42]` is represented as `[a, [Call(34), Select(42)]]`, but Access call expressions
// are recursive, so it is `Select(Call(a, 34), 42)`. We apply this transformation here

View File

@ -33,7 +33,7 @@ impl<'ast> From<AstFunctionInput<'ast>> for FunctionInput {
FunctionInput {
identifier: Identifier::from(parameter.identifier),
mutable: parameter.mutable.is_some(),
type_: Type::from(parameter._type),
type_: Type::from(parameter.type_),
span: Span::from(parameter.span),
}
}