Skip to content

Commit

Permalink
Use BigInt instead of FieldElement in noirc_frontend (except the inte…
Browse files Browse the repository at this point in the history
…rpreter)
  • Loading branch information
asterite committed Jun 26, 2024
1 parent 03e25b4 commit 79de236
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 100 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions aztec_macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ noirc_errors.workspace = true
iter-extended.workspace = true
convert_case = "0.6.0"
regex = "1.10"
num-bigint.workspace = true
num-traits.workspace = true

10 changes: 2 additions & 8 deletions aztec_macros/src/transforms/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use noirc_frontend::ast::{
UnresolvedTypeData, Visibility,
};

use noirc_frontend::{macros_api::FieldElement, parse_program};
use noirc_frontend::parse_program;

use crate::utils::ast_utils::member_access;
use crate::{
Expand Down Expand Up @@ -754,13 +754,7 @@ fn create_loop_over(var: Expression, loop_body: Vec<Statement>) -> Statement {

// `for i in 0..{ident}.len()`
make_statement(StatementKind::For(ForLoopStatement {
range: ForRange::Range(
expression(ExpressionKind::Literal(Literal::Integer(
FieldElement::from(i128::from(0)),
false,
))),
end_range_expression,
),
range: ForRange::Range(expression(ExpressionKind::zero()), end_range_expression),
identifier: ident("i"),
block: for_loop_block,
span,
Expand Down
7 changes: 2 additions & 5 deletions aztec_macros/src/transforms/storage.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use acvm::acir::AcirField;
use noirc_errors::Span;
use noirc_frontend::ast::{
BlockExpression, Expression, ExpressionKind, FunctionDefinition, Ident, Literal, NoirFunction,
BlockExpression, Expression, ExpressionKind, FunctionDefinition, Ident, NoirFunction,
NoirStruct, Pattern, StatementKind, TypeImpl, UnresolvedType, UnresolvedTypeData,
};
use noirc_frontend::{
Expand Down Expand Up @@ -201,10 +201,7 @@ pub fn generate_storage_implementation(
.find(|r#struct| r#struct.name.0.contents == *storage_struct_name)
.unwrap();

let slot_zero = expression(ExpressionKind::Literal(Literal::Integer(
FieldElement::from(i128::from(0)),
false,
)));
let slot_zero = expression(ExpressionKind::zero());

let field_constructors = definition
.fields
Expand Down
37 changes: 23 additions & 14 deletions compiler/noirc_frontend/src/ast/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ use crate::macros_api::StructId;
use crate::node_interner::ExprId;
use crate::token::{Attributes, Token, Tokens};
use crate::{Kind, Type};
use acvm::{acir::AcirField, FieldElement};
use iter_extended::vecmap;
use noirc_errors::{Span, Spanned};
use num_bigint::BigInt;
use num_traits::Zero;

use super::UnaryRhsMemberAccess;

Expand Down Expand Up @@ -46,6 +47,12 @@ pub enum ExpressionKind {
Error,
}

impl ExpressionKind {
pub fn zero() -> Self {
ExpressionKind::Literal(Literal::zero())
}
}

/// A Vec of unresolved names for type variables.
/// For `fn foo<A, B>(...)` this corresponds to vec!["A", "B"].
pub type UnresolvedGenerics = Vec<UnresolvedGeneric>;
Expand Down Expand Up @@ -134,8 +141,8 @@ impl ExpressionKind {
match (operator, &rhs) {
(
UnaryOp::Minus,
Expression { kind: ExpressionKind::Literal(Literal::Integer(field, sign)), .. },
) => ExpressionKind::Literal(Literal::Integer(*field, !sign)),
Expression { kind: ExpressionKind::Literal(Literal::Integer(value)), .. },
) => ExpressionKind::Literal(Literal::Integer(-value)),
_ => ExpressionKind::Prefix(Box::new(PrefixExpression { operator, rhs })),
}
}
Expand All @@ -162,8 +169,8 @@ impl ExpressionKind {
}))
}

pub fn integer(contents: FieldElement) -> ExpressionKind {
ExpressionKind::Literal(Literal::Integer(contents, false))
pub fn integer(contents: BigInt) -> ExpressionKind {
ExpressionKind::Literal(Literal::Integer(contents))
}

pub fn boolean(contents: bool) -> ExpressionKind {
Expand Down Expand Up @@ -195,14 +202,14 @@ impl ExpressionKind {
self.as_integer().is_some()
}

fn as_integer(&self) -> Option<FieldElement> {
fn as_integer(&self) -> Option<&BigInt> {
let literal = match self {
ExpressionKind::Literal(literal) => literal,
_ => return None,
};

match literal {
Literal::Integer(integer, _) => Some(*integer),
Literal::Integer(integer) => Some(integer),
_ => None,
}
}
Expand Down Expand Up @@ -433,13 +440,19 @@ pub enum Literal {
Array(ArrayLiteral),
Slice(ArrayLiteral),
Bool(bool),
Integer(FieldElement, /*sign*/ bool), // false for positive integer and true for negative
Integer(BigInt),
Str(String),
RawStr(String, u8),
FmtStr(String),
Unit,
}

impl Literal {
pub fn zero() -> Literal {
Literal::Integer(BigInt::zero())
}
}

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct PrefixExpression {
pub operator: UnaryOp,
Expand Down Expand Up @@ -646,12 +659,8 @@ impl Display for Literal {
write!(f, "&[{repeated_element}; {length}]")
}
Literal::Bool(boolean) => write!(f, "{}", if *boolean { "true" } else { "false" }),
Literal::Integer(integer, sign) => {
if *sign {
write!(f, "-{}", integer.to_u128())
} else {
write!(f, "{}", integer.to_u128())
}
Literal::Integer(integer) => {
write!(f, "{}", integer)
}
Literal::Str(string) => write!(f, "\"{string}\""),
Literal::RawStr(string, num_hashes) => {
Expand Down
12 changes: 6 additions & 6 deletions compiler/noirc_frontend/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub use expression::*;
pub use function::*;

use noirc_errors::Span;
use num_bigint::Sign;
use serde::{Deserialize, Serialize};
pub use statement::*;
pub use structure::*;
Expand All @@ -27,7 +28,6 @@ use crate::{
token::IntType,
BinaryTypeOperator,
};
use acvm::acir::AcirField;
use iter_extended::vecmap;

#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Ord, PartialOrd)]
Expand Down Expand Up @@ -323,11 +323,11 @@ impl UnresolvedTypeExpression {

fn from_expr_helper(expr: Expression) -> Result<UnresolvedTypeExpression, Expression> {
match expr.kind {
ExpressionKind::Literal(Literal::Integer(int, sign)) => {
assert!(!sign, "Negative literal is not allowed here");
match int.try_to_u32() {
Some(int) => Ok(UnresolvedTypeExpression::Constant(int, expr.span)),
None => Err(expr),
ExpressionKind::Literal(Literal::Integer(ref int)) => {
assert!(int.sign() != Sign::Minus, "Negative literal is not allowed here");
match int.try_into() {
Ok(int) => Ok(UnresolvedTypeExpression::Constant(int, expr.span)),
Err(_) => Err(expr),
}
}
ExpressionKind::Variable(path, _) => Ok(UnresolvedTypeExpression::Variable(path)),
Expand Down
4 changes: 1 addition & 3 deletions compiler/noirc_frontend/src/ast/statement.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use std::fmt::Display;
use std::sync::atomic::{AtomicU32, Ordering};

use acvm::acir::AcirField;
use acvm::FieldElement;
use iter_extended::vecmap;
use noirc_errors::{Span, Spanned};

Expand Down Expand Up @@ -577,7 +575,7 @@ impl ForRange {
}
ForRange::Array(array) => {
let array_span = array.span;
let start_range = ExpressionKind::integer(FieldElement::zero());
let start_range = ExpressionKind::zero();
let start_range = Expression::new(start_range, array_span);

let next_unique_id = UNIQUE_NAME_COUNTER.fetch_add(1, Ordering::Relaxed);
Expand Down
10 changes: 2 additions & 8 deletions compiler/noirc_frontend/src/debug/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -721,15 +721,9 @@ fn id_expr(id: &ast::Ident) -> ast::Expression {
}

fn uint_expr(x: u128, span: Span) -> ast::Expression {
ast::Expression {
kind: ast::ExpressionKind::Literal(ast::Literal::Integer(x.into(), false)),
span,
}
ast::Expression { kind: ast::ExpressionKind::Literal(ast::Literal::Integer(x.into())), span }
}

fn sint_expr(x: i128, span: Span) -> ast::Expression {
ast::Expression {
kind: ast::ExpressionKind::Literal(ast::Literal::Integer(x.abs().into(), x < 0)),
span,
}
ast::Expression { kind: ast::ExpressionKind::Literal(ast::Literal::Integer(x.into())), span }
}
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/elaborator/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ impl<'context> Elaborator<'context> {
match literal {
Literal::Unit => (Lit(HirLiteral::Unit), Type::Unit),
Literal::Bool(b) => (Lit(HirLiteral::Bool(b)), Type::Bool),
Literal::Integer(integer, sign) => {
let int = HirLiteral::Integer(integer, sign);
Literal::Integer(ref integer) => {
let int = HirLiteral::from_big_int(integer);
(Lit(int), self.polymorphic_integer_or_field())
}
Literal::Str(str) | Literal::RawStr(str, _) => {
Expand Down
50 changes: 13 additions & 37 deletions compiler/noirc_frontend/src/hir/comptime/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use chumsky::Parser;
use im::Vector;
use iter_extended::{try_vecmap, vecmap};
use noirc_errors::Location;
use num_bigint::{BigInt, Sign};

use crate::{
ast::{ArrayLiteral, ConstructorExpression, Ident, IntegerBitSize, Signedness},
Expand Down Expand Up @@ -90,43 +91,18 @@ impl Value {
let kind = match self {
Value::Unit => ExpressionKind::Literal(Literal::Unit),
Value::Bool(value) => ExpressionKind::Literal(Literal::Bool(value)),
Value::Field(value) => ExpressionKind::Literal(Literal::Integer(value, false)),
Value::I8(value) => {
let negative = value < 0;
let value = value.abs();
let value = (value as u128).into();
ExpressionKind::Literal(Literal::Integer(value, negative))
}
Value::I16(value) => {
let negative = value < 0;
let value = value.abs();
let value = (value as u128).into();
ExpressionKind::Literal(Literal::Integer(value, negative))
}
Value::I32(value) => {
let negative = value < 0;
let value = value.abs();
let value = (value as u128).into();
ExpressionKind::Literal(Literal::Integer(value, negative))
}
Value::I64(value) => {
let negative = value < 0;
let value = value.abs();
let value = (value as u128).into();
ExpressionKind::Literal(Literal::Integer(value, negative))
}
Value::U8(value) => {
ExpressionKind::Literal(Literal::Integer((value as u128).into(), false))
}
Value::U16(value) => {
ExpressionKind::Literal(Literal::Integer((value as u128).into(), false))
}
Value::U32(value) => {
ExpressionKind::Literal(Literal::Integer((value as u128).into(), false))
}
Value::U64(value) => {
ExpressionKind::Literal(Literal::Integer((value as u128).into(), false))
}
Value::Field(value) => {
let value = BigInt::from_bytes_be(Sign::NoSign, &value.to_be_bytes());
ExpressionKind::Literal(Literal::Integer(value))
}
Value::I8(value) => ExpressionKind::Literal(Literal::Integer(value.into())),
Value::I16(value) => ExpressionKind::Literal(Literal::Integer(value.into())),
Value::I32(value) => ExpressionKind::Literal(Literal::Integer(value.into())),
Value::I64(value) => ExpressionKind::Literal(Literal::Integer(value.into())),
Value::U8(value) => ExpressionKind::Literal(Literal::Integer(value.into())),
Value::U16(value) => ExpressionKind::Literal(Literal::Integer(value.into())),
Value::U32(value) => ExpressionKind::Literal(Literal::Integer(value.into())),
Value::U64(value) => ExpressionKind::Literal(Literal::Integer(value.into())),
Value::String(value) => ExpressionKind::Literal(Literal::Str(unwrap_rc(value))),
Value::Function(id, typ) => {
let id = interner.function_definition_id(id);
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/hir/resolution/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1486,7 +1486,7 @@ impl<'a> Resolver<'a> {
Literal::Slice(array_literal) => {
HirLiteral::Slice(self.resolve_array_literal(array_literal))
}
Literal::Integer(integer, sign) => HirLiteral::Integer(integer, sign),
Literal::Integer(ref integer) => HirLiteral::from_big_int(integer),
Literal::Str(str) => HirLiteral::Str(str),
Literal::RawStr(str, _) => HirLiteral::Str(str),
Literal::FmtStr(str) => self.resolve_fmt_str_literal(str, expr.span),
Expand Down
10 changes: 10 additions & 0 deletions compiler/noirc_frontend/src/hir_def/expr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use acvm::FieldElement;
use fm::FileId;
use noirc_errors::Location;
use num_bigint::{BigInt, Sign};

use crate::ast::{BinaryOp, BinaryOpKind, Ident, UnaryOp};
use crate::node_interner::{DefinitionId, ExprId, FuncId, NodeInterner, StmtId, TraitMethodId};
Expand Down Expand Up @@ -114,6 +115,15 @@ pub enum HirLiteral {
Unit,
}

impl HirLiteral {
pub fn from_big_int(big_int: &BigInt) -> Self {
let is_negative = big_int.sign() == Sign::Minus;
let field = FieldElement::try_from_str(&big_int.to_string())
.expect("ice: failed to convert BigInt to FieldElement");
HirLiteral::Integer(field, is_negative)
}
}

#[derive(Debug, Clone)]
pub enum HirArrayLiteral {
Standard(Vec<ExprId>),
Expand Down
Loading

0 comments on commit 79de236

Please sign in to comment.