diff --git a/simple.program b/simple.program index c099914c19..b71faab37d 100644 --- a/simple.program +++ b/simple.program @@ -1,5 +1,10 @@ -bool[2] a = [true, false] +struct Point { + field x + field y +} -p = a[0..2] +Point p = Point {x: 1, y: 0} + +p.x = 2 return p \ No newline at end of file diff --git a/src/aleo_program/constraints.rs b/src/aleo_program/constraints.rs index 3979060e75..fdaeadca1e 100644 --- a/src/aleo_program/constraints.rs +++ b/src/aleo_program/constraints.rs @@ -437,10 +437,6 @@ impl ResolvedProgram { if let Some(resolved_value) = self.resolved_variables.get_mut(&variable) { match resolved_value { ResolvedValue::StructDefinition(struct_definition) => { - // for (field, member) in struct_definition.fields.iter().zip(members.into_iter()) { - // self.enforce_expression(cs, member.expression); - // } - struct_definition .fields .clone() @@ -524,7 +520,27 @@ impl ResolvedProgram { } } } - value => unimplemented!("Cannot access element of untyped array"), + value => unimplemented!("Cannot access element of untyped array {}", value), + } + } + + fn enforce_struct_access_expression>( + &mut self, + cs: &mut CS, + struct_variable: Box, + struct_member: Variable, + ) -> ResolvedValue { + match self.enforce_expression(cs, *struct_variable) { + ResolvedValue::StructExpression(_name, members) => { + let matched_member = members + .into_iter() + .find(|member| member.variable == struct_member); + match matched_member { + Some(member) => self.enforce_expression(cs, member.expression), + None => unimplemented!("Cannot access struct member {}", struct_member.0), + } + } + value => unimplemented!("Cannot access element of untyped struct {}", value), } } @@ -566,7 +582,10 @@ impl ResolvedProgram { } Expression::ArrayAccess(array, index) => { self.enforce_array_access_expression(cs, array, index) - } // _ => unimplemented!("expression not enforced yet") + } + Expression::StructMemberAccess(struct_variable, struct_member) => { + self.enforce_struct_access_expression(cs, struct_variable, struct_member) + } } } @@ -581,68 +600,6 @@ impl ResolvedProgram { println!(" statement result: {} = {}", variable.0, result); self.insert(variable, result); } - // Expression::Boolean(boolean_expression) => { - // let res = self.enforce_boolean_expression(cs, boolean_expression); - // println!(" variable boolean result: {} = {}", variable.0, res); - // self.insert(variable, res); - // } - // Expression::FieldElement(field_expression) => { - // let res = self.enforce_field_expression(cs, field_expression); - // println!(" variable field result: {} = {}", variable.0, res); - // self.insert(variable, res); - // } - // Expression::Variable(unresolved_variable) => { - // if self.resolved_variables.contains_key(&unresolved_variable) { - // // Reassigning variable to another variable - // let already_assigned = self - // .resolved_variables - // .get_mut(&unresolved_variable) - // .unwrap() - // .clone(); - // self.insert(variable, already_assigned); - // } else { - // // The type of the unassigned variable depends on what is passed in - // if std::env::args() - // .nth(1) - // .expect("variable declaration not passed in") - // .parse::() - // .is_ok() - // { - // let resolved_boolean = self.bool_from_variable(cs, unresolved_variable); - // println!( - // "variable boolean result: {} = {}", - // variable.0, - // resolved_boolean.get_value().unwrap() - // ); - // self.insert(variable, ResolvedValue::Boolean(resolved_boolean)); - // } else { - // let resolved_field_element = - // self.u32_from_variable(cs, unresolved_variable); - // println!( - // " variable field result: {} = {}", - // variable.0, - // resolved_field_element.value.unwrap() - // ); - // self.insert( - // variable, - // ResolvedValue::FieldElement(resolved_field_element), - // ); - // } - // } - // } - // Expression::Struct(struct_name, members) => { - // let resolved_struct = self.enforce_struct_expression(cs, struct_name, members); - // println!( - // " inline struct declared: {} = {}", - // variable.0, - // resolved_struct - // ); - // self.insert( - // variable, - // resolved_struct - // ); - // } - // }, Statement::Return(statements) => { statements .into_iter() diff --git a/src/aleo_program/types.rs b/src/aleo_program/types.rs index b319fccb5e..f2a3112bb2 100644 --- a/src/aleo_program/types.rs +++ b/src/aleo_program/types.rs @@ -94,7 +94,7 @@ pub enum Expression { Variable(Variable), ArrayAccess(Box, FieldRangeOrExpression), Struct(Variable, Vec), - // StructMemberAccess(Variable, Variable)// (struct name, struct member name) + StructMemberAccess(Box, Variable), // (struct name, struct member name) } /// Program statement that defines some action (or expression) to be carried out. diff --git a/src/aleo_program/types_display.rs b/src/aleo_program/types_display.rs index 41b039aeb6..c63a4415ab 100644 --- a/src/aleo_program/types_display.rs +++ b/src/aleo_program/types_display.rs @@ -142,7 +142,10 @@ impl<'ast> fmt::Display for Expression { write!(f, "}}") } Expression::ArrayAccess(ref array, ref index) => write!(f, "{}[{}]", array, index), - _ => unimplemented!("can't display expression yet"), + Expression::StructMemberAccess(ref struct_variable, ref member) => { + write!(f, "{}.{}", struct_variable, member) + } + // _ => unimplemented!("can't display expression yet"), } } } diff --git a/src/aleo_program/types_from.rs b/src/aleo_program/types_from.rs index 50c0a5df95..40ea30eb9a 100644 --- a/src/aleo_program/types_from.rs +++ b/src/aleo_program/types_from.rs @@ -327,9 +327,10 @@ impl<'ast> From> for types::Expression { unimplemented!("only function names are callable, found \"{}\"", expression) } }, - ast::Access::Member(struct_member) => { - unimplemented!("struct calls not implemented") - } + ast::Access::Member(struct_member) => types::Expression::StructMemberAccess( + Box::new(acc), + types::Variable::from(struct_member.variable), + ), ast::Access::Select(array) => types::Expression::ArrayAccess( Box::new(acc), types::FieldRangeOrExpression::from(array.expression), @@ -697,12 +698,12 @@ impl<'ast> From> for types::Program { let mut functions = HashMap::new(); file.structs.into_iter().for_each(|struct_def| { - println!("{:#?}", struct_def); + // println!("{:#?}", struct_def); let struct_definition = types::Struct::from(struct_def); structs.insert(struct_definition.variable.clone(), struct_definition); }); file.functions.into_iter().for_each(|function_def| { - println!("{:#?}", function_def); + // println!("{:#?}", function_def); let function_definition = types::Function::from(function_def); functions.insert(function_definition.variable.clone(), function_definition); });