Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use expect_asg_error where appropriate and add license headers #562

Merged
merged 2 commits into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions asg/src/checks/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.

// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.

mod return_path;
pub use return_path::*;
59 changes: 50 additions & 9 deletions asg/src/checks/return_path.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@
use crate::{ BoolAnd, MonoidalReducerExpression, MonoidalReducerStatement, Monoid, Expression, statement::*, Span, Node };
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.

// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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::*,
BoolAnd,
Expression,
Monoid,
MonoidalReducerExpression,
MonoidalReducerStatement,
Node,
Span,
};
use std::sync::Arc;

pub struct ReturnPathReducer {
Expand All @@ -11,9 +36,7 @@ impl ReturnPathReducer {
}

pub fn new() -> ReturnPathReducer {
ReturnPathReducer {
errors: vec![],
}
ReturnPathReducer { errors: vec![] }
}
}

Expand All @@ -38,16 +61,28 @@ impl MonoidalReducerStatement<BoolAnd> for ReturnPathReducer {
if statements.len() == 0 {
BoolAnd(false)
} else if let Some(index) = statements[..statements.len() - 1].iter().map(|x| x.0).position(|x| x) {
self.record_error(input.statements[index].span(), "dead code due to unconditional early return".to_string());
self.record_error(
input.statements[index].span(),
"dead code due to unconditional early return".to_string(),
);
BoolAnd(true)
} else {
BoolAnd(statements[statements.len() - 1].0)
}
}

fn reduce_conditional_statement(&mut self, input: &ConditionalStatement, condition: BoolAnd, if_true: BoolAnd, if_false: Option<BoolAnd>) -> BoolAnd {
fn reduce_conditional_statement(
&mut self,
input: &ConditionalStatement,
condition: BoolAnd,
if_true: BoolAnd,
if_false: Option<BoolAnd>,
) -> BoolAnd {
if if_false.as_ref().map(|x| x.0).unwrap_or(false) != if_true.0 {
self.record_error(input.span(), "cannot have asymmetrical return in if statement".to_string());
self.record_error(
input.span(),
"cannot have asymmetrical return in if statement".to_string(),
);
}
if_true.append(if_false.unwrap_or_else(|| BoolAnd(false)))
}
Expand All @@ -68,12 +103,18 @@ impl MonoidalReducerStatement<BoolAnd> for ReturnPathReducer {
BoolAnd(false)
}

fn reduce_iteration(&mut self, input: &IterationStatement, start: BoolAnd, stop: BoolAnd, body: BoolAnd) -> BoolAnd {
fn reduce_iteration(
&mut self,
input: &IterationStatement,
start: BoolAnd,
stop: BoolAnd,
body: BoolAnd,
) -> BoolAnd {
// loops are const defined ranges, so we could probably check if they run one and emit here
BoolAnd(false)
}

fn reduce_return(&mut self, input: &ReturnStatement, value: BoolAnd) -> BoolAnd {
BoolAnd(true)
}
}
}
61 changes: 44 additions & 17 deletions asg/src/const_value.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
use crate::{ Type, IntegerType, AsgConvertError, Span };
use std::convert::TryInto;
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.

// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public 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::{AsgConvertError, IntegerType, Span, Type};
use num_bigint::BigInt;
use std::fmt;
use std::{convert::TryInto, fmt};

#[derive(Clone, Debug, PartialEq)]
pub enum ConstInt {
Expand Down Expand Up @@ -137,7 +152,6 @@ macro_rules! const_int_map {
};
}


