[svn:parrot] r46160 - branches/codestring/src/pmc

coke at svn.parrot.org coke at svn.parrot.org
Thu Apr 29 22:52:14 UTC 2010


Author: coke
Date: Thu Apr 29 22:52:14 2010
New Revision: 46160
URL: https://trac.parrot.org/parrot/changeset/46160

Log:
First pass at converting codestring to swap out its storage for
a RSA instead of a String - will avoid doing as many concats
as possible.

Build fails - need to fix String vtables (or Codestring) to avoid
trying to access the string value via ATTR instead of the vtables.

Modified:
   branches/codestring/src/pmc/codestring.pmc

Modified: branches/codestring/src/pmc/codestring.pmc
==============================================================================
--- branches/codestring/src/pmc/codestring.pmc	Thu Apr 29 22:42:48 2010	(r46159)
+++ branches/codestring/src/pmc/codestring.pmc	Thu Apr 29 22:52:14 2010	(r46160)
@@ -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... */
 
 /*
 
@@ -54,6 +55,7 @@
     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);
     }
 
@@ -70,11 +72,13 @@
     VTABLE void mark() {
         SUPER();
         if (PMC_data(SELF)) {
-            PMC *linepos;
+            PMC *linepos, *strings;
 
             GET_ATTR_linepos(INTERP, SELF, linepos);
-
             Parrot_gc_mark_PMC_alive(INTERP, linepos);
+
+            GET_ATTR_strings(INTERP, SELF, strings);
+            Parrot_gc_mark_PMC_alive(INTERP, strings);
         }
     }
 
@@ -97,7 +101,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,59 +113,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 (pos < 0) {
+            /* 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 the to just before the % sign... */
+            VTABLE_push_string(INTERP, strings,
+                key = Parrot_str_substr(INTERP, fmt, pos, percentPos - pos)
+            );
+            /* skip the % sign */
+            pos = percentPos + 1 ;
+        }
+
+        /* key is always a single character */
+        key = Parrot_str_substr(INTERP, fmt, pos++, 1);
 
-        key = Parrot_str_substr(INTERP, fmt, pos+1, 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);
+ }
+
+
+/*
 
-        fmt    = Parrot_str_replace(INTERP, fmt, pos, 2, repl);
-        replen = Parrot_str_byte_length(INTERP, repl);
+=item get_string()
+
+Stringify ourselves.
+
+=cut
+
+*/
+
+
+    VTABLE STRING *get_string() {
+        PMC *strings;
+        STRING * const empty = CONST_STRING(INTERP, "");
+        STRING *result;
+        GET_ATTR_strings(INTERP, SELF, strings);
+
+        result = Parrot_str_join(INTERP, empty, strings);
+        /* cache the result */
+        SELF.set_string_native(result);
+
+        return result;
     }
 
-    GET_ATTR_str_val(INTERP, SELF, S1);
+/*
+
+=item set_string_native()
 
-    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);
+Stringify ourselves.
 
-    /* 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);
+=cut
 
-    S1 = Parrot_str_join(INTERP, STRINGNULL, parts);
-    VTABLE_set_string_native(INTERP, SELF, S1);
-    Parrot_pmc_free_temporary(INTERP, parts);
+*/
 
-    RETURN(PMC *SELF);
-  }
+
+    VTABLE void set_string_native(STRING *value) {
+        PMC *strings = pmc_new(INTERP, enum_class_ResizableStringArray);
+        VTABLE_push_string(INTERP, strings, value);
+        SET_ATTR_strings(INTERP, SELF, strings);
+    }
 
 
 /*
@@ -189,7 +265,7 @@
 
         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,


More information about the parrot-commits mailing list