Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fastc-core-regex

Minimal regex engine for fastC — Thompson NFA, no backreferences.

Part of the fastc-core launch set. The implementation ships alongside the fastC v1.0 compiler — every fastC v1.0 program already gets use regex::* for free. This repository is the public home for the module's API and will become installable via fastc add github.com/Skelf-Research/fastc-core-regex once stage 1.7's vendor-consumption flow completes the loop.

Surface

use regex::Regex;          // opaque compiled pattern
use regex::Match;          // struct Match { start: usize, end: usize }
use regex::RegexError;     // compile-time syntax error

use regex::compile;        // (pattern: Str) -> res(Regex, RegexError)
use regex::match_one;      // (re: ref(Regex), text: Str) -> opt(Match)
use regex::match_all;      // (re: ref(Regex), text: Str) -> Vec[Match]
use regex::replace;        // (re: ref(Regex), text: Str, replacement: Str) -> Str
use regex::release;        // (re: Regex) -> void

match_one returns the leftmost match or None. match_all returns every non-overlapping match left-to-right. replace substitutes every match with the replacement string.

release is explicit cleanup. A Drop impl lands in a later v1.x slice once the language-level destructor story settles — the surface above is the v1.0 floor.

Supported syntax

Construct Meaning
a, b, ... Literal characters
. Any character except newline
[a-z] Character class
[^a-z] Negated character class
^ Start anchor
$ End anchor
* Zero or more (greedy)
+ One or more (greedy)
? Zero or one (greedy)
{n,m} Bounded repetition
(...) Grouping
| Alternation

Anything outside this table is a syntax error from compile.

Example

use regex::compile;
use regex::match_one;
use regex::match_all;
use regex::release;
use io::println;
use io::print_int;
use io::put_char;

fn main() -> i32 {
    let re: Regex = compile(cstr("[a-z]+"))?;
    let text: Str = cstr("the quick brown fox");

    // Leftmost match.
    let first: opt(Match) = match_one(ref(re), text);
    if (is_some(first)) {
        println(cstr("found a word"));
    }

    // Count every non-overlapping match.
    let hits: Vec[Match] = match_all(ref(re), text);
    print_int(len(hits));
    put_char(10);

    release(re);
    return 0;
}

Capability policy

None required. regex is a pure data transform — it reads the pattern and the input, allocates internal state for the NFA, and returns matches. No syscalls, no ambient I/O, no Cap* token.

Why no backreferences

Thompson NFA matching is O(n * m) in the length of the input and the size of the compiled pattern — linear in the input, with no catastrophic backtracking. Backreferences (\1, \2, ...) blow this guarantee up: matching with backrefs is NP-hard in the general case and exponential in practice for adversarial inputs, which is the same class of bug behind the well-known ReDoS incidents in production regex libraries.

fastc-core-regex picks the linear-time floor and holds it. Code that genuinely needs backreferences — usually one-off scraping or migration scripts — can call PCRE through FFI and pay the performance variance explicitly.

Status

v0.1.0 — preview. API is final; the package becomes a true installable via fastc add once the consumption flow ships. Until then, the same API is available in every fastC v1.0 program via the built-in prelude.

License

MIT

About

Minimal regex engine for fastC — Thompson NFA, no backreferences, linear-time matching. Part of the fastc-core six-month set.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors