コード例 #1
0
ファイル: Match.java プロジェクト: taolong001/wyvern
  /**
   * Checks that the tag we are matching over is a supertag of every tag in the case-list.
   *
   * <p>This ensures that each tag could actually have a match and that case is not unreachable
   * code.
   *
   * @param matchingOverTag
   */
  private void checkStaticSubtags(TaggedInfo matchingOver) {
    for (Case c : cases) {
      TaggedInfo matchTarget = TaggedInfo.lookupTagByType(c.getTaggedTypeMatch()); // FIXME:

      if (!isSubtag(matchTarget, matchingOver)) {
        ToolError.reportError(
            ErrorMessage.UNMATCHABLE_CASE,
            this.matchingOver,
            matchingOver.getTagName(),
            matchTarget.getTagName());
      }
    }
  }
コード例 #2
0
ファイル: Match.java プロジェクト: taolong001/wyvern
  private boolean comprisesSatisfied(TaggedInfo matchBinding) {
    List<Type> comprisesTags = matchBinding.getComprisesTags();

    // add this tag because it needs to be included too
    comprisesTags.add(matchBinding.getTagType());

    // check that each tag is present
    for (Type t : comprisesTags) {
      if (containsTagBinding(cases, t)) continue;

      // tag wasn't present
      return false;
    }

    // we made it through them all
    return true;
  }
コード例 #3
0
ファイル: Match.java プロジェクト: taolong001/wyvern
  private void checkBoundedAndUnbounded(TaggedInfo matchTaggedInfo) {

    // If we're an unbounded type, check default exists
    if (!matchTaggedInfo.hasComprises()) {
      if (defaultCase == null) {
        ToolError.reportError(ErrorMessage.UNBOUNDED_WITHOUT_DEFAULT, matchingOver);
      }
    } else {
      // we're bounded. Check if comprises is satisfied
      boolean comprisesSatisfied = comprisesSatisfied(matchTaggedInfo);

      // if comprises is satisfied, default must be excluded
      if (comprisesSatisfied && defaultCase != null) {
        ToolError.reportError(ErrorMessage.BOUNDED_EXHAUSTIVE_WITH_DEFAULT, matchingOver);
      }

      // if comprises is not satisfied, default must be present
      if (!comprisesSatisfied && defaultCase == null) {
        ToolError.reportError(ErrorMessage.BOUNDED_INEXHAUSTIVE_WITHOUT_DEFAULT, matchingOver);
      }
    }
  }
コード例 #4
0
ファイル: Match.java プロジェクト: taolong001/wyvern
  private void checkAllCasesAreTagged(Environment env) {
    // All things we match over must be tagged types
    for (Case c : cases) {
      if (c.isDefault()) continue;

      Type tagName = c.getTaggedTypeMatch();

      if (tagName instanceof UnresolvedType) {
        UnresolvedType ut = (UnresolvedType) tagName;
        // System.out.println("ut = " + ut.resolve(env));
      }

      if (tagName instanceof TypeInv) {
        // TypeInv ti = (TypeInv) tagName;
        // System.out.println("ti = " + ti.resolve(env));
        // tagName = ti.resolve(env);
        // if (tagName instanceof UnresolvedType) {
        // tagName = ((UnresolvedType) tagName).resolve(env);
        // } DO NOT UNCOMMENT THIS AS BREAKS CASES
        return; // FIXME: Assume TypeInv will sort itself out during runtime.
      }

      // System.out.println(tagName);

      // check type exists
      // TypeBinding type = env.lookupType(tagName.toString()); // FIXME:

      // if (type == null) {
      //	ToolError.reportError(ErrorMessage.TYPE_NOT_DECLARED, this, tagName.toString());
      // }

      // check it is tagged
      TaggedInfo info = TaggedInfo.lookupTagByType(tagName); // FIXME:

      if (info == null) {
        ToolError.reportError(ErrorMessage.TYPE_NOT_TAGGED, matchingOver, tagName.toString());
      }
    }
  }
コード例 #5
0
ファイル: Match.java プロジェクト: taolong001/wyvern
  // TODO: rename this method to something like isSubtag()
  private boolean isSubtag(TaggedInfo matchingOver, TaggedInfo matchTarget) {
    if (matchingOver == null) throw new NullPointerException("Matching Binding cannot be null");
    if (matchTarget == null) throw new NullPointerException("match target cannot be null");

    // String matchingOverTag = matchingOver.getTagName();
    // String matchTargetTag = matchTarget.getTagName();

    // System.out.println("matchingOverTag = " + matchingOverTag + " and matchTargetTag = " +
    // matchTargetTag);

    // FIXME: Why do equals when that may not correspond to the tags being the same? Only reference
    // == is safe I guess?
    // if (matchingOverTag.equals(matchTargetTag)) return true;
    if (matchingOver == matchTarget) return true;

    // If caseOf is hopelessly broken, this is a "fix": return false; :-)d

    TaggedInfo ti = matchingOver.getCaseOfTaggedInfo();

    if (ti == null) return false;
    return isSubtag(ti, matchTarget); // FIXME:
  }
