#! /usr/bin/awk -f
# Maxima optimized expression format:
# (C1) DISPLAY2D:FALSE$
# (C2) OPTIMIZE(x);
# (D2) x
# (C3) OPTIMIZE((1.0+a*b)/(2.0+a*b));
# (D3) BLOCK([%1],%1:a*b,(%1+1.0)/(%1+2.0))
function decipher_block(lhs,rhs)
{
s=rhs;
s=gensub(/BLOCK/, "", "1", s); # strip BLOCK keyword
s=gensub(/\(/, "", "1", s); # strip leading (
s=gensub(/\)$/, "", "1", s); # strip trailing )
s=gensub(/\[.*\],/, "", "g", s); # strip declarations
s=gensub(/%/, "mtt_tmp", "g", s); # rename tmp variables
s=gensub(/:/, " := ", "g", s); # fix assignment operator
# commas delimit statements in maxima, so
# preserve commas within function calls
# replace remaining commas with semi-colons
# then put commas back in functions and reinstate parentheses
while (match(s, (/\(([^()]*),([^()]*)\)/))) {
s=gensub(/\(([^()]*),([^()]*)\)/, "(\\1__MTT_COMMA__\\2)", "g", s);
s=gensub(/\(([^,()]*)\)/, "__MTT_LPAREN__\\1__MTT_RPAREN__", "g", s);
}
s=gensub(/,/, ";\n", "g", s);
s=gensub(/__MTT_COMMA__/, ",", "g", s);
s=gensub(/__MTT_LPAREN__/, "(", "g", s);
s=gensub(/__MTT_RPAREN__/, ")", "g", s);
# separate statements
rhs=gensub(/.*;([^;]*)\n/, "\\1", 1, s);
s=gensub(/;([^;]*)$/, ";", 1, s);
print s; # print intermediate statements
printf "%s := %s;\n", lhs, rhs; # print final assignment
}
# pattern matching:
(! /.* BLOCK.*/ ) { # unoptimised statement
print $1" := "$2";";
}
( /.* BLOCK.*/ ) { # optimised statement
decipher_block($1,$2)
}