use of suite.jdk.gen.FunCreator in project suite by stupidsing.
the class CompileBinderImpl method binder.
public Bind_ binder(Node node) {
FunCreator<Bind_> fc = FunCreator.of(Bind_.class, false);
return fc.create(new BinOp<>() {
private FunExpr env, trail, b;
public FunExpr apply(FunExpr bindEnv, FunExpr target) {
this.env = bindEnv.field("env");
this.trail = bindEnv.field("trail");
return f.declare(ok, b -> {
this.b = b;
return compile_(node, target);
});
}
private FunExpr compile_(Node node, FunExpr target) {
FunExpr br = bind(f.object_(node, Node.class), target);
FunExpr brc = bindClone(node, target);
return new //
SwitchNode<FunExpr>(//
node).applyIf(Atom.class, n -> {
return f.ifEquals(target, f.object(node), ok, br);
}).applyIf(Int.class, n -> {
return f.ifInstance(Int.class, target, i -> f.ifEquals(i.field("number"), f.int_(n.number), ok, fail), br);
}).applyIf(Reference.class, n -> {
FunExpr ref = env.field("refs").index(f.int_(mapper().computeIndex(n)));
return f.invokeStatic(Binder.class, "bind", target, ref.cast_(Node.class), trail);
}).applyIf(Str.class, n -> {
return f.ifInstance(Str.class, target, s -> f.object(n.value).invoke("equals", s.field("value").cast_(Object.class)), br);
}).applyIf(Tree.class, tree -> {
return f.declare(f.invokeStatic(Tree.class, "decompose", target, f.object(tree.getOperator())), t -> {
Node lt = tree.getLeft();
Node rt = tree.getRight();
return f.ifNonNull(t, compile_(lt, t.invoke("getLeft"), compile_(rt, t.invoke("getRight"), ok)), brc);
});
}).applyIf(Tuple.class, n -> {
return f.ifInstance(Tuple.class, target, tuple -> f.declare(tuple.field("nodes"), targets -> {
Node[] nodes = n.nodes;
FunExpr fe = ok;
for (int i = 0; i < nodes.length; i++) fe = compile_(nodes[i], targets.index(f.int_(i)), fe);
return f.if_(targets.length(), fe, brc);
}), brc);
}).applyIf(Node.class, n -> {
Clone_ cloner = cloner(n);
return f.invokeStatic(Binder.class, "bind", target, f.object(cloner).invoke("apply", env), trail);
}).nonNullResult();
}
private FunExpr compile_(Node node, FunExpr target, FunExpr cps) {
return f.assign(b, compile_(node, target), f.if_(b, cps, fail));
}
private FunExpr bindClone(Node node, FunExpr target) {
if (isBindTrees)
return bind(f.object(cloner(node)).apply(env), target);
else
return fail;
}
private FunExpr bind(FunExpr node, FunExpr target) {
return f.ifInstanceAnd(Reference.class, target, ref -> f.seq(trail.invoke("addBind", ref, node), ok));
}
}).apply(Map.ofEntries());
}
use of suite.jdk.gen.FunCreator in project suite by stupidsing.
the class CompileClonerImpl method cloner.
@Override
public Clone_ cloner(Node node) {
FunCreator<Clone_> fc = FunCreator.of(Clone_.class, false);
return fc.create(new Iterate<>() {
private FunExpr env;
public FunExpr apply(FunExpr env) {
this.env = env;
return compile_(node);
}
private FunExpr compile_(Node node_) {
return new //
SwitchNode<FunExpr>(//
node_).applyIf(Atom.class, n -> {
return f.object(node_);
}).applyIf(Dict.class, n -> {
FunExpr[] exprs = //
Read.from2(//
n.map).map(//
(key, value) -> f.invokeStatic(Pair.class, "of", compile_(key), compile_(value))).toArray(FunExpr.class);
return f.invokeStatic(Dict.class, "of", f.array(Pair.class, exprs));
}).applyIf(Int.class, n -> {
return f.object(node_);
}).applyIf(Reference.class, n -> {
return env.field("refs").index(f.int_(vm.computeIndex(n)));
}).applyIf(Str.class, n -> {
return f.object(node_);
}).applyIf(Tree.class, tree -> {
FunExpr fe0 = compile_(tree.getLeft()).cast_(Node.class);
FunExpr fe1 = compile_(tree.getRight()).cast_(Node.class);
return f.invokeStatic(Tree.class, "of", f.object(tree.getOperator()), fe0, fe1);
}).applyIf(Tuple.class, n -> {
FunExpr[] exprs = Read.from(n.nodes).map(this::compile_).toArray(FunExpr.class);
return f.invokeStatic(Tuple.class, "of", f.array(Node.class, exprs));
}).nonNullResult();
}
}).apply(Map.ofEntries());
}
use of suite.jdk.gen.FunCreator in project suite by stupidsing.
the class FunRewrite method rewrite_.
private FunExpr rewrite_(FunExpr e0) {
return //
e0.<//
FunExpr>switch_().applyIf(ApplyFunExpr.class, e1 -> {
FunExpr object = rewrite(e1.object);
FunExpr[] parameters = Read.from(e1.parameters).map(this::rewrite).toArray(FunExpr.class);
Method method = fti.methodOf(object);
return object.invoke(method.getName(), parameters);
}).applyIf(CastFunExpr.class, e1 -> {
FunExpr e2 = e1.expr;
if (e2 instanceof DeclareParameterFunExpr) {
Class<?> interfaceClass = Type_.classOf(e1.type);
Map<String, Type> fieldTypes = new HashMap<>();
Map<String, FunExpr> fieldValues = new HashMap<>();
FunExpr e3 = rewrite(e -> {
FunExpr fieldValue;
if (e instanceof FieldStaticFunExpr) {
FieldStaticFunExpr e_ = (FieldStaticFunExpr) e;
String fieldName = e_.fieldName;
Type fieldType = fieldTypes.get(fieldName);
fieldTypes.put(fieldName, fieldType);
fieldValues.put(fieldName, e_);
return e;
} else if (e instanceof PlaceholderFunExpr && (fieldValue = placeholders.get(e)) != null) {
String fieldName = "e" + Util.temp();
Type fieldType = fti.typeOf(fieldValue);
fieldTypes.put(fieldName, fieldType);
fieldValues.put(fieldName, fieldValue);
return this_().field(fieldName, fieldType);
} else
return null;
}, e2);
FunCreator<?>.CreateClass cc = FunCreator.of(LambdaInterface.of(interfaceClass), fieldTypes).create_(e3);
Streamlet2<String, FunExpr> fieldValues0 = Read.from2(cc.fieldTypeValues).mapValue(tv -> objectField(tv.t1, tv.t0));
Streamlet2<String, FunExpr> fieldValues1 = Read.from2(fieldValues);
NewFunExpr e4 = new NewFunExpr();
e4.className = cc.className;
e4.fieldValues = Streamlet2.concat(fieldValues0, fieldValues1).toMap();
e4.implementationClass = cc.clazz;
e4.interfaceClass = interfaceClass;
return e4;
} else
return null;
}).applyIf(DeclareLocalFunExpr.class, e1 -> {
FunExpr value = rewrite(e1.value);
FunExpr lfe = local(localTypes.size());
localTypes.add(fti.typeOf(value));
AssignLocalFunExpr alfe = new AssignLocalFunExpr();
alfe.var = lfe;
alfe.value = value;
placeholders.put(e1.var, lfe);
return seq(alfe, rewrite(e1.do_));
}).applyIf(FieldFunExpr_.class, e1 -> {
FunExpr set = e1 instanceof FieldSetFunExpr ? ((FieldSetFunExpr) e1).value : null;
FunExpr object0 = rewrite(e1.object);
String fieldName = e1.fieldName;
Class<?> clazz = fti.classOf(object0);
Field field = Rethrow.ex(() -> clazz.getField(fieldName));
FunExpr object1 = object0.cast_(field.getDeclaringClass());
Type fieldType = Type.getType(field.getType());
return set == null ? object1.field(fieldName, fieldType) : object1.fieldSet(fieldName, fieldType, set);
}).applyIf(FieldInjectFunExpr.class, e1 -> {
Type type = fieldTypes.get(e1.fieldName);
if (type != null)
return rewrite(this_().field(e1.fieldName, type));
else
return Fail.t(e1.fieldName);
}).applyIf(InvokeLambdaFunExpr.class, e1 -> {
LambdaInstance<?> l_inst = e1.lambda;
LambdaImplementation<?> l_impl = l_inst.lambdaImplementation;
LambdaInterface<?> l_iface = l_impl.lambdaInterface;
FunExpr object = object_(l_impl.newFun(l_inst.fieldValues), l_iface.interfaceClass);
return rewrite(object.invoke(l_iface.interfaceClass, l_iface.methodName, e1.parameters));
}).applyIf(ObjectFunExpr.class, e1 -> {
return objectField(e1.object, e1.type);
}).applyIf(PlaceholderFunExpr.class, e1 -> {
FunExpr e2 = placeholders.get(e1);
if (e2 != null)
return e2;
else
return Fail.t("cannot resolve placeholder");
}).applyIf(ProfileFunExpr.class, e1 -> {
fieldTypeValues.put(e1.counterFieldName, Pair.of(Type.INT, 0));
return null;
}).result();
}
use of suite.jdk.gen.FunCreator in project suite by stupidsing.
the class CompileExpressionImpl method evaluator.
public Evaluate_ evaluator(Node node) {
FunCreator<Evaluate_> fc = FunCreator.of(Evaluate_.class, false);
return fc.create(new Iterate<>() {
private FunExpr env;
public FunExpr apply(FunExpr env) {
this.env = env;
return compile_(node);
}
private FunExpr compile_(Node node) {
return new //
SwitchNode<FunExpr>(//
node).match2(".0 + .1", (a, b) -> {
return compileOperator(a, b, "+");
}).match2(".0 - .1", (a, b) -> {
return compileOperator(a, b, "-");
}).match2(".0 * .1", (a, b) -> {
return compileOperator(a, b, "*");
}).match2(".0 / .1", (a, b) -> {
return compileOperator(a, b, "/");
}).match2(".0 and .1", (a, b) -> {
return compileOperator(a, b, "&&");
}).match2(".0 or .1", (a, b) -> {
return compileOperator(a, b, "||");
}).match2(".0 shl .1", (a, b) -> {
return compileOperator(a, b, "<<");
}).match2(".0 shr .1", (a, b) -> {
return compileOperator(a, b, ">>");
}).applyIf(Int.class, i -> {
return f.int_(i.number);
}).applyIf(Node.class, i -> {
Clone_ n_ = clonerFactory.cloner(node);
Evaluate_ evaluate = env -> TreeUtil.evaluate(n_.apply(env));
return f.object(evaluate).invoke("evaluate", env);
}).nonNullResult();
}
private FunExpr compileOperator(Node a, Node b, String op) {
FunExpr fe0 = compile_(a);
FunExpr fe1 = compile_(b);
return f.bi(op, fe0, fe1);
}
}).apply(Map.ofEntries());
}
Aggregations