mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-22 17:51:39 +03:00
Merge pull request #2427 from AleoHQ/feat/group-to-coordinate
[Feature] Support `to_x_coordinate` for `group`s.
This commit is contained in:
commit
c373b898c4
@ -36,6 +36,10 @@ pub enum UnaryOperation {
|
||||
Square,
|
||||
/// Square root operation, i.e. `.sqrt()`.
|
||||
SquareRoot,
|
||||
/// Converts a group element to its x-coordinate, i.e. `.to_x_coordinate()`.
|
||||
ToXCoordinate,
|
||||
/// Converts a group element to its y-coordinate, i.e. `.to_y_coordinate()`.
|
||||
ToYCoordinate,
|
||||
}
|
||||
|
||||
impl UnaryOperation {
|
||||
@ -50,6 +54,8 @@ impl UnaryOperation {
|
||||
sym::not => Self::Not,
|
||||
sym::square => Self::Square,
|
||||
sym::square_root => Self::SquareRoot,
|
||||
sym::to_x_coordinate => Self::ToXCoordinate,
|
||||
sym::to_y_coordinate => Self::ToYCoordinate,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@ -65,6 +71,8 @@ impl UnaryOperation {
|
||||
Self::Not => "not",
|
||||
Self::Square => "square",
|
||||
Self::SquareRoot => "square_root",
|
||||
Self::ToXCoordinate => "to_x_coordinate",
|
||||
Self::ToYCoordinate => "to_y_coordinate",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +175,9 @@ pub enum CoreFunction {
|
||||
MappingGet,
|
||||
MappingGetOrUse,
|
||||
MappingSet,
|
||||
|
||||
GroupToXCoordinate,
|
||||
GroupToYCoordinate,
|
||||
}
|
||||
|
||||
impl CoreFunction {
|
||||
@ -338,6 +341,9 @@ impl CoreFunction {
|
||||
(sym::Mapping, sym::get) => Self::MappingGet,
|
||||
(sym::Mapping, sym::get_or_use) => Self::MappingGetOrUse,
|
||||
(sym::Mapping, sym::set) => Self::MappingSet,
|
||||
|
||||
(sym::group, sym::to_x_coordinate) => Self::GroupToXCoordinate,
|
||||
(sym::group, sym::to_y_coordinate) => Self::GroupToYCoordinate,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@ -502,6 +508,9 @@ impl CoreFunction {
|
||||
Self::MappingGet => 2,
|
||||
Self::MappingGetOrUse => 3,
|
||||
Self::MappingSet => 3,
|
||||
|
||||
Self::GroupToXCoordinate => 1,
|
||||
Self::GroupToYCoordinate => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,19 +149,22 @@ impl<'a> CodeGenerator<'a> {
|
||||
fn visit_unary(&mut self, input: &'a UnaryExpression) -> (String, String) {
|
||||
let (expression_operand, expression_instructions) = self.visit_expression(&input.receiver);
|
||||
|
||||
let opcode = match input.op {
|
||||
UnaryOperation::Abs => String::from("abs"),
|
||||
UnaryOperation::AbsWrapped => String::from("abs.w"),
|
||||
UnaryOperation::Double => String::from("double"),
|
||||
UnaryOperation::Inverse => String::from("inv"),
|
||||
UnaryOperation::Not => String::from("not"),
|
||||
UnaryOperation::Negate => String::from("neg"),
|
||||
UnaryOperation::Square => String::from("square"),
|
||||
UnaryOperation::SquareRoot => String::from("sqrt"),
|
||||
// Note that non-empty suffixes must be preceded by a space.
|
||||
let (opcode, suffix) = match input.op {
|
||||
UnaryOperation::Abs => ("abs", ""),
|
||||
UnaryOperation::AbsWrapped => ("abs.w", ""),
|
||||
UnaryOperation::Double => ("double", ""),
|
||||
UnaryOperation::Inverse => ("inv", ""),
|
||||
UnaryOperation::Not => ("not", ""),
|
||||
UnaryOperation::Negate => ("neg", ""),
|
||||
UnaryOperation::Square => ("square", ""),
|
||||
UnaryOperation::SquareRoot => ("sqrt", ""),
|
||||
UnaryOperation::ToXCoordinate => ("cast", " as group.x"),
|
||||
UnaryOperation::ToYCoordinate => ("cast", " as group.y"),
|
||||
};
|
||||
|
||||
let destination_register = format!("r{}", self.next_register);
|
||||
let unary_instruction = format!(" {opcode} {expression_operand} into {destination_register};\n");
|
||||
let unary_instruction = format!(" {opcode} {expression_operand} into {destination_register}{suffix};\n");
|
||||
|
||||
// Increment the register counter.
|
||||
self.next_register += 1;
|
||||
@ -299,7 +302,7 @@ impl<'a> CodeGenerator<'a> {
|
||||
};
|
||||
|
||||
// Construct the instruction.
|
||||
let (destination, instruction) = match input.ty {
|
||||
let (destination, instruction) = match &input.ty {
|
||||
Type::Identifier(Identifier { name: sym::BHP256, .. }) => {
|
||||
construct_simple_function_call(&input.name, "bhp256", arguments)
|
||||
}
|
||||
@ -357,6 +360,27 @@ impl<'a> CodeGenerator<'a> {
|
||||
}
|
||||
_ => unreachable!("The only variants of Mapping are get, get_or, and set"),
|
||||
},
|
||||
Type::Identifier(Identifier { name: sym::group, .. }) => {
|
||||
match input.name {
|
||||
Identifier { name: sym::to_x_coordinate, .. } => {
|
||||
let mut instruction = " cast".to_string();
|
||||
let destination_register = get_destination_register();
|
||||
// Write the argument and the destination register.
|
||||
writeln!(instruction, " {} into {destination_register} as group.x;", arguments[0],)
|
||||
.expect("failed to write to string");
|
||||
(destination_register, instruction)
|
||||
}
|
||||
Identifier { name: sym::to_y_coordinate, .. } => {
|
||||
let mut instruction = " cast".to_string();
|
||||
let destination_register = get_destination_register();
|
||||
// Write the argument and the destination register.
|
||||
writeln!(instruction, " {} into {destination_register} as group.y;", arguments[0],)
|
||||
.expect("failed to write to string");
|
||||
(destination_register, instruction)
|
||||
}
|
||||
_ => unreachable!("The only associated methods of group are to_x_coordinate and to_y_coordinate"),
|
||||
}
|
||||
}
|
||||
_ => unreachable!("All core functions should be known at this phase of compilation"),
|
||||
};
|
||||
// Add the instruction to the list of instructions.
|
||||
|
@ -730,6 +730,11 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
||||
self.assert_field_type(destination, input.span());
|
||||
self.visit_expression(&input.receiver, destination)
|
||||
}
|
||||
UnaryOperation::ToXCoordinate | UnaryOperation::ToYCoordinate => {
|
||||
// Only field type.
|
||||
self.assert_field_type(destination, input.span());
|
||||
self.visit_expression(&input.receiver, &Some(Type::Group))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -861,6 +861,11 @@ impl<'a> TypeChecker<'a> {
|
||||
None
|
||||
}
|
||||
}
|
||||
CoreFunction::GroupToXCoordinate | CoreFunction::GroupToYCoordinate => {
|
||||
// Check that the first argument is a group.
|
||||
self.assert_group_type(&arguments[0].0, arguments[0].1);
|
||||
Some(Type::Field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
pub mod symbol;
|
||||
pub use symbol::{sym, Symbol};
|
||||
|
@ -175,6 +175,8 @@ symbols! {
|
||||
Poseidon4,
|
||||
Poseidon8,
|
||||
set,
|
||||
to_x_coordinate,
|
||||
to_y_coordinate,
|
||||
|
||||
// types
|
||||
address,
|
||||
|
12
tests/expectations/compiler/group/to_x_coordinate.out
Normal file
12
tests/expectations/compiler/group/to_x_coordinate.out
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 20332c6a83a3628dd4f17d8653acdf28dd8e54bcaf9cab071fda7cbbf3ff3d29
|
||||
unrolled_ast: 20332c6a83a3628dd4f17d8653acdf28dd8e54bcaf9cab071fda7cbbf3ff3d29
|
||||
ssa_ast: 2bfa5ff05133abdf9553186a96a35c8466b5a49366ea07cea92e01f30c04f769
|
||||
flattened_ast: f7fd524a8a3e98f0e01f4c71b09bea3032867a086447ea72f4cdded1a581983d
|
||||
inlined_ast: f7fd524a8a3e98f0e01f4c71b09bea3032867a086447ea72f4cdded1a581983d
|
||||
dce_ast: 644ec7d38093f28ca0b0908282d7ff8032f7b22a0cf98c47d5ffa0ad16f047b8
|
||||
bytecode: 51e95e10668242bec30e9917715d9856da632e933c33207ee41c5ed38d6366aa
|
||||
warnings: ""
|
12
tests/expectations/compiler/group/to_y_coordinate.out
Normal file
12
tests/expectations/compiler/group/to_y_coordinate.out
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 62e89c72fcd4f62002450d1c82060f2f662ad6e1c12a19f0e6b994c50ba0491b
|
||||
unrolled_ast: 62e89c72fcd4f62002450d1c82060f2f662ad6e1c12a19f0e6b994c50ba0491b
|
||||
ssa_ast: b3c38a64899eef777c4bdd38d5db3f68148334795f4e9b89449eb9148db03eb3
|
||||
flattened_ast: da24a573e4ff569e242f88f73869c2251e19bb5ae62ef602773c0a48863bb9b3
|
||||
inlined_ast: da24a573e4ff569e242f88f73869c2251e19bb5ae62ef602773c0a48863bb9b3
|
||||
dce_ast: d313e678afef867d5cbca6829c81515387bcc768eeb4044b25c7996f4d177c63
|
||||
bytecode: ea2e94f0f589fac4565040575643b1b7cd7813fe513d5b09b17c191bbf0f727e
|
||||
warnings: ""
|
18
tests/expectations/execution/group_operations.out
Normal file
18
tests/expectations/execution/group_operations.out
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
namespace: Execute
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: ccfa20fa35d720984742081098965806736ba374ad046b3aadf6d899663375da
|
||||
unrolled_ast: ccfa20fa35d720984742081098965806736ba374ad046b3aadf6d899663375da
|
||||
ssa_ast: ab06973a60d8da80b174deae3dc4ee88216894503e613d3ba3ecd74c7f38e408
|
||||
flattened_ast: 9a9c3bc868b2e83c0cb0822e5bbf1d6f782f7992e0b748c6390a57768c44a4a7
|
||||
inlined_ast: 9a9c3bc868b2e83c0cb0822e5bbf1d6f782f7992e0b748c6390a57768c44a4a7
|
||||
dce_ast: 9a9c3bc868b2e83c0cb0822e5bbf1d6f782f7992e0b748c6390a57768c44a4a7
|
||||
bytecode: 5c20fda21a40464a1462524cf913438776a39383a671949312f48ce8ceb2dd16
|
||||
warnings: ""
|
||||
results:
|
||||
main:
|
||||
- input: "[0group]"
|
||||
output: "[0field, 1field]"
|
||||
- input: "[2group]"
|
||||
output: "[2field, 5553594316923449299484601589326170487897520766531075014687114064346375156608field]"
|
@ -0,0 +1,24 @@
|
||||
---
|
||||
namespace: ParseExpression
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- Access:
|
||||
AssociatedFunction:
|
||||
ty:
|
||||
Identifier: "{\"name\":\"group\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":5}\"}"
|
||||
name: "{\"name\":\"to_x_coordinate\",\"span\":\"{\\\"lo\\\":7,\\\"hi\\\":22}\"}"
|
||||
arguments:
|
||||
- Identifier: "{\"name\":\"a\",\"span\":\"{\\\"lo\\\":23,\\\"hi\\\":24}\"}"
|
||||
span:
|
||||
lo: 0
|
||||
hi: 25
|
||||
- Access:
|
||||
AssociatedFunction:
|
||||
ty:
|
||||
Identifier: "{\"name\":\"group\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":5}\"}"
|
||||
name: "{\"name\":\"to_y_coordinate\",\"span\":\"{\\\"lo\\\":7,\\\"hi\\\":22}\"}"
|
||||
arguments:
|
||||
- Identifier: "{\"name\":\"a\",\"span\":\"{\\\"lo\\\":23,\\\"hi\\\":24}\"}"
|
||||
span:
|
||||
lo: 0
|
||||
hi: 25
|
@ -0,0 +1,18 @@
|
||||
---
|
||||
namespace: ParseExpression
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- Unary:
|
||||
receiver:
|
||||
Identifier: "{\"name\":\"a\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":1}\"}"
|
||||
op: ToXCoordinate
|
||||
span:
|
||||
lo: 0
|
||||
hi: 19
|
||||
- Unary:
|
||||
receiver:
|
||||
Identifier: "{\"name\":\"b\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":1}\"}"
|
||||
op: ToYCoordinate
|
||||
span:
|
||||
lo: 0
|
||||
hi: 19
|
12
tests/tests/compiler/group/to_x_coordinate.leo
Normal file
12
tests/tests/compiler/group/to_x_coordinate.leo
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
*/
|
||||
|
||||
program test.aleo {
|
||||
transition main(a: group) -> field {
|
||||
let x: field = a.to_x_coordinate();
|
||||
let y: field = 0group.to_y_coordinate();
|
||||
return group::to_x_coordinate(a);
|
||||
}
|
||||
}
|
12
tests/tests/compiler/group/to_y_coordinate.leo
Normal file
12
tests/tests/compiler/group/to_y_coordinate.leo
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
*/
|
||||
|
||||
program test.aleo {
|
||||
transition main(a: group) -> field {
|
||||
let x: field = a.to_x_coordinate();
|
||||
let y: field = 0group.to_y_coordinate();
|
||||
return group::to_y_coordinate(a);
|
||||
}
|
||||
}
|
22
tests/tests/execution/group_operations.leo
Normal file
22
tests/tests/execution/group_operations.leo
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
namespace: Execute
|
||||
expectation: Pass
|
||||
cases:
|
||||
main:
|
||||
- input: ["0group"]
|
||||
- input: ["2group"]
|
||||
*/
|
||||
|
||||
program test.aleo {
|
||||
transition main(a: group) -> (field, field) {
|
||||
let b: field = group::to_x_coordinate(a);
|
||||
let c: field = a as field;
|
||||
let e: field = a.to_x_coordinate();
|
||||
assert_eq(b, c);
|
||||
assert_eq(b, e);
|
||||
let d: field = group::to_y_coordinate(a);
|
||||
let f: field = a.to_y_coordinate();
|
||||
assert_eq(d, f);
|
||||
return (b, d);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/*
|
||||
namespace: ParseExpression
|
||||
expectation: Pass
|
||||
*/
|
||||
|
||||
group::to_x_coordinate(a)
|
||||
group::to_y_coordinate(a)
|
7
tests/tests/parser/expression/access/method_function.leo
Normal file
7
tests/tests/parser/expression/access/method_function.leo
Normal file
@ -0,0 +1,7 @@
|
||||
/*
|
||||
namespace: ParseExpression
|
||||
expectation: Pass
|
||||
*/
|
||||
|
||||
a.to_x_coordinate()
|
||||
b.to_y_coordinate()
|
Loading…
Reference in New Issue
Block a user