diff --git a/Cargo.lock b/Cargo.lock index e2f65fa2..fc7401e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -245,6 +245,12 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "lua-patterns" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3da90ef01f4466adefe593c05d534fe270d04a2b067608cf8b230123e5a281" + [[package]] name = "memchr" version = "2.6.4" @@ -286,6 +292,7 @@ dependencies = [ "clap", "gc-arena", "hashbrown", + "lua-patterns", "rand", "rustc-hash", "rustyline", diff --git a/Cargo.toml b/Cargo.toml index 55be93ed..d8ff792e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ allocator-api2 = "0.2" anyhow = "1.0" gc-arena = { version = "0.4" , features = ["allocator-api2", "hashbrown"] } hashbrown = { version = "0.14", features = ["raw"] } +lua-patterns = "0.4.0" rand = { version = "0.8", features = ["small_rng"] } rustc-hash = "1.1" thiserror = "1.0" diff --git a/src/stdlib/string.rs b/src/stdlib/string.rs index 9c2fe85a..ed42dde7 100644 --- a/src/stdlib/string.rs +++ b/src/stdlib/string.rs @@ -1,4 +1,6 @@ -use crate::{AnyCallback, CallbackReturn, Context, IntoValue, Table, Value}; +use lua_patterns::LuaPattern; + +use crate::{AnyCallback, CallbackReturn, Context, IntoValue, String, Table, Value}; pub fn load_string<'gc>(ctx: Context<'gc>) { let string = Table::new(&ctx); @@ -24,5 +26,28 @@ pub fn load_string<'gc>(ctx: Context<'gc>) { ) .unwrap(); + string + .set( + ctx, + "match", + AnyCallback::from_fn(&ctx, |ctx, _, stack| { + let (v1, v2): (Value, Value) = stack.consume(ctx)?; + + if let Value::String(s1) = v1 { + if let Value::String(s2) = v2 { + let mut m = LuaPattern::new(s2.to_str()?); + + if let Some(str_match) = m.match_maybe(s1.to_str()?) { + stack.replace(ctx, String::from_slice(&ctx, str_match)); + return Ok(CallbackReturn::Return); + } + } + } + + Err("Bad argument to string.match".into_value(ctx).into()) + }), + ) + .unwrap(); + ctx.state.globals.set(ctx, "string", string).unwrap(); } diff --git a/tests/scripts/string.lua b/tests/scripts/string.lua index 277b82b4..951a32d8 100644 --- a/tests/scripts/string.lua +++ b/tests/scripts/string.lua @@ -35,7 +35,14 @@ function test_len() string.len(-2147483648) == 11 end +function test_match() + return + string.match("a4b", "%d") == "4" and + string.match("hello world", "%a+") == "hello" +end + assert( test_concat() and - test_len() + test_len() and + test_match() )