Bugfix for fixed-size integer ranges
This commit is contained in:
parent
898bee1581
commit
06d3ec1380
@ -387,6 +387,7 @@ env_t *new_compilation_unit(CORD libname)
|
||||
{"as_c_string", "Text$as_c_string", "func(text:Text -> CString)"},
|
||||
{"codepoint_names", "Text$codepoint_names", "func(text:Text -> [Text])"},
|
||||
{"ends_with", "Text$ends_with", "func(text,suffix:Text -> Bool)"},
|
||||
{"each", "Text$each", "func(text:Text, pattern:Pattern, fn:func(match:Match))"},
|
||||
{"find", "Text$find", "func(text:Text, pattern:Pattern, start=1 -> Match?)"},
|
||||
{"find_all", "Text$find_all", "func(text:Text, pattern:Pattern -> [Match])"},
|
||||
{"from_bytes", "Text$from_bytes", "func(bytes:[Byte] -> Text?)"},
|
||||
|
@ -409,7 +409,7 @@ public const TypeInfo_t Int$info = {
|
||||
return bit_array; \
|
||||
} \
|
||||
public to_attr Range_t KindOfInt ## $to(c_type from, c_type to) { \
|
||||
return (Range_t){Int64_to_Int(from), Int64_to_Int(to), to >= from ? (Int_t){.small=(1<<2)&1} : (Int_t){.small=(1<<2)&1}}; \
|
||||
return (Range_t){Int64_to_Int(from), Int64_to_Int(to), to >= from ? I_small(1): I_small(-1)}; \
|
||||
} \
|
||||
public PUREFUNC Optional ## KindOfInt ## _t KindOfInt ## $parse(Text_t text) { \
|
||||
OptionalInt_t full_int = Int$parse(text); \
|
||||
|
@ -1050,6 +1050,41 @@ public Text_t Text$map(Text_t text, Pattern_t pattern, Closure_t fn)
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void Text$each(Text_t text, Pattern_t pattern, Closure_t fn)
|
||||
{
|
||||
int32_t first_grapheme = Text$get_grapheme(pattern, 0);
|
||||
bool find_first = (first_grapheme != '{'
|
||||
&& !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_QUOTATION_MARK)
|
||||
&& !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_PAIRED_PUNCTUATION));
|
||||
|
||||
TextIter_t text_state = {text, 0, 0};
|
||||
void (*action)(Match_t, void*) = fn.fn;
|
||||
for (int64_t pos = 0; pos < text.length; pos++) {
|
||||
// Optimization: quickly skip ahead to first char in pattern:
|
||||
if (find_first) {
|
||||
while (pos < text.length && Text$get_grapheme_fast(&text_state, pos) != first_grapheme)
|
||||
++pos;
|
||||
}
|
||||
|
||||
capture_t captures[MAX_BACKREFS] = {};
|
||||
int64_t match_len = match(text, pos, pattern, 0, captures, 0);
|
||||
if (match_len < 0) continue;
|
||||
|
||||
Match_t m = {
|
||||
.text=Text$slice(text, I(pos+1), I(pos+match_len)),
|
||||
.index=I(pos+1),
|
||||
.captures={},
|
||||
};
|
||||
for (int i = 0; captures[i].occupied; i++) {
|
||||
Text_t capture = Text$slice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length));
|
||||
Array$insert(&m.captures, &capture, I(0), sizeof(Text_t));
|
||||
}
|
||||
|
||||
action(m, fn.userdata);
|
||||
pos += (match_len - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public Text_t Text$replace_all(Text_t text, Table_t replacements, Text_t backref_pat, bool recursive)
|
||||
{
|
||||
if (replacements.entries.length == 0) return text;
|
||||
|
@ -33,6 +33,7 @@ Array_t Text$find_all(Text_t text, Pattern_t pattern);
|
||||
PUREFUNC bool Text$has(Text_t text, Pattern_t pattern);
|
||||
OptionalArray_t Text$matches(Text_t text, Pattern_t pattern);
|
||||
Text_t Text$map(Text_t text, Pattern_t pattern, Closure_t fn);
|
||||
void Text$each(Text_t text, Pattern_t pattern, Closure_t fn);
|
||||
|
||||
#define Pattern$hash Text$hash
|
||||
#define Pattern$compare Text$compare
|
||||
|
Loading…
Reference in New Issue
Block a user