From 70c4e33cf2cbb78a3e1dcfe72ca1ed00b983b797 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Thu, 15 Nov 2018 13:05:29 -0800 Subject: [PATCH] feat(runtime/object): missing `string.iterator` builtin functions --- src/runtime/object.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/runtime/object.h | 3 +++ 2 files changed, 41 insertions(+) diff --git a/src/runtime/object.cpp b/src/runtime/object.cpp index 787d153061..44d815b39e 100644 --- a/src/runtime/object.cpp +++ b/src/runtime/object.cpp @@ -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 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 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 diff --git a/src/runtime/object.h b/src/runtime/object.h index 312318e66f..d677c06390 100644 --- a/src/runtime/object.h +++ b/src/runtime/object.h @@ -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); }