コード例 #6
0
ファイル: Match.java プロジェクト: taolong001/wyvern
  private void checkSubtagsPreceedSupertags() {
    // A tag cannot be earlier than one of its subtags
    for (int i = 0; i < cases.size() - 1; i++) {
      Case beforeCase = cases.get(i);
      TaggedInfo beforeTag = TaggedInfo.lookupTagByType(beforeCase.getTaggedTypeMatch()); // FIXME:

      for (int j = i + 1; j < cases.size(); j++) {
        Case afterCase = cases.get(j);

        if (afterCase.isDefault()) break;

        TaggedInfo afterTag = TaggedInfo.lookupTagByType(afterCase.getTaggedTypeMatch()); // FIXME:
        // TagBinding afterBinding = TagBinding.get(afterCase.getTaggedTypeMatch());

        if (afterTag != null && beforeTag != null && isSubtag(afterTag, beforeTag)) {
          ToolError.reportError(
              ErrorMessage.SUPERTAG_PRECEEDS_SUBTAG,
              matchingOver,
              beforeTag.getTagName(),
              afterTag.getTagName());
        }
      }
    }
  }
コード例 #7
0
ファイル: Match.java プロジェクト: taolong001/wyvern
  @Override
  public Value evaluate(EvaluationEnvironment env) {
    // TaggedInfo.resolveAll(env, this);

    Type mo = matchingOver.getType();

    TaggedInfo matchingOverTag = TaggedInfo.lookupTagByType(mo); // FIXME:

    if (matchingOver instanceof Variable) {
      Variable w = (Variable) matchingOver;
      // ClassType wType = (ClassType) env.lookup(w.getName()).getType();
      // System.out.println("wType = " + wType);
      // System.out.println("looked up = " + TaggedInfo.lookupTagByType(wType));
      // System.out.println("but mot = " + matchingOverTag);
      matchingOverTag =
          ((Obj)
                  env.lookup(w.getName())
                      .map(ib -> ib.getValue(env))
                      .orElseThrow(() -> new RuntimeException("Invalid matching over tag")))
              .getTaggedInfo();
    }

    // System.out.println("Evaluating match with matchingOver = " + matchingOver + " its class " +
    // matchingOver.getClass());
    /*
    Variable v = (Variable) matchingOver;
    System.out.println("v.getType() = " + v.getType());
    System.out.println("v.getName() = " + v.getName());
    System.out.println(env);
    System.out.println(env.lookup(v.getName()));

    System.out.println("mo = " + mo + " and its class is " + mo.getClass());
    System.out.println(env.lookup(v.getName()).getUse());
    System.out.println(env.lookup(v.getName()).getValue(env));

    TypeType ttmo = (TypeType) mo;
    System.out.println("ttmo.getName() is declared but not actual type = " + ttmo.getName());
    TypeType tttmo = (TypeType) ((MetadataWrapper) v.typecheck(env, Optional.empty())).getInner();
    System.out.println("v.type = " + tttmo.getName());

    TaggedInfo.dumpall(env);
    */

    // System.out.println("Evaluating match over tag: " + matchingOverTag + " with matchingOver = "
    // + matchingOver.getType());
    if (matchingOver.getType() instanceof ClassType) {
      ClassType ct = (ClassType) matchingOver.getType();
      // System.out.println("hmm = " + this.matchingOver.typecheck(env, Optional.empty()));
      // System.out.println("ct = " + ct.getName());
    }

    // System.out.println("matchingOverTag (latest) = " + matchingOverTag);
    int cnt = 0;

    for (Case c : cases) {
      cnt++;

      // String caseTypeName = getTypeName(c.getAST());

      // System.out.println("case "+ cnt + " = " + c);

      Type tt = c.getTaggedTypeMatch();

      TaggedInfo caseTag;
      if (tt instanceof TypeInv) {
        TypeInv ti = (TypeInv) tt;

        // System.out.println("Processing TypeInv case: " + ti);

        // FIXME: In ECOOP2015Artifact, I am trying to tell the difference between winMod.Win and
        // bigWinMod.Win...

        Type ttti = ti.getInnerType();
        String mbr = ti.getInvName();

        if (ttti instanceof UnresolvedType) {
          Value objVal = env.lookup(((UnresolvedType) ttti).getName()).get().getValue(env);
          caseTag =
              ((Obj) objVal)
                  .getIntEnv()
                  .lookupBinding(mbr, HackForArtifactTaggedInfoBinding.class)
                  .map(b -> b.getTaggedInfo())
                  .orElseThrow(() -> new RuntimeException("Invalid tag invocation"));

        } else {
          // tt = ti.resolve(env); TODO: is this valid?
          caseTag = TaggedInfo.lookupTagByType(tt); // FIXME:
        }
      } else {
        caseTag = TaggedInfo.lookupTagByType(tt); // FIXME:
      }

      // System.out.println("case " + cnt + " type = " + tt);

      // System.out.println("caseTag = " + caseTag);

      if (caseTag != null && isSubtag(matchingOverTag, caseTag)) {
        // We've got a match, evaluate this case
        // System.out.println("MAAAAATTTCH!");
        return c.getAST().evaluate(env);
      }
    }

    // No match, evaluate the default case
    // System.out.println("DEFAULT: " + defaultCase.getAST().evaluate(env));
    return defaultCase.getAST().evaluate(env);
  }
コード例 #8
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;
  }