package Macro; use strict; use warnings; use Filter::Simple; my %macros; FILTER_ONLY executable => sub { while( s[ MACRO\s+ sub\s+ (\w+)\s+ \{\s+ my\s*\( \s* ( [^\)]+? ) \s* \)\s* =\s* \@_;\s+ ( .*? ) \} \s* ENDMACRO ][]xsmg ) { my( $name, $args, $body ) = ( $1, $2, $3 ); $body =~ s[[\r\n]+][]g; $macros{ $name } = [ [ split ',\s*', $args ], "do{ our \$MACRO_RETURN; local \$MACRO_RETURN; $body; MACRO_RETURN: \$MACRO_RETURN }" ]; } for my $macro ( keys %macros ) { s[ $macro\( \s* ( [^\)]+ ) \s* \) ]{ my @actual = split '\s*,\s*', $1; my @formal = @{ $macros{ $macro }[ 0 ] }; my $do = $macros{ $macro }[ 1 ]; my %substs; @substs{ @formal } = @actual; $do =~ s[([\$][\w]+)]{ exists $substs{ $1 } ? $substs{ $1 } : $1 }eg; $do =~ s[return\s*(.*?)\s*;] [\$MACRO_RETURN = $1; goto MACRO_RETURN;]g; $do; }xeg; } $_; }; 1;