Search in sources :

Example 51 with Err

use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.

the class CompModule method addFunc.

/**
 * Add a FUN or PRED declaration.
 */
void addFunc(Pos p, Pos isPrivate, String n, Expr f, List<Decl> decls, Expr t, Expr v) throws Err {
    if (decls == null)
        decls = new ArrayList<Decl>();
    else
        decls = new ArrayList<Decl>(decls);
    if (f != null)
        decls.add(0, new Decl(null, null, null, Util.asList(ExprVar.make(f.span(), "this")), f));
    for (Decl d : decls) {
        if (d.isPrivate != null) {
            ExprHasName name = d.names.get(0);
            throw new ErrorSyntax(d.isPrivate.merge(name.pos), "Function parameter \"" + name.label + "\" is always private already.");
        }
        if (d.disjoint2 != null) {
            ExprHasName name = d.names.get(d.names.size() - 1);
            throw new ErrorSyntax(d.disjoint2.merge(name.pos), "Function parameter \"" + name.label + "\" cannot be bound to a 'disjoint' expression.");
        }
    }
    status = 3;
    dup(p, n, false);
    ExprHasName dup = Decl.findDuplicateName(decls);
    if (dup != null)
        throw new ErrorSyntax(dup.span(), "The parameter name \"" + dup.label + "\" cannot appear more than once.");
    Func ans = new Func(p, isPrivate, n, decls, t, v);
    ArrayList<Func> list = funcs.get(n);
    if (list == null) {
        list = new ArrayList<Func>();
        funcs.put(n, list);
    }
    list.add(ans);
}
Also used : ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) Func(edu.mit.csail.sdg.ast.Func) ExprHasName(edu.mit.csail.sdg.ast.ExprHasName) ArrayList(java.util.ArrayList) Decl(edu.mit.csail.sdg.ast.Decl)

Example 52 with Err

use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.

the class CompModule method resolveFuncDecls.

/**
 * Each FunAST will now point to a bodyless Func object.
 */
private JoinableList<Err> resolveFuncDecls(A4Reporter rep, JoinableList<Err> errors, List<ErrorWarning> warns) throws Err {
    for (ArrayList<Func> list : funcs.values()) {
        for (int listi = 0; listi < list.size(); listi++) {
            Func f = list.get(listi);
            String fullname = (path.length() == 0 ? "this/" : (path + "/")) + f.label;
            // Each PARAMETER can refer to earlier parameter in the same
            // function, and any SIG or FIELD visible from here.
            // Each RETURNTYPE can refer to the parameters of the same
            // function, and any SIG or FIELD visible from here.
            Context cx = new Context(this, warns);
            cx.rootfunparam = true;
            TempList<Decl> tmpdecls = new TempList<Decl>();
            boolean err = false;
            for (Decl d : f.decls) {
                TempList<ExprVar> tmpvars = new TempList<ExprVar>();
                Expr val = cx.check(d.expr).resolve_as_set(warns);
                if (!val.errors.isEmpty()) {
                    err = true;
                    errors = errors.make(val.errors);
                }
                for (ExprHasName n : d.names) {
                    ExprVar v = ExprVar.make(n.span(), n.label, val.type());
                    cx.put(n.label, v);
                    tmpvars.add(v);
                    rep.typecheck((f.isPred ? "pred " : "fun ") + fullname + ", Param " + n.label + ": " + v.type() + "\n");
                }
                tmpdecls.add(new Decl(d.isPrivate, d.disjoint, d.disjoint2, tmpvars.makeConst(), val));
            }
            Expr ret = null;
            if (!f.isPred) {
                ret = cx.check(f.returnDecl).resolve_as_set(warns);
                if (!ret.errors.isEmpty()) {
                    err = true;
                    errors = errors.make(ret.errors);
                }
            }
            if (err)
                continue;
            try {
                f = new Func(f.pos, f.isPrivate, fullname, tmpdecls.makeConst(), ret, f.getBody());
                list.set(listi, f);
                rep.typecheck("" + f + ", RETURN: " + f.returnDecl.type() + "\n");
            } catch (Err ex) {
                errors = errors.make(ex);
            }
        }
    }
    return errors;
}
Also used : ExprVar(edu.mit.csail.sdg.ast.ExprVar) Err(edu.mit.csail.sdg.alloy4.Err) Func(edu.mit.csail.sdg.ast.Func) Decl(edu.mit.csail.sdg.ast.Decl) TempList(edu.mit.csail.sdg.alloy4.ConstList.TempList) Expr(edu.mit.csail.sdg.ast.Expr) ExprHasName(edu.mit.csail.sdg.ast.ExprHasName)

Example 53 with Err

use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.

the class CompModule method populate.

/**
 * Resolve the name based on the current context and this module.
 */
private Expr populate(TempList<Expr> ch, TempList<String> re, Decl rootfield, Sig rootsig, boolean rootfunparam, Func rootfunbody, Pos pos, String fullname, Expr THIS) {
    // Return object can be Func(with > 0 arguments) or Expr
    final String name = (fullname.charAt(0) == '@') ? fullname.substring(1) : fullname;
    boolean fun = (rootsig != null && (rootfield == null || rootfield.expr.mult() == ExprUnary.Op.EXACTLYOF)) || (rootsig == null && !rootfunparam);
    if (name.equals("univ"))
        return ExprUnary.Op.NOOP.make(pos, UNIV);
    if (name.equals("Int"))
        return ExprUnary.Op.NOOP.make(pos, SIGINT);
    if (name.equals("seq/Int"))
        return ExprUnary.Op.NOOP.make(pos, SEQIDX);
    if (name.equals("String"))
        return ExprUnary.Op.NOOP.make(pos, STRING);
    if (name.equals("none"))
        return ExprUnary.Op.NOOP.make(pos, NONE);
    if (name.equals("iden"))
        return ExprConstant.Op.IDEN.make(pos, 0);
    if (name.equals("sig$") || name.equals("field$"))
        if (world != null) {
            Sig s = world.sigs.get(name);
            if (s != null)
                return ExprUnary.Op.NOOP.make(pos, s);
        }
    final List<Object> ans = name.indexOf('/') >= 0 ? getRawQS(fun ? 5 : 1, name) : getRawNQS(this, fun ? 5 : 1, name);
    final Sig param = params.get(name);
    if (param != null && !ans.contains(param))
        ans.add(param);
    for (Object x : ans) {
        if (x instanceof Sig) {
            Sig y = (Sig) x;
            ch.add(ExprUnary.Op.NOOP.make(pos, y, null, 0));
            re.add("sig " + y.label);
        } else if (x instanceof Func) {
            Func f = (Func) x;
            int fn = f.count();
            int penalty = 0;
            if (resolution == 1 && fn > 0 && rootsig != null && THIS != null && THIS.type().hasArity(1) && f.get(0).type().intersects(THIS.type())) {
                // If we're inside a sig, and there is a unary variable
                // bound to "this",
                // we should consider it as a possible FIRST ARGUMENT of a
                // fun/pred call
                ConstList<Expr> t = Util.asList(THIS);
                // penalty
                ch.add(fn == 1 ? ExprCall.make(pos, null, f, t, 1 + penalty) : ExprBadCall.make(pos, null, f, t, 1 + penalty));
                // of
                // 1
                re.add((f.isPred ? "pred this." : "fun this.") + f.label);
            }
            if (resolution == 1) {
                ch.add(fn == 0 ? ExprCall.make(pos, null, f, null, penalty) : ExprBadCall.make(pos, null, f, null, penalty));
                re.add((f.isPred ? "pred " : "fun ") + f.label);
            }
            if (resolution == 2 && f != rootfunbody && THIS != null && fullname.charAt(0) != '@' && fn > 0 && f.get(0).type().intersects(THIS.type())) {
                // If there is some value bound to "this", we should
                // consider it as a possible FIRST ARGUMENT of a fun/pred
                // call
                ConstList<Expr> t = Util.asList(THIS);
                ch.add(fn == 1 ? ExprCall.make(pos, null, f, t, 0) : ExprBadCall.make(pos, null, f, t, 0));
                re.add((f.isPred ? "pred this." : "fun this.") + f.label);
            }
            if (resolution != 1) {
                ch.add(fn == 0 ? ExprCall.make(pos, null, f, null, 0) : ExprBadCall.make(pos, null, f, null, 0));
                re.add((f.isPred ? "pred " : "fun ") + f.label);
            }
        }
    }
    // All else: we can call, and can refer to anything visible.
    for (CompModule m : getAllNameableModules()) for (Sig s : m.sigs.values()) if (m == this || s.isPrivate == null)
        for (Field f : s.getFields()) if (f.isMeta == null && (m == this || f.isPrivate == null) && f.label.equals(name))
            if (resolution == 1) {
                Expr x = null;
                if (rootsig == null) {
                    x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
                } else if (rootsig.isSameOrDescendentOf(f.sig)) {
                    x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
                    if (fullname.charAt(0) != '@')
                        x = THIS.join(x);
                } else if (rootfield == null || rootfield.expr.mult() == ExprUnary.Op.EXACTLYOF) {
                    x = ExprUnary.Op.NOOP.make(pos, f, null, 1);
                }
                // penalty of 1
                if (x != null) {
                    ch.add(x);
                    re.add("field " + f.sig.label + " <: " + f.label);
                }
            } else if (rootfield == null || rootsig.isSameOrDescendentOf(f.sig)) {
                Expr x0 = ExprUnary.Op.NOOP.make(pos, f, null, 0);
                if (resolution == 2 && THIS != null && fullname.charAt(0) != '@' && f.type().firstColumnOverlaps(THIS.type())) {
                    ch.add(THIS.join(x0));
                    re.add("field " + f.sig.label + " <: this." + f.label);
                    if (rootsig != null)
                        continue;
                }
                ch.add(x0);
                re.add("field " + f.sig.label + " <: " + f.label);
            }
    if (metaSig() != null && (rootsig == null || rootfield == null)) {
        SafeList<PrimSig> children = null;
        try {
            children = metaSig().children();
        } catch (Err err) {
            return null;
        }
        // exception NOT possible
        for (PrimSig s : children) for (Field f : s.getFields()) if (f.label.equals(name)) {
            Expr x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
            ch.add(x);
            re.add("field " + f.sig.label + " <: " + f.label);
        }
    }
    if (metaField() != null && (rootsig == null || rootfield == null)) {
        SafeList<PrimSig> children = null;
        try {
            children = metaField().children();
        } catch (Err err) {
            return null;
        }
        // exception NOT possible
        for (PrimSig s : children) for (Field f : s.getFields()) if (f.label.equals(name)) {
            Expr x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
            ch.add(x);
            re.add("field " + f.sig.label + " <: " + f.label);
        }
    }
    return null;
}
Also used : Err(edu.mit.csail.sdg.alloy4.Err) Func(edu.mit.csail.sdg.ast.Func) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) Sig(edu.mit.csail.sdg.ast.Sig) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) Field(edu.mit.csail.sdg.ast.Sig.Field) Expr(edu.mit.csail.sdg.ast.Expr) ConstList(edu.mit.csail.sdg.alloy4.ConstList) PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig)

Example 54 with Err

use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.

the class CompModule method resolveParams.

/**
 * Every param in every module will now point to a nonnull Sig.
 */
private static void resolveParams(A4Reporter rep, List<CompModule> modules) throws Err {
    while (true) {
        boolean chg = false;
        Open missing = null;
        String missingName = "";
        for (CompModule mod : modules) for (Open open : mod.opens.values()) {
            CompModule sub = open.realModule;
            if (open.args.size() != sub.params.size())
                throw new ErrorSyntax(open.pos, "You supplied " + open.args.size() + " arguments to the open statement, but the imported module requires " + sub.params.size() + " arguments.");
            int i = 0;
            for (Map.Entry<String, Sig> p : sub.params.entrySet()) {
                Sig old = p.getValue();
                String kn = p.getKey(), vn = open.args.get(i);
                i++;
                Sig vv = mod.getRawSIG(open.pos, vn);
                if (vv == null) {
                    if (old == null) {
                        missing = open;
                        missingName = vn;
                    }
                    continue;
                }
                if (old == vv)
                    continue;
                if (old != null)
                    throw new ErrorFatal(open.pos, "Internal error (module re-instantiated with different arguments)");
                if (vv == NONE)
                    throw new ErrorSyntax(open.pos, "You cannot use \"none\" as an instantiating argument.");
                chg = true;
                p.setValue(vv);
                rep.parse("RESOLVE: " + (sub.path.length() == 0 ? "this/" : sub.path) + "/" + kn + " := " + vv + "\n");
            }
        }
        if (!chg && missing == null)
            return;
        if (!chg)
            throw new ErrorSyntax(missing.pos, "The signature name \"" + missingName + "\" cannot be found.");
    }
}
Also used : PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) Sig(edu.mit.csail.sdg.ast.Sig) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) ErrorFatal(edu.mit.csail.sdg.alloy4.ErrorFatal)

