示例#1
0
  public IValue buildCollection(Type type, List<Record> records, IEvaluatorContext ctx) {
    IWriter writer;
    while (type.isAliased()) {
      type = type.getAliased();
    }

    if (type.isList()) {
      writer = values.listWriter(type.getElementType());
    } else if (type.isRelation()) {
      writer = values.relationWriter(type.getElementType());
    } else {
      throw RuntimeExceptionFactory.illegalTypeArgument(
          "Invalid result type for CSV reading: " + type, ctx.getCurrentAST(), ctx.getStackTrace());
    }

    // reverse traversal so that the order in case of ListWriter is correct
    // (IWriter only supports inserts at the front).
    Type eltType = type.getElementType();
    for (int i = records.size() - 1; i >= 0; i--) {
      Record record = records.get(i);
      checkRecord(eltType, record, ctx);
      writer.insert(record.getTuple(eltType));
    }
    return writer.done();
  }
示例#2
0
  @Override
  public Type getType(Environment env, HashMap<String, IVarPattern> patternVars) {
    if (patternSize == 0) {
      return tf.listType(tf.voidType());
    }

    Type elemType = tf.voidType();
    for (int i = 0; i < patternSize; i += delta) {
      IMatchingResult child = patternChildren.get(i);
      Type childType = child.getType(env, patternVars);
      patternVars = merge(patternVars, patternChildren.get(i).getVariables());
      boolean isMultiVar =
          child instanceof MultiVariablePattern || child instanceof TypedMultiVariablePattern;

      if (childType.isList() && isMultiVar) {
        elemType = elemType.lub(childType.getElementType());
      } else {
        elemType = elemType.lub(childType);
      }
    }
    if (debug) {
      System.err.println("ListPattern.getType: " + tf.listType(elemType));
    }
    return tf.listType(elemType);
  }
示例#3
0
 public static boolean isAnyListType(Type type) {
   return type.isList() || isConcreteListType(type);
 }
