From 9b7a4ba456392759475ef38d8df22f3fd15be747 Mon Sep 17 00:00:00 2001
From: Pranav Gaddamadugu <pranav@aleo.org>
Date: Fri, 23 Jun 2023 14:59:36 -0400
Subject: [PATCH 1/6] WIP associated function syntax for group::to_*_coordinate

---
 compiler/ast/src/functions/core_function.rs   |  9 ++++++++
 .../src/code_generation/visit_expressions.rs  | 21 +++++++++++++++++++
 compiler/passes/src/type_checking/checker.rs  |  5 +++++
 compiler/span/src/lib.rs                      |  1 +
 compiler/span/src/symbol.rs                   |  2 ++
 5 files changed, 38 insertions(+)

diff --git a/compiler/ast/src/functions/core_function.rs b/compiler/ast/src/functions/core_function.rs
index 1f8f8c0c3f..379271ff0d 100644
--- a/compiler/ast/src/functions/core_function.rs
+++ b/compiler/ast/src/functions/core_function.rs
@@ -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,
         }
     }
 }
diff --git a/compiler/passes/src/code_generation/visit_expressions.rs b/compiler/passes/src/code_generation/visit_expressions.rs
index a5378e68a4..c55f6989b9 100644
--- a/compiler/passes/src/code_generation/visit_expressions.rs
+++ b/compiler/passes/src/code_generation/visit_expressions.rs
@@ -357,6 +357,27 @@ impl<'a> CodeGenerator<'a> {
                 }
                 _ => unreachable!("The only variants of Mapping are get, get_or, and set"),
             },
+            Type::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.
diff --git a/compiler/passes/src/type_checking/checker.rs b/compiler/passes/src/type_checking/checker.rs
index 8baf15ddd2..1262e597fb 100644
--- a/compiler/passes/src/type_checking/checker.rs
+++ b/compiler/passes/src/type_checking/checker.rs
@@ -861,6 +861,11 @@ impl<'a> TypeChecker<'a> {
                     None
                 }
             }
+            CoreFunction::GroupToXCoordinate | CoreFunction::GroupToYCoordinate => {
+                // Check that the first argument is a group.
+                self.assert_scalar_type(&arguments[0].0, arguments[0].1);
+                Some(Type::Group)
+            }
         }
     }
 
diff --git a/compiler/span/src/lib.rs b/compiler/span/src/lib.rs
index 7bc511f832..03dbe28720 100644
--- a/compiler/span/src/lib.rs
+++ b/compiler/span/src/lib.rs
@@ -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};
diff --git a/compiler/span/src/symbol.rs b/compiler/span/src/symbol.rs
index 57beba56ce..fd0575b6a5 100644
--- a/compiler/span/src/symbol.rs
+++ b/compiler/span/src/symbol.rs
@@ -175,6 +175,8 @@ symbols! {
     Poseidon4,
     Poseidon8,
     set,
+    to_x_coordinate,
+    to_y_coordinate,
 
     // types
     address,

From 8b4552efd53635a1d0f59b3c800ed5ec2f83b4b3 Mon Sep 17 00:00:00 2001
From: Pranav Gaddamadugu <pranav@aleo.org>
Date: Fri, 23 Jun 2023 20:35:42 -0400
Subject: [PATCH 2/6] Fix implementation

---
 .../src/code_generation/visit_expressions.rs   |  4 ++--
 compiler/passes/src/type_checking/checker.rs   |  4 ++--
 .../compiler/group/to_x_coordinate.out         | 12 ++++++++++++
 .../compiler/group/to_y_coordinate.out         | 12 ++++++++++++
 tests/tests/compiler/group/to_x_coordinate.leo | 10 ++++++++++
 tests/tests/compiler/group/to_y_coordinate.leo | 10 ++++++++++
 tests/tests/execution/group_operations.leo     | 18 ++++++++++++++++++
 7 files changed, 66 insertions(+), 4 deletions(-)
 create mode 100644 tests/expectations/compiler/group/to_x_coordinate.out
 create mode 100644 tests/expectations/compiler/group/to_y_coordinate.out
 create mode 100644 tests/tests/compiler/group/to_x_coordinate.leo
 create mode 100644 tests/tests/compiler/group/to_y_coordinate.leo
 create mode 100644 tests/tests/execution/group_operations.leo

diff --git a/compiler/passes/src/code_generation/visit_expressions.rs b/compiler/passes/src/code_generation/visit_expressions.rs
index c55f6989b9..59de1d9909 100644
--- a/compiler/passes/src/code_generation/visit_expressions.rs
+++ b/compiler/passes/src/code_generation/visit_expressions.rs
@@ -299,7 +299,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,7 +357,7 @@ impl<'a> CodeGenerator<'a> {
                 }
                 _ => unreachable!("The only variants of Mapping are get, get_or, and set"),
             },
