feat(runtime/object): missing string.iterator builtin functions

This commit is contained in:
Leonardo de Moura 2018-11-15 13:05:29 -08:00
parent 4a0a3f8d85
commit 70c4e33cf2
2 changed files with 41 additions and 0 deletions

View file

@ -1198,6 +1198,21 @@ static std::string list_as_string(b_obj_arg lst) {
return s;
}
static std::string rev_list_as_string(b_obj_arg lst) {
buffer<unsigned> codes;
b_obj_arg o = lst;
while (!is_scalar(o)) {
codes.push_back(unbox(cnstr_get(o, 0)));
o = cnstr_get(o, 1);
}
std::reverse(codes.begin(), codes.end());
std::string s;
for (unsigned c : codes) {
push_unicode_scalar(s, c);
}
return s;
}
static obj_res string_to_list_core(std::string const & s, bool reverse = false) {
buffer<unsigned> tmp;
utf8_decode(s, tmp);
@ -1477,6 +1492,29 @@ obj_res string_iterator_extract(b_obj_arg it1, b_obj_arg it2) {
return mk_option_some(r);
}
obj_res string_iterator_mk(b_obj_arg l1, b_obj_arg l2) {
std::string s1 = rev_list_as_string(l1);
std::string s2 = list_as_string(l2);
size_t i = s1.size();
std::reverse(s1.begin(), s1.end());
s1 += s2;
return mk_iterator(mk_string(s1), i, utf8_strlen(s2));
}
obj_res string_iterator_fst(b_obj_arg it) {
object * s = string_iterator_prev_to_string(it);
object * r = string_to_list_core(std::string(string_cstr(s), string_size(s)), true /* reverse */);
dec_ref(s);
return r;
}
obj_res string_iterator_snd(b_obj_arg it) {
object * s = string_iterator_remaining_to_string(it);
object * r = string_to_list_core(std::string(string_cstr(s), string_size(s)));
dec_ref(s);
return r;
}
// =======================================
// Debugging helper functions

View file

@ -1048,6 +1048,9 @@ obj_res string_iterator_prev_to_string(b_obj_arg it);
obj_res string_iterator_to_string(b_obj_arg it);
obj_res string_iterator_to_end(obj_arg it);
obj_res string_iterator_extract(b_obj_arg it1, b_obj_arg it2);
obj_res string_iterator_mk(obj_arg cs1, obj_arg cs2);
obj_res string_iterator_fst(b_obj_arg it);
obj_res string_iterator_snd(b_obj_arg it);
bool string_eq(b_obj_arg s1, b_obj_arg s2);
inline bool string_ne(b_obj_arg s1, b_obj_arg s2) { return !string_eq(s1, s2); }