001package org.clafer.javascript; 002 003import java.util.ArrayList; 004import java.util.HashMap; 005import java.util.List; 006import java.util.Map; 007import java.util.Map.Entry; 008import org.clafer.ast.AstClafer; 009import org.clafer.ast.AstModel; 010import org.clafer.ast.AstSetExpr; 011import org.clafer.ast.Asts; 012import org.clafer.objective.Objective; 013import org.clafer.scope.Scope; 014import org.mozilla.javascript.NativeJavaObject; 015import org.mozilla.javascript.Scriptable; 016 017/** 018 * 019 * @author jimmy 020 */ 021public class JavascriptContext { 022 023 private final Map<String, Integer> scope = new HashMap<>(); 024 private final List<Objective> objectives = new ArrayList<>(0); 025 private int defaultScope = 1; 026 private int intLow = -16; 027 private int intHigh = 16; 028 private final AstModel model = Asts.newModel(); 029 030 public void setScope(Map<String, Number> scope) { 031 for (Entry<String, Number> entry : scope.entrySet()) { 032 // Javascript integers are doubles. 033 this.scope.put(entry.getKey(), entry.getValue().intValue()); 034 } 035 } 036 037 public void setDefaultScope(int defaultScope) { 038 if (defaultScope < 1) { 039 throw new IllegalArgumentException(); 040 } 041 this.defaultScope = defaultScope; 042 } 043 044 public void setIntRange(int intLow, int intHigh) { 045 if (intLow > intHigh) { 046 throw new IllegalArgumentException(); 047 } 048 this.intLow = intLow; 049 this.intHigh = intHigh; 050 } 051 052 public Scope getScope(Scriptable engine) { 053 Map<AstClafer, Integer> resolvedScope = new HashMap<>(); 054 for (Entry<String, Integer> entry : scope.entrySet()) { 055 String key = entry.getKey(); 056 Object value = engine.get(key, engine); 057 if (!(value instanceof NativeJavaObject)) { 058 throw new IllegalStateException(key + " is not a Clafer, found " + value); 059 } 060 NativeJavaObject object = (NativeJavaObject) value; 061 if (!(object.unwrap() instanceof AstClafer)) { 062 throw new IllegalStateException(key + " is not a Clafer, found " + object.unwrap()); 063 } 064 AstClafer clafer = (AstClafer) object.unwrap(); 065 if (clafer == null) { 066 throw new IllegalStateException("Cannot set scope for unknown Clafer \"" + key + "\", " 067 + "."); 068 } 069 resolvedScope.put(clafer, entry.getValue()); 070 } 071 return new Scope(resolvedScope, defaultScope, intLow, intHigh); 072 } 073 074 public void addMaximizeObjective(AstSetExpr expr) { 075 objectives.add(Objective.maximize(expr)); 076 } 077 078 public void addMinimizeObjective(AstSetExpr expr) { 079 objectives.add(Objective.minimize(expr)); 080 } 081 082 public Objective[] getObjectives() { 083 return objectives.toArray(new Objective[objectives.size()]); 084 } 085 086 public AstModel getModel() { 087 return model; 088 } 089}