-            Type::Group => {
+            Type::Identifier(Identifier { name: sym::group, .. }) => {
                 match input.name {
                     Identifier { name: sym::to_x_coordinate, .. } => {
                         let mut instruction = "    cast".to_string();
diff --git a/compiler/passes/src/type_checking/checker.rs b/compiler/passes/src/type_checking/checker.rs
index 1262e597fb..2eb3a2c1ea 100644
--- a/compiler/passes/src/type_checking/checker.rs
+++ b/compiler/passes/src/type_checking/checker.rs
@@ -863,8 +863,8 @@ impl<'a> TypeChecker<'a> {
             }
             CoreFunction::GroupToXCoordinate | CoreFunction::GroupToYCoordinate => {
                 // Check that the first argument is a group.
-                self.assert_scalar_type(&arguments[0].0, arguments[0].1);
-                Some(Type::Group)
+                self.assert_group_type(&arguments[0].0, arguments[0].1);
+                Some(Type::Field)
             }
         }
     }
diff --git a/tests/expectations/compiler/group/to_x_coordinate.out b/tests/expectations/compiler/group/to_x_coordinate.out
new file mode 100644
index 0000000000..e0b12ce010
--- /dev/null
+++ b/tests/expectations/compiler/group/to_x_coordinate.out
@@ -0,0 +1,12 @@
+---
+namespace: Compile
+expectation: Pass
+outputs:
+  - - initial_ast: 466c3da8bb0bc3711a3071784e06a475abbd95c4afa46ce2149bdaf8fbabe6e4
+      unrolled_ast: 466c3da8bb0bc3711a3071784e06a475abbd95c4afa46ce2149bdaf8fbabe6e4
+      ssa_ast: 9455d0f91c594cacc93cba0358e1d40017f65765b59b18a341ea2966b4ecb1df
+      flattened_ast: b0caf68c1a6fe8ee511a80829ab30c35630daa28f86b4be4bf25adf1a0a367a8
+      inlined_ast: b0caf68c1a6fe8ee511a80829ab30c35630daa28f86b4be4bf25adf1a0a367a8
+      dce_ast: b0caf68c1a6fe8ee511a80829ab30c35630daa28f86b4be4bf25adf1a0a367a8
+      bytecode: 51e95e10668242bec30e9917715d9856da632e933c33207ee41c5ed38d6366aa
+      warnings: ""
diff --git a/tests/expectations/compiler/group/to_y_coordinate.out b/tests/expectations/compiler/group/to_y_coordinate.out
new file mode 100644
index 0000000000..636a1d1a5c
--- /dev/null
+++ b/tests/expectations/compiler/group/to_y_coordinate.out
@@ -0,0 +1,12 @@
+---
+namespace: Compile
+expectation: Pass
+outputs:
+  - - initial_ast: 6cc132d16506cefce980b7ecb6637bc89a6db79e90073c307dbb75a2a25e3251
+      unrolled_ast: 6cc132d16506cefce980b7ecb6637bc89a6db79e90073c307dbb75a2a25e3251
+      ssa_ast: 8b8a2daa8b7e32c23f2d3290ab3557b7b6d98afeb2ae55c35795de7e8180ef79
+      flattened_ast: 00b4b6055c4035a3c016a88afa60f8504dec8542ad6413bd8340f75ce60564b2
+      inlined_ast: 00b4b6055c4035a3c016a88afa60f8504dec8542ad6413bd8340f75ce60564b2
+      dce_ast: 00b4b6055c4035a3c016a88afa60f8504dec8542ad6413bd8340f75ce60564b2
+      bytecode: ea2e94f0f589fac4565040575643b1b7cd7813fe513d5b09b17c191bbf0f727e
+      warnings: ""
diff --git a/tests/tests/compiler/group/to_x_coordinate.leo b/tests/tests/compiler/group/to_x_coordinate.leo
new file mode 100644
index 0000000000..1ad42ea324
--- /dev/null
+++ b/tests/tests/compiler/group/to_x_coordinate.leo
@@ -0,0 +1,10 @@
+/*
+namespace: Compile
+expectation: Pass
+*/
+
+program test.aleo {
+    transition main(a: group) -> field {
+        return group::to_x_coordinate(a);
+    }
+}
diff --git a/tests/tests/compiler/group/to_y_coordinate.leo b/tests/tests/compiler/group/to_y_coordinate.leo
new file mode 100644
index 0000000000..236f44e733
--- /dev/null
+++ b/tests/tests/compiler/group/to_y_coordinate.leo
@@ -0,0 +1,10 @@
+/*
+namespace: Compile
+expectation: Pass
+*/
+
+program test.aleo {
+    transition main(a: group) -> field {
+        return group::to_y_coordinate(a);
+    }
+}
diff --git a/tests/tests/execution/group_operations.leo b/tests/tests/execution/group_operations.leo
new file mode 100644
index 0000000000..6dcdc25b27
--- /dev/null
+++ b/tests/tests/execution/group_operations.leo
@@ -0,0 +1,18 @@
+/*
+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;
+        assert_eq(b, c);
+        let d: field = group::to_y_coordinate(a);
+        return (b, d);
+    }
+}

From 4bbdf63da9a7874ef52fb949c2f9e5234a76c7ff Mon Sep 17 00:00:00 2001
From: Pranav Gaddamadugu <pranav@aleo.org>
Date: Fri, 23 Jun 2023 20:36:16 -0400
Subject: [PATCH 3/6] Add tests and regen expectations

---
 .../execution/group_operations.out            | 18 ++++++++++++++
 .../expression/access/associated_function.out | 24 +++++++++++++++++++
 .../expression/access/associated_function.leo |  7 ++++++
 3 files changed, 49 insertions(+)
 create mode 100644 tests/expectations/execution/group_operations.out
 create mode 100644 tests/expectations/parser/expression/access/associated_function.out
 create mode 100644 tests/tests/parser/expression/access/associated_function.leo

diff --git a/tests/expectations/execution/group_operations.out b/tests/expectations/execution/group_operations.out
new file mode 100644
index 0000000000..d8a0992f1c
--- /dev/null
+++ b/tests/expectations/execution/group_operations.out
@@ -0,0 +1,18 @@
+---
+namespace: Execute
+expectation: Pass
+outputs:
+  - - initial_ast: 0f695b51ab88009feefe657770a42c5e87c5406b480c48636bf96170be3cd606
+      unrolled_ast: 0f695b51ab88009feefe657770a42c5e87c5406b480c48636bf96170be3cd606
+      ssa_ast: 5d78ad9fd293c3227d2a7ddadff8c7c0689794fe983ab4c8370683b2ba05643e
+      flattened_ast: b50634e2bc12b8e27f6f6fc00cc8ab56407fdb5aec190992106cbf45143f7c96
+      inlined_ast: b50634e2bc12b8e27f6f6fc00cc8ab56407fdb5aec190992106cbf45143f7c96
+      dce_ast: b50634e2bc12b8e27f6f6fc00cc8ab56407fdb5aec190992106cbf45143f7c96
+      bytecode: e556ad690ff212037476e85570be2afb974da528efb4688626d824a886f9013e
+      warnings: ""
+      results:
+        main:
+          - input: "[0group]"
+            output: "[0field, 1field]"
+          - input: "[2group]"
+            output: "[2field, 5553594316923449299484601589326170487897520766531075014687114064346375156608field]"
diff --git a/tests/expectations/parser/expression/access/associated_function.out b/tests/expectations/parser/expression/access/associated_function.out
new file mode 100644
index 0000000000..bc8d7ee84a
--- /dev/null
+++ b/tests/expectations/parser/expression/access/associated_function.out
@@ -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
diff --git a/tests/tests/parser/expression/access/associated_function.leo b/tests/tests/parser/expression/access/associated_function.leo
new file mode 100644
index 0000000000..a688fe6098
--- /dev/null
+++ b/tests/tests/parser/expression/access/associated_function.leo
@@ -0,0 +1,7 @@
+/*
+namespace: ParseExpression
+expectation: Pass
+*/
+
+group::to_x_coordinate(a)
+group::to_y_coordinate(a)

From 8062693f3d3bbd5664f495ae867edcbe5f0ac183 Mon Sep 17 00:00:00 2001
From: Pranav Gaddamadugu <pranav@aleo.org>
Date: Fri, 23 Jun 2023 21:03:11 -0400
Subject: [PATCH 4/6] Support method calls for group coordinates

---
 compiler/ast/src/expressions/unary.rs         |  8 +++++++
 .../src/code_generation/visit_expressions.rs  | 22 ++++++++++---------
 .../src/type_checking/check_expressions.rs    |  5 +++++
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/compiler/ast/src/expressions/unary.rs b/compiler/ast/src/expressions/unary.rs
index b1557cd58b..0355179f57 100644
--- a/compiler/ast/src/expressions/unary.rs
+++ b/compiler/ast/src/expressions/unary.rs
@@ -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",
         }
     }
 }
