import { ASTVisitor } from "." import { Application, Lambda, Variable } from "../ast/" export class BoundingFinder extends ASTVisitor { public lambdas : Set = new Set private argName : string private unboundVars : Set = new Set constructor ( public tree : Lambda, public freeVars : Set ) { super() this.argName = tree.argument.name() tree.body.visit(this) } onApplication (application : Application) : void { const unbounds : Set = new Set(this.unboundVars) let combined : Set = new Set application.left.visit(this) combined = new Set([...combined.values(), ...this.unboundVars.values()]) this.unboundVars = unbounds application.right.visit(this) combined = new Set([...combined.values(), ...this.unboundVars.values()]) this.unboundVars = combined } onLambda (lambda : Lambda) : void { if (lambda.argument.name() === this.argName) { return } lambda.body.visit(this) this.unboundVars.delete(lambda.argument.name()) // binding argument name if (this.unboundVars.has(this.argName) && this.freeVars.has(lambda.argument.name()) ) { this.lambdas.add(lambda) } } onVariable (variable : Variable) { this.unboundVars.add(variable.name()) } }