[svn:parrot] r46540 - in branches/codestring: src/pmc t/pmc
bacek at svn.parrot.org
bacek at svn.parrot.org
Wed May 12 21:24:41 UTC 2010
Author: bacek
Date: Wed May 12 21:24:40 2010
New Revision: 46540
URL: https://trac.parrot.org/parrot/changeset/46540
Log:
Add StringBuilder.append_format method (copyed from CodeString.emit method without adding newline
Modified:
branches/codestring/src/pmc/stringbuilder.pmc
branches/codestring/t/pmc/stringbuilder.t
Modified: branches/codestring/src/pmc/stringbuilder.pmc
==============================================================================
--- branches/codestring/src/pmc/stringbuilder.pmc Wed May 12 21:02:57 2010 (r46539)
+++ branches/codestring/src/pmc/stringbuilder.pmc Wed May 12 21:24:40 2010 (r46540)
@@ -282,6 +282,104 @@
Parrot_str_substr(INTERP, buffer, offset, length));
}
+/*
+
+=item C<append_format(string fmt [, pmc args ] [, pmc hash ])>
+
+Add a line to a C<StringBuilder> object according to C<fmt>.
+The C<fmt> string can contain any number of "%-replacements"
+which are replaced by the corresponding values from C<args>
+or C<hash> prior to being appended to the string. (Here
+C<args> is a slurpy array, and C<hash> is a slurpy hash.)
+
+The currently defined replacements include:
+
+ %0 %1 ... %9 the value from the args array at index 0..9
+ %, the values of the args array separated by commas
+ %% a percent sign
+
+A percent-sign followed by any other character that is a hash
+key receives the value of the hash element.
+
+=cut
+
+*/
+
+ METHOD append_format(STRING *fmt, PMC *args :slurpy, PMC *hash :slurpy :named) {
+ STRING * const percent = CONST_STRING(INTERP, "%");
+ STRING * const comma = CONST_STRING(INTERP, ",");
+ STRING * const comma_space = CONST_STRING(INTERP, ", ");
+ STRING * const newline = CONST_STRING(INTERP, "\n");
+ STRING *key;
+ PMC *stringbuilder = SELF;
+ INTVAL percentPos;
+ INTVAL pos = 0;
+
+ /* Loop over the format string, splitting it into chunks
+ * for the string builder. */
+ while (pos >= 0) {
+ /* Find the next % */
+ percentPos = Parrot_str_find_index(INTERP, fmt, percent, pos);
+
+ if (percentPos < 0) {
+ if (pos == 0) {
+ VTABLE_push_string(INTERP, stringbuilder, fmt);
+ }
+ else {
+ /* remaining string can be added as is. */
+ VTABLE_push_string(INTERP, stringbuilder,
+ Parrot_str_substr(INTERP, fmt, pos,
+ Parrot_str_length(INTERP, fmt) -pos));
+ }
+ break;
+ }
+ else {
+ /* slurp up to just before the % sign... */
+ VTABLE_push_string(INTERP, stringbuilder,
+ 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);
+
+ if (VTABLE_exists_keyed_str(INTERP, hash, key)) {
+ VTABLE_push_string(INTERP, stringbuilder,
+ VTABLE_get_string_keyed_str(INTERP, hash, key));
+ }
+ else if (Parrot_str_is_cclass(INTERP, enum_cclass_numeric, key, 0)) {
+ VTABLE_push_string(INTERP, stringbuilder,
+ VTABLE_get_string_keyed_int(INTERP, args,
+ Parrot_str_to_int(INTERP, key)));
+ }
+ else if (Parrot_str_equal(INTERP, key, comma)) {
+ INTVAL num_args = VTABLE_elements(INTERP, args);
+ INTVAL pos_args = 1;
+
+ VTABLE_push_string(INTERP, stringbuilder,
+ VTABLE_get_string_keyed_int(INTERP, args, 0));
+
+ while (pos_args < num_args) {
+ VTABLE_push_string(INTERP, stringbuilder, comma_space);
+ VTABLE_push_string(INTERP, stringbuilder,
+ VTABLE_get_string_keyed_int(INTERP, args, pos_args));
+ pos_args++;
+ }
+ }
+ else if (Parrot_str_equal(INTERP, key, percent)) {
+ VTABLE_push_string(INTERP, stringbuilder, percent);
+ }
+ else {
+ /* %foo has no special meaning, pass it through unchanged */
+ VTABLE_push_string(INTERP, stringbuilder,
+ Parrot_str_substr(INTERP, fmt, pos-2, 2));
+ }
+ }
+
+ RETURN(PMC *SELF);
+ }
+
/*
Modified: branches/codestring/t/pmc/stringbuilder.t
==============================================================================
--- branches/codestring/t/pmc/stringbuilder.t Wed May 12 21:02:57 2010 (r46539)
+++ branches/codestring/t/pmc/stringbuilder.t Wed May 12 21:24:40 2010 (r46540)
@@ -20,7 +20,6 @@
.sub 'main' :main
.include 'test_more.pir'
- plan(23)
test_create() # 2 tests
test_push_string() # 9 tests
test_push_pmc() # 4 tests
@@ -29,6 +28,13 @@
test_set_string_native() # 3 tests
test_set_string_native_with_hash() # 2 tests
+ emit_with_pos_args()
+ emit_with_percent_args()
+ emit_with_named_args()
+ emit_with_pos_and_named_args()
+
+ done_testing()
+
# END_OF_TESTS
.end
@@ -184,6 +190,61 @@
.end
+.sub emit_with_pos_args
+ .local pmc code
+ code = new ["StringBuilder"]
+ code."append_format"("label_%0:\n", 1234)
+ code."append_format"(" say '%0, %1'\n", "Hello", "World")
+ code."append_format"(" %0 = %2\n", "$I0", 24, 48)
+ is(code, <<'CODE', "code string with positional args looks fine")
+label_1234:
+ say 'Hello, World'
+ $I0 = 48
+CODE
+.end
+
+.sub emit_with_percent_args
+ .local pmc code
+ code = new ['StringBuilder']
+ code."append_format"("label_%0:\n", 1234)
+ code."append_format"(" say '%,'\n", "Hello")
+ code."append_format"(" say '%,'\n", "Hello", "World", "of", "Parrot")
+ code."append_format"(" say '%%0'\n")
+ is(code, <<'CODE', "code string with % args looks fine")
+label_1234:
+ say 'Hello'
+ say 'Hello, World, of, Parrot'
+ say '%0'
+CODE
+.end
+
+.sub emit_with_named_args
+ .local pmc code
+ code = new ['StringBuilder']
+ code."append_format"("label_%a:\n", "a"=>1234)
+ code."append_format"(" say '%b, %c'\n", "b"=>"Hello", "c"=>"World")
+ code."append_format"(" say '%d'\n", "b"=>"Hello", "c"=>"World")
+ is(code, <<'CODE', "emit with named args looks fine")
+label_1234:
+ say 'Hello, World'
+ say '%d'
+CODE
+.end
+
+.sub emit_with_pos_and_named_args
+ .local pmc code
+ code = new ['StringBuilder']
+ code."append_format"("label_%a:\n", "a"=>1234)
+ code."append_format"(" %0 '%b, %c'\n", "say", "print", "b"=>"H", "c"=>"W")
+ code."append_format"(" say '%,, %c'\n", "alpha", "beta", "b"=>"H", "c"=>"W")
+ is(code, <<'CODE', "emit with pos + named args")
+label_1234:
+ say 'H, W'
+ say 'alpha, beta, W'
+CODE
+.end
+
+
# Local Variables:
# mode: pir
# fill-column: 100
More information about the parrot-commits
mailing list