diff --git a/compiler/passes/src/code_generation/visit_expressions.rs b/compiler/passes/src/code_generation/visit_expressions.rs
index 59de1d9909..6027600ff4 100644
--- a/compiler/passes/src/code_generation/visit_expressions.rs
+++ b/compiler/passes/src/code_generation/visit_expressions.rs
@@ -149,19 +149,21 @@ 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"),
+        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;
diff --git a/compiler/passes/src/type_checking/check_expressions.rs b/compiler/passes/src/type_checking/check_expressions.rs
index bbd9b673a1..13d1b76169 100644
--- a/compiler/passes/src/type_checking/check_expressions.rs
+++ b/compiler/passes/src/type_checking/check_expressions.rs
@@ -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))
+            }
         }
     }
 

From 5699352ce62a7c589044adaae2078df6ca4dcc1f Mon Sep 17 00:00:00 2001
From: Pranav Gaddamadugu <pranav@aleo.org>
Date: Fri, 23 Jun 2023 21:03:32 -0400
Subject: [PATCH 5/6] Add tests and regen expectations

---
 .../compiler/group/to_x_coordinate.out         | 12 ++++++------
 .../compiler/group/to_y_coordinate.out         | 12 ++++++------
 .../execution/group_operations.out             | 14 +++++++-------
 .../expression/access/method_function.out      | 18 ++++++++++++++++++
 tests/tests/compiler/group/to_x_coordinate.leo |  2 ++
 tests/tests/compiler/group/to_y_coordinate.leo |  2 ++
 tests/tests/execution/group_operations.leo     |  4 ++++
 .../expression/access/method_function.leo      |  7 +++++++
 8 files changed, 52 insertions(+), 19 deletions(-)
 create mode 100644 tests/expectations/parser/expression/access/method_function.out
 create mode 100644 tests/tests/parser/expression/access/method_function.leo

