package org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.traverse; import java.util.HashSet; import org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.RascalExecutionContext; import org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.RascalPrimitive; import org.rascalmpl.value.IBool; import org.rascalmpl.value.IConstructor; import org.rascalmpl.value.IMap; import org.rascalmpl.value.ISet; import org.rascalmpl.value.IValue; import org.rascalmpl.value.IValueFactory; import org.rascalmpl.value.type.Type; import org.rascalmpl.values.uptr.ITree; /** * Create a descendant descriptor given * 1: symbolset, ISet of symbols * 2: prodset, ISet of productions * 3: concreteMatch, indicates a concrete or abstract match * * [ IString id, ISet symbolset, ISet prodset, IBool concreteMatch] => descendant_descriptor */ public class DescendantDescriptor { private final HashSet<Object> mSymbolSet; private final boolean concreteMatch; private final boolean containsNodeOrValueType; //private int counter = 0; public DescendantDescriptor(IValueFactory vf, ISet symbolset, ISet prodset, IMap definitions, IBool concreteMatch, RascalExecutionContext rex){ mSymbolSet = new HashSet<Object>(symbolset.size() + prodset.size()); this.concreteMatch = concreteMatch.getValue(); boolean nodeOrValue = true; // for(IValue v : symbolset){ // Type tp = rex.symbolToType((IConstructor) v, definitions); // mSymbolSet.add(tp); // Add as TYPE to the set // if(tp == RascalPrimitive.nodeType || tp == RascalPrimitive.valueType){ // nodeOrValue = true; // } // } // for(IValue v : prodset){ // IConstructor cons = (IConstructor) v; // mSymbolSet.add(cons); // Add the production itself to the set // } containsNodeOrValueType = nodeOrValue; } public boolean isConcreteMatch(){ return concreteMatch; } public boolean isAllwaysTrue(){ return containsNodeOrValueType; } public IBool shouldDescentInAbstractValue(final IValue subject) { //assert !concreteMatch : "shouldDescentInAbstractValue: abstract traversal required"; //System.out.println("shouldDescentInAbstractValue: " + ++counter + ", " + subject.toString()); if (containsNodeOrValueType) { return RascalPrimitive.Rascal_TRUE; } Type type = subject instanceof IConstructor ? ((IConstructor) subject).getConstructorType() : subject.getType(); return mSymbolSet.contains(type) ? RascalPrimitive.Rascal_TRUE : RascalPrimitive.Rascal_FALSE; } public IBool shouldDescentInConcreteValue(final ITree subject) { //assert concreteMatch : "shouldDescentInConcreteValue: concrete traversal required"; if (subject.isAppl()) { if (containsNodeOrValueType) { return RascalPrimitive.Rascal_TRUE; } IConstructor prod = (IConstructor) subject.getProduction(); return mSymbolSet.contains(prod) ? RascalPrimitive.Rascal_TRUE : RascalPrimitive.Rascal_FALSE; } if (subject.isAmb()) { return RascalPrimitive.Rascal_TRUE; } return RascalPrimitive.Rascal_FALSE; } // public IBool shouldDescentInType(Type type) { // assert !concreteMatch : "shouldDescentInType: abstract traversal required"; // if (containsNodeOrValueType) { // return RascalPrimitive.Rascal_TRUE; // } // return mSymbolSet.contains(type) ? RascalPrimitive.Rascal_TRUE : RascalPrimitive.Rascal_FALSE; // } }