public class TranslationContext extends TypeTranslationContext implements EnvironmentalContext {
+ public static class ExistentialFrame {
+ THashSet<String> variables = new THashSet<String>(4);
+ ArrayList<Variable> blanks = new ArrayList<Variable>(2);
+ boolean disallowNewExistentials;
+ }
+
THashMap<String, Variable> variables = new THashMap<String, Variable>();
ArrayList<Entry> variableEntries = new ArrayList<Entry>();
LocalEnvironment localEnvironment;
TIntArrayList frames = new TIntArrayList();
ArrayList<THashSet<String>> frameNameSets = new ArrayList<THashSet<String>>();
- ArrayList<THashSet<String>> existentialFrames = new ArrayList<THashSet<String>>();
- ArrayList<ArrayList<Variable>> blanksInExistentialFrame = new ArrayList<ArrayList<Variable>>();
+ ArrayList<ExistentialFrame> existentialFrames = new ArrayList<ExistentialFrame>(2);
SCLValue bindFunction;
public PreQuery currentPreQuery;
char c = name.charAt(0);
switch(c) {
- case '?':
- if(existentialFrames.isEmpty()) {
- errorLog.log(location, "Existential variables can be used only in queries.");
+ case '?': {
+ ExistentialFrame existentialFrame = getCurrentExistentialFrame();
+ if(existentialFrame == null || existentialFrame.disallowNewExistentials) {
+ errorLog.log(location, "New existential variables can be defined only in queries.");
return new EError(location);
}
variable = new Variable(name);
variables.put(name, variable);
- existentialFrames.get(existentialFrames.size()-1).add(name);
+ existentialFrame.variables.add(name);
return new EVariable(variable);
- case '_':
+ }
+ case '_': {
if(name.length()==1) {
variable = new Variable("_");
- if(blanksInExistentialFrame.isEmpty()) {
- errorLog.log(location, "Cannot use blank variables in this context.");
+ ExistentialFrame existentialFrame = getCurrentExistentialFrame();
+ if(existentialFrame == null || existentialFrame.disallowNewExistentials) {
+ errorLog.log(location, "Blank variables can be used only in queries.");
return new EError(location);
}
- blanksInExistentialFrame.get(blanksInExistentialFrame.size()-1).add(variable);
+ existentialFrame.blanks.add(variable);
return new EVariable(variable);
}
break;
}
+ }
return null;
}
+ private ExistentialFrame getCurrentExistentialFrame() {
+ int size = existentialFrames.size();
+ if(size == 0)
+ return null;
+ else
+ return existentialFrames.get(size-1);
+ }
+
private Expression resolveFieldAccess(Expression base, int pos, String name) {
while(pos != -1) {
int p = findSeparator(name, pos+1);
public void pushExistentialFrame() {
pushFrame();
- existentialFrames.add(new THashSet<String>());
- blanksInExistentialFrame.add(new ArrayList<Variable>(2));
+ existentialFrames.add(new ExistentialFrame());
}
public Variable[] popExistentialFrame() {
popFrame();
- THashSet<String> set = existentialFrames.remove(existentialFrames.size()-1);
- ArrayList<Variable> blanks = blanksInExistentialFrame.remove(blanksInExistentialFrame.size()-1);
- Variable[] result = new Variable[set.size() + blanks.size()];
+ ExistentialFrame frame = existentialFrames.remove(existentialFrames.size()-1);
+ Variable[] result = new Variable[frame.variables.size() + frame.blanks.size()];
int i=0;
- for(String name : set)
+ for(String name : frame.variables)
result[i++] = variables.remove(name);
- for(Variable blank : blanks)
+ for(Variable blank : frame.blanks)
result[i++] = blank;
return result;
}
public CHRRuleset resolveRuleset(String name) throws AmbiguousNameException {
return Environments.getRuleset(environment, name);
}
+
+ public void disallowNewExistentials() {
+ getCurrentExistentialFrame().disallowNewExistentials = true;
+ }
}