Here is a first version of a "Data::Dumper" i've written to be able to dump
the AST of my C parser.
A dumpertest.imc is included, which shows the dumper in action.
I'am sorry, but I have no idea how to convert this to a test. BTW, is the
order of the hash elements guaranteed to be equal across platforms?
jens
=head1 TITLE
dumper.imc - PIR version of Data::Dumper
=head1 SYNOPSIS
...
# not needed anymore in the near future
_init_dumper()
...
# dump the P0 register
_dumper( "P0", P0 )
...
END
.include "library/dumper.imc"
=head1 DESCRIPTION
PIR implementation of Perl's Data::Dumper module.
=cut
.include "../../runtime/parrot/include/datatypes.pasm"
=head1 FUNCTIONS
This library provides the following functions:
=over 4
=item _init_dumper()
For internal use only. Initializes a hash with helper callbacks.
At the moment, this function has to be called before any use of C<_dumper()>.
This will change in the near future.
This function returns nothing.
=cut
.sub _init_dumper
saveall
.local pmc helper
.local pmc sub
new helper, .PerlArray
global "Data::Dumper::helper" = helper
newsub sub, .Sub, _dump_PerlArray
_register_dumper( .PerlArray, sub )
newsub sub, .Sub, _dump_PerlHash
_register_dumper( .PerlHash, sub )
newsub sub, .Sub, _dump_PerlVal
_register_dumper( .PerlInt, sub )
_register_dumper( .PerlNum, sub )
newsub sub, .Sub, _dump_PerlString
_register_dumper( .PerlString, sub )
restoreall
.pcc_begin_return
.pcc_end_return
.end
=item _register_dumper( id, sub )
Registers a dumper for new PMC type.
=over 4
=item id
the PMC id, as returned by the C<typeof> op.
=item sub
a Sub pmc, that gets called in order to dump the content of the given PMC
=back
For example:
newsub sub, .Sub, _dump_PerlArray
_register_dumper( .PerlArray, sub )
This function returns nothing.
=cut
.sub _register_dumper
.param int id
.param pmc sub
.local pmc helper
helper = global "Data::Dumper::helper"
set helper[id], sub
.pcc_begin_return
.pcc_end_return
.end
=item _dumper( name, pmc[, indent] )
This is the public interface to the dumper library.
=over 4
=item name
Required. The name of the PMC.
=item pmc
Required. The PMC to dump.
=item indent
Optional. The indent used at the start of each line printed.
=back
B<Note:> This function currently returns nothing. It should return
the dumped data as a string, like Perl's Data::Dumper. Instead,
everything is printed out using C<print>.
=cut
.sub _dumper
.param string name
.param pmc dump
.param string indent
_do_dumper_named( name, dump, indent )
print "\n"
.pcc_begin_return
.pcc_end_return
.end
#
# internal helper function
#
.sub _do_dumper_named
.param string name
.param pmc dump
.param string indent
print indent
print "\""
print name
print "\" => "
_do_dumper_unnamed( dump, indent )
.pcc_begin_return
.pcc_end_return
.end
#
# internal helper function
#
.sub _do_dumper_unnamed
.param pmc dump
.param string indent
.local pmc helper
.local int type
.local int exist
.local pmc cb
helper = global "Data::Dumper::helper"
typeof type, dump
exists exist, helper[type]
if exist, CALL_HELPER
print "unkown-type(pmc #"
print type
print ")"
branch DONE
CALL_HELPER:
cb = helper[type]
saveall
set S5, indent
set P6, dump
invokecc cb
restoreall
DONE:
.pcc_begin_return
.pcc_end_return
.end
#
# Dumps a PerlString pmc
#
.sub _dump_PerlString
.param pmc str
.param string indent
print "\""
print str
print "\""
.pcc_begin_return
.pcc_end_return
.end
#
# Dumps a Perl[Num,Int] pmc
#
.sub _dump_PerlVal
.param pmc val
.param string indent
print val
.pcc_begin_return
.pcc_end_return
.end
#
# Dumps a PerlArray pmc
#
.sub _dump_PerlArray
.param pmc array
.param string indent
.local string subindent
.local int size
.local int pos
.local pmc val
.local string posstr
.local int tmp
subindent = " "
concat subindent, indent
print "PerlArray (size:"
print array
print ") ["
set size, array
set pos, 0
unless size, iter_end
iter_loop:
print "\n"
set val, array[pos]
print subindent
_do_dumper_unnamed( val, subindent )
# next array member
inc pos
# skip the ',' after the last element
if pos >= size goto iter_end
print ","
# elements left?
branch iter_loop
iter_end:
print "\n"
print indent
print "]"
.pcc_begin_return
.pcc_end_return
.end
#
# Dumps a PerlHash pmc
#
.sub _dump_PerlHash
.param pmc hash
.param string indent
.local string subindent
.local pmc iter
.local string key
.local pmc val
subindent = " "
concat subindent, indent
print "PerlHash {"
new iter, .Iterator, hash
set iter, 0
unless iter, iter_end
iter_loop:
print "\n"
shift key, iter
set val, hash[key]
_do_dumper_named( key, val, subindent )
unless iter, iter_end
print ","
branch iter_loop
iter_end:
print "\n"
print indent
print "}"
.pcc_begin_return
.pcc_end_return
.end
=head1 AUTHOR
Jens Rieks E<lt>parrot at jensbeimsurfen dot deE<gt> is the author
and maintainer.
Please send patches and suggestions to the Perl 6 Internals mailing list.
=head1 COPYRIGHT
Copyright (c) 2004, the Perl Foundation.
=cut