add regex lib

This commit is contained in:
ValKmjolnir 2024-03-01 22:39:43 +08:00
parent b3e6b5784a
commit 22b9bce298
7 changed files with 160 additions and 3 deletions

View File

@ -4,9 +4,9 @@ ifndef OS
OS = $(shell uname)
endif
ifeq ($(OS), Darwin)
CXXFLAGS = -std=$(STD) -c -O3 -fno-exceptions -fPIC -mmacosx-version-min=10.15
CXXFLAGS = -std=$(STD) -c -O3 -fPIC -mmacosx-version-min=10.15
else
CXXFLAGS = -std=$(STD) -c -O3 -fno-exceptions -fPIC
CXXFLAGS = -std=$(STD) -c -O3 -fPIC
endif
NASAL_HEADER = \
@ -35,7 +35,8 @@ NASAL_HEADER = \
src/json_lib.h\
src/unix_lib.h\
src/coroutine.h\
src/repl.h
src/repl.h\
src/regex_lib.h
NASAL_OBJECT = \
build/nasal_err.o\
@ -64,6 +65,7 @@ NASAL_OBJECT = \
build/nasal_vm.o\
build/nasal_dbg.o\
build/repl.o\
build/regex_lib.o\
build/main.o
@ -177,6 +179,13 @@ build/unix_lib.o: \
src/unix_lib.h src/unix_lib.cpp | build
$(CXX) $(CXXFLAGS) src/unix_lib.cpp -o build/unix_lib.o
build/regex_lib.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/regex_lib.h src/regex_lib.cpp | build
$(CXX) $(CXXFLAGS) src/regex_lib.cpp -o build/regex_lib.o
build/fg_props.o: \
src/nasal.h\
src/nasal_type.h\
@ -279,6 +288,7 @@ test:nasal
@ ./nasal -t -d test/prime.nas
@ ./nasal -e test/qrcode.nas
@ ./nasal -t -d test/quick_sort.nas
@ ./nasal -t -d test/regex_test.nas
@ ./nasal -e test/scalar.nas hello world
@ ./nasal -e test/trait.nas
@ ./nasal -t -d test/turingmachine.nas

View File

@ -37,6 +37,7 @@ void codegen::init_native_function() {
load_native_function_table(dylib_lib_native);
load_native_function_table(unix_lib_native);
load_native_function_table(json_lib_native);
load_native_function_table(regex_lib_native);
}
void codegen::check_id_exist(identifier* node) {

View File

@ -17,6 +17,7 @@
#include "json_lib.h"
#include "dylib_lib.h"
#include "unix_lib.h"
#include "regex_lib.h"
#include <iomanip>
#include <list>

99
src/regex_lib.cpp Normal file
View File

@ -0,0 +1,99 @@
#include "regex_lib.h"
namespace nasal {
var builtin_regex_match(context* ctx, gc* ngc) {
auto source = ctx->localr[1];
auto reg_str = ctx->localr[2];
if (!source.is_str()) {
return nas_err("regex::match", "\"src\" must be a string");
}
if (!reg_str.is_str()) {
return nas_err("regex::match", "\"reg\" must be a format string");
}
try {
auto res = std::regex_match(source.str(), std::regex(reg_str.str()));
return res? one:zero;
} catch(const std::regex_error& e) {
return nas_err("regex::match", e.what());
}
return zero;
}
var builtin_regex_search(context* ctx, gc* ngc) {
auto source = ctx->localr[1];
auto reg_str = ctx->localr[2];
if (!source.is_str()) {
return nas_err("regex::search", "\"src\" must be a string");
}
if (!reg_str.is_str()) {
return nas_err("regex::search", "\"reg\" must be a format string");
}
try {
auto res = std::regex_search(source.str(), std::regex(reg_str.str()));
return res? one:zero;
} catch(const std::regex_error& e) {
return nas_err("regex::search", e.what());
}
return nil;
}
var builtin_regex_replace(context* ctx, gc* ngc) {
auto source = ctx->localr[1];
auto reg_str = ctx->localr[2];
auto fmt = ctx->localr[3];
if (!source.is_str()) {
return nas_err("regex::replace", "\"src\" must be a string");
}
if (!reg_str.is_str()) {
return nas_err("regex::replace", "\"reg\" must be a format string");
}
if (!fmt.is_str()) {
return nas_err("regex::replace", "\"fmt\" must be a format string");
}
try {
auto res = std::regex_replace(
source.str(),
std::regex(reg_str.str()),
fmt.str()
);
return ngc->newstr(res);
} catch(const std::regex_error& e) {
return nas_err("regex::replace", e.what());
}
return ngc->newstr(source.str());
}
var builtin_regex_match_all(context* ctx, gc* ngc) {
auto source = ctx->localr[1];
auto reg_str = ctx->localr[2];
if (!source.is_str()) {
return nas_err("regex::match_all", "\"src\" must be a string");
}
if (!reg_str.is_str()) {
return nas_err("regex::match_all", "\"reg\" must be a format string");
}
auto res = ngc->temp = ngc->alloc(vm_type::vm_vec);
try {
const auto& src = source.str();
auto words_regex = std::regex(reg_str.str());
auto begin = std::sregex_iterator(src.begin(), src.end(), words_regex);
auto end = std::sregex_iterator();
for (auto i = begin; i!=end; ++i) {
res.vec().elems.push_back(ngc->newstr((*i).str()));
}
} catch(const std::regex_error& e) {
return nas_err("regex::match_all", e.what());
}
return res;
}
nasal_builtin_table regex_lib_native[] = {
{"__regex_match", builtin_regex_match},
{"__regex_search", builtin_regex_search},
{"__regex_replace", builtin_regex_replace},
{"__regex_match_all", builtin_regex_match_all},
{nullptr, nullptr}
};
}

18
src/regex_lib.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include <regex>
#include "nasal.h"
#include "nasal_gc.h"
#include "nasal_builtin.h"
namespace nasal {
var builtin_regex_match(context*, gc*);
var builtin_regex_search(context*, gc*);
var builtin_regex_replace(context*, gc*);
var builtin_regex_match_all(context*, gc*);
extern nasal_builtin_table regex_lib_native[];
}

18
std/regex.nas Normal file
View File

@ -0,0 +1,18 @@
# regex.nas
# 2024/3/1 by ValKmjolnir
var match = func(src, reg) {
return __regex_match(src, reg);
}
var search = func(src, reg) {
return __regex_search(src, reg);
}
var replace = func(src, reg, fmt) {
return __regex_replace(src, reg, fmt);
}
var match_all = func(src, reg) {
return __regex_match_all(src, reg);
}

10
test/regex_test.nas Normal file
View File

@ -0,0 +1,10 @@
use std.regex;
println(regex.match("aaa", "[a]*"));
println(regex.search("aabcaa", "abc"));
var s = "aaaaa";
println(regex.replace(s, "a", "[$&]"));
println(s);
println(regex.match_all("a,b,c,d,e,f,g,h,i", "[a-z]"));