1 # Copyright (C) 2008, The Perl Foundation.
6 APL::Grammar::Actions - ast transformations for APL
8 This file contains the methods that are used by the parse grammar
9 to build the PAST representation of an APL program.
10 Each method below corresponds to a rule in F<src/parser/grammar.pg>,
11 and is invoked at the point where C<{*}> appears in the rule,
12 with the current match object as the first argument. If the
13 line containing C<{*}> also has a C<#= key> comment, then the
14 value of the comment is passed as the second argument to the method.
18 class APL::Grammar::Actions;
21 my $catchpir := " get_results '0,0', $P0, $S0\n print $S0\n exit 1\n";
22 my $past := PAST::Op.new( $( $<statement_list> ),
23 PAST::Op.new( :inline( $catchpir) ),
29 method statement_list($/) {
30 my $past := PAST::Stmts.new( :node($/) );
32 $past.push( $( $_ ) );
37 method statement($/) {
38 my $past := $( $<expression> );
39 if $past.WHAT() ne 'Op' || $past.pasttype() ne 'copy' {
40 $past := PAST::Op.new( $past, :name('aplprint'), :node( $/ ) );
46 method expression($/, $key) {
48 if ($key eq 'assign') {
49 my $past := PAST::Op.new( $($<target>),
55 elsif ($key eq 'monadic') {
56 my $name := 'monadic:' ~ $<monadic_identifier>;
57 my $past := PAST::Op.new( $($<expression>), :node($/) );
58 if %inlinetable{$name} {
59 $past.inline( %inlinetable{$name} );
67 my $past := $( $<subexpression> );
68 if $<dyadic_identifier>[0] {
69 my $name := 'dyadic:' ~ $<dyadic_identifier>[0];
70 $past := PAST::Op.new( $past,
73 if %inlinetable{$name} {
74 $past.inline(%inlinetable{$name});
85 method subexpression($/) {
86 make $( $<simple_expression> );
90 method simple_expression($/, $key) {
95 my $past := $( $<variable_identifier> );
100 method array_identifier($/, $key) {
104 method constant($/, $key) {
108 method numeric_constant($/) {
109 if +$<decimal_representation> != 1 {
110 my $past := PAST::Op.new( :name('aplvector'), :node($/) );
111 for $<decimal_representation> {
112 $past.push( $( $_ ) );
117 make $( $<decimal_representation>[0] );
121 method decimal_representation($/) {
123 $value.replace("\x207b", '-');
124 PIR q< $P0 = find_lex '$value' >;
126 PIR q< $I0 = index $S0, '.' >;
127 PIR q< unless $I0 < 0 goto ffff >;
128 PIR q< $I0 = index $S0, 'E' >;
129 PIR q< unless $I0 < 0 goto ffff >;
130 PIR q< concat $P0, '.' >;
132 make PAST::Val.new( :value($value), :returns('Float'), :node($/) );
135 method variable_identifier($/) {
136 make PAST::Var.new( :name( ~$/ ),
142 method character_constant_double($/) {
144 $value.replace('""', '"');
145 make PAST::Op.new( PAST::Val.new( :value($value) ),
150 method character_constant_single($/) {
152 $value.replace("''", "'");
153 make PAST::Op.new( PAST::Val.new( :value($value) ),
161 # cperl-indent-level: 4
164 # vim: expandtab shiftwidth=4: