diff --git a/src/main/java/de/tla2b/analysis/TypeChecker.java b/src/main/java/de/tla2b/analysis/TypeChecker.java index 101dbb429b7d2d2bf93364e31740d052f615a599..d02927d87c4f0c31b8e6452e8b6cca3d316aff71 100644 --- a/src/main/java/de/tla2b/analysis/TypeChecker.java +++ b/src/main/java/de/tla2b/analysis/TypeChecker.java @@ -1119,24 +1119,18 @@ public class TypeChecker extends BuiltInOPs implements BBuildIns, TranslationGlo case B_OPCODE_gt: // > case B_OPCODE_lt: // < case B_OPCODE_leq: // <= - case B_OPCODE_geq: // >= - { - try { - BoolType.getInstance().unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException(String.format("Expected %s, found BOOL at '%s',%n%s", expected, - n.getOperator().getName(), n.getLocation())); - } + case B_OPCODE_geq: { // >= + TLAType boolType = unify(BoolType.getInstance(), expected, n); try { - for (int i = 0; i < n.getArgs().length; i++) { - visitExprOrOpArgNode(n.getArgs()[i], IntType.getInstance()); + for (ExprOrOpArgNode arg : n.getArgs()) { + visitExprOrOpArgNode(arg, IntType.getInstance()); } } catch (TypeErrorException e) { - for (int i = 0; i < n.getArgs().length; i++) { - visitExprOrOpArgNode(n.getArgs()[i], RealType.getInstance()); + for (ExprOrOpArgNode arg : n.getArgs()) { + visitExprOrOpArgNode(arg, RealType.getInstance()); } } - return BoolType.getInstance(); + return boolType; } // arithmetic operators: support both integers and reals @@ -1151,96 +1145,49 @@ public class TypeChecker extends BuiltInOPs implements BBuildIns, TranslationGlo try { IntType.getInstance().unify(expected); // throws UnificationException type = IntType.getInstance(); - for (int i = 0; i < n.getArgs().length; i++) { + for (ExprOrOpArgNode arg : n.getArgs()) { // throws TypeErrorException; check whether IntType is OK, else try the same with RealType - visitExprOrOpArgNode(n.getArgs()[i], type); + visitExprOrOpArgNode(arg, type); } } catch (UnificationException | TypeErrorException e) { - try { - RealType.getInstance().unify(expected); - type = RealType.getInstance(); - for (int i = 0; i < n.getArgs().length; i++) { - // if TypeErrorException is thrown here, the type is incompatible and it is a real type error! - visitExprOrOpArgNode(n.getArgs()[i], type); - } - } catch (UnificationException ue) { - throw new TypeErrorException(String.format("Expected %s, found INTEGER at '%s',%n%s", expected, - n.getOperator().getName(), n.getLocation())); + type = unify(RealType.getInstance(), expected, n); + for (ExprOrOpArgNode arg : n.getArgs()) { + // if TypeErrorException is thrown here, the type is incompatible and it is a real type error! + visitExprOrOpArgNode(arg, type); } } - return type; } case B_OPCODE_realdiv: { // / - try { - RealType.getInstance().unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException(String.format("Expected %s, found REAL at '%s',%n%s", expected, - n.getOperator().getName(), n.getLocation())); + TLAType realType = unify(RealType.getInstance(), expected, n); + for (ExprOrOpArgNode arg : n.getArgs()) { + visitExprOrOpArgNode(arg, realType); } - for (int i = 0; i < n.getArgs().length; i++) { - visitExprOrOpArgNode(n.getArgs()[i], RealType.getInstance()); - } - return RealType.getInstance(); + return realType; } - case B_OPCODE_dotdot: // .. - { - try { - expected.unify(new SetType(IntType.getInstance())); - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found POW(INTEGER) at '..',%n%s", expected, n.getLocation())); - } - - for (int i = 0; i < n.getArgs().length; i++) { - visitExprOrOpArgNode(n.getArgs()[i], IntType.getInstance()); + case B_OPCODE_dotdot: { // .. + TLAType type = unify(new SetType(IntType.getInstance()), expected, n); + for (ExprOrOpArgNode arg : n.getArgs()) { + visitExprOrOpArgNode(arg, IntType.getInstance()); } - return new SetType(IntType.getInstance()); + return type; } case B_OPCODE_nat: // Nat - { - try { - SetType found = new SetType(IntType.getInstance()); - found = found.unify(expected); - return found; - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found POW(INTEGER) at 'Nat',%n%s", expected, n.getLocation())); - } - } + return unify(new SetType(IntType.getInstance()), expected, n); /* - * Standard Module Integers + * Standard Module Integers / Reals */ case B_OPCODE_int: // Int - { - try { - SetType found = new SetType(IntType.getInstance()); - found = found.unify(expected); - return found; - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found POW(INTEGER) at 'Int',%n%s", expected, n.getLocation())); - } - } + return unify(new SetType(IntType.getInstance()), expected, n); case B_OPCODE_real: // Real - { - try { - SetType found = new SetType(RealType.getInstance()); - found = found.unify(expected); - return found; - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found POW(REAL) at 'Real',%n%s", expected, n.getLocation())); - } - } + return unify(new SetType(RealType.getInstance()), expected, n); - case B_OPCODE_uminus: // -x - { + case B_OPCODE_uminus: { // -x TLAType type; try { IntType.getInstance().unify(expected); // throws UnificationException @@ -1248,126 +1195,67 @@ public class TypeChecker extends BuiltInOPs implements BBuildIns, TranslationGlo // throws TypeErrorException; check whether IntType is OK, else try the same with RealType visitExprOrOpArgNode(n.getArgs()[0], type); } catch (UnificationException | TypeErrorException e) { - try { - RealType.getInstance().unify(expected); - type = RealType.getInstance(); - // if TypeErrorException is thrown here, the type is incompatible and it is a real type error! - visitExprOrOpArgNode(n.getArgs()[0], type); - } catch (UnificationException ue) { - throw new TypeErrorException( - String.format("Expected %s, found INTEGER at '-',%n%s", expected, n.getLocation())); - } + type = unify(RealType.getInstance(), expected, n); + // if TypeErrorException is thrown here, the type is incompatible and it is a real type error! + visitExprOrOpArgNode(n.getArgs()[0], type); } - return type; } /* * Standard Module FiniteSets */ - case B_OPCODE_finite: // IsFiniteSet - { - try { - BoolType.getInstance().unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found BOOL at 'IsFiniteSet',%n%s", expected, n.getLocation())); - } + case B_OPCODE_finite: { // IsFiniteSet + TLAType boolType = unify(BoolType.getInstance(), expected, n); visitExprOrOpArgNode(n.getArgs()[0], new SetType(new UntypedType())); - return BoolType.getInstance(); + return boolType; } - case B_OPCODE_card: // Cardinality - { - try { - IntType.getInstance().unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found INTEGER at 'Cardinality',%n%s", expected, n.getLocation())); - } + case B_OPCODE_card: { // Cardinality + TLAType intType = unify(IntType.getInstance(), expected, n); visitExprOrOpArgNode(n.getArgs()[0], new SetType(new UntypedType())); - return IntType.getInstance(); + return intType; } /* * Standard Module Sequences */ case B_OPCODE_seq: { // Seq(S) - set of sequences, S must be a set - SetType S = (SetType) visitExprOrOpArgNode(n.getArgs()[0], new SetType(new UntypedType())); - SetType set_of_seq = new SetType(new FunctionType(IntType.getInstance(), S.getSubType())); - try { - set_of_seq = set_of_seq.unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found %s at 'Seq',%n%s", expected, set_of_seq, n.getLocation())); - } - return set_of_seq; + return unify(set_of_seq, expected, n); } case B_OPCODE_len: { // length of the sequence - try { - IntType.getInstance().unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found INTEGER at 'Len',%n%s", expected, n.getLocation())); - } - visitExprOrOpArgNode(n.getArgs()[0], new FunctionType(IntType.getInstance(), new UntypedType())); - return IntType.getInstance(); + TLAType intType = unify(IntType.getInstance(), expected, n); + visitExprOrOpArgNode(n.getArgs()[0], new FunctionType(intType, new UntypedType())); + return intType; } case B_OPCODE_conc: { // s \o s2 - concatenation of s and s2 TLAType found = new FunctionType(IntType.getInstance(), new UntypedType()); found = visitExprOrOpArgNode(n.getArgs()[0], found); found = visitExprOrOpArgNode(n.getArgs()[1], found); - try { - found = found.unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found POW(INTEGER*_A) at '\\o',%n%s", expected, n.getLocation())); - } - return found; + return unify(found, expected, n); } - case B_OPCODE_append: // Append(s, e) - { + case B_OPCODE_append: { // Append(s, e) FunctionType found = new FunctionType(IntType.getInstance(), new UntypedType()); found = (FunctionType) visitExprOrOpArgNode(n.getArgs()[0], found); visitExprOrOpArgNode(n.getArgs()[1], found.getRange()); - try { - found = (FunctionType) found.unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found %s at 'Append',%n%s", expected, found, n.getLocation())); - } - return found; + return unify(found, expected, n); } case B_OPCODE_head: { // HEAD(s) - the first element of the sequence FunctionType func = new FunctionType(IntType.getInstance(), new UntypedType()); func = (FunctionType) visitExprOrOpArgNode(n.getArgs()[0], func); - - TLAType found = func.getRange(); - try { - found = found.unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found %s at 'Head',%n%s", expected, found, n.getLocation())); - } - return found; + return unify(func.getRange(), expected, n); } case B_OPCODE_tail: { // Tail(s) FunctionType found = new FunctionType(IntType.getInstance(), new UntypedType()); found = (FunctionType) visitExprOrOpArgNode(n.getArgs()[0], found); - try { - found = (FunctionType) found.unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found %s at 'Tail',%n%s", expected, found, n.getLocation())); - } - return found; + return unify(found, expected, n); } case B_OPCODE_subseq: { // SubSeq(s,m,n) @@ -1375,13 +1263,7 @@ public class TypeChecker extends BuiltInOPs implements BBuildIns, TranslationGlo found = visitExprOrOpArgNode(n.getArgs()[0], found); visitExprOrOpArgNode(n.getArgs()[1], IntType.getInstance()); visitExprOrOpArgNode(n.getArgs()[2], IntType.getInstance()); - try { - found = found.unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found %s at 'SubSeq',%n%s", expected, found, n.getLocation())); - } - return found; + return unify(found, expected, n); } // TODO add BSeq to tla standard modules @@ -1389,116 +1271,57 @@ public class TypeChecker extends BuiltInOPs implements BBuildIns, TranslationGlo /* * Standard Module TLA2B */ - case B_OPCODE_min: // MinOfSet(S) case B_OPCODE_max: // MaxOfSet(S) case B_OPCODE_setprod: // SetProduct(S) - case B_OPCODE_setsum: // SetSummation(S) - { + case B_OPCODE_setsum: { // SetSummation(S) // TODO: do we need support for Reals here? - try { - IntType.getInstance().unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException(String.format("Expected %s, found INTEGER at '%s',%n%s", expected, - n.getOperator().getName(), n.getLocation())); - } - visitExprOrOpArgNode(n.getArgs()[0], new SetType(IntType.getInstance())); - return IntType.getInstance(); + TLAType intType = unify(IntType.getInstance(), expected, n); + visitExprOrOpArgNode(n.getArgs()[0], new SetType(intType)); + return intType; } case B_OPCODE_permseq: { // PermutedSequences(S) SetType argType = (SetType) visitExprOrOpArgNode(n.getArgs()[0], new SetType(new UntypedType())); SetType found = new SetType(new FunctionType(IntType.getInstance(), argType.getSubType())); - try { - found = found.unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException(String.format("Expected %s, found %s at 'PermutedSequences',%n%s", - expected, found, n.getLocation())); - } - return found; + return unify(found, expected, n); } /* * Standard Module TLA2B */ - case B_OPCODE_pow1: // POW1 - { - + case B_OPCODE_pow1: { // POW1 SetType set = new SetType(new UntypedType()); set = (SetType) visitExprOrOpArgNode(n.getArgs()[0], set); SetType found = new SetType(set); - try { - found = found.unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException(String.format("Expected %s, found %s at '%s',%n%s", expected, found, - n.getOperator().getName(), n.getLocation())); - } - return found; + return unify(found, expected, n); } /* * Standard Module Relations */ - case B_OPCODE_rel_inverse: // POW1 - { + case B_OPCODE_rel_inverse: { // POW1 SetType set = new SetType(new TupleType(2)); set = (SetType) visitExprOrOpArgNode(n.getArgs()[0], set); TupleType t = (TupleType) set.getSubType(); - ArrayList<TLAType> list = new ArrayList<>(); - list.add(t.getTypes().get(1)); - list.add(t.getTypes().get(0)); + List<TLAType> list = Arrays.asList(t.getTypes().get(1), t.getTypes().get(0)); SetType found = new SetType(new TupleType(list)); - try { - found = found.unify(expected); - } catch (UnificationException e) { - throw new TypeErrorException(String.format("Expected %s, found %s at '%s',%n%s", expected, found, - n.getOperator().getName(), n.getLocation())); - } - return found; + return unify(found, expected, n); } /* * TLA+ Built-Ins, but not in tlc.tool.BuiltInOPs */ case B_OPCODE_bool: // BOOLEAN - try { - SetType found = new SetType(BoolType.getInstance()); - found = found.unify(expected); - return found; - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found POW(BOOL) at 'BOOLEAN',%n%s", expected, n.getLocation())); - } + return unify(new SetType(BoolType.getInstance()), expected, n); case B_OPCODE_string: // STRING - try { - SetType found = new SetType(StringType.getInstance()); - found = found.unify(expected); - return found; - } catch (UnificationException e) { - throw new TypeErrorException( - String.format("Expected %s, found POW(STRING) at 'STRING',%n%s", expected, n.getLocation())); - } + return unify(new SetType(StringType.getInstance()), expected, n); case B_OPCODE_true: case B_OPCODE_false: - try { - BoolType.getInstance().unify(expected); - return BoolType.getInstance(); - } catch (Exception e) { - throw new TypeErrorException(String.format("Expected %s, found BOOL at '%s',%n%s", expected, - n.getOperator().getName(), n.getLocation())); - } - - case B_OPCODE_assert: { - try { - BoolType.getInstance().unify(expected); - return BoolType.getInstance(); - } catch (Exception e) { - throw new TypeErrorException(String.format("Expected %s, found BOOL at '%s',%n%s", expected, - n.getOperator().getName(), n.getLocation())); - } - } + case B_OPCODE_assert: + return unify(BoolType.getInstance(), expected, n); default: { throw new NotImplementedException(n.getOperator().getName().toString());