From fd51ee28e23f9e345a32cf7f47dea87b2afb90e2 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 15 May 2020 13:43:06 -0700 Subject: [PATCH] add from type conversion method --- compiler/src/ast.rs | 2 +- compiler/src/constraints/expression.rs | 1 + compiler/src/constraints/value.rs | 32 +++++++++++++++++++++--- compiler/src/errors/constraints/value.rs | 26 ++++++++++++++++--- compiler/src/leo.pest | 2 +- compiler/src/types.rs | 8 +----- compiler/src/types_display.rs | 5 ++-- compiler/src/types_from.rs | 16 +++--------- 8 files changed, 62 insertions(+), 30 deletions(-) diff --git a/compiler/src/ast.rs b/compiler/src/ast.rs index 055e62bf40..b99d89904f 100644 --- a/compiler/src/ast.rs +++ b/compiler/src/ast.rs @@ -265,7 +265,7 @@ impl<'ast> fmt::Display for NumberImplicit<'ast> { #[pest_ast(rule(Rule::value_integer))] pub struct Integer<'ast> { pub number: Number<'ast>, - pub _type: Option, + pub _type: IntegerType, #[pest_ast(outer())] pub span: Span<'ast>, } diff --git a/compiler/src/constraints/expression.rs b/compiler/src/constraints/expression.rs index 9740ac5f0c..cc941b50bf 100644 --- a/compiler/src/constraints/expression.rs +++ b/compiler/src/constraints/expression.rs @@ -645,6 +645,7 @@ impl> ConstrainedProgra Expression::FieldElement(fe) => Ok(Self::get_field_element_constant(fe)), Expression::GroupElement(gr) => Ok(ConstrainedValue::GroupElement(gr)), Expression::Boolean(bool) => Ok(Self::get_boolean_constant(bool)), + Expression::Implicit(string) => unimplemented!(), // Binary operations Expression::Add(left, right) => { diff --git a/compiler/src/constraints/value.rs b/compiler/src/constraints/value.rs index 3a2f69360a..08c82a066a 100644 --- a/compiler/src/constraints/value.rs +++ b/compiler/src/constraints/value.rs @@ -2,13 +2,15 @@ use crate::{ errors::ValueError, - types::{Circuit, FieldElement, Function, Identifier, Type}, - Integer, + types::{Circuit, FieldElement, Function, Identifier, Integer, IntegerType, Type}, }; use snarkos_models::{ curves::{Field, Group, PrimeField}, - gadgets::utilities::boolean::Boolean, + gadgets::utilities::{ + boolean::Boolean, uint128::UInt128, uint16::UInt16, uint32::UInt32, uint64::UInt64, + uint8::UInt8, + }, }; use std::fmt; @@ -106,6 +108,30 @@ impl ConstrainedValue { Ok(()) } + + pub(crate) fn from_type(value: String, _type: &Type) -> Result { + Ok(match _type { + Type::IntegerType(integer_type) => ConstrainedValue::Integer(match integer_type { + IntegerType::U8 => Integer::U8(UInt8::constant(value.parse::()?)), + IntegerType::U16 => Integer::U16(UInt16::constant(value.parse::()?)), + IntegerType::U32 => Integer::U32(UInt32::constant(value.parse::()?)), + IntegerType::U64 => Integer::U64(UInt64::constant(value.parse::()?)), + IntegerType::U128 => Integer::U128(UInt128::constant(value.parse::()?)), + }), + Type::FieldElement => ConstrainedValue::FieldElement(FieldElement::Constant( + F::from_str(&value).unwrap_or_default(), + )), + Type::GroupElement => ConstrainedValue::GroupElement({ + use std::str::FromStr; + + let scalar = G::ScalarField::from_str(&value).unwrap_or_default(); + let point = G::default().mul(&scalar); + point + }), + Type::Boolean => ConstrainedValue::Boolean(Boolean::Constant(value.parse::()?)), + _ => unimplemented!("Cannot implicitly create type"), + }) + } } impl fmt::Display for ConstrainedValue { diff --git a/compiler/src/errors/constraints/value.rs b/compiler/src/errors/constraints/value.rs index 4428083f35..95197819c6 100644 --- a/compiler/src/errors/constraints/value.rs +++ b/compiler/src/errors/constraints/value.rs @@ -1,7 +1,18 @@ use crate::errors::IntegerError; +use std::num::ParseIntError; +use std::str::ParseBoolError; + #[derive(Debug, Error)] pub enum ValueError { + #[error("{}", _0)] + ParseIntError(ParseIntError), + + #[error("{}", _0)] + ParseBoolError(ParseBoolError), + + #[error("{}", _0)] + IntegerError(IntegerError), /// Unexpected array length #[error("{}", _0)] ArrayLength(String), @@ -9,9 +20,6 @@ pub enum ValueError { #[error("Expected type array, got {}", _0)] ArrayModel(String), - #[error("{}", _0)] - IntegerError(IntegerError), - /// Unexpected circuit name #[error("Expected circuit name {} got {}", _0, _1)] CircuitName(String, String), @@ -21,6 +29,18 @@ pub enum ValueError { TypeError(String), } +impl From for ValueError { + fn from(error: ParseIntError) -> Self { + ValueError::ParseIntError(error) + } +} + +impl From for ValueError { + fn from(error: ParseBoolError) -> Self { + ValueError::ParseBoolError(error) + } +} + impl From for ValueError { fn from(error: IntegerError) -> Self { ValueError::IntegerError(error) diff --git a/compiler/src/leo.pest b/compiler/src/leo.pest index ec0d3d0015..ac30a4d5f0 100644 --- a/compiler/src/leo.pest +++ b/compiler/src/leo.pest @@ -90,7 +90,7 @@ type_list = _{(_type ~ ("," ~ _type)*)?} value_number = @{ "0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* } value_implicit = { value_number } -value_integer = { value_number ~ type_integer? } +value_integer = { value_number ~ type_integer } value_field = { value_number ~ type_field } value_group = { value_number ~ type_group } value_boolean = { "true" | "false" } diff --git a/compiler/src/types.rs b/compiler/src/types.rs index 8fbea85e70..28ca8b7c77 100644 --- a/compiler/src/types.rs +++ b/compiler/src/types.rs @@ -95,13 +95,6 @@ pub enum FieldElement { Allocated(Option, R1CSVariable), } -// /// A constant or allocated element in the field -// #[derive(Clone, PartialEq, Eq)] -// pub enum GroupElement { -// Constant(G), -// Allocated(Option, R1CSVariable), -// } - /// Range or expression enum #[derive(Debug, Clone, PartialEq, Eq)] pub enum RangeOrExpression { @@ -127,6 +120,7 @@ pub enum Expression { FieldElement(FieldElement), GroupElement(G), Boolean(Boolean), + Implicit(String), // Number operations Add(Box>, Box>), diff --git a/compiler/src/types_display.rs b/compiler/src/types_display.rs index c90a1497b6..e777b11052 100644 --- a/compiler/src/types_display.rs +++ b/compiler/src/types_display.rs @@ -104,9 +104,10 @@ impl<'ast, F: Field + PrimeField, G: Group> fmt::Display for Expression { // Values Expression::Integer(ref integer) => write!(f, "{}", integer), - Expression::FieldElement(ref fe) => write!(f, "{}", fe), - Expression::GroupElement(ref gr) => write!(f, "{}", gr), + Expression::FieldElement(ref field) => write!(f, "{}", field), + Expression::GroupElement(ref group) => write!(f, "{}", group), Expression::Boolean(ref bool) => write!(f, "{}", bool.get_value().unwrap()), + Expression::Implicit(ref value) => write!(f, "{}", value), // Number operations Expression::Add(ref left, ref right) => write!(f, "{} + {}", left, right), diff --git a/compiler/src/types_from.rs b/compiler/src/types_from.rs index ef5f6b09f8..f8e6955dfd 100644 --- a/compiler/src/types_from.rs +++ b/compiler/src/types_from.rs @@ -65,17 +65,7 @@ impl<'ast> types::Integer { impl<'ast, F: Field + PrimeField, G: Group> From> for types::Expression { fn from(field: ast::Integer<'ast>) -> Self { - types::Expression::Integer(match field._type { - Some(_type) => types::Integer::from(field.number, _type), - // default integer type is u32 - None => types::Integer::U32(UInt32::constant( - field - .number - .value - .parse::() - .expect("unable to parse u32"), - )), - }) + types::Expression::Integer(types::Integer::from(field.number, field._type)) } } @@ -152,8 +142,8 @@ impl<'ast, F: Field + PrimeField, G: Group> From> for types:: impl<'ast, F: Field + PrimeField, G: Group> From> for types::Expression { - fn from(_number: ast::NumberImplicit<'ast>) -> Self { - unimplemented!() + fn from(number: ast::NumberImplicit<'ast>) -> Self { + types::Expression::Implicit(number.number.value) } }