[svn:parrot] r38432 - in branches/pmc_pct/compilers/pmc: src src/emitter t
bacek at svn.parrot.org
bacek at svn.parrot.org
Fri May 1 23:32:52 UTC 2009
Author: bacek
Date: Fri May 1 23:32:52 2009
New Revision: 38432
URL: https://trac.parrot.org/parrot/changeset/38432
Log:
First cut for emitting C body for VTable methods. Hooray!
Added:
branches/pmc_pct/compilers/pmc/t/06-body.t
Modified:
branches/pmc_pct/compilers/pmc/src/emitter.pm
branches/pmc_pct/compilers/pmc/src/emitter/pmc.pir
branches/pmc_pct/compilers/pmc/t/harness
Modified: branches/pmc_pct/compilers/pmc/src/emitter.pm
==============================================================================
--- branches/pmc_pct/compilers/pmc/src/emitter.pm Fri May 1 23:11:18 2009 (r38431)
+++ branches/pmc_pct/compilers/pmc/src/emitter.pm Fri May 1 23:32:52 2009 (r38432)
@@ -19,7 +19,28 @@
# Generate header.
dont_edit($filename)
# PMC functions
- ~ $pmc_emitter.generate_h_file($past);
+ ~ $pmc_emitter.generate_h_file($past)
+ # C code
+ ~ c_code_coda();
+
+ $res;
+}
+
+# Generate .c file for pmc.
+method generate_c_file($past) {
+ my $res;
+
+ my $name := $past.name();
+ my $filename := self.filename();
+
+ # Get emitter for (specific) PMC.
+ my $pmc_emitter := get_pmc_emitter($name);
+
+ $res :=
+ # Generate header.
+ dont_edit($filename)
+ # PMC functions
+ ~ $pmc_emitter.generate_c_file($past)
# C code
~ c_code_coda();
@@ -69,7 +90,7 @@
~" *\n"
~" * Any changes made here will be lost!\n"
~" *\n"
- ~" */\n";
+ ~" */\n\n";
}
#=item C<c_code_coda()>
@@ -80,7 +101,8 @@
#
#=cut
sub c_code_coda() {
- "/*\n"
+ "\n\n"
+ ~"/*\n"
~" * Local variables:\n"
~" * c-file-style: parrot\n"
~" * End:\n"
Modified: branches/pmc_pct/compilers/pmc/src/emitter/pmc.pir
==============================================================================
--- branches/pmc_pct/compilers/pmc/src/emitter/pmc.pir Fri May 1 23:11:18 2009 (r38431)
+++ branches/pmc_pct/compilers/pmc/src/emitter/pmc.pir Fri May 1 23:32:52 2009 (r38432)
@@ -104,6 +104,75 @@
.return (res)
.end
+=item C<generate_c_file>
+
+Generate C file for PMC.
+
+=cut
+
+.sub 'generate_c_file' :method
+ .param pmc past
+ .local string res
+
+ .local string guard
+ .local string name
+
+ name = past.'name'()
+ $S0 = 'uc'(name)
+
+ $S0 = self.'generate_c_file_functions'(past)
+ concat res, $S0
+
+ .return (res)
+.end
+
+=item C<generate_c_file_functions>
+
+Generate C declarations for vtable functions
+
+=cut
+
+.sub 'generate_c_file_functions' :method
+ .param pmc past
+ .local string res
+ .local pmc vtable_info, vtable_hash
+ .local pmc vtables, it, entry, class_init
+ .local string pmc_name, vtable_name
+
+ .local pmc res_builder
+
+ pmc_name = past.'name'()
+
+ $P0 = get_hll_global ['PMC'; 'VTableInfo'], 'vtable_hash'
+ vtable_hash = $P0()
+
+ vtables = self.'!vtables'(past)
+
+ it = iter vtables
+ loop:
+ unless it goto done
+ res_builder = new 'ResizableStringArray'
+ vtable_name = shift it
+ entry = vtables[vtable_name]
+ vtable_info = vtable_hash[vtable_name]
+
+ # Generate 2 methods. One for read, one for write.
+ $S0 = self.'!generate_signature'(pmc_name, entry, 0 :named('ro'))
+ push res_builder, $S0
+ $S0 = self.'!generate_body'(entry)
+ push res_builder, $S0
+
+ $S0 = join '', res_builder
+ concat res, $S0
+
+ goto loop
+
+ done:
+ .return (res)
+.end
+
+
+
=item C<!generate_signature>
Generate full signature of vtable.
@@ -150,6 +219,47 @@
.return ($S0)
.end
+=item C<!generate_body>
+
+Generate C function body from PAST.
+
+=cut
+
+.sub '!generate_body' :method
+ .param pmc entry
+
+ .local pmc res
+ res = new 'ResizableStringArray'
+ $P0 = entry.'iterator'()
+ loop:
+ unless $P0 goto done
+ $P1 = shift $P0
+ #print 'P1 '
+ #say $P1
+ $S0 = self.'!generate_body_part'($P1)
+ push res, $S0
+ goto loop
+ done:
+
+ $S0 = join '', res
+ .return ($S0)
+.end
+
+=item C<!generate_body_part>
+
+Multi-methods for generating C body.
+
+TODO: Parse c_body properly and implement all other functions.
+
+=cut
+
+.sub '!generate_body_part' :method :multi(_, ['PAST';'Op'])
+ .param pmc past
+ $S0 = past['inline']
+ .return ($S0)
+.end
+
+
.sub '!class_init' :method
.param pmc past
.tailcall past.'class_init'()
Added: branches/pmc_pct/compilers/pmc/t/06-body.t
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/pmc_pct/compilers/pmc/t/06-body.t Fri May 1 23:32:52 2009 (r38432)
@@ -0,0 +1,52 @@
+#! ../../parrot
+# Check generating header for parsed PMC
+
+.include 't/common.pir'
+
+.sub 'main' :main
+.include 'test_more.pir'
+load_bytecode 'pmc.pbc'
+ .local int total
+
+ plan(3)
+
+ .local string filename
+
+ filename = 't/data/class08.pmc'
+ $S0 = _slurp(filename)
+
+ check_one_file(filename, $S0, "'DO NOT EDIT THIS FILE'", "Warning generated")
+ check_one_file(filename, $S0, "'PMC * Parrot_Integer_instantiate(PARROT_INTERP, PMC *sig)'", "VTable method generated")
+ check_one_file(filename, $S0, "'Integer.instantiate: unhandled initializer'", "VTable body generated")
+
+.end
+
+# Check genrated header.
+# Parse passed string, generate header, check against supplied pattern
+.sub 'check_one_file'
+ .param string name
+ .param string source
+ .param string pattern
+ .param string message
+
+ .local pmc compiler
+ compiler = compreg 'PMC'
+ $P0 = compiler.'compile'(source, 'target'=>'past')
+
+ .local pmc emitter
+ $P1 = split '::', 'PMC::Emitter'
+ emitter = new $P1
+ emitter.'set_filename'(name)
+ $S0 = emitter.'generate_c_file'($P0)
+ #say $S0
+ like($S0, pattern, message)
+.end
+
+# Don't forget to update plan!
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
Modified: branches/pmc_pct/compilers/pmc/t/harness
==============================================================================
--- branches/pmc_pct/compilers/pmc/t/harness Fri May 1 23:11:18 2009 (r38431)
+++ branches/pmc_pct/compilers/pmc/t/harness Fri May 1 23:32:52 2009 (r38432)
@@ -4,5 +4,5 @@
use FindBin;
use lib qw( . lib ../lib ../../lib ../../lib );
-use Parrot::Test::Harness language => 'pmc'
+use Parrot::Test::Harness language => 'pmc', verbosity => 0;
More information about the parrot-commits
mailing list