macro_rules! const_int_bimap {
($name: ident, $x: ident, $y: ident, $transform: expr) => {
pub fn $name(&self, other: &ConstInt) -> Option<ConstInt> {
Expand All @@ -159,6 +173,29 @@ macro_rules! const_int_bimap {
}

impl ConstInt {
const_int_op!(raw_value, String, x, format!("{}", x));

const_int_map!(value_negate, x, x.checked_neg()?);

const_int_bimap!(value_add, x, y, x.checked_add(*y)?);

const_int_bimap!(value_sub, x, y, x.checked_sub(*y)?);

const_int_bimap!(value_mul, x, y, x.checked_mul(*y)?);

const_int_bimap!(value_div, x, y, x.checked_div(*y)?);

const_int_bimap!(value_pow, x, y, x.checked_pow((*y).try_into().ok()?)?);

// TODO: limited to 32 bit exponents
const_int_biop!(value_lt, bool, x, y, Some(x < y));

const_int_biop!(value_le, bool, x, y, Some(x <= y));

const_int_biop!(value_gt, bool, x, y, Some(x > y));

const_int_biop!(value_ge, bool, x, y, Some(x >= y));

pub fn get_int_type(&self) -> IntegerType {
match self {
ConstInt::I8(_) => IntegerType::I8,
Expand All @@ -178,18 +215,6 @@ impl ConstInt {
Type::Integer(self.get_int_type())
}

const_int_op!(raw_value, String, x, format!("{}", x));
const_int_map!(value_negate, x, x.checked_neg()?);
const_int_bimap!(value_add, x, y, x.checked_add(*y)?);
const_int_bimap!(value_sub, x, y, x.checked_sub(*y)?);
const_int_bimap!(value_mul, x, y, x.checked_mul(*y)?);
const_int_bimap!(value_div, x, y, x.checked_div(*y)?);
const_int_bimap!(value_pow, x, y, x.checked_pow((*y).try_into().ok()?)?); // TODO: limited to 32 bit exponents
const_int_biop!(value_lt, bool, x, y, Some(x < y));
const_int_biop!(value_le, bool, x, y, Some(x <= y));
const_int_biop!(value_gt, bool, x, y, Some(x > y));
const_int_biop!(value_ge, bool, x, y, Some(x >= y));

pub fn parse(int_type: &IntegerType, value: &str, span: &Span) -> Result<ConstInt, AsgConvertError> {
Ok(match int_type {
IntegerType::I8 => ConstInt::I8(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
Expand All @@ -214,7 +239,9 @@ impl ConstValue {
ConstValue::Field(_) => Type::Field,
ConstValue::Address(_) => Type::Address,
ConstValue::Boolean(_) => Type::Boolean,
ConstValue::Tuple(sub_consts) => Type::Tuple(sub_consts.iter().map(|x| x.get_type()).collect::<Option<Vec<Type>>>()?),
ConstValue::Tuple(sub_consts) => {
Type::Tuple(sub_consts.iter().map(|x| x.get_type()).collect::<Option<Vec<Type>>>()?)
}
ConstValue::Array(values) => Type::Array(Box::new(values.get(0)?.get_type()?), values.len()),
})
}
Expand Down
113 changes: 98 additions & 15 deletions asg/src/error/mod.rs
Original file line number Diff line number Diff line change
@@ -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::Span;
use leo_ast::Error as FormattedError;
use leo_grammar::ParserError;
Expand Down Expand Up @@ -28,39 +44,84 @@ impl AsgConvertError {
}

pub fn unresolved_circuit_member(circuit_name: &str, name: &str, span: &Span) -> Self {
Self::new_from_span(format!("illegal reference to non-existant member '{}' of circuit '{}'", name, circuit_name), span)
Self::new_from_span(
format!(
"illegal reference to non-existant member '{}' of circuit '{}'",
name, circuit_name
),
span,
)
}

pub fn missing_circuit_member(circuit_name: &str, name: &str, span: &Span) -> Self {
Self::new_from_span(format!("missing circuit member '{}' for initialization of circuit '{}'", name, circuit_name), span)
Self::new_from_span(
format!(
"missing circuit member '{}' for initialization of circuit '{}'",
name, circuit_name
),
span,
)
}

pub fn extra_circuit_member(circuit_name: &str, name: &str, span: &Span) -> Self {
Self::new_from_span(format!("extra circuit member '{}' for initialization of circuit '{}' is not allowed", name, circuit_name), span)
Self::new_from_span(
format!(
"extra circuit member '{}' for initialization of circuit '{}' is not allowed",
name, circuit_name
),
span,
)
}

pub fn illegal_function_assign( name: &str, span: &Span) -> Self {
pub fn illegal_function_assign(name: &str, span: &Span) -> Self {
Self::new_from_span(format!("attempt to assign to function '{}'", name), span)
}

pub fn circuit_variable_call(circuit_name: &str, name: &str, span: &Span) -> Self {
Self::new_from_span(format!("cannot call variable member '{}' of circuit '{}'", name, circuit_name), span)
Self::new_from_span(
format!("cannot call variable member '{}' of circuit '{}'", name, circuit_name),
span,
)
}

pub fn circuit_static_call_invalid(circuit_name: &str, name: &str, span: &Span) -> Self {
Self::new_from_span(format!("cannot call static function '{}' of circuit '{}' from target", name, circuit_name), span)
Self::new_from_span(
format!(
"cannot call static function '{}' of circuit '{}' from target",
name, circuit_name
),
span,
)
}

pub fn circuit_member_mut_call_invalid(circuit_name: &str, name: &str, span: &Span) -> Self {
Self::new_from_span(format!("cannot call mutable member function '{}' of circuit '{}' from immutable context", name, circuit_name), span)
Self::new_from_span(
format!(
"cannot call mutable member function '{}' of circuit '{}' from immutable context",
name, circuit_name
),
span,
)
}

pub fn circuit_member_call_invalid(circuit_name: &str, name: &str, span: &Span) -> Self {
Self::new_from_span(format!("cannot call member function '{}' of circuit '{}' from static context", name, circuit_name), span)
Self::new_from_span(
format!(
"cannot call member function '{}' of circuit '{}' from static context",
name, circuit_name
),
span,
)
}

pub fn circuit_function_ref(circuit_name: &str, name: &str, span: &Span) -> Self {
Self::new_from_span(format!("cannot reference function member '{}' of circuit '{}' as value", name, circuit_name), span)
Self::new_from_span(
format!(
"cannot reference function member '{}' of circuit '{}' as value",
name, circuit_name
),
span,
)
}

pub fn index_into_non_array(name: &str, span: &Span) -> Self {
Expand All @@ -76,20 +137,33 @@ impl AsgConvertError {
}

pub fn unexpected_call_argument_count(expected: usize, got: usize, span: &Span) -> Self {
Self::new_from_span(format!("function call expected {} arguments, got {}", expected, got), span)
Self::new_from_span(
format!("function call expected {} arguments, got {}", expected, got),
span,
)
}

pub fn unresolved_function(name: &str, span: &Span) -> Self {
Self::new_from_span(format!("failed to resolve function: '{}'", name), span)
}

pub fn unresolved_type(name: &str, span: &Span) -> Self {
Self::new_from_span(format!("failed to resolve type for variable definition '{}'", name), span)
Self::new_from_span(
format!("failed to resolve type for variable definition '{}'", name),
span,
)
}

pub fn unexpected_type(expected: &str, received: Option<&str>, span: &Span) -> Self {
// panic!(format!("unexpected type, expected: '{}', received: '{}'", expected, received.unwrap_or("unknown")));
Self::new_from_span(format!("unexpected type, expected: '{}', received: '{}'", expected, received.unwrap_or("unknown")), span)
Self::new_from_span(
format!(
"unexpected type, expected: '{}', received: '{}'",
expected,
received.unwrap_or("unknown")
),
span,
)
}

pub fn unresolved_reference(name: &str, span: &Span) -> Self {
Expand All @@ -113,15 +187,24 @@ impl AsgConvertError {
}

pub fn function_return_validation(name: &str, description: &str, span: &Span) -> Self {
Self::new_from_span(format!("function '{}' failed to validate return path: '{}'", name, description), span)
Self::new_from_span(
format!("function '{}' failed to validate return path: '{}'", name, description),
span,
)
}

pub fn input_ref_needs_type(category: &str, name: &str, span: &Span) -> Self {
Self::new_from_span(format!("could not infer type for input in '{}': '{}'", category, name), span)
Self::new_from_span(
format!("could not infer type for input in '{}': '{}'", category, name),
span,
)
}

pub fn invalid_self_in_global(span: &Span) -> Self {
Self::new_from_span("cannot have `mut self` or `self` arguments in global functions".to_string(), span)
Self::new_from_span(
"cannot have `mut self` or `self` arguments in global functions".to_string(),
span,
)
}

pub fn parse_index_error() -> Self {
Expand Down
Loading