Skip to content

MacroHowTo

Kervius edited this page Oct 26, 2014 · 4 revisions

How to define and use a macro

There is no native support for the macros, thus the intermediate language facilities should be used instead. Since all boa does is generate print statements of the language, the macro can be mapped onto the language's function which either prints or returns the string containing the desired expansion.

Shell

@@@ shell @@@
@{{
str_start_with()
{
	echo -n 'test "x${'$1'#$'$2'}" != "x${'$1'}"'
}
}}@

A="hello"
B="hell"

if @{!str_start_with A B}; then
	echo "$A starts with $B"
fi

Looks pretty hairy, because str_starts_with has to generate the code which operates on the names of the variables. Additionally, since the @{something} in case of the shell would expand into echo something, backticks are required to force the function to run. Running that with boa -d, it expands to:

str_start_with()
{
	echo -n 'test "x${'$1'#$'$2'}" != "x${'$1'}"'
}
echo
echo -n 'A="hello"'
echo
echo -n 'B="hell"'
echo
echo
echo -n 'if '
str_start_with A B
echo -n '; then'
echo
echo -n '	echo "$A starts with $B"'
echo
echo -n 'fi'
echo

Running that with boa, without -d, it expands to:

A="hello"
B="hell"

if test "x${A#$B}" != "x${A}"; then
	echo "$A starts with $B"
fi

And piping the output to the sh, one should see the message hello starts with hell.

Perl

It looks more straightforward and also is more efficient, since unlike Shell, Perl functions can return string:

@@@ perl @@@
@{{
sub str_starts_with
{
	my ($a, $b) = @_;
	return qq/test "x\${$a#\$$b}" != "x\${$a}"/;
};
}}@

A="hello"
B="hell"

if @{str_starts_with('A','B')}; then
	echo "$A starts with $B"
fi

Output of boa -d:

sub str_starts_with
{
	my ($a, $b) = @_;
	return qq/test "x\${$a#\$$b}" != "x\${$a}"/;
};
print qq{\n};
print 'A="hello"';
print qq{\n};
print 'B="hell"';
print qq{\n};
print qq{\n};
print 'if ';
print str_starts_with('A','B');
print '; then';
print qq{\n};
print '	echo "$A starts with $B"';
print qq{\n};
print 'fi';
print qq{\n};

Running it without -d and piping the preprocessed result to the /bin/sh produces the same output as in the Shell example above.

Clone this wiki locally