package org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.traverse; import org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.CompilerError; import org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.FunctionInstance; import org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.RVMCore; import org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.Reference; import org.rascalmpl.value.IValue; import org.rascalmpl.value.IValueFactory; import org.rascalmpl.value.type.Type; public class Traverse { public enum DIRECTION {BottomUp, TopDown} // Parameters for traversing trees public enum FIXEDPOINT {Yes, No} public enum PROGRESS {Continuing, Breaking} public enum REBUILD {Yes, No}; private final IValueFactory vf; public Traverse(IValueFactory vf) { this.vf = vf; } public IValue traverse(DIRECTION direction, PROGRESS progress, FIXEDPOINT fixedpoint, REBUILD rebuild, IValue subject, FunctionInstance phi, Reference refMatched, Reference refChanged, Reference refLeaveVisit, Reference refBegin, Reference refEnd, RVMCore rvm, DescendantDescriptor descriptor) { refMatched.setValue(vf.bool(false)); refChanged.setValue(vf.bool(false)); refLeaveVisit.setValue(vf.bool(false)); Type subjectType = subject.getType(); TraversalState tr = new TraversalState(rvm, phi, refMatched, refChanged, refLeaveVisit, refBegin, refEnd, descriptor); ITraverseSpecialization traversals = rebuild == REBUILD.Yes ? new TraverseOnceRebuild(vf) :new TraverseOnceNoRebuild(vf); try { if(subjectType.isString()){ IValue result = traversals.traverseStringOnce(subject, tr); return result; } switch(direction){ case BottomUp: switch(progress){ case Continuing: switch(fixedpoint){ case Yes: if(descriptor.isConcreteMatch()){ tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceBottomUpContinuingFixedPointConcrete(s,t); return tr.traverse.once(subject, tr); } else { tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceBottomUpContinuingFixedPointAbstract(s, t); return tr.traverse.once(subject, tr); } case No: if(descriptor.isConcreteMatch()){ tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceBottomUpContinuingNoFixedPointConcrete(s, t); return tr.traverse.once(subject, tr); } else { tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceBottomUpContinuingNoFixedPointAbstract(s, t); return tr.traverse.once(subject, tr); } } case Breaking: switch(fixedpoint){ case Yes: if(descriptor.isConcreteMatch()){ tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceBottomUpBreakingFixedPointConcrete(s, t); return tr.traverse.once(subject, tr); } else { tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceBottomUpBreakingFixedPointAbstract(s, t); return tr.traverse.once(subject, tr); } case No: if(descriptor.isConcreteMatch()){ tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceBottomUpBreakingNoFixedPointConcrete(subject, tr); return tr.traverse.once(subject, tr); } else { tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceBottomUpBreakingNoFixedPointAbstract(s, t); return tr.traverse.once(subject, tr); } } } case TopDown: switch(progress){ case Continuing: switch(fixedpoint){ case Yes: if(descriptor.isConcreteMatch()){ tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceTopDownContinuingFixedPointConcrete(s, t); return tr.traverse.once(subject, tr); } else { tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceTopDownContinuingFixedPointAbstract(s, t); return tr.traverse.once(subject, tr); } case No: if(descriptor.isConcreteMatch()){ tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceTopDownContinuingNoFixedPointConcrete(s, t); return tr.traverse.once(subject, tr); } else { tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceTopDownContinuingNoFixedPointAbstract(s, t); return tr.traverse.once(subject, tr); } } case Breaking: switch(fixedpoint){ case Yes: if(descriptor.isConcreteMatch()){ tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceTopDownBreakingFixedPointConcrete(s, t); return tr.traverse.once(subject, tr); } else { tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceTopDownBreakingFixedPointAbstract(s, t); return tr.traverse.once(subject, tr); } case No: if(descriptor.isConcreteMatch()){ tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceTopDownBreakingNoFixedPointConcrete(s, t); return tr.traverse.once(subject, tr); } else { tr.traverse = (IValue s, TraversalState t) -> traversals.traverseOnceTopDownBreakingNoFixedPointAbstract(s, t); return tr.traverse.once(subject, tr); } } } } throw new CompilerError("Traversal specialization not found: " + direction + ", " + progress + ", " + fixedpoint + ", " + rebuild + ", concreteMatch = " + descriptor.isConcreteMatch()); } catch (ReturnFromTraversalException e) { return e.getValue(); } } }