@Override protected Type doTypecheck(Environment env, Optional<Type> expected) { this.resolve(env); Type matchOverType = matchingOver.typecheck(env, expected); // System.out.println("env = " + env); // System.out.println("matchingOver = " + matchingOver); // System.out.println("matchOverType = " + matchOverType); if (!(matchingOver instanceof Variable)) { throw new RuntimeException("Can only match over variable"); } // Variable v = (Variable) matchingOver; // System.out.println("v = " + v); // System.out.println("v.getType()=" + v.getType()); StaticTypeBinding staticBinding = getStaticTypeBinding(matchingOver, env); // System.out.println(staticBinding); /* if (staticBinding == null) { throw new RuntimeException("variable matching over must be statically tagged"); } */ // Variable we're matching must exist and be a tagged type // String typeName = getTypeName(matchOverType); TaggedInfo matchTaggedInfo = TaggedInfo.lookupTagByType(matchOverType); // FIXME: // System.out.println(matchOverType); if (matchTaggedInfo == null) { ToolError.reportError(ErrorMessage.TYPE_NOT_TAGGED, matchingOver, matchOverType.toString()); } // System.out.println(matchTaggedInfo); matchTaggedInfo.resolve(env, this); // System.out.println(matchTaggedInfo); checkNotMultipleDefaults(); checkDefaultLast(); Type returnType = typecheckCases(env, expected); checkAllCasesAreTagged(env); checkAllCasesAreUnique(); checkSubtagsPreceedSupertags(); // ONLY FOR STATICS FIXME: // System.out.println(env); if (staticBinding != null) { NameBinding nb = env.lookup(staticBinding.getTypeName()); if (nb != null) { checkStaticSubtags(TaggedInfo.lookupTagByType(nb.getType())); // matchTaggedInfo checkBoundedAndUnbounded(TaggedInfo.lookupTagByType(nb.getType())); // matchTaggedInfo } } // If we've omitted default, we must included all possible sub-tags if (defaultCase == null) { // first, the variables tag must use comprised-of! // next, the match cases must include all those in the comprises-of list if (true) {} } // If we've included default, we can't have included all subtags for a tag using comprised-of if (defaultCase != null) { // We only care if tag specifies comprises-of if (matchTaggedInfo.hasComprises()) { // all subtags were specified, error if (comprisesSatisfied(matchTaggedInfo)) { // ToolError.reportError(ErrorMessage.DEFAULT_PRESENT, matchingOver); } } } // System.out.println(expected); if (returnType == null) { if (defaultCase != null) { if (!expected.equals(Optional.empty())) { // System.out.println(defaultCase.getAST().getType()); // System.out.println(expected.get()); if (!expected.get().equals(defaultCase.getAST().getType())) { ToolError.reportError(ErrorMessage.MATCH_NO_COMMON_RETURN, this); return null; } } } } return returnType; }