Example 55 with Err

use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.

the class CompModule method unique.

/**
 * Throw an exception if there are more than 1 match; return nonnull if only one
 * match; return null if no match.
 */
private Object unique(Pos pos, String name, List<Object> objs) throws Err {
    if (objs.size() == 0)
        return null;
    if (objs.size() == 1)
        return objs.get(0);
    StringBuilder msg = new StringBuilder("The name \"").append(name);
    msg.append("\" is ambiguous.\n" + "There are ").append(objs.size()).append(" choices:");
    for (int i = 0; i < objs.size(); i++) {
        msg.append("\n\n#").append(i + 1).append(": ");
        Object x = objs.get(i);
        if (x instanceof Sig) {
            Sig y = (Sig) x;
            msg.append("sig ").append(y.label).append("\n" + "at ").append(y.pos.toShortString());
        } else if (x instanceof Func) {
            Func y = (Func) x;
            msg.append(y.isPred ? "pred " : "fun ").append(y.label).append("\n" + "at ").append(y.pos.toShortString());
        } else if (x instanceof Expr) {
            Expr y = (Expr) x;
            msg.append("assertion at ").append(y.pos.toShortString());
        }
    }
    throw new ErrorSyntax(pos, msg.toString());
}
Also used : PrimSig(edu.mit.csail.sdg.ast.Sig.PrimSig) Sig(edu.mit.csail.sdg.ast.Sig) SubsetSig(edu.mit.csail.sdg.ast.Sig.SubsetSig) ErrorSyntax(edu.mit.csail.sdg.alloy4.ErrorSyntax) Expr(edu.mit.csail.sdg.ast.Expr) Func(edu.mit.csail.sdg.ast.Func)

Aggregations

ErrorSyntax (edu.mit.csail.sdg.alloy4.ErrorSyntax)32 PrimSig (edu.mit.csail.sdg.ast.Sig.PrimSig)28 ErrorFatal (edu.mit.csail.sdg.alloy4.ErrorFatal)27 Err (edu.mit.csail.sdg.alloy4.Err)25 Expr (edu.mit.csail.sdg.ast.Expr)25 Sig (edu.mit.csail.sdg.ast.Sig)24 Pos (edu.mit.csail.sdg.alloy4.Pos)16 ErrorType (edu.mit.csail.sdg.alloy4.ErrorType)15 ExprVar (edu.mit.csail.sdg.ast.ExprVar)15 SubsetSig (edu.mit.csail.sdg.ast.Sig.SubsetSig)15 ArrayList (java.util.ArrayList)15 Field (edu.mit.csail.sdg.ast.Sig.Field)12 LinkedHashMap (java.util.LinkedHashMap)10 IOException (java.io.IOException)9 TempList (edu.mit.csail.sdg.alloy4.ConstList.TempList)8 Func (edu.mit.csail.sdg.ast.Func)8 TupleSet (kodkod.instance.TupleSet)8 Command (edu.mit.csail.sdg.ast.Command)7 ErrorAPI (edu.mit.csail.sdg.alloy4.ErrorAPI)6 XMLNode (edu.mit.csail.sdg.alloy4.XMLNode)5