🐐 QVAERE
This commit is contained in:
@@ -1277,6 +1277,19 @@ class BuiltIn(Node):
|
||||
with open(path, "a") as f:
|
||||
f.write(content)
|
||||
return vtable, ValNul()
|
||||
case "QVAERE":
|
||||
pattern = params[0]
|
||||
text = params[1]
|
||||
if not isinstance(pattern, ValStr) or not isinstance(text, ValStr):
|
||||
raise CentvrionError("QVAERE requires two strings")
|
||||
try:
|
||||
matches = [
|
||||
ValStr(m.group(0))
|
||||
for m in re.finditer(pattern.value(), text.value())
|
||||
]
|
||||
except re.error as e:
|
||||
raise CentvrionError(f"Invalid regex: {e}")
|
||||
return vtable, ValList(matches)
|
||||
case _:
|
||||
raise NotImplementedError(self.builtin)
|
||||
|
||||
|
||||
@@ -297,6 +297,9 @@ def _emit_builtin(node, ctx):
|
||||
lines.append(f"cent_adivnge({param_vars[0]}, {param_vars[1]});")
|
||||
lines.append(f"CentValue {tmp} = cent_null();")
|
||||
|
||||
case "QVAERE":
|
||||
lines.append(f"CentValue {tmp} = cent_qvaere({param_vars[0]}, {param_vars[1]});")
|
||||
|
||||
case _:
|
||||
raise NotImplementedError(node.builtin)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <regex.h>
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Global arena */
|
||||
@@ -870,6 +871,37 @@ CentValue cent_dict_keys(CentValue dict) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Regex */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
CentValue cent_qvaere(CentValue pattern, CentValue text) {
|
||||
if (pattern.type != CENT_STR || text.type != CENT_STR)
|
||||
cent_type_error("'QVAERE' requires two strings");
|
||||
regex_t re;
|
||||
int rc = regcomp(&re, pattern.sval, REG_EXTENDED);
|
||||
if (rc != 0) {
|
||||
char errbuf[256];
|
||||
regerror(rc, &re, errbuf, sizeof(errbuf));
|
||||
regfree(&re);
|
||||
cent_runtime_error(errbuf);
|
||||
}
|
||||
CentValue result = cent_list_new(8);
|
||||
const char *cursor = text.sval;
|
||||
regmatch_t match;
|
||||
while (*cursor && regexec(&re, cursor, 1, &match, 0) == 0) {
|
||||
int len = match.rm_eo - match.rm_so;
|
||||
char *buf = cent_arena_alloc(cent_arena, len + 1);
|
||||
memcpy(buf, cursor + match.rm_so, len);
|
||||
buf[len] = '\0';
|
||||
cent_list_push(&result, cent_str(buf));
|
||||
cursor += match.rm_eo;
|
||||
if (len == 0) cursor++; // avoid infinite loop on zero-length match
|
||||
}
|
||||
regfree(&re);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Initialisation */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
@@ -232,6 +232,7 @@ CentValue cent_ordina(CentValue lst); /* ORDINA */
|
||||
CentValue cent_lege(CentValue path); /* LEGE */
|
||||
void cent_scribe(CentValue path, CentValue content); /* SCRIBE */
|
||||
void cent_adivnge(CentValue path, CentValue content); /* ADIVNGE */
|
||||
CentValue cent_qvaere(CentValue pattern, CentValue text); /* QVAERE */
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Array helpers */
|
||||
|
||||
@@ -57,7 +57,8 @@ builtin_tokens = [("BUILTIN", i) for i in [
|
||||
"TYPVS",
|
||||
"LEGE",
|
||||
"SCRIBE",
|
||||
"ADIVNGE"
|
||||
"ADIVNGE",
|
||||
"QVAERE"
|
||||
]]
|
||||
|
||||
data_tokens = [
|
||||
|
||||
Reference in New Issue
Block a user