use of suite.funp.P0.FunpVariable in project suite by stupidsing.
the class P2InferType method captureLambdas.
private Funp captureLambdas(Funp node0) {
class Capture {
private Fun<String, Funp> accesses;
private ISet<String> locals;
private ISet<String> globals;
private Capture(Fun<String, Funp> accesses, ISet<String> locals, ISet<String> globals) {
this.accesses = accesses;
this.locals = locals;
this.globals = globals;
}
private Funp capture(Funp n) {
return inspect.rewrite(Funp.class, this::capture_, n);
}
private Funp capture_(Funp n) {
return //
n.<//
Funp>switch_().applyIf(FunpDefine.class, f -> f.apply((isPolyType, var, value, expr) -> {
Capture c1 = new Capture(accesses, locals.add(var), globals);
return FunpDefine.of(isPolyType, var, capture(value), c1.capture(expr));
})).applyIf(FunpDefineRec.class, f -> f.apply((vars, expr) -> {
List<Pair<String, Funp>> vars1 = new ArrayList<>();
ISet<String> locals1 = locals;
for (Pair<String, Funp> pair : vars) {
locals1 = locals1.add(pair.t0);
vars1.add(Pair.of(pair.t0, capture(pair.t1)));
}
Capture c1 = new Capture(accesses, locals1, globals);
return FunpDefineRec.of(vars1, c1.capture(expr));
})).applyIf(FunpGlobal.class, f -> f.apply((var, value, expr) -> {
Capture c1 = new Capture(accesses, locals, globals.add(var));
return FunpGlobal.of(var, capture(value), c1.capture(expr));
})).applyIf(FunpIterate.class, f -> f.apply((var, init, cond, iterate) -> {
Capture c1 = new Capture(accesses, locals.add(var), globals);
return FunpIterate.of(var, capture(init), c1.capture(cond), c1.capture(iterate));
})).applyIf(FunpLambda.class, f -> f.apply((var, expr) -> {
ISet<String> locals1 = ISet.empty();
String capn = "cap" + Util.temp();
FunpVariable cap = FunpVariable.of(capn);
FunpReference ref = FunpReference.of(cap);
Set<String> set = new HashSet<>();
List<Pair<String, Funp>> list = new ArrayList<>();
FunpStruct struct = FunpStruct.of(list);
Capture c1 = new Capture(v -> {
if (set.add(v))
list.add(Pair.of(v, FunpVariable.of(v)));
return FunpField.of(ref, v);
}, locals1.add(capn).add(var), globals);
return FunpGlobal.of(capn, struct, FunpLambdaCapture.of(var, capn, cap, c1.capture(expr)));
// TODO allocate cap on heap
// TODO free cap after use
})).applyIf(FunpVariable.class, f -> f.apply(var -> {
return locals.contains(var) || globals.contains(var) ? f : accesses.apply(var);
})).result();
}
}
return new Capture(v -> Fail.t(), ISet.empty(), ISet.empty()).capture(node0);
}
Aggregations