Skip to content

Commit

Permalink
fix: implement as_field and from_field in the interpreter (#6829)
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite authored Dec 16, 2024
1 parent 920bf75 commit f037c36
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 13 deletions.
26 changes: 13 additions & 13 deletions compiler/noirc_frontend/src/hir/comptime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1380,13 +1380,19 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {

fn evaluate_cast(&mut self, cast: &HirCastExpression, id: ExprId) -> IResult<Value> {
let evaluated_lhs = self.evaluate(cast.lhs)?;
Self::evaluate_cast_one_step(cast, id, evaluated_lhs, self.elaborator.interner)
let location = self.elaborator.interner.expr_location(&id);
Self::evaluate_cast_one_step(
&cast.r#type,
location,
evaluated_lhs,
self.elaborator.interner,
)
}

/// evaluate_cast without recursion
pub fn evaluate_cast_one_step(
cast: &HirCastExpression,
id: ExprId,
typ: &Type,
location: Location,
evaluated_lhs: Value,
interner: &NodeInterner,
) -> IResult<Value> {
Expand Down Expand Up @@ -1417,7 +1423,6 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
(if value { FieldElement::one() } else { FieldElement::zero() }, false)
}
value => {
let location = interner.expr_location(&id);
let typ = value.get_type().into_owned();
return Err(InterpreterError::NonNumericCasted { typ, location });
}
Expand All @@ -1434,7 +1439,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
}

// Now actually cast the lhs, bit casting and wrapping as necessary
match cast.r#type.follow_bindings() {
match typ.follow_bindings() {
Type::FieldElement => {
if lhs_is_negative {
lhs = FieldElement::zero() - lhs;
Expand All @@ -1443,8 +1448,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
}
Type::Integer(sign, bit_size) => match (sign, bit_size) {
(Signedness::Unsigned, IntegerBitSize::One) => {
let location = interner.expr_location(&id);
Err(InterpreterError::TypeUnsupported { typ: cast.r#type.clone(), location })
Err(InterpreterError::TypeUnsupported { typ: typ.clone(), location })
}
(Signedness::Unsigned, IntegerBitSize::Eight) => cast_to_int!(lhs, to_u128, u8, U8),
(Signedness::Unsigned, IntegerBitSize::Sixteen) => {
Expand All @@ -1457,8 +1461,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
cast_to_int!(lhs, to_u128, u64, U64)
}
(Signedness::Signed, IntegerBitSize::One) => {
let location = interner.expr_location(&id);
Err(InterpreterError::TypeUnsupported { typ: cast.r#type.clone(), location })
Err(InterpreterError::TypeUnsupported { typ: typ.clone(), location })
}
(Signedness::Signed, IntegerBitSize::Eight) => cast_to_int!(lhs, to_i128, i8, I8),
(Signedness::Signed, IntegerBitSize::Sixteen) => {
Expand All @@ -1472,10 +1475,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
}
},
Type::Bool => Ok(Value::Bool(!lhs.is_zero() || lhs_is_negative)),
typ => {
let location = interner.expr_location(&id);
Err(InterpreterError::CastToNonNumericType { typ, location })
}
typ => Err(InterpreterError::CastToNonNumericType { typ, location }),
}
}

Expand Down
23 changes: 23 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ impl<'local, 'context> Interpreter<'local, 'context> {
"array_len" => array_len(interner, arguments, location),
"array_refcount" => Ok(Value::U32(0)),
"assert_constant" => Ok(Value::Bool(true)),
"as_field" => as_field(interner, arguments, location),
"as_slice" => as_slice(interner, arguments, location),
"ctstring_eq" => ctstring_eq(arguments, location),
"ctstring_hash" => ctstring_hash(arguments, location),
Expand Down Expand Up @@ -116,6 +117,7 @@ impl<'local, 'context> Interpreter<'local, 'context> {
"field_less_than" => field_less_than(arguments, location),
"fmtstr_as_ctstring" => fmtstr_as_ctstring(interner, arguments, location),
"fmtstr_quoted_contents" => fmtstr_quoted_contents(interner, arguments, location),
"from_field" => from_field(interner, arguments, return_type, location),
"fresh_type_variable" => fresh_type_variable(interner),
"function_def_add_attribute" => function_def_add_attribute(self, arguments, location),
"function_def_body" => function_def_body(interner, arguments, location),
Expand Down Expand Up @@ -290,6 +292,16 @@ fn array_as_str_unchecked(
Ok(Value::String(Rc::new(string)))
}

// fn as_field<T>(x: T) -> Field {}
fn as_field(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
location: Location,
) -> IResult<Value> {
let (value, value_location) = check_one_argument(arguments, location)?;
Interpreter::evaluate_cast_one_step(&Type::FieldElement, value_location, value, interner)
}

fn as_slice(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
Expand Down Expand Up @@ -2224,6 +2236,17 @@ fn fmtstr_quoted_contents(
Ok(Value::Quoted(Rc::new(tokens)))
}

// fn from_field<T>(x: Field) -> T {}
fn from_field(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
return_type: Type,
location: Location,
) -> IResult<Value> {
let (value, value_location) = check_one_argument(arguments, location)?;
Interpreter::evaluate_cast_one_step(&return_type, value_location, value, interner)
}

// fn fresh_type_variable() -> Type
fn fresh_type_variable(interner: &NodeInterner) -> IResult<Value> {
Ok(Value::Type(interner.next_type_variable_with_kind(Kind::Any)))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "comptime_as_field"
type = "bin"
authors = [""]

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
comptime {
let _: U128 = U128::from_integer(1);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "comptime_from_field"
type = "bin"
authors = [""]

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
comptime {
let _: Field = U128::from_hex("0x0").to_integer();
}
}

0 comments on commit f037c36

Please sign in to comment.