use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.
the class CompModule method addMacro.
// ============================================================================================================================//
/**
* Add a MACRO declaration.
*/
void addMacro(Pos p, Pos isPrivate, String n, List<ExprVar> decls, Expr v) throws Err {
if (!Version.experimental)
throw new ErrorSyntax(p, "LET declaration is allowed only inside a toplevel paragraph.");
ConstList<ExprVar> ds = ConstList.make(decls);
status = 3;
dup(p, n, false);
for (int i = 0; i < ds.size(); i++) for (int j = i + 1; j < ds.size(); j++) if (ds.get(i).label.equals(ds.get(j).label))
throw new ErrorSyntax(ds.get(j).span(), "The parameter name \"" + ds.get(j).label + "\" cannot appear more than once.");
Macro ans = new Macro(p, isPrivate, this, n, ds, v);
Macro old = macros.put(n, ans);
if (old != null) {
macros.put(n, old);
throw new ErrorSyntax(p, "You cannot declare more than one macro with the same name \"" + n + "\" in the same file.");
}
}
use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.
the class CompModule method addEnum.
/**
* Add an enumeration.
*/
void addEnum(Pos pos, Pos priv, ExprVar name, List<ExprVar> atoms, Pos closingBracket) throws Err {
ExprVar EXTENDS = ExprVar.make(null, "extends");
ExprVar THIS = ExprVar.make(null, "this/" + name);
List<ExprVar> THESE = Arrays.asList(THIS);
if (atoms == null || atoms.size() == 0)
throw new ErrorSyntax(pos, "Enumeration must contain at least one name.");
addSig(name.label, null, null, null, null, WHERE.make(name.pos), ABSTRACT.make(name.pos), PRIVATE.makenull(priv), Attr.ENUM);
for (ExprVar a : atoms) addSig(a.label, EXTENDS, THESE, null, null, WHERE.make(a.pos), ONE.make(a.pos), PRIVATE.makenull(priv));
int oldStatus = status;
status = 0;
try {
addOpen(null, null, ExprVar.make(pos, "util/ordering"), Arrays.asList(THIS), null);
} finally {
status = oldStatus;
}
}
use of edu.mit.csail.sdg.alloy4.Err 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);
}
use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveFieldDecl.
// ============================================================================================================================//
private static void resolveFieldDecl(CompModule res, final A4Reporter rep, final Sig s, final List<ErrorWarning> warns, boolean defined) throws Err {
// When typechecking each field:
// * it is allowed to refer to earlier fields in the same SIG or in any
// visible ancestor sig
// * it is allowed to refer to visible sigs
// * it is NOT allowed to refer to any predicate or function
// For example, if A.als opens B.als, and B/SIGX extends A/SIGY,
// then B/SIGX's fields cannot refer to A/SIGY, nor any fields in
// A/SIGY)
final List<Decl> oldDecls = res.old2fields.get(res.new2old.get(s));
if (oldDecls == null)
return;
final CompModule m = res.sig2module.get(s);
final Context cx = new Context(m, warns);
final ExprHasName dup = Decl.findDuplicateName(oldDecls);
if (dup != null)
throw new ErrorSyntax(dup.span(), "sig \"" + s + "\" cannot have 2 fields named \"" + dup.label + "\"");
for (final Decl d : oldDecls) {
if (d.expr.mult() != ExprUnary.Op.EXACTLYOF) {
if (defined)
continue;
} else {
if (!defined)
continue;
}
// The name "this" does matter, since the parser and the typechecker
// both refer to it as "this"
cx.rootfield = d;
cx.rootsig = s;
cx.put("this", s.decl.get());
Expr bound = cx.check(d.expr).resolve_as_set(warns);
cx.remove("this");
String[] names = new String[d.names.size()];
for (int i = 0; i < names.length; i++) names[i] = d.names.get(i).label;
Field[] fields = s.addTrickyField(d.span(), d.isPrivate, d.disjoint, d.disjoint2, null, names, bound);
for (Field f : fields) {
rep.typecheck("Sig " + s + ", Field " + f.label + ": " + f.type() + "\n");
}
}
}
use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveFuncBody.
/**
* Each Func's body will now be typechecked Expr object.
*/
private JoinableList<Err> resolveFuncBody(A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
for (ArrayList<Func> entry : funcs.values()) for (Func ff : entry) {
Context cx = new Context(this, warns);
cx.rootfunbody = ff;
for (Decl d : ff.decls) for (ExprHasName n : d.names) cx.put(n.label, n);
Expr newBody = cx.check(ff.getBody());
if (ff.isPred)
newBody = newBody.resolve_as_formula(warns);
else
newBody = newBody.resolve_as_set(warns);
errors = errors.make(newBody.errors);
if (!newBody.errors.isEmpty())
continue;
try {
ff.setBody(newBody);
} catch (Err er) {
errors = errors.make(er);
continue;
}
if (warns != null && ff.returnDecl.type().hasTuple() && newBody.type().hasTuple() && !newBody.type().intersects(ff.returnDecl.type()))
warns.add(new ErrorWarning(newBody.span(), "Function return value is disjoint from its return type.\n" + "Function body has type " + newBody.type() + "\n" + "but the return type is " + ff.returnDecl.type()));
// else if (warns!=null && Version.experimental &&
// !newBody.type.isSubtypeOf(ff.returnDecl.type))
// warns.add(new ErrorWarning(newBody.span(),
// "Function may return a tuple not in its declared return
// type.\n"
// +"The Alloy Analyzer's analysis may be unsound\n"
// +"if it returns a tuple outside its declared return type.\n"
// +"Function body has type "+newBody.type+"\nbut the return
// type is "+ff.returnDecl.type));
rep.typecheck(ff.toString() + ", BODY:" + newBody.type() + "\n");
}
return errors;
}
Aggregations