use of edu.mit.csail.sdg.ast.Expr in project org.alloytools.alloy by AlloyTools.
the class SimInstance method visit.
/**
* {@inheritDoc}
*/
@Override
public Object visit(ExprCall x) throws Err {
final Func f = x.fun;
final int n = f.count();
final Object candidate = n == 0 ? cacheForConstants.get(f) : null;
if (candidate != null)
return candidate;
final Expr body = f.getBody();
if (body.type().arity() < 0 || body.type().arity() != f.returnDecl.type().arity())
throw new ErrorType(body.span(), "Function return value not fully resolved.");
for (Func ff : current_function) if (ff == f)
throw new ErrorSyntax(x.span(), "" + f + " cannot call itself recursively!");
Env<ExprVar, Object> newenv = new Env<ExprVar, Object>();
List<SimTupleset> list = new ArrayList<SimTupleset>(x.args.size());
for (int i = 0; i < n; i++) {
SimTupleset ts = cset(x.args.get(i));
newenv.put(f.get(i), ts);
list.add(ts);
}
final SimCallback cb = callbacks.get(f);
if (cb != null) {
try {
Object answer = cb.compute(f, list);
if (answer != null) {
if (x.args.size() == 0)
cacheForConstants.put(f, answer);
return answer;
}
} catch (Exception ex) {
// if the callback failed, we can just continue with our
// original attempt to evaluate this call
}
}
Env<ExprVar, Object> oldenv = env;
env = newenv;
current_function.add(f);
Object ans = visitThis(body);
env = oldenv;
current_function.remove(current_function.size() - 1);
if (f.count() == 0)
cacheForConstants.put(f, ans);
return ans;
}
use of edu.mit.csail.sdg.ast.Expr in project org.alloytools.alloy by AlloyTools.
the class CompModule method getRawQS.
/**
* Lookup a fully-qualified Sig/Func/Assertion from the current module; it skips
* PARAMs.
*/
private List<Object> getRawQS(final int r, String name) {
// (r&1)!=0 => Sig, (r&2) != 0 => assertion, (r&4)!=0 => Func
List<Object> ans = new ArrayList<Object>();
CompModule u = this;
if (name.startsWith("this/"))
name = name.substring(5);
for (int level = 0; ; level++) {
int i = name.indexOf('/');
if (i < 0) {
if ((r & 1) != 0) {
Sig x = u.sigs.get(name);
if (x != null)
if (level == 0 || x.isPrivate == null)
ans.add(x);
}
if ((r & 2) != 0) {
Expr x = u.asserts.get(name);
if (x != null)
ans.add(x);
}
if ((r & 4) != 0) {
ArrayList<Func> x = u.funcs.get(name);
if (x != null)
for (Func y : x) if (level == 0 || y.isPrivate == null)
ans.add(y);
}
if (ans.size() == 0)
// If nothing at this
return u.getRawNQS(this, r, name);
// from this module
return ans;
}
String alias = name.substring(0, i);
Open uu = u.opens.get(alias);
if (uu == null || uu.realModule == null)
// may happen during the initial "module"
return ans;
if (level > 0 && uu.isPrivate)
// that means the module is imported privately
return ans;
u = uu.realModule;
name = name.substring(i + 1);
}
}
use of edu.mit.csail.sdg.ast.Expr in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveMeta.
// ============================================================================================================================//
private static void resolveMeta(final CompModule root) throws Err {
// Now, add the meta sigs and fields if needed
Map<Sig, PrimSig> sig2meta = new LinkedHashMap<Sig, PrimSig>();
Map<Field, PrimSig> field2meta = new LinkedHashMap<Field, PrimSig>();
boolean hasMetaSig = false, hasMetaField = false;
root.new2old.put(root.metaSig, root.metaSig);
root.sigs.put(base(root.metaSig), root.metaSig);
root.new2old.put(root.metaField, root.metaField);
root.sigs.put(base(root.metaField), root.metaField);
for (CompModule m : root.allModules) for (Sig s : new ArrayList<Sig>(m.sigs.values())) if (m != root || (s != root.metaSig && s != root.metaField)) {
PrimSig ka = new PrimSig(s.label + "$", root.metaSig, Attr.ONE, PRIVATE.makenull(s.isPrivate), Attr.META);
sig2meta.put(s, ka);
ka.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "value", s);
m.new2old.put(ka, ka);
m.sigs.put(base(ka), ka);
hasMetaSig = true;
Expr allfields = ExprConstant.EMPTYNESS;
for (Field field : s.getFields()) {
Pos priv = field.isPrivate;
if (priv == null)
priv = s.isPrivate;
PrimSig kb = new PrimSig(s.label + "$" + field.label, root.metaField, Attr.ONE, PRIVATE.makenull(priv), Attr.META);
field2meta.put(field, kb);
m.new2old.put(kb, kb);
m.sigs.put(base(kb), kb);
hasMetaField = true;
kb.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "value", field);
if (allfields == ExprConstant.EMPTYNESS)
allfields = kb;
else
allfields = allfields.plus(kb);
}
ka.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "fields", allfields);
}
for (Map.Entry<Sig, PrimSig> e : sig2meta.entrySet()) {
Expr expr = null;
if ((e.getKey()) instanceof PrimSig) {
PrimSig a = (PrimSig) (e.getKey());
if (a.parent != null && a.parent != UNIV)
expr = sig2meta.get(a.parent);
}
e.getValue().addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "parent", (expr == null ? ExprConstant.EMPTYNESS : expr));
}
for (Map.Entry<Sig, PrimSig> e : sig2meta.entrySet()) {
Sig s = e.getKey();
PrimSig s2 = e.getValue();
Expr allfields = ExprConstant.EMPTYNESS;
for (Field f : s.getFields()) {
PrimSig metaF = field2meta.get(f);
if (allfields == ExprConstant.EMPTYNESS)
allfields = metaF;
else
allfields = allfields.plus(metaF);
}
if (s instanceof PrimSig)
for (Sig c : (((PrimSig) s).descendents())) for (Field f : c.getFields()) {
PrimSig metaF = field2meta.get(f);
if (allfields == ExprConstant.EMPTYNESS)
allfields = metaF;
else
allfields = allfields.plus(metaF);
}
s2.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "subfields", allfields);
}
if (hasMetaSig == false)
root.facts.add(new Pair<String, Expr>("sig$fact", root.metaSig.no().and(root.metaField.no())));
else if (hasMetaField == false)
root.facts.add(new Pair<String, Expr>("sig$fact", root.metaField.no()));
}
use of edu.mit.csail.sdg.ast.Expr in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveAssertions.
/**
* Each assertion name now points to a typechecked Expr rather than an
* untypechecked Exp.
*/
private JoinableList<Err> resolveAssertions(A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
Context cx = new Context(this, warns);
for (Map.Entry<String, Expr> e : asserts.entrySet()) {
Expr expr = e.getValue();
expr = cx.check(expr).resolve_as_formula(warns);
if (expr.errors.isEmpty()) {
e.setValue(expr);
rep.typecheck("Assertion " + e.getKey() + ": " + expr.type() + "\n");
} else
errors = errors.make(expr.errors);
}
return errors;
}
use of edu.mit.csail.sdg.ast.Expr in project org.alloytools.alloy by AlloyTools.
the class CompModule method addOpen.
/**
* Add an OPEN declaration.
*/
void addOpen(Pos pos, Pos isPrivate, ExprVar name, List<ExprVar> args, ExprVar alias) throws Err {
if (status > 2)
throw new ErrorSyntax(pos, "The \"open\" declaration must occur before any\n" + "sig/pred/fun/fact/assert/check/run command.");
String as = (alias == null ? "" : alias.label);
if (name.label.length() == 0)
throw new ErrorSyntax(name.span(), "The filename cannot be empty.");
if (as.indexOf('$') >= 0)
throw new ErrorSyntax(alias == null ? null : alias.span(), "Alias must not contain the \'$\' character");
if (as.indexOf('@') >= 0)
throw new ErrorSyntax(alias == null ? null : alias.span(), "Alias must not contain the \'@\' character");
if (as.indexOf('/') >= 0)
throw new ErrorSyntax(alias == null ? null : alias.span(), "Alias must not contain the \'/\' character");
if (as.length() == 0) {
as = "open$" + (1 + opens.size());
if (args == null || args.size() == 0) {
for (int i = 0; ; i++) {
if (i >= name.label.length()) {
as = name.label;
break;
}
char c = name.label.charAt(i);
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
continue;
if (i == 0)
break;
if (!(c >= '0' && c <= '9') && c != '_' && c != '\'' && c != '\"')
break;
}
}
}
final TempList<String> newlist = new TempList<String>(args == null ? 0 : args.size());
if (args != null)
for (int i = 0; i < args.size(); i++) {
ExprVar arg = args.get(i);
if (arg.label.length() == 0)
throw new ErrorSyntax(arg.span(), "Argument cannot be empty.");
if (arg.label.indexOf('@') >= 0)
throw new ErrorSyntax(arg.span(), "Argument cannot contain the \'@\' chracter.");
newlist.add(arg.label);
}
Open x = opens.get(as);
if (x != null) {
// we allow this, especially because of util/sequniv
if (x.args.equals(newlist.makeConst()) && x.filename.equals(name.label))
return;
throw new ErrorSyntax(pos, "You cannot import two different modules\n" + "using the same alias.");
}
List<Expr> expressions = new ArrayList<>(args == null ? Collections.emptySet() : args);
expressions.add(0, name);
expressions.add(alias);
x = new Open(pos, isPrivate != null, as, newlist.makeConst(), name.label, expressions);
opens.put(as, x);
}
Aggregations