[svn:parrot] r44864 - in branches/ops_pct/compilers/opsc/src/Ops: . Compiler
bacek at svn.parrot.org
bacek at svn.parrot.org
Thu Mar 11 05:09:43 UTC 2010
Author: bacek
Date: Thu Mar 11 05:09:41 2010
New Revision: 44864
URL: https://trac.parrot.org/parrot/changeset/44864
Log:
Implement generating C code for new Ops::Op past
Modified:
branches/ops_pct/compilers/opsc/src/Ops/Compiler/Actions.pm
branches/ops_pct/compilers/opsc/src/Ops/Op.pm
Modified: branches/ops_pct/compilers/opsc/src/Ops/Compiler/Actions.pm
==============================================================================
--- branches/ops_pct/compilers/opsc/src/Ops/Compiler/Actions.pm Thu Mar 11 05:09:01 2010 (r44863)
+++ branches/ops_pct/compilers/opsc/src/Ops/Compiler/Actions.pm Thu Mar 11 05:09:41 2010 (r44864)
@@ -90,10 +90,12 @@
$op<normalized_args> := @norm_args;
if !%flags<flow> {
- $op.push(PAST::Op.new(
- :pasttype('inline'),
- :inline("\n" ~ 'goto_next')
- ));
+ my $goto_next := PAST::Op.new(
+ :pasttype('call'),
+ :name('goto_offset')
+ );
+ $goto_next<is_next> := 1;
+ $op.push($goto_next);
}
my $past := PAST::Stmts.new(
@@ -247,7 +249,7 @@
else {
$past.push(PAST::Op.new(
:pasttype('inline'),
- $prev_words
+ :inline($prev_words),
));
$prev_words := '';
@@ -265,7 +267,7 @@
if $prev_words {
$past.push(PAST::Op.new(
:pasttype('inline'),
- $prev_words
+ :inline($prev_words)
));
}
make $past;
@@ -273,7 +275,7 @@
method macro_param($/) {
make PAST::Var.new(
- :name(~$/),
+ :name(~$<num>),
:node($/),
);
}
@@ -302,7 +304,8 @@
method op_macro($/) {
#say('# op_macro');
- my $macro_name := ~$<macro_type> ~ '_' ~ lc(~$<macro_destination>);
+ my $is_next := ~$<macro_destination> eq 'NEXT';
+ my $macro_name := ~$<macro_type> ~ '_' ~ lc($is_next ?? 'offset' !! ~$<macro_destination>);
my $past := PAST::Op.new(
:pasttype('call'),
@@ -318,6 +321,7 @@
for $<body_word> {
$past.push($_.ast);
}
+ $past<is_next> := $is_next;
make $past;
}
Modified: branches/ops_pct/compilers/opsc/src/Ops/Op.pm
==============================================================================
--- branches/ops_pct/compilers/opsc/src/Ops/Op.pm Thu Mar 11 05:09:01 2010 (r44863)
+++ branches/ops_pct/compilers/opsc/src/Ops/Op.pm Thu Mar 11 05:09:41 2010 (r44864)
@@ -253,7 +253,7 @@
method source( $trans ) {
my $prelude := $trans.body_prelude;
- return self.get_body( $prelude, $trans );
+ return $prelude ~ self.get_body( $trans );
}
@@ -326,7 +326,7 @@
=begin
-=item C<get_body($prelude, $trans)>
+=item C<get_body($trans)>
Performs the various macro substitutions using the specified transform,
correctly handling nested substitions, and repeating over the whole string
@@ -337,19 +337,71 @@
=end
-method get_body( $prelude, $trans ) {
+method get_body( $trans ) {
- my $body := $prelude;
+ my @body := list();
#work through the op_body tree
- for $self<op_body> {
-
- pir::say("found an op body thing");
+ for @(self) {
+ my $chunk := self.process_body_chunk($trans, $_);
+ #pir::say('# chunk ' ~ $chunk);
+ @body.push($chunk);
}
- return self.substitute( $body, $trans );
+ join('', |@body);
}
+# Recursively process body chunks returning string.
+# Ideally bunch of multisubs, but...
+method process_body_chunk($trans, $chunk) {
+ my $what := $chunk.WHAT;
+ # Poor man multis...
+ if $what eq 'PAST::Var()' {
+ my $n := +$chunk.name;
+ return $trans.access_arg( self.arg_type($n - 1), $n);
+ }
+ elsif $what eq 'PAST::Op()' {
+ my $type := $chunk.pasttype;
+ #say('OP ' ~ $type);
+ if $type eq 'inline' {
+ #_dumper($chunk);
+ #pir::say('RET ' ~ $chunk<inline>);
+ return $chunk.inline;
+ }
+ elsif $type eq 'call' {
+ my $name := $chunk.name;
+ my $is_next := $chunk<is_next>;
+ #say('NAME '~$name ~ ' ' ~ $is_next);
+ my $children;
+ if $is_next {
+ #say('is_next');
+ $children := ~self.size;
+ }
+ else {
+ my @children := list();
+ for @($chunk) {
+ @children.push(self.process_body_chunk($trans, $_));
+ }
+ $children := join('', |@children);
+ }
+ #pir::say('children ' ~ $children);
+ my $ret := Q:PIR<
+ $P0 = find_lex '$trans'
+ $P1 = find_lex '$name'
+ $S0 = $P1
+ $P1 = find_lex '$children'
+ %r = $P0.$S0($P1)
+ >;
+ #pir::say('RET ' ~ $ret);
+ return $ret;
+ }
+ }
+ else {
+ pir::die('HOLEY');
+ }
+}
+
+
=begin
=item C<size()>
More information about the parrot-commits
mailing list