From 0967550f5b2bc46442f65b0d1e3682144736aa5b Mon Sep 17 00:00:00 2001 From: Tom French Date: Mon, 2 Sep 2024 21:05:53 +0100 Subject: [PATCH] feat: implement `str_as_bytes` in the `comptime` interpreter --- .../src/hir/comptime/interpreter/builtin.rs | 27 +++++++++++++++++++ .../comptime_str_as_bytes/Nargo.toml | 7 +++++ .../comptime_str_as_bytes/src/main.nr | 9 +++++++ 3 files changed, 43 insertions(+) create mode 100644 test_programs/compile_success_empty/comptime_str_as_bytes/Nargo.toml create mode 100644 test_programs/compile_success_empty/comptime_str_as_bytes/src/main.nr diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 7a196d98f52..e5b098b41ed 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -126,6 +126,7 @@ impl<'local, 'context> Interpreter<'local, 'context> { "slice_push_back" => slice_push_back(interner, arguments, location), "slice_push_front" => slice_push_front(interner, arguments, location), "slice_remove" => slice_remove(interner, arguments, location, call_stack), + "str_as_bytes" => str_as_bytes(interner, arguments, location), "struct_def_as_type" => struct_def_as_type(interner, arguments, location), "struct_def_fields" => struct_def_fields(interner, arguments, location), "struct_def_generics" => struct_def_generics(interner, arguments, location), @@ -242,6 +243,32 @@ fn slice_push_back( Ok(Value::Slice(values, typ)) } +fn str_as_bytes( + interner: &NodeInterner, + arguments: Vec<(Value, Location)>, + location: Location, +) -> IResult { + let (string, string_location) = check_one_argument(arguments, location)?; + + match string { + Value::String(string) => { + let string_as_bytes = string.as_bytes(); + let bytes_vector: Vec = string_as_bytes.iter().cloned().map(Value::U8).collect(); + let byte_array_type = Type::Array( + Box::new(Type::Constant(string_as_bytes.len() as u32)), + Box::new(Type::Integer(Signedness::Unsigned, IntegerBitSize::Eight)), + ); + Ok(Value::Array(bytes_vector.into(), byte_array_type)) + } + value => { + let type_var = Box::new(interner.next_type_variable()); + let expected = Type::Array(type_var.clone(), type_var); + let actual = value.get_type().into_owned(); + Err(InterpreterError::TypeMismatch { expected, actual, location: string_location }) + } + } +} + /// fn as_type(self) -> Type fn struct_def_as_type( interner: &NodeInterner, diff --git a/test_programs/compile_success_empty/comptime_str_as_bytes/Nargo.toml b/test_programs/compile_success_empty/comptime_str_as_bytes/Nargo.toml new file mode 100644 index 00000000000..f387e0e393a --- /dev/null +++ b/test_programs/compile_success_empty/comptime_str_as_bytes/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "comptime_str_as_bytes" +type = "bin" +authors = [""] +compiler_version = ">=0.24.0" + +[dependencies] diff --git a/test_programs/compile_success_empty/comptime_str_as_bytes/src/main.nr b/test_programs/compile_success_empty/comptime_str_as_bytes/src/main.nr new file mode 100644 index 00000000000..eefea67100f --- /dev/null +++ b/test_programs/compile_success_empty/comptime_str_as_bytes/src/main.nr @@ -0,0 +1,9 @@ +fn main() { + comptime + { + let hello_world_string = "hello world"; + let hello_world_bytes: [u8; 11] = [0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]; + + assert_eq(hello_world_string.as_bytes(), hello_world_bytes); + } +}