diff --git a/tests/expectations/compiler/group/to_x_coordinate.out b/tests/expectations/compiler/group/to_x_coordinate.out
index e0b12ce010..d708a63580 100644
--- a/tests/expectations/compiler/group/to_x_coordinate.out
+++ b/tests/expectations/compiler/group/to_x_coordinate.out
@@ -2,11 +2,11 @@
 namespace: Compile
 expectation: Pass
 outputs:
-  - - initial_ast: 466c3da8bb0bc3711a3071784e06a475abbd95c4afa46ce2149bdaf8fbabe6e4
-      unrolled_ast: 466c3da8bb0bc3711a3071784e06a475abbd95c4afa46ce2149bdaf8fbabe6e4
-      ssa_ast: 9455d0f91c594cacc93cba0358e1d40017f65765b59b18a341ea2966b4ecb1df
-      flattened_ast: b0caf68c1a6fe8ee511a80829ab30c35630daa28f86b4be4bf25adf1a0a367a8
-      inlined_ast: b0caf68c1a6fe8ee511a80829ab30c35630daa28f86b4be4bf25adf1a0a367a8
-      dce_ast: b0caf68c1a6fe8ee511a80829ab30c35630daa28f86b4be4bf25adf1a0a367a8
+  - - initial_ast: 20332c6a83a3628dd4f17d8653acdf28dd8e54bcaf9cab071fda7cbbf3ff3d29
+      unrolled_ast: 20332c6a83a3628dd4f17d8653acdf28dd8e54bcaf9cab071fda7cbbf3ff3d29
+      ssa_ast: 2bfa5ff05133abdf9553186a96a35c8466b5a49366ea07cea92e01f30c04f769
+      flattened_ast: f7fd524a8a3e98f0e01f4c71b09bea3032867a086447ea72f4cdded1a581983d
+      inlined_ast: f7fd524a8a3e98f0e01f4c71b09bea3032867a086447ea72f4cdded1a581983d
+      dce_ast: 644ec7d38093f28ca0b0908282d7ff8032f7b22a0cf98c47d5ffa0ad16f047b8
       bytecode: 51e95e10668242bec30e9917715d9856da632e933c33207ee41c5ed38d6366aa
       warnings: ""
diff --git a/tests/expectations/compiler/group/to_y_coordinate.out b/tests/expectations/compiler/group/to_y_coordinate.out
index 636a1d1a5c..c182766986 100644
--- a/tests/expectations/compiler/group/to_y_coordinate.out
+++ b/tests/expectations/compiler/group/to_y_coordinate.out
@@ -2,11 +2,11 @@
 namespace: Compile
 expectation: Pass
 outputs:
-  - - initial_ast: 6cc132d16506cefce980b7ecb6637bc89a6db79e90073c307dbb75a2a25e3251
-      unrolled_ast: 6cc132d16506cefce980b7ecb6637bc89a6db79e90073c307dbb75a2a25e3251
-      ssa_ast: 8b8a2daa8b7e32c23f2d3290ab3557b7b6d98afeb2ae55c35795de7e8180ef79
-      flattened_ast: 00b4b6055c4035a3c016a88afa60f8504dec8542ad6413bd8340f75ce60564b2
-      inlined_ast: 00b4b6055c4035a3c016a88afa60f8504dec8542ad6413bd8340f75ce60564b2
-      dce_ast: 00b4b6055c4035a3c016a88afa60f8504dec8542ad6413bd8340f75ce60564b2
+  - - initial_ast: 62e89c72fcd4f62002450d1c82060f2f662ad6e1c12a19f0e6b994c50ba0491b
+      unrolled_ast: 62e89c72fcd4f62002450d1c82060f2f662ad6e1c12a19f0e6b994c50ba0491b
+      ssa_ast: b3c38a64899eef777c4bdd38d5db3f68148334795f4e9b89449eb9148db03eb3
+      flattened_ast: da24a573e4ff569e242f88f73869c2251e19bb5ae62ef602773c0a48863bb9b3
+      inlined_ast: da24a573e4ff569e242f88f73869c2251e19bb5ae62ef602773c0a48863bb9b3
+      dce_ast: d313e678afef867d5cbca6829c81515387bcc768eeb4044b25c7996f4d177c63
       bytecode: ea2e94f0f589fac4565040575643b1b7cd7813fe513d5b09b17c191bbf0f727e
       warnings: ""
diff --git a/tests/expectations/execution/group_operations.out b/tests/expectations/execution/group_operations.out
index d8a0992f1c..b6a5e19dc9 100644
--- a/tests/expectations/execution/group_operations.out
+++ b/tests/expectations/execution/group_operations.out
@@ -2,13 +2,13 @@
 namespace: Execute
 expectation: Pass
 outputs:
