forked from M-Labs/nac3
Compare commits
6 Commits
master
...
backup-bra
Author | SHA1 | Date | |
---|---|---|---|
f2880dce03 | |||
c6e6b7bc95 | |||
914e3ba096 | |||
887f24093f | |||
4211858273 | |||
|
399af54043 |
@ -3,3 +3,4 @@
|
||||
#include "irrt/math.hpp"
|
||||
#include "irrt/ndarray.hpp"
|
||||
#include "irrt/slice.hpp"
|
||||
#include "irrt/string.hpp"
|
22
nac3core/irrt/irrt/string.hpp
Normal file
22
nac3core/irrt/irrt/string.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "irrt/int_types.hpp"
|
||||
namespace {
|
||||
template<typename SizeT>
|
||||
int32_t __nac3_str_eq_impl(const char* str1, SizeT len1, const char* str2, SizeT len2) {
|
||||
if (str1 == str2) return 1;
|
||||
if (len1 != len2) return 0;
|
||||
for (SizeT i = 0; i < len1; ++i) {
|
||||
if (static_cast<unsigned char>(str1[i]) != static_cast<unsigned char>(str2[i])) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
int32_t nac3_str_eq(const char* str1, uint64_t len1, const char* str2, uint64_t len2) {
|
||||
return __nac3_str_eq_impl<uint64_t>(str1, len1, str2, len2);
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ mod list;
|
||||
mod math;
|
||||
mod ndarray;
|
||||
mod slice;
|
||||
mod string;
|
||||
|
||||
#[must_use]
|
||||
pub fn load_irrt<'ctx>(ctx: &'ctx Context, symbol_resolver: &dyn SymbolResolver) -> Module<'ctx> {
|
||||
|
45
nac3core/src/codegen/irrt/string.rs
Normal file
45
nac3core/src/codegen/irrt/string.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use inkwell::{
|
||||
values::{BasicValueEnum, CallSiteValue, IntValue, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Either;
|
||||
|
||||
use crate::codegen::{CodeGenContext, CodeGenerator};
|
||||
|
||||
/// Generates a call to string equality comparison. Returns an `i1` representing whether the strings are equal.
|
||||
pub fn call_string_eq<'ctx, G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
str1_ptr: PointerValue<'ctx>,
|
||||
str1_len: IntValue<'ctx>,
|
||||
str2_ptr: PointerValue<'ctx>,
|
||||
str2_len: IntValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let string_eq_fn = ctx.module.get_function("nac3_str_eq").unwrap_or_else(|| {
|
||||
let i8_ptr_type = ctx.ctx.i8_type().ptr_type(AddressSpace::default());
|
||||
let i64_type = ctx.ctx.i64_type();
|
||||
let i32_type = ctx.ctx.i32_type();
|
||||
let fn_type = i32_type.fn_type(
|
||||
&[i8_ptr_type.into(), i64_type.into(), i8_ptr_type.into(), i64_type.into()],
|
||||
false,
|
||||
);
|
||||
ctx.module.add_function("nac3_str_eq", fn_type, None)
|
||||
});
|
||||
let result = ctx
|
||||
.builder
|
||||
.build_call(
|
||||
string_eq_fn,
|
||||
&[
|
||||
str1_ptr.into(),
|
||||
ctx.builder.build_int_z_extend(str1_len, ctx.ctx.i64_type(), "").unwrap().into(),
|
||||
str2_ptr.into(),
|
||||
ctx.builder.build_int_z_extend(str2_len, ctx.ctx.i64_type(), "").unwrap().into(),
|
||||
],
|
||||
"string_eq",
|
||||
)
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_int_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap();
|
||||
generator.bool_to_i1(ctx, result)
|
||||
}
|
@ -135,4 +135,4 @@ extern int32_t run(void);
|
||||
|
||||
int main(void) {
|
||||
run();
|
||||
}
|
||||
}
|
@ -2,29 +2,37 @@
|
||||
def output_bool(x: bool):
|
||||
...
|
||||
|
||||
|
||||
def str_eq():
|
||||
def test_str_eq():
|
||||
output_bool("" == "")
|
||||
output_bool("a" == "")
|
||||
output_bool("a" == "b")
|
||||
output_bool("b" == "a")
|
||||
output_bool("a" == "a")
|
||||
output_bool("a" == "b")
|
||||
output_bool("test string" == "test string")
|
||||
output_bool("test string1" == "test string2")
|
||||
output_bool("Lorem ipsum dolor sit amet" == "Lorem ipsum dolor sit amet")
|
||||
output_bool("test1" == "test2")
|
||||
output_bool("123" == "123")
|
||||
output_bool("123" == "321")
|
||||
output_bool("abc" == "abcde")
|
||||
output_bool("a" == "aa")
|
||||
output_bool(" " == " ")
|
||||
output_bool(" a " == " a ")
|
||||
|
||||
|
||||
def str_ne():
|
||||
def test_str_ne():
|
||||
output_bool("" != "")
|
||||
output_bool("a" != "")
|
||||
output_bool("a" != "b")
|
||||
output_bool("b" != "a")
|
||||
output_bool("a" != "a")
|
||||
output_bool("a" != "b")
|
||||
output_bool("test string" != "test string")
|
||||
output_bool("test string1" != "test string2")
|
||||
|
||||
|
||||
output_bool("Lorem ipsum dolor sit amet" != "Lorem ipsum dolor sit amet")
|
||||
output_bool("test1" != "test2")
|
||||
output_bool("123" != "123")
|
||||
output_bool("123" != "321")
|
||||
output_bool("abc" != "abcde")
|
||||
output_bool("a" != "aa")
|
||||
output_bool(" " != " ")
|
||||
output_bool(" a " != " a ")
|
||||
|
||||
def run() -> int32:
|
||||
str_eq()
|
||||
str_ne()
|
||||
|
||||
return 0
|
||||
test_str_eq()
|
||||
test_str_ne()
|
||||
return 0
|
Loading…
Reference in New Issue
Block a user