#! /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)
}