示例#4
0
  @Override
  public void initMatch(Result<IValue> subject) {
    if (debug) {
      System.err.println("List: initMatch: subject=" + subject);
    }

    //    This is an experiment to add abstract list matching for concrete subjects
    //    if (subject.getType().isSubtypeOf(Factory.Tree)) {
    //      IConstructor tree = (IConstructor) subject.getValue();
    //      if (TreeAdapter.isList(tree)) {
    //        subject = ResultFactory.makeResult(Factory.Args, TreeAdapter.getArgs(tree), ctx);
    //        IConstructor rhs = TreeAdapter.getType(tree);
    //
    //        if (SymbolAdapter.isIterPlusSeps(rhs) || SymbolAdapter.isIterStarSeps(rhs)) {
    //          this.delta = SymbolAdapter.getSeparators(rhs).length() + 1;
    //        }
    //      }
    //      else {
    //        hasNext = false;
    //        return;
    //      }
    //    }

    super.initMatch(subject);

    if (!subject.getValue().getType().isList()) {
      hasNext = false;
      return;
    }
    listSubject = (IList) subject.getValue();
    listSubjectType = listSubject.getType();
    staticListSubjectType = subject.getType();
    staticListSubjectElementType =
        staticListSubjectType.isList() ? subject.getType().getElementType() : tf.valueType();

    subjectCursor = 0;
    patternCursor = 0;
    subjectSize = ((IList) subject.getValue()).length();
    reducedSubjectSize = (subjectSize + delta - 1) / delta;

    if (debug) {
      System.err.println("reducedPatternSize=" + reducedPatternSize);
      System.err.println("reducedSubjectSize=" + reducedSubjectSize);
    }

    isListVar = new boolean[patternSize];
    isBindingVar = new boolean[patternSize];
    varName = new String[patternSize];
    allVars = new HashSet<String>();
    listVarStart = new int[patternSize];
    listVarLength = new int[patternSize];
    listVarMinLength = new int[patternSize];
    listVarMaxLength = new int[patternSize];
    listVarOccurrences = new int[patternSize];

    int nListVar = 0;
    /*
     * Pass #1: determine the list variables
     */
    for (int i = 0; i < patternSize; i += delta) {
      IMatchingResult child = patternChildren.get(i);
      isListVar[i] = false;
      isBindingVar[i] = false;
      Environment env = ctx.getCurrentEnvt();

      if (child instanceof TypedMultiVariablePattern) {
        TypedMultiVariablePattern tmvVar = (TypedMultiVariablePattern) child;
        Type tmvType = tmvVar.getType(env, null);
        String name = tmvVar.getName();

        varName[i] = name;
        isListVar[i] = true;
        listVarOccurrences[i] = 1;
        ++nListVar;

        if (!tmvVar.isAnonymous() && allVars.contains(name)) {
          throw new RedeclaredVariable(name, getAST());
        } else if (tmvType.comparable(listSubject.getType().getElementType())
            || (tmvVar.bindingInstance() && tmvType.comparable(listSubject.getType()))) {
          tmvVar.convertToListType();
          if (!tmvVar.isAnonymous()) {
            allVars.add(name);
          }
          isBindingVar[i] = true;
        } else {
          hasNext = false;
          return;
        }
      } else if (child instanceof MultiVariablePattern) {
        MultiVariablePattern multiVar = (MultiVariablePattern) child;
        String name = multiVar.getName();
        varName[i] = name;
        isListVar[i] = true;
        nListVar++;

        if (!multiVar.isAnonymous() && allVars.contains(name)) {
          isBindingVar[i] = false;
        } else if (multiVar.isAnonymous()) {
          isBindingVar[i] = true;
        } else {
          allVars.add(name);
          Result<IValue> varRes = env.getVariable(name);

          if (varRes == null || multiVar.bindingInstance()) {
            isBindingVar[i] = true;
          } else {
            isBindingVar[i] = false;
            Type varType = varRes.getType();
            if (isAnyListType(varType)) {
              if (!varType.comparable(listSubjectType)) {
                hasNext = false;
                return;
              }
            } else {
              if (!(varType instanceof NonTerminalType)
                  && !(varType.comparable(staticListSubjectElementType))) {
                hasNext = false;
                return;
              }
            }
          }
        }
      } else if (child instanceof ConcreteListVariablePattern) {
        ConcreteListVariablePattern listVar = (ConcreteListVariablePattern) child;
        String name = listVar.getName();
        varName[i] = name;
        isListVar[i] = true;
        if (!listVar.isAnonymous()) allVars.add(name);
        isBindingVar[i] = true;
        listVarOccurrences[i] = 1;
        nListVar++;
      } else if (child instanceof QualifiedNamePattern) {
        QualifiedNamePattern qualName = (QualifiedNamePattern) child;
        String name = qualName.getName();
        varName[i] = name;
        if (!qualName.isAnonymous() && allVars.contains(name)) {
          /*
           * A variable that was declared earlier in the pattern
           */
          isListVar[i] = true;
          nListVar++;
          listVarOccurrences[i]++;
        } else if (qualName.isAnonymous()) {
          /*
           * Nothing to do
           */
        } else {
          Result<IValue> varRes = env.getVariable(name);

          if (varRes == null || qualName.bindingInstance()) {
            // A completely new non-list variable, nothing to do
          } else {
            Type varType = varRes.getType();
            if (isAnyListType(varType)) {
              /*
               * A variable declared in the current scope.
               */
              if (varType.comparable(listSubjectType)) {
                isListVar[i] = true;
                isBindingVar[i] = varRes.getValue() == null;
                nListVar++;
              } else {
                hasNext = false;
                return;
              }
            } else {
              if (varType instanceof NonTerminalType) {
                // suppress comparable test for Nonterminal types
                // TODO: this should be done better
              } else if (!varType.comparable(staticListSubjectElementType)) {
                hasNext = false;
                return;
              }
            }
          }
        }
      } else if (child instanceof VariableBecomesPattern) {
        // Nothing to do
      } else {
        if (debug) {
          System.err.println("List: child " + child);
          System.err.println("List: child is a" + child.getClass());
        }
        Type childType = child.getType(env, null);

        // TODO: pattern matching should be specialized such that matching appl(prod...)'s does not
        // need to use list matching on the fixed arity children of the application of a production
        if (!(childType instanceof NonTerminalType)
            && !childType.comparable(staticListSubjectElementType)) {
          hasNext = false;
          return;
        }
        java.util.List<IVarPattern> childVars = child.getVariables();
        if (!childVars.isEmpty()) {
          for (IVarPattern vp : childVars) { // TODO: This does not profit from extra information
            allVars.add(vp.name());
          }
          isListVar[i] = false;
          nListVar++;
        }
      }
    }
    /*
     * Pass #2: assign minimum and maximum length to each list variable
     */
    for (int i = 0; i < patternSize; i += delta) {
      if (isListVar[i]) {
        // TODO: reduce max length according to number of occurrences
        listVarMaxLength[i] =
            delta * Math.max(reducedSubjectSize - (reducedPatternSize - nListVar), 0);
        listVarLength[i] = 0;
        listVarMinLength[i] =
            delta
                * ((nListVar == 1) ? Math.max(reducedSubjectSize - reducedPatternSize - 1, 0) : 0);

        if (debug) {
          System.err.println(
              "listvar " + i + " min= " + listVarMinLength[i] + " max=" + listVarMaxLength[i]);
        }
      }
    }

    firstMatch = true;

    hasNext =
        subject.getValue().getType().isList()
            && reducedSubjectSize >= reducedPatternSize - nListVar;

    if (debug) {
      System.err.println("List: hasNext=" + hasNext);
    }
  }