Skip to content

Commit

Permalink
Basic regex methods (#40)
Browse files Browse the repository at this point in the history
Added the following regex methods to the `str` module:
- `str:regex-test(string, pattern) -> bool`
- `str:regex-match(string, pattern) -> string`
- `str:regex-match-all(string, pattern) -> List(String)`

---------

Co-authored-by: leonskidev <[email protected]>
  • Loading branch information
Vandesm14 and leonskidev authored Jun 10, 2024
1 parent 4e5c37c commit 6b90b90
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 2 deletions.
39 changes: 39 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions stack-std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ name = "stack-std"
version = "0.1.0"
edition = "2021"

[features]
default = ["regex"]
regex = ["dep:regex"]

[dependencies]
stack-core = { path = "../stack-core" }
unicode-segmentation.workspace = true
compact_str.workspace = true
regex = { version = "1", optional = true }
104 changes: 102 additions & 2 deletions stack-std/src/str.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use compact_str::{CompactString, ToCompactString};
use regex::Regex;
use stack_core::prelude::*;
use unicode_segmentation::UnicodeSegmentation;

// TODO: Add str:escape and str:unescape.

pub fn module() -> Module {
Module::new(Symbol::from_ref("str"))
let mut module = Module::new(Symbol::from_ref("str"))
.with_func(Symbol::from_ref("trim-start"), |_, mut context, expr| {
let item = context.stack_pop(&expr)?;

Expand Down Expand Up @@ -241,5 +242,104 @@ pub fn module() -> Module {
context.stack_push(kind.into())?;

Ok(context)
})
});

#[cfg(feature = "regex")]
{
module = module
.with_func(Symbol::from_ref("regex-test"), |_, mut context, expr| {
let pattern = context.stack_pop(&expr)?;
let string = context.stack_pop(&expr)?;

let kind = match (string.kind, pattern.kind) {
(ExprKind::String(ref string), ExprKind::String(ref pattern)) => {
let re = Regex::new(pattern);
match re {
Ok(re) => ExprKind::Boolean(re.captures(string).is_some()),
Err(err) => {
todo!()
}
}
}
(_, _) => ExprKind::Nil,
};

context.stack_push(kind.into())?;

Ok(context)
})
.with_func(Symbol::from_ref("regex-match"), |_, mut context, expr| {
let pattern = context.stack_pop(&expr)?;
let string = context.stack_pop(&expr)?;

let kind = match (string.kind, pattern.kind) {
(ExprKind::String(ref string), ExprKind::String(ref pattern)) => {
let re = Regex::new(pattern);
match re {
Ok(re) => re
.find(string)
.map(|m| {
ExprKind::String(
string
.chars()
.skip(m.start())
.take(m.end() - m.start())
.collect::<String>()
.into(),
)
})
.unwrap_or(ExprKind::Nil),
Err(err) => {
todo!()
}
}
}
(_, _) => ExprKind::Nil,
};

context.stack_push(kind.into())?;

Ok(context)
})
.with_func(
Symbol::from_ref("regex-match-all"),
|_, mut context, expr| {
let pattern = context.stack_pop(&expr)?;
let string = context.stack_pop(&expr)?;

let kind = match (string.kind, pattern.kind) {
(ExprKind::String(ref string), ExprKind::String(ref pattern)) => {
let re = Regex::new(pattern);
match re {
Ok(re) => ExprKind::List(
re.find_iter(string)
.map(|m| {
ExprKind::String(
string
.chars()
.skip(m.start())
.take(m.end() - m.start())
.collect::<String>()
.into(),
)
.into()
})
.collect::<Vec<_>>(),
),
Err(err) => {
todo!()
}
}
}
(_, _) => ExprKind::Nil,
};

context.stack_push(kind.into())?;

Ok(context)
},
)
}

module
}

0 comments on commit 6b90b90

Please sign in to comment.