mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-23 18:21:38 +03:00
impl circuit Self type
This commit is contained in:
parent
b984c46a51
commit
021379458d
@ -7,7 +7,7 @@ circuit PedersenHash {
|
||||
|
||||
}
|
||||
|
||||
function main() -> u32{
|
||||
function main() -> PedersenHash {
|
||||
let parameters = [0group; 1];
|
||||
let pedersen = PedersenHash::new(parameters);
|
||||
|
||||
|
@ -171,24 +171,15 @@ pub enum IntegerType {
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_field))]
|
||||
pub struct FieldType<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
pub struct FieldType {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_group))]
|
||||
pub struct GroupType<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
pub struct GroupType {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_bool))]
|
||||
pub struct BooleanType<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
pub struct BooleanType {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_circuit))]
|
||||
@ -204,17 +195,17 @@ pub struct SelfType {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_basic))]
|
||||
pub enum BasicType<'ast> {
|
||||
pub enum BasicType {
|
||||
Integer(IntegerType),
|
||||
Field(FieldType<'ast>),
|
||||
Group(GroupType<'ast>),
|
||||
Boolean(BooleanType<'ast>),
|
||||
Field(FieldType),
|
||||
Group(GroupType),
|
||||
Boolean(BooleanType),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_array))]
|
||||
pub struct ArrayType<'ast> {
|
||||
pub _type: BasicType<'ast>,
|
||||
pub _type: BasicType,
|
||||
pub dimensions: Vec<Value<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
@ -223,7 +214,7 @@ pub struct ArrayType<'ast> {
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::_type))]
|
||||
pub enum Type<'ast> {
|
||||
Basic(BasicType<'ast>),
|
||||
Basic(BasicType),
|
||||
Array(ArrayType<'ast>),
|
||||
Circuit(CircuitType<'ast>),
|
||||
SelfType(SelfType),
|
||||
@ -275,7 +266,7 @@ impl<'ast> fmt::Display for Integer<'ast> {
|
||||
#[pest_ast(rule(Rule::value_field))]
|
||||
pub struct Field<'ast> {
|
||||
pub number: Number<'ast>,
|
||||
pub _type: FieldType<'ast>,
|
||||
pub _type: FieldType,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
@ -290,7 +281,7 @@ impl<'ast> fmt::Display for Field<'ast> {
|
||||
#[pest_ast(rule(Rule::value_group))]
|
||||
pub struct Group<'ast> {
|
||||
pub number: Number<'ast>,
|
||||
pub _type: GroupType<'ast>,
|
||||
pub _type: GroupType,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
use crate::{
|
||||
constraints::{
|
||||
new_scope_from_variable, new_variable_from_variable, ConstrainedCircuitMember,
|
||||
ConstrainedProgram, ConstrainedValue,
|
||||
new_scope_from_variable, ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue,
|
||||
},
|
||||
errors::ExpressionError,
|
||||
new_scope,
|
||||
@ -354,14 +353,19 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
variable: Identifier<F, G>,
|
||||
identifier: Identifier<F, G>,
|
||||
members: Vec<CircuitFieldDefinition<F, G>>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let circuit_name = new_variable_from_variable(file_scope.clone(), &variable);
|
||||
let mut program_identifier = new_scope(file_scope.clone(), identifier.to_string());
|
||||
|
||||
if identifier.is_self() {
|
||||
program_identifier = file_scope.clone();
|
||||
}
|
||||
|
||||
if let Some(ConstrainedValue::CircuitDefinition(circuit_definition)) =
|
||||
self.get_mut_variable(&circuit_name)
|
||||
self.get_mut(&program_identifier)
|
||||
{
|
||||
let circuit_identifier = circuit_definition.identifier.clone();
|
||||
let mut resolved_members = vec![];
|
||||
for member in circuit_definition.members.clone().into_iter() {
|
||||
match member {
|
||||
@ -395,7 +399,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
}
|
||||
CircuitMember::CircuitFunction(_static, function) => {
|
||||
let identifier = function.function_name.clone();
|
||||
let mut constrained_function_value = ConstrainedValue::Function(function);
|
||||
let mut constrained_function_value =
|
||||
ConstrainedValue::Function(Some(circuit_identifier.clone()), function);
|
||||
|
||||
if _static {
|
||||
constrained_function_value =
|
||||
@ -411,11 +416,11 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
}
|
||||
|
||||
Ok(ConstrainedValue::CircuitExpression(
|
||||
variable,
|
||||
circuit_identifier.clone(),
|
||||
resolved_members,
|
||||
))
|
||||
} else {
|
||||
Err(ExpressionError::UndefinedCircuit(variable.to_string()))
|
||||
Err(ExpressionError::UndefinedCircuit(identifier.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -497,7 +502,10 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
}
|
||||
};
|
||||
|
||||
Ok(ConstrainedValue::Function(function))
|
||||
Ok(ConstrainedValue::Function(
|
||||
Some(circuit.identifier),
|
||||
function,
|
||||
))
|
||||
}
|
||||
|
||||
fn enforce_function_call_expression(
|
||||
@ -515,12 +523,20 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
*function.clone(),
|
||||
)?;
|
||||
|
||||
let function_call = match function_value {
|
||||
ConstrainedValue::Function(function) => function.clone(),
|
||||
let (outer_scope, function_call) = match function_value {
|
||||
ConstrainedValue::Function(circuit_identifier, function) => {
|
||||
let mut outer_scope = file_scope.clone();
|
||||
// If this is a circuit function, evaluate inside the circuit scope
|
||||
if circuit_identifier.is_some() {
|
||||
outer_scope = new_scope(file_scope, circuit_identifier.unwrap().to_string());
|
||||
}
|
||||
|
||||
(outer_scope, function.clone())
|
||||
}
|
||||
value => return Err(ExpressionError::UndefinedFunction(value.to_string())),
|
||||
};
|
||||
|
||||
match self.enforce_function(cs, file_scope, function_scope, function_call, arguments) {
|
||||
match self.enforce_function(cs, outer_scope, function_scope, function_call, arguments) {
|
||||
Ok(ConstrainedValue::Return(return_values)) => {
|
||||
if return_values.len() == 1 {
|
||||
Ok(return_values[0].clone())
|
||||
|
@ -247,7 +247,10 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
.for_each(|(function_name, function)| {
|
||||
let resolved_function_name =
|
||||
new_scope(program_name.to_string(), function_name.to_string());
|
||||
self.store(resolved_function_name, ConstrainedValue::Function(function));
|
||||
self.store(
|
||||
resolved_function_name,
|
||||
ConstrainedValue::Function(None, function),
|
||||
);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
@ -67,7 +67,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
|
||||
match matched_function {
|
||||
Some((_function_name, function)) => {
|
||||
ConstrainedValue::Function(function)
|
||||
ConstrainedValue::Function(None, function)
|
||||
}
|
||||
None => unimplemented!(
|
||||
"cannot find imported symbol {} in imported file {}",
|
||||
|
@ -56,7 +56,7 @@ pub fn generate_constraints<F: Field + PrimeField, G: Group, CS: ConstraintSyste
|
||||
.ok_or_else(|| CompilerError::NoMain)?;
|
||||
|
||||
match main.clone() {
|
||||
ConstrainedValue::Function(function) => {
|
||||
ConstrainedValue::Function(_circuit_identifier, function) => {
|
||||
let result =
|
||||
resolved_program.enforce_main_function(cs, program_name, function, parameters)?;
|
||||
log::debug!("{}", result);
|
||||
|
@ -65,11 +65,4 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
pub(crate) fn get_mut(&mut self, name: &String) -> Option<&mut ConstrainedValue<F, G>> {
|
||||
self.identifiers.get_mut(name)
|
||||
}
|
||||
|
||||
pub(crate) fn get_mut_variable(
|
||||
&mut self,
|
||||
variable: &Identifier<F, G>,
|
||||
) -> Option<&mut ConstrainedValue<F, G>> {
|
||||
self.get_mut(&variable.name)
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
|
||||
match matched_field {
|
||||
Some(object) => match &object.1 {
|
||||
ConstrainedValue::Function(function) => {
|
||||
ConstrainedValue::Function(_circuit_identifier, function) => {
|
||||
return Err(StatementError::ImmutableCircuitFunction(
|
||||
function.function_name.to_string(),
|
||||
))
|
||||
@ -193,6 +193,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
variable: Variable<F, G>,
|
||||
expression: Expression<F, G>,
|
||||
) -> Result<(), StatementError> {
|
||||
// println!("evaluating {}", expression);
|
||||
let value =
|
||||
self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), expression)?;
|
||||
|
||||
|
@ -30,7 +30,7 @@ pub enum ConstrainedValue<F: Field + PrimeField, G: Group> {
|
||||
CircuitDefinition(Circuit<F, G>),
|
||||
CircuitExpression(Identifier<F, G>, Vec<ConstrainedCircuitMember<F, G>>),
|
||||
|
||||
Function(Function<F, G>),
|
||||
Function(Option<Identifier<F, G>>, Function<F, G>), // (optional circuit identifier, function definition)
|
||||
Return(Vec<ConstrainedValue<F, G>>),
|
||||
|
||||
Mutable(Box<ConstrainedValue<F, G>>),
|
||||
@ -74,6 +74,17 @@ impl<F: Field + PrimeField, G: Group> ConstrainedValue<F, G> {
|
||||
));
|
||||
}
|
||||
}
|
||||
(
|
||||
ConstrainedValue::CircuitExpression(ref actual_name, ref _members),
|
||||
Type::SelfType,
|
||||
) => {
|
||||
if Identifier::new("Self".into()) == *actual_name {
|
||||
return Err(ValueError::CircuitName(
|
||||
"Self".into(),
|
||||
actual_name.to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
(ConstrainedValue::Return(ref values), _type) => {
|
||||
for value in values {
|
||||
value.expect_type(_type)?;
|
||||
@ -137,7 +148,9 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for ConstrainedValue<F, G> {
|
||||
ConstrainedValue::CircuitDefinition(ref _definition) => {
|
||||
unimplemented!("cannot return circuit definition in program")
|
||||
}
|
||||
ConstrainedValue::Function(ref function) => write!(f, "{}();", function.function_name),
|
||||
ConstrainedValue::Function(ref _circuit_option, ref function) => {
|
||||
write!(f, "{}();", function.function_name)
|
||||
}
|
||||
ConstrainedValue::Mutable(ref value) => write!(f, "mut {}", value),
|
||||
ConstrainedValue::Static(ref value) => write!(f, "static {}", value),
|
||||
}
|
||||
|
@ -30,6 +30,10 @@ impl<F: Field + PrimeField, G: Group> Identifier<F, G> {
|
||||
_engine: PhantomData::<F>,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_self(&self) -> bool {
|
||||
self.name == "Self"
|
||||
}
|
||||
}
|
||||
|
||||
/// A variable that is assigned to a value in the constrained program
|
||||
@ -188,6 +192,7 @@ pub enum Type<F: Field + PrimeField, G: Group> {
|
||||
Boolean,
|
||||
Array(Box<Type<F, G>>, Vec<usize>),
|
||||
Circuit(Identifier<F, G>),
|
||||
SelfType,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Type<F, G> {
|
||||
|
@ -281,6 +281,7 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for Type<F, G> {
|
||||
Type::GroupElement => write!(f, "group"),
|
||||
Type::Boolean => write!(f, "bool"),
|
||||
Type::Circuit(ref variable) => write!(f, "{}", variable),
|
||||
Type::SelfType => write!(f, "Self"),
|
||||
Type::Array(ref array, ref dimensions) => {
|
||||
write!(f, "{}", *array)?;
|
||||
for row in dimensions {
|
||||
|
@ -656,8 +656,8 @@ impl From<ast::IntegerType> for types::IntegerType {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::BasicType<'ast>> for types::Type<F, G> {
|
||||
fn from(basic_type: ast::BasicType<'ast>) -> Self {
|
||||
impl<F: Field + PrimeField, G: Group> From<ast::BasicType> for types::Type<F, G> {
|
||||
fn from(basic_type: ast::BasicType) -> Self {
|
||||
match basic_type {
|
||||
ast::BasicType::Integer(_type) => {
|
||||
types::Type::IntegerType(types::IntegerType::from(_type))
|
||||
@ -694,7 +694,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Type<'ast>> for types::Typ
|
||||
ast::Type::Basic(_type) => types::Type::from(_type),
|
||||
ast::Type::Array(_type) => types::Type::from(_type),
|
||||
ast::Type::Circuit(_type) => types::Type::from(_type),
|
||||
ast::Type::SelfType(_type) => unimplemented!("no Self yet")
|
||||
ast::Type::SelfType(_type) => types::Type::SelfType,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user