[svn:parrot] r39780 - branches/tt761_keys_revamp/src/pmc
bacek at svn.parrot.org
bacek at svn.parrot.org
Thu Jun 25 21:27:08 UTC 2009
Author: bacek
Date: Thu Jun 25 21:27:07 2009
New Revision: 39780
URL: https://trac.parrot.org/parrot/changeset/39780
Log:
[pmc] Implement StringIterator.
Added:
branches/tt761_keys_revamp/src/pmc/stringiterator.pmc
Modified:
branches/tt761_keys_revamp/src/pmc/iterator.pmc
branches/tt761_keys_revamp/src/pmc/string.pmc
Modified: branches/tt761_keys_revamp/src/pmc/iterator.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/iterator.pmc Thu Jun 25 21:26:47 2009 (r39779)
+++ branches/tt761_keys_revamp/src/pmc/iterator.pmc Thu Jun 25 21:27:07 2009 (r39780)
@@ -17,7 +17,7 @@
=head2 default usage
.local pmc iterator, array, entry
- iterator = new 'Iterator', array
+ iterator = iter array
iter_loop:
unless iterator, iter_end # while (more values)
entry = shift iterator # get an entry
@@ -25,14 +25,10 @@
goto iter_loop
iter_end:
-The C<new> can alternatively be written as:
-
- iterator = iter array
-
=head2 iterate from the end, for arrays
.local pmc iterator, array, entry
- iterator = new 'Iterator', array
+ iterator = iter array
iterator = .ITERATE_FROM_END
iter_loop:
unless iterator, iter_end # while (more values)
@@ -44,7 +40,7 @@
=head2 iterate over a hash
.local pmc iterator, hash, key, entry
- iterator = new 'Iterator', hash
+ iterator = iter hash
iter_loop:
unless iterator, iter_end # while (more values)
key = shift iterator # get the key..
@@ -91,7 +87,9 @@
VTABLE void init_pmc(PMC *aggregate) {
if (VTABLE_does(INTERP, aggregate, CONST_STRING(INTERP, "array"))
- || VTABLE_does(INTERP, aggregate, CONST_STRING(INTERP, "hash"))) {
+ || VTABLE_does(INTERP, aggregate, CONST_STRING(INTERP, "hash"))
+ || VTABLE_does(INTERP, aggregate, CONST_STRING(INTERP, "string"))
+ ) {
/* It's ugly hack... But I cant figure out proper way to do it. */
PMC *real_iter = VTABLE_get_iter(INTERP, aggregate);
SELF = pmc_reuse_init(INTERP, SELF, VTABLE_type(INTERP, real_iter), aggregate, 0);
@@ -156,57 +154,6 @@
/*
-=item C<opcode_t *invoke(void *next)>
-
-Return the next element of the aggregate. The return type may depend on
-the aggregate. If there are no more items in the aggregate, I1 .. I4 are
-zero.
-
-See F<docs/pdds/pdd03_calling_conventions.pod>.
-
-=cut
-
-*/
- VTABLE opcode_t *invoke(void *next) {
- PMC *agg;
-
- /* iterator constructor */
- if (REG_INT(interp, 3) == 1) {
- PMC * const arg = REG_PMC(interp, 5);
- PMC *iter;
-
- if (PObj_is_object_TEST(arg)) {
- REG_PMC(interp, 5) = VTABLE_get_iter(INTERP, arg);
- return (opcode_t *)next;
- }
-
- REG_PMC(interp, 5) = iter = pmc_new_init(INTERP,
- enum_class_Iterator, arg);
- VTABLE_set_integer_native(INTERP, iter, 0);
- return (opcode_t *)next;
- }
- /* TODO function + sentinel */
- else if (REG_INT(interp, 3) == 2)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
- "Iterator: invoke 2 args");
-
- REG_INT(interp, 1) =
- REG_INT(interp, 2) =
- REG_INT(interp, 3) =
- REG_INT(interp, 4) = 0;
-
- agg = SELF.get_pmc();
-
- {
- PMC * const res = SELF.shift_pmc();
- REG_INT(interp, 3) = 1;
- REG_PMC(interp, 5) = res;
- return (opcode_t *)next;
- }
- }
-
-/*
-
=item C<INTVAL exists_keyed(PMC *key)>
Returns whether an element for C<*key> exists in the aggregate.
Modified: branches/tt761_keys_revamp/src/pmc/string.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/string.pmc Thu Jun 25 21:26:47 2009 (r39779)
+++ branches/tt761_keys_revamp/src/pmc/string.pmc Thu Jun 25 21:27:07 2009 (r39780)
@@ -811,19 +811,7 @@
}
VTABLE PMC *get_iter() {
- STRING *name = CONST_STRING(interp, "set_key");
- PMC * const iter = pmc_new_init(INTERP, enum_class_Iterator, SELF);
- PMC * const key = pmc_new(INTERP, enum_class_Key);
-
- Parrot_PCCINVOKE(interp, iter, name, "P->", key);
- PObj_get_FLAGS(key) |= KEY_integer_FLAG;
-
- if (!Parrot_str_byte_length(INTERP, VTABLE_get_string(INTERP, SELF)))
- VTABLE_set_integer_native(INTERP, key, -1);
- else
- VTABLE_set_integer_native(INTERP, key, 0);
-
- return iter;
+ return pmc_new_init(INTERP, enum_class_StringIterator, SELF);
}
/*
Added: branches/tt761_keys_revamp/src/pmc/stringiterator.pmc
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/tt761_keys_revamp/src/pmc/stringiterator.pmc Thu Jun 25 21:27:07 2009 (r39780)
@@ -0,0 +1,314 @@
+/*
+Copyright (C) 2001-2009, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/stringiterator.pmc - StringIterator PMC
+
+=head1 DESCRIPTION
+
+Implementation of Iterator for String PMC.
+
+=head1 SYNOPSIS
+
+
+=head1 Methods
+
+=over 4
+
+=cut
+
+*/
+
+
+pmclass StringIterator extends Iterator {
+ ATTR PMC *string; /* String to iterate over */
+ ATTR INTVAL pos; /* Current position of iterator for forward iterator */
+ /* Previous position of iterator for reverse iterator */
+ ATTR INTVAL length; /* Length of C<string> */
+ ATTR INTVAL reverse; /* Direction of iteration. 1 - for reverse iteration */
+
+/*
+
+=item C<void init_pmc()>
+
+Initialize StringIterator.
+
+=cut
+
+*/
+ VTABLE void init_pmc(PMC *string) {
+ Parrot_StringIterator_attributes *attrs =
+ mem_allocate_zeroed_typed(Parrot_StringIterator_attributes);
+
+ attrs->string = string;
+ PMC_data(SELF) = attrs;
+
+ PObj_custom_mark_destroy_SETALL(SELF);
+
+ /* by default, iterate from start */
+ SELF.set_integer_native(ITERATE_FROM_START);
+ }
+
+/*
+
+=item C<void destroy()>
+
+destroys this PMC
+
+=cut
+
+*/
+
+ VTABLE void destroy() {
+ mem_sys_free(PMC_data(SELF));
+ }
+
+/*
+
+=item C<void mark()>
+
+Marks the current idx/key and the aggregate as live.
+
+=cut
+
+*/
+
+ VTABLE void mark() {
+ PMC *string;
+ GET_ATTR_string(INTERP, SELF, string);
+ if (string)
+ Parrot_gc_mark_PObj_alive(INTERP, (PObj *)string);
+ }
+
+/*
+
+=item C<PMC *clone()>
+
+=cut
+
+*/
+ VTABLE PMC* clone() {
+ Parrot_StringIterator_attributes *attrs =
+ PARROT_STRINGITERATOR(SELF);
+ PMC *clone =
+ pmc_new_init(INTERP, enum_class_StringIterator, attrs->string);
+ Parrot_StringIterator_attributes *clone_attrs =
+ PARROT_STRINGITERATOR(clone);
+
+ clone_attrs->pos = attrs->pos;
+ clone_attrs->reverse = attrs->reverse;
+ return clone;
+ }
+
+/*
+
+=item C<INTVAL get_bool()>
+
+Returns true if there is more elements to iterate over.
+
+=cut
+
+*/
+
+ VTABLE INTVAL get_bool() {
+ return SELF.elements() > 0;
+ }
+
+/*
+
+=item C<INTVAL elements()>
+
+Returns the number of remaining elements in the C<string>.
+
+=cut
+
+*/
+
+ VTABLE INTVAL elements() {
+ Parrot_StringIterator_attributes *attrs =
+ PARROT_STRINGITERATOR(SELF);
+ if (attrs->reverse)
+ return attrs->pos;
+ else
+ return attrs->length - attrs->pos;
+ }
+
+ VTABLE INTVAL get_integer() {
+ return SELF.elements();
+ }
+
+/*
+
+=item C<void set_integer_native(INTVAL value)>
+
+Reset the Iterator. C<value> must be one of
+
+ ITERATE_FROM_START ... Iterate from start
+ ITERATE_FROM_END ... Iterate from end
+
+=cut
+
+*/
+
+ VTABLE void set_integer_native(INTVAL value) {
+ Parrot_StringIterator_attributes *attrs =
+ PARROT_STRINGITERATOR(SELF);
+ if (value == ITERATE_FROM_START) {
+ attrs->reverse = 0;
+ attrs->pos = 0;
+ attrs->length = VTABLE_elements(INTERP, attrs->string);
+ }
+ else if (value == ITERATE_FROM_END) {
+ attrs->reverse = 1;
+ attrs->pos = attrs->length
+ = VTABLE_elements(INTERP, attrs->string);
+ }
+ else
+ Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
+ "Wrong direction for StringIterator");
+ }
+
+/*
+
+=item C<PMC *get_pmc()>
+
+Returns this Iterator's string.
+
+=cut
+
+*/
+
+ VTABLE PMC *get_pmc() {
+ PMC *string;
+ GET_ATTR_string(INTERP, SELF, string);
+ return string ? string : PMCNULL;
+ }
+
+/*
+
+=item C<STRING *shift_string()>
+
+Shift next character from C<string>.
+
+=cut
+
+*/
+ VTABLE STRING *shift_string() {
+ Parrot_StringIterator_attributes *attrs =
+ PARROT_STRINGITERATOR(SELF);
+
+ if (attrs->pos >= attrs->length)
+ Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+ "StopIteration");
+
+ return VTABLE_get_string_keyed_int(INTERP, attrs->string, attrs->pos++);
+ }
+
+/*
+
+=item C<INTVAL shift_integer()>
+
+Shift next character code from C<string>.
+
+=cut
+
+*/
+ VTABLE INTVAL shift_integer() {
+ Parrot_StringIterator_attributes *attrs =
+ PARROT_STRINGITERATOR(SELF);
+
+ if (attrs->pos >= attrs->length)
+ Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+ "StopIteration");
+
+ return VTABLE_get_integer_keyed_int(INTERP, attrs->string, attrs->pos++);
+ }
+
+/*
+
+=item C<STRING *pop_string()>
+
+Shift "next" character from C<string> for reverse iterator.
+
+=cut
+
+*/
+ VTABLE STRING *pop_string() {
+ Parrot_StringIterator_attributes *attrs =
+ PARROT_STRINGITERATOR(SELF);
+
+ if (!STATICSELF.get_bool())
+ Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+ "StopIteration");
+
+ return VTABLE_get_string_keyed_int(INTERP, attrs->string, --attrs->pos);
+ }
+
+/*
+
+=item C<INTVAL pop_integer()>
+
+Shift "next" character code from C<string> for reverse iterator.
+
+=cut
+
+*/
+ VTABLE INTVAL pop_integer() {
+ Parrot_StringIterator_attributes *attrs =
+ PARROT_STRINGITERATOR(SELF);
+
+ if (!STATICSELF.get_bool())
+ Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+ "StopIteration");
+
+ return VTABLE_get_integer_keyed_int(INTERP, attrs->string, --attrs->pos);
+ }
+
+/*
+
+=item C<INTVAL get_integer_keyed_int(INTVAL idx)>
+
+Get integer value of current position plus idx.
+
+=cut
+
+*/
+
+ VTABLE INTVAL get_integer_keyed_int(INTVAL idx) {
+ return VTABLE_get_integer_keyed_int(INTERP, STATICSELF.get_pmc(),
+ PARROT_STRINGITERATOR(SELF)->pos + idx);
+ }
+
+/*
+
+=item C<STRING *get_string_keyed_int(INTVAL idx)>
+
+Get string value of current position plus idx.
+
+=cut
+
+*/
+
+ VTABLE STRING *get_string_keyed_int(INTVAL idx) {
+ return VTABLE_get_string_keyed_int(INTERP, STATICSELF.get_pmc(),
+ PARROT_STRINGITERATOR(SELF)->pos + idx);
+ }
+}
+
+
+/*
+
+=back
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
More information about the parrot-commits
mailing list