Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for u16/i16 #4985

Merged
merged 5 commits into from
May 7, 2024
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 @@
pub enum IntegerBitSize {
One,
Eight,
Sixteen,
ThirtyTwo,
SixtyFour,
}
Expand All @@ -48,6 +49,7 @@
match size {
One => 1,
Eight => 8,
Sixteen => 16,
ThirtyTwo => 32,
SixtyFour => 64,
}
Expand All @@ -64,6 +66,7 @@
match value {
1 => Ok(One),
8 => Ok(Eight),
16 => Ok(Sixteen),
32 => Ok(ThirtyTwo),
64 => Ok(SixtyFour),
_ => Err(InvalidIntegerBitSizeError(value)),
Expand Down Expand Up @@ -112,7 +115,7 @@
/*env:*/ Box<UnresolvedType>,
),

// The type of quoted code for metaprogramming

Check warning on line 118 in compiler/noirc_frontend/src/ast/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (metaprogramming)
Code,

Unspecified, // This is for when the user declares a variable without specifying it's type
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 @@ -47,7 +47,7 @@

use chumsky::prelude::*;
use iter_extended::vecmap;
use lalrpop_util::lalrpop_mod;

Check warning on line 50 in compiler/noirc_frontend/src/parser/parser.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (lalrpop)

Check warning on line 50 in compiler/noirc_frontend/src/parser/parser.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (lalrpop)
use noirc_errors::{Span, Spanned};

mod assertion;
Expand All @@ -60,8 +60,8 @@
mod structs;
mod traits;

// synthesized by LALRPOP

Check warning on line 63 in compiler/noirc_frontend/src/parser/parser.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (LALRPOP)
lalrpop_mod!(pub noir_parser);

Check warning on line 64 in compiler/noirc_frontend/src/parser/parser.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (lalrpop)

#[cfg(test)]
mod test_helpers;
Expand All @@ -85,12 +85,12 @@

if cfg!(feature = "experimental_parser") {
for parsed_item in &parsed_module.items {
if lalrpop_parser_supports_kind(&parsed_item.kind) {

Check warning on line 88 in compiler/noirc_frontend/src/parser/parser.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (lalrpop)
match &parsed_item.kind {
ItemKind::Import(parsed_use_tree) => {
prototype_parse_use_tree(Some(parsed_use_tree), source_program);
}
// other kinds prevented by lalrpop_parser_supports_kind

Check warning on line 93 in compiler/noirc_frontend/src/parser/parser.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (lalrpop)
_ => unreachable!(),
}
}
Expand All @@ -107,7 +107,7 @@
}

let mut lexer = Lexer::new(input);
lexer = lexer.skip_whitespaces(false);

Check warning on line 110 in compiler/noirc_frontend/src/parser/parser.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (whitespaces)
let mut errors = Vec::new();

// NOTE: this is a hack to get the references working
Expand Down Expand Up @@ -1374,7 +1374,7 @@
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 @@
// 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);
}
Loading