[svn:parrot] r46242 - branches/codestring/src/pmc
darbelo at svn.parrot.org
darbelo at svn.parrot.org
Mon May 3 17:42:20 UTC 2010
Author: darbelo
Date: Mon May 3 17:42:20 2010
New Revision: 46242
URL: https://trac.parrot.org/parrot/changeset/46242
Log:
Merge codestring.pmc changes from trunk as a separate commit to ease review.
Modified:
branches/codestring/src/pmc/codestring.pmc
Modified: branches/codestring/src/pmc/codestring.pmc
==============================================================================
--- branches/codestring/src/pmc/codestring.pmc Mon May 3 17:42:05 2010 (r46241)
+++ branches/codestring/src/pmc/codestring.pmc Mon May 3 17:42:20 2010 (r46242)
@@ -39,7 +39,8 @@
/* HEADERIZER END: static */
pmclass CodeString extends String provides string auto_attrs {
- ATTR PMC *linepos; /* start of line positions */
+ ATTR PMC *linepos; /* start of line positions */
+ ATTR PMC *strings; /* array of strings... */
/*
@@ -52,8 +53,8 @@
*/
VTABLE void init() {
- SUPER();
SET_ATTR_linepos(INTERP, SELF, PMCNULL);
+ SET_ATTR_strings(INTERP, SELF, pmc_new(INTERP, enum_class_ResizableStringArray));
PObj_custom_mark_SET(SELF);
}
@@ -68,13 +69,19 @@
*/
VTABLE void mark() {
- SUPER();
if (PMC_data(SELF)) {
- PMC *linepos;
+ PMC *linepos, *strings;
- GET_ATTR_linepos(INTERP, SELF, linepos);
+ /* force the join to avoid marking the RPA and lots of STRINGs */
+ STRING *contents = SELF.get_string();
+ UNUSED(contents);
+ GET_ATTR_linepos(INTERP, SELF, linepos);
Parrot_gc_mark_PMC_alive(INTERP, linepos);
+
+ /* all that's in here now is a single STRING */
+ GET_ATTR_strings(INTERP, SELF, strings);
+ Parrot_gc_mark_PMC_alive(INTERP, strings);
}
}
@@ -97,7 +104,8 @@
A percent-sign followed by any other character that is a hash
key receives the value of the hash element.
-A newline is automatically added to the end of the fmt.
+A newline is automatically added to the end of the fmt, if one
+is not already present.
=cut
@@ -108,60 +116,130 @@
STRING * const comma = CONST_STRING(INTERP, ",");
STRING * const comma_space = CONST_STRING(INTERP, ", ");
STRING * const newline = CONST_STRING(INTERP, "\n");
- PMC *parts = PMCNULL;
- STRING *key, *repl, *S1;
- INTVAL pos = 0;
- INTVAL replen = 0;
+ STRING *key;
+ PMC *strings;
+ INTVAL percentPos;
+ INTVAL pos = 0;
+ GET_ATTR_strings(INTERP, SELF, strings);
+
+ /* Loop over the format string, splitting it into chunks
+ * for the string builder. */
while (pos >= 0) {
- pos += replen;
- pos = Parrot_str_find_index(INTERP, fmt, percent, pos);
- if (pos < 0)
+ /* Find the next % */
+ percentPos = Parrot_str_find_index(INTERP, fmt, percent, pos);
+
+ if (percentPos < 0) {
+ if (pos == 0) {
+ VTABLE_push_string(INTERP, strings, fmt);
+ }
+ else {
+ /* remaining string can be added as is. */
+ VTABLE_push_string(INTERP, strings,
+ Parrot_str_substr(INTERP, fmt, pos,
+ Parrot_str_byte_length(INTERP, fmt) -pos));
+ }
break;
+ }
+ else {
+ /* slurp up to just before the % sign... */
+ VTABLE_push_string(INTERP, strings,
+ Parrot_str_substr(INTERP, fmt, pos, percentPos - pos));
+ /* skip the % sign */
+ pos = percentPos + 1 ;
+ }
- key = Parrot_str_substr(INTERP, fmt, pos+1, 1);
+ /* key is always a single character */
+ key = Parrot_str_substr(INTERP, fmt, pos++, 1);
if (VTABLE_exists_keyed_str(INTERP, hash, key)) {
- repl = VTABLE_get_string_keyed_str(INTERP, hash, key);
+ VTABLE_push_string(INTERP, strings,
+ VTABLE_get_string_keyed_str(INTERP, hash, key));
}
- else if (Parrot_str_is_cclass(INTERP, enum_cclass_numeric, fmt, (UINTVAL)pos + 1)) {
- const INTVAL I0 = Parrot_str_to_int(INTERP, key);
- repl = VTABLE_get_string_keyed_int(INTERP, args, I0);
+ else if (Parrot_str_is_cclass(INTERP, enum_cclass_numeric, key, 0)) {
+ VTABLE_push_string(INTERP, strings,
+ VTABLE_get_string_keyed_int(INTERP, args,
+ Parrot_str_to_int(INTERP, key)));
}
else if (Parrot_str_equal(INTERP, key, comma)) {
- repl = Parrot_str_join(INTERP, comma_space, args);
+ INTVAL num_args = VTABLE_elements(INTERP, args);
+ INTVAL pos_args = 1;
+
+ VTABLE_push_string(INTERP, strings,
+ VTABLE_get_string_keyed_int(INTERP, args, 0));
+
+ while (pos_args < num_args) {
+ VTABLE_push_string(INTERP, strings, comma_space);
+ VTABLE_push_string(INTERP, strings,
+ VTABLE_get_string_keyed_int(INTERP, args, pos_args));
+ pos_args++;
+ }
}
else if (Parrot_str_equal(INTERP, key, percent)) {
- repl = percent;
+ VTABLE_push_string(INTERP, strings, percent);
}
else {
- /* No substitution is necessary */
- replen = 2;
- continue;
+ /* %foo has no special meaning, pass it through unchanged */
+ VTABLE_push_string(INTERP, strings,
+ key = Parrot_str_substr(INTERP, fmt, pos-2, 2));
}
+ }
+
+ /* Add a newline if necessary */
+ if ('\n' != Parrot_str_indexed(INTERP, fmt, Parrot_str_byte_length(INTERP, fmt) - 1))
+ VTABLE_push_string(INTERP, strings, newline);
+
+ RETURN(PMC *SELF);
+}
+
+/*
+
+=item get_string()
+
+Stringify ourselves.
+
+=cut
+
+*/
+
+
+ VTABLE STRING *get_string() {
+ PMC *strings;
+
+ GET_ATTR_strings(INTERP, SELF, strings);
+
+ /* avoid unnecessary joins */
+ if (VTABLE_elements(INTERP, strings) <= 1)
+ return VTABLE_get_string_keyed_int(INTERP, strings, 0);
+ else {
+ STRING const *empty = CONST_STRING(INTERP, "");
+ STRING const *result = Parrot_str_join(INTERP, empty, strings);
+
+ /* cache the result to avoid a join the next time. */
+ SELF.set_string_native(result);
- fmt = Parrot_str_replace(INTERP, fmt, pos, 2, repl);
- replen = Parrot_str_byte_length(INTERP, repl);
+ return result;
+ }
}
- GET_ATTR_str_val(INTERP, SELF, S1);
+/*
- parts = Parrot_pmc_new_temporary(INTERP, enum_class_ResizableStringArray);
- VTABLE_set_integer_native(INTERP, parts, 3);
- VTABLE_set_string_keyed_int(INTERP, parts, 0, S1);
- VTABLE_set_string_keyed_int(INTERP, parts, 1, fmt);
+=item set_string_native()
- /* Add a newline if necessary */
- if ('\n' != Parrot_str_indexed(INTERP, fmt, Parrot_str_byte_length(INTERP, fmt) - 1))
- VTABLE_set_string_keyed_int(INTERP, parts, 2, newline);
+Save our value as a single entry in the StringBuilder.
- S1 = Parrot_str_join(INTERP, STRINGNULL, parts);
- VTABLE_set_string_native(INTERP, SELF, S1);
- Parrot_pmc_free_temporary(INTERP, parts);
+=cut
- RETURN(PMC *SELF);
- }
+*/
+ VTABLE void set_string_native(STRING *value) {
+ /* reuse our old stringBuilder */
+ PMC *strings;
+
+ GET_ATTR_strings(INTERP, SELF, strings);
+ VTABLE_set_integer_native(INTERP, strings, 0);
+ VTABLE_push_string(INTERP, strings, value);
+ }
/*
@@ -189,13 +267,13 @@
linepos = Parrot_pmc_new(INTERP, enum_class_ResizableIntegerArray);
/* get the string itself */
- GET_ATTR_str_val(INTERP, SELF, str);
+ str = SELF.get_string();
eos = Parrot_str_byte_length(INTERP, str);
/* find the first newline, if any */
jpos = Parrot_str_find_cclass(INTERP, enum_cclass_newline,
str, 0, eos);
while (jpos < eos) {
- jpos++;
+ ++jpos;
/* add the start of line position */
VTABLE_push_integer(INTERP, linepos, jpos);
@@ -203,7 +281,7 @@
if (jpos < eos
&& string_ord(INTERP, str, jpos - 1) == 13
&& string_ord(INTERP, str, jpos) == 10) {
- jpos++;
+ ++jpos;
}
/* search for the next newline */
jpos = Parrot_str_find_cclass(INTERP, enum_cclass_newline,
@@ -220,7 +298,7 @@
count = VTABLE_elements(INTERP, linepos);
while (line < count
&& VTABLE_get_integer_keyed_int(INTERP, linepos, line) <= pos)
- line++;
+ ++line;
RETURN(INTVAL line);
}
@@ -245,7 +323,7 @@
STRING * const counter_as_string = Parrot_str_from_int(INTERP, counter);
UNUSED(SELF);
- counter++;
+ ++counter;
if (!has_fmt) {
RETURN(STRING *counter_as_string);
@@ -347,7 +425,7 @@
STRING * prefix = NULL;
STRING * out = open_bracket;
- for (index = 0; index < elements; index++) {
+ for (index = 0; index < elements; ++index) {
PMC * const P0 = VTABLE_get_pmc_keyed_int(INTERP, args, index);
if (!PMC_IS_NULL(P0)) {
@@ -355,7 +433,7 @@
const INTVAL elements2 = VTABLE_elements(INTERP, P0);
INTVAL index2;
- for (index2 = 0; index2 < elements2; index2++) {
+ for (index2 = 0; index2 < elements2; ++index2) {
STRING *S0 = VTABLE_get_string_keyed_int(INTERP, P0, index2);
(STRING *S0) = PCCINVOKE(INTERP, SELF, "escape", STRING *S0);
if (prefix)
More information about the parrot-commits
mailing list