-  - - initial_ast: 0f695b51ab88009feefe657770a42c5e87c5406b480c48636bf96170be3cd606
-      unrolled_ast: 0f695b51ab88009feefe657770a42c5e87c5406b480c48636bf96170be3cd606
-      ssa_ast: 5d78ad9fd293c3227d2a7ddadff8c7c0689794fe983ab4c8370683b2ba05643e
-      flattened_ast: b50634e2bc12b8e27f6f6fc00cc8ab56407fdb5aec190992106cbf45143f7c96
-      inlined_ast: b50634e2bc12b8e27f6f6fc00cc8ab56407fdb5aec190992106cbf45143f7c96
-      dce_ast: b50634e2bc12b8e27f6f6fc00cc8ab56407fdb5aec190992106cbf45143f7c96
-      bytecode: e556ad690ff212037476e85570be2afb974da528efb4688626d824a886f9013e
+  - - initial_ast: ccfa20fa35d720984742081098965806736ba374ad046b3aadf6d899663375da
+      unrolled_ast: ccfa20fa35d720984742081098965806736ba374ad046b3aadf6d899663375da
+      ssa_ast: ab06973a60d8da80b174deae3dc4ee88216894503e613d3ba3ecd74c7f38e408
+      flattened_ast: 9a9c3bc868b2e83c0cb0822e5bbf1d6f782f7992e0b748c6390a57768c44a4a7
+      inlined_ast: 9a9c3bc868b2e83c0cb0822e5bbf1d6f782f7992e0b748c6390a57768c44a4a7
+      dce_ast: 9a9c3bc868b2e83c0cb0822e5bbf1d6f782f7992e0b748c6390a57768c44a4a7
+      bytecode: 5c20fda21a40464a1462524cf913438776a39383a671949312f48ce8ceb2dd16
       warnings: ""
       results:
         main:
diff --git a/tests/expectations/parser/expression/access/method_function.out b/tests/expectations/parser/expression/access/method_function.out
new file mode 100644
index 0000000000..65a3250809
--- /dev/null
+++ b/tests/expectations/parser/expression/access/method_function.out
@@ -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
diff --git a/tests/tests/compiler/group/to_x_coordinate.leo b/tests/tests/compiler/group/to_x_coordinate.leo
index 1ad42ea324..4bbd40f38b 100644
--- a/tests/tests/compiler/group/to_x_coordinate.leo
+++ b/tests/tests/compiler/group/to_x_coordinate.leo
@@ -5,6 +5,8 @@ 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);
     }
 }
diff --git a/tests/tests/compiler/group/to_y_coordinate.leo b/tests/tests/compiler/group/to_y_coordinate.leo
index 236f44e733..3687999cc0 100644
--- a/tests/tests/compiler/group/to_y_coordinate.leo
+++ b/tests/tests/compiler/group/to_y_coordinate.leo
@@ -5,6 +5,8 @@ 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);
     }
 }
diff --git a/tests/tests/execution/group_operations.leo b/tests/tests/execution/group_operations.leo
index 6dcdc25b27..6137a10a9e 100644
--- a/tests/tests/execution/group_operations.leo
+++ b/tests/tests/execution/group_operations.leo
@@ -11,8 +11,12 @@ 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);
     }
 }
diff --git a/tests/tests/parser/expression/access/method_function.leo b/tests/tests/parser/expression/access/method_function.leo
new file mode 100644
index 0000000000..f2169a44c7
--- /dev/null
+++ b/tests/tests/parser/expression/access/method_function.leo
@@ -0,0 +1,7 @@
+/*
+namespace: ParseExpression
+expectation: Pass
+*/
+
+a.to_x_coordinate()
+b.to_y_coordinate()

From 1fbb2280924aaa7beef626abaf25f9dd3f3bca88 Mon Sep 17 00:00:00 2001
From: Pranav Gaddamadugu <pranav@aleo.org>
Date: Wed, 28 Jun 2023 10:09:33 -0400
Subject: [PATCH 6/6] Add comment

---
 compiler/passes/src/code_generation/visit_expressions.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/compiler/passes/src/code_generation/visit_expressions.rs b/compiler/passes/src/code_generation/visit_expressions.rs
index 6027600ff4..40f38d23ea 100644
--- a/compiler/passes/src/code_generation/visit_expressions.rs
+++ b/compiler/passes/src/code_generation/visit_expressions.rs
@@ -149,6 +149,7 @@ impl<'a> CodeGenerator<'a> {
     fn visit_unary(&mut self, input: &'a UnaryExpression) -> (String, String) {
         let (expression_operand, expression_instructions) = self.visit_expression(&input.receiver);
 
+        // Note that non-empty suffixes must be preceded by a space.
         let (opcode, suffix) = match input.op {
             UnaryOperation::Abs => ("abs", ""),
             UnaryOperation::AbsWrapped => ("abs.w", ""),