Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}