コード例 #1
0
ファイル: Match.java プロジェクト: taolong001/wyvern
  @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;
  }