Skip to content

Commit

Permalink
feat: add support for u16/i16 (#4985)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves #4908

## Summary\*

Adds cases for `u16`. `i16` was right there so added at the same time.

## Additional Context



## Documentation\*

Check one:
- [ ] No documentation needed.
- [x] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
  • Loading branch information
michaeljklein and TomAFrench committed May 7, 2024
1 parent a1a2afb commit e43661d
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 3 deletions.
3 changes: 3 additions & 0 deletions compiler/noirc_frontend/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use iter_extended::vecmap;
pub enum IntegerBitSize {
One,
Eight,
Sixteen,
ThirtyTwo,
SixtyFour,
}
Expand All @@ -48,6 +49,7 @@ impl From<IntegerBitSize> for u32 {
match size {
One => 1,
Eight => 8,
Sixteen => 16,
ThirtyTwo => 32,
SixtyFour => 64,
}
Expand All @@ -64,6 +66,7 @@ impl TryFrom<u32> for IntegerBitSize {
match value {
1 => Ok(One),
8 => Ok(Eight),
16 => Ok(Sixteen),
32 => Ok(ThirtyTwo),
64 => Ok(SixtyFour),
_ => Err(InvalidIntegerBitSizeError(value)),
Expand Down
64 changes: 64 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/interpreter.rs

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ fn for_loop() {
assert_eq!(result, Value::U8(15));
}

#[test]
fn for_loop_u16() {
let program = "fn main() -> pub u16 {
let mut x = 0;
for i in 0 .. 6 {
x += i;
}
x
}";
let result = interpret(program, vec!["main".into()]);
assert_eq!(result, Value::U16(15));
}

#[test]
fn for_loop_with_break() {
let program = "unconstrained fn main() -> pub u32 {
Expand Down
13 changes: 13 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ pub enum Value {
Bool(bool),
Field(FieldElement),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
String(Rc<String>),
Expand All @@ -45,9 +47,11 @@ impl Value {
Value::Bool(_) => Type::Bool,
Value::Field(_) => Type::FieldElement,
Value::I8(_) => Type::Integer(Signedness::Signed, IntegerBitSize::Eight),
Value::I16(_) => Type::Integer(Signedness::Signed, IntegerBitSize::Sixteen),
Value::I32(_) => Type::Integer(Signedness::Signed, IntegerBitSize::ThirtyTwo),
Value::I64(_) => Type::Integer(Signedness::Signed, IntegerBitSize::SixtyFour),
Value::U8(_) => Type::Integer(Signedness::Unsigned, IntegerBitSize::Eight),
Value::U16(_) => Type::Integer(Signedness::Unsigned, IntegerBitSize::Sixteen),
Value::U32(_) => Type::Integer(Signedness::Unsigned, IntegerBitSize::ThirtyTwo),
Value::U64(_) => Type::Integer(Signedness::Unsigned, IntegerBitSize::SixtyFour),
Value::String(value) => {
Expand Down Expand Up @@ -87,6 +91,12 @@ impl Value {
let value = (value as u128).into();
HirExpression::Literal(HirLiteral::Integer(value, negative))
}
Value::I16(value) => {
let negative = value < 0;
let value = value.abs();
let value = (value as u128).into();
HirExpression::Literal(HirLiteral::Integer(value, negative))
}
Value::I32(value) => {
let negative = value < 0;
let value = value.abs();
Expand All @@ -102,6 +112,9 @@ impl Value {
Value::U8(value) => {
HirExpression::Literal(HirLiteral::Integer((value as u128).into(), false))
}
Value::U16(value) => {
HirExpression::Literal(HirLiteral::Integer((value as u128).into(), false))
}
Value::U32(value) => {
HirExpression::Literal(HirLiteral::Integer((value as u128).into(), false))
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/noirc_frontend/src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1374,7 +1374,7 @@ mod test {
fresh_statement(),
true,
),
vec!["x as u8", "0 as Field", "(x + 3) as [Field; 8]"],
vec!["x as u8", "x as u16", "0 as Field", "(x + 3) as [Field; 8]"],
);
parse_all_failing(
atom_or_right_unary(
Expand Down Expand Up @@ -1546,7 +1546,10 @@ mod test {
// Let statements are not type checked here, so the parser will accept as
// long as it is a type. Other statements such as Public are type checked
// Because for now, they can only have one type
parse_all(declaration(expression()), vec!["let _ = 42", "let x = y", "let x : u8 = y"]);
parse_all(
declaration(expression()),
vec!["let _ = 42", "let x = y", "let x : u8 = y", "let x: u16 = y"],
);
}

#[test]
Expand Down
4 changes: 3 additions & 1 deletion docs/docs/noir/concepts/data_types/integers.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ keywords: [noir, integer types, methods, examples, arithmetic]
sidebar_position: 1
---

An integer type is a range constrained field type. The Noir frontend supports both unsigned and signed integer types. The allowed sizes are 1, 8, 32 and 64 bits.
An integer type is a range constrained field type.
The Noir frontend supports both unsigned and signed integer types.
The allowed sizes are 1, 8, 16, 32 and 64 bits.

:::info

Expand Down
7 changes: 7 additions & 0 deletions test_programs/execution_success/u16_support/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "u16_support"
type = "bin"
authors = [""]
compiler_version = ">=0.29.0"

[dependencies]
1 change: 1 addition & 0 deletions test_programs/execution_success/u16_support/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = "2"
24 changes: 24 additions & 0 deletions test_programs/execution_success/u16_support/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
fn main(x: u16) {
test_u16(x);
test_u16_unconstrained(x);
}

unconstrained fn test_u16_unconstrained(x: u16) {
test_u16(x)
}

fn test_u16(x: u16) {
let t1: u16 = 1234;
let t2: u16 = 4321;
let t = t1 + t2;

let t4 = t - t2;
assert(t4 == t1);

let mut small_int = x as u16;
let shift = small_int << (x as u8);
assert(shift == 8);
assert(shift >> (x as u8) == small_int);
assert(shift >> 15 == 0);
assert(shift << 15 == 0);
}

0 comments on commit e43661d

Please sign in to comment.