Skip to content

Instantly share code, notes, and snippets.

@samcv
Created July 20, 2017 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samcv/94faeab2ea8a1a3e1b5ec0d2189d3909 to your computer and use it in GitHub Desktop.
Save samcv/94faeab2ea8a1a3e1b5ec0d2189d3909 to your computer and use it in GitHub Desktop.
diff --git a/src/strings/iter.h b/src/strings/iter.h
index 21679304..2b7d8925 100644
--- a/src/strings/iter.h
+++ b/src/strings/iter.h
@@ -171,6 +171,35 @@ MVM_STATIC_INLINE void MVM_string_ci_init(MVMThreadContext *tc, MVMCodepointIter
ci->synth_codes = NULL;
ci->translate_newlines = translate_newlines;
};
+/* Iterates on a grapheme. Returns the grapheme's base character. Can only be used on synthetics */
+MVM_STATIC_INLINE MVMGrapheme32 MVM_grapheme_ci_init(MVMThreadContext *tc, MVMCodepointIter *ci, MVMGrapheme32 g) {
+ if (g < 0) {
+ /* Get the synthetics info. */
+ MVMNFGSynthetic *synth = MVM_nfg_get_synthetic_info(tc, g);
+ /* Set up the iterator so in the next iteration we will start to
+ * hand back combiners. */
+ ci->synth_codes = synth->combs;
+ ci->visited_synth_codes = 0;
+ ci->total_synth_codes = synth->num_combs;
+
+ /* Return the base character of the grapheme. */
+ return synth->base;
+ }
+ else {
+ ci->synth_codes = NULL;
+ ci->visited_synth_codes = 0;
+ ci->total_synth_codes = 0;
+ return g;
+ }
+}
+MVM_STATIC_INLINE MVMCodepoint MVM_grapheme_ci_get_codepoint(MVMThreadContext *tc, MVMCodepointIter *ci) {
+ MVMCodepoint result;
+ result = ci->synth_codes[ci->visited_synth_codes];
+ ci->visited_synth_codes++;
+ if (ci->visited_synth_codes == ci->total_synth_codes)
+ ci->synth_codes = NULL;
+ return result;
+}
/* Checks if there is more to read from a code point iterator; this is the
* case if we're still walking through a synthetic or we have more things
@@ -178,6 +207,9 @@ MVM_STATIC_INLINE void MVM_string_ci_init(MVMThreadContext *tc, MVMCodepointIter
MVM_STATIC_INLINE MVMint32 MVM_string_ci_has_more(MVMThreadContext *tc, MVMCodepointIter *ci) {
return ci->synth_codes || MVM_string_gi_has_more(tc, &(ci->gi));
}
+MVM_STATIC_INLINE MVMint32 MVM_grapheme_ci_has_more(MVMThreadContext *tc, MVMCodepointIter *ci) {
+ return ci->synth_codes ? 1 : 0;
+}
/* Gets the next code point. */
MVM_STATIC_INLINE MVMCodepoint MVM_string_ci_get_codepoint(MVMThreadContext *tc, MVMCodepointIter *ci) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment