X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fcontexts%2FTranslationContext.java;h=0331f9a50b86a7715405afc9bb37da2441d8b5b2;hp=d9746bb04c1d9a2524e82a03193c80a6773ee450;hb=1ec0193a5a5b8f368b03adb24acd762838ddf8ea;hpb=78f577368ba4c71ad6fb3d9f16c03c634585cf7b diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java index d9746bb04..0331f9a50 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java @@ -43,13 +43,26 @@ import gnu.trove.set.hash.THashSet; public class TranslationContext extends TypeTranslationContext implements EnvironmentalContext { + public static class ExistentialFrame { + THashSet variables = new THashSet(4); + ArrayList blanks = new ArrayList(2); + public boolean disallowNewExistentials; + + public EVariable createBlank(long location) { + Variable variable = new Variable("_"); + blanks.add(variable); + EVariable result = new EVariable(variable); + result.location = location; + return result; + } + } + THashMap variables = new THashMap(); ArrayList variableEntries = new ArrayList(); LocalEnvironment localEnvironment; TIntArrayList frames = new TIntArrayList(); ArrayList> frameNameSets = new ArrayList>(); - ArrayList> existentialFrames = new ArrayList>(); - ArrayList> blanksInExistentialFrame = new ArrayList>(); + ArrayList existentialFrames = new ArrayList(2); SCLValue bindFunction; public PreQuery currentPreQuery; @@ -110,30 +123,40 @@ public class TranslationContext extends TypeTranslationContext implements Enviro 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); - return new EVariable(variable); + return existentialFrame.createBlank(location); } break; } + } return null; } + public 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); @@ -380,19 +403,17 @@ public class TranslationContext extends TypeTranslationContext implements Enviro public void pushExistentialFrame() { pushFrame(); - existentialFrames.add(new THashSet()); - blanksInExistentialFrame.add(new ArrayList(2)); + existentialFrames.add(new ExistentialFrame()); } public Variable[] popExistentialFrame() { popFrame(); - THashSet set = existentialFrames.remove(existentialFrames.size()-1); - ArrayList 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; } @@ -526,4 +547,8 @@ public class TranslationContext extends TypeTranslationContext implements Enviro public CHRRuleset resolveRuleset(String name) throws AmbiguousNameException { return Environments.getRuleset(environment, name); } + + public void disallowNewExistentials() { + getCurrentExistentialFrame().disallowNewExistentials = true; + } }