Files
kraken/koka_bench/java/cfold.java
2022-05-19 00:43:27 -04:00

157 lines
3.8 KiB
Java

interface XExpr {
}
final class ValXExpr implements XExpr {
long value;
ValXExpr(long i) {
value = i;
}
}
final class VarXExpr implements XExpr {
long name;
VarXExpr(long i) {
name = i;
}
}
final class AddXExpr implements XExpr {
XExpr left;
XExpr right;
AddXExpr(XExpr l, XExpr r) {
left = l;
right = r;
}
}
final class MulXExpr implements XExpr {
XExpr left;
XExpr right;
MulXExpr(XExpr l, XExpr r) {
left = l;
right = r;
}
}
public class cfold {
static XExpr mk_expr( long n, long v ) {
if (n == 0) {
return (v==0 ? new VarXExpr(1) : new ValXExpr(v));
}
else {
return new AddXExpr( mk_expr(n-1, v+1), mk_expr(n - 1, v == 0 ? 0 : v - 1));
}
}
static XExpr append_add( XExpr e1, XExpr e2 ) {
if (e1 instanceof AddXExpr a) {
return new AddXExpr(a.left, append_add(a.right, e2));
}
else {
return new AddXExpr(e1,e2);
}
}
static XExpr tail_append_add( XExpr e1, XExpr e2 ) {
AddXExpr hd = null;
AddXExpr acc = null;
while(e1 instanceof AddXExpr x) {
if (acc==null) {
hd = acc = new AddXExpr(x.left,null);
}
else {
AddXExpr y = new AddXExpr(x.left,null);
acc.right = y;
acc = y;
}
e1 = x.right;
}
if (acc==null) hd = acc = new AddXExpr(e1,e2);
else acc.right = new AddXExpr(e1,e2);
return hd;
}
static XExpr append_mul( XExpr e1, XExpr e2 ) {
if (e1 instanceof MulXExpr a) {
return new MulXExpr(a.left, append_mul(a.right, e2));
}
else {
return new MulXExpr(e1,e2);
}
}
static XExpr reassoc( XExpr e ) {
if (e instanceof AddXExpr a) {
return append_add( reassoc(a.left), reassoc(a.right) );
}
else if (e instanceof MulXExpr m) {
return append_mul( reassoc(m.left), reassoc(m.right) );
}
else return e;
}
static XExpr const_folding( XExpr e ) {
if (e instanceof AddXExpr x) {
XExpr e1 = const_folding(x.left);
XExpr e2 = const_folding(x.right);
if (e1 instanceof ValXExpr a && e2 instanceof ValXExpr b) {
return new ValXExpr(a.value + b.value );
}
else if (e1 instanceof ValXExpr a && e2 instanceof AddXExpr b && b.right instanceof ValXExpr br) {
return new AddXExpr( new ValXExpr(a.value + br.value), b.left );
}
else if (e1 instanceof ValXExpr a && e2 instanceof AddXExpr b && b.left instanceof ValXExpr bl) {
return new AddXExpr( new ValXExpr(a.value + bl.value), b.right );
}
else {
return new AddXExpr(e1,e2);
}
}
else if (e instanceof MulXExpr x) {
XExpr e1 = const_folding(x.left);
XExpr e2 = const_folding(x.right);
if (e1 instanceof ValXExpr a && e2 instanceof ValXExpr b) {
return new ValXExpr(a.value * b.value );
}
else if (e1 instanceof ValXExpr a && e2 instanceof MulXExpr b && b.right instanceof ValXExpr br) {
return new MulXExpr( new ValXExpr(a.value * br.value), b.left );
}
else if (e1 instanceof ValXExpr a && e2 instanceof MulXExpr b && b.left instanceof ValXExpr bl) {
return new MulXExpr( new ValXExpr(a.value * bl.value), b.right );
}
else {
return new MulXExpr(e1,e2);
}
}
else return e;
}
static long eval( XExpr e ) {
if (e instanceof VarXExpr x) {
return 0;
}
else if (e instanceof ValXExpr x) {
return x.value;
}
else if (e instanceof AddXExpr x) {
return eval(x.left) + eval(x.right);
}
else if (e instanceof MulXExpr x) {
return eval(x.left) * eval(x.right);
}
else {
return 0;
}
}
public static void main(String args[])
{
XExpr e = mk_expr(Integer.parseInt(args[0]),1);
long v1 = eval(e);
long v2 = eval(const_folding(reassoc(e)));
System.out.println( v1 + ", " + v2 );
}
}