Support method calls for group coordinates

This commit is contained in:
Pranav Gaddamadugu 2023-06-23 21:03:11 -04:00
parent 4bbdf63da9
commit 8062693f3d
3 changed files with 25 additions and 10 deletions

View File

@ -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",
}
}
}

View File

@ -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;

View File

@ -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))
}
}
}