Esempio n. 1
0
  /*package*/ public NonTerminalType(IConstructor cons) {
    // TODO refactor this into different factory methods in RascalTypeFactory

    if (cons.getConstructorType() == RascalValueFactory.Tree_Appl) {
      // Note that here we go from * to + lists if the list is not empty
      this.symbol = TreeAdapter.getType((ITree) cons);
    } else if (cons.getConstructorType() == RascalValueFactory.Tree_Amb) {
      ISet alts = TreeAdapter.getAlternatives((ITree) cons);

      if (!alts.isEmpty()) {
        ITree first = (ITree) alts.iterator().next();
        this.symbol = TreeAdapter.getType(first);
      } else {
        this.symbol =
            IRascalValueFactory.getInstance().constructor(RascalValueFactory.Symbol_Empty);
      }
    } else if (cons.getConstructorType() == RascalValueFactory.Tree_Cycle) {
      this.symbol = TreeAdapter.getType((ITree) cons);
    } else if (cons.getType() == RascalValueFactory.Symbol) {
      this.symbol = cons;
    } else if (cons.getType() == RascalValueFactory.Production) {
      this.symbol = ProductionAdapter.getType(cons);
    } else {
      throw new ImplementationError("Invalid concrete syntax type constructor:" + cons);
    }
  }
 @Override
 public Result<IBool> is(Name name) {
   if (TreeAdapter.isAppl(getValue())) {
     String consName = TreeAdapter.getConstructorName(getValue());
     if (consName != null) {
       return ResultFactory.bool(Names.name(name).equals(consName), ctx);
     }
   }
   return ResultFactory.bool(false, ctx);
 }
  private ISourceLocation getLocation(Object node) {
    if (node instanceof ITree) {
      return TreeAdapter.getLocation((ITree) node);
    }

    if (node instanceof INode) {
      INode n = (INode) node;
      IValue ann = n.asAnnotatable().getAnnotation("loc");
      if (ann != null) {
        return (ISourceLocation) ann;
      }
    }

    if (node instanceof AbstractAST) {
      return ((AbstractAST) node).getLocation();
    }

    if (node instanceof ModelTreeNode) {
      return getLocation(((ModelTreeNode) node).getASTNode());
    }

    if (node instanceof Group<?>) {
      Group<?> group = (Group<?>) node;
      Iterator<?> i = group.iterator();
      if (i.hasNext()) {
        return getLocation(i.next());
      }
      return group.getLocation();
    }

    return null;
  }
Esempio n. 4
0
  private void printResult(IRascalResult result) throws IOException {
    if (result == null) {
      return;
    }
    PrintWriter out = getOutputWriter();
    IValue value = result.getValue();
    if (value == null) {
      out.println("ok");
      out.flush();
      return;
    }
    Type type = result.getType();

    if (type.isAbstractData() && type.isStrictSubtypeOf(RascalValueFactory.Tree)) {
      out.print(type.toString());
      out.print(": ");
      // we unparse the tree
      out.print("(" + type.toString() + ") `");
      TreeAdapter.yield((IConstructor) result.getValue(), true, out);
      out.print("`");
    } else {
      out.print(type.toString());
      out.print(": ");
      // limit both the lines and the characters
      try (Writer wrt = new LimitedWriter(new LimitedLineWriter(out, LINE_LIMIT), CHAR_LIMIT)) {
        indentedPrettyPrinter.write(value, wrt);
      } catch (IOLimitReachedException e) {
        // ignore since this is what we wanted
      }
    }
    out.println();
    out.flush();
  }
  @Override
  public ITree filterProduction(ITree tree, Object environment) {
    String cons = TreeAdapter.getConstructorName(tree);

    if (cons != null) {
      Environment env = (Environment) environment;
      Result<IValue> var = env.getFrameVariable(cons);

      if (var != null && var instanceof ICallableValue) {
        ICallableValue function = (ICallableValue) var;

        try {
          Result<IValue> result = null;
          if (TreeAdapter.isContextFree(tree)) {
            // For context free trees, try it without layout and literal arguments first.
            result = call(function, TreeAdapter.getASTArgs(tree));
          }

          if (result == null) {
            result = call(function, TreeAdapter.getArgs(tree));
          }

          if (result == null) {
            return tree;
          }

          if (result.getType().isBottom()) {
            return tree;
          }

          if (!(result.getType() instanceof NonTerminalType
              && SymbolAdapter.isEqual(
                  ((NonTerminalType) result.getType()).getSymbol(), TreeAdapter.getType(tree)))) {
            // do not call the function if it does not return the right type
            return tree;
          }

          return (ITree) result.getValue();
        } catch (Filtered f) {
          return null;
        }
      }
    }

    return tree;
  }
  @Override
  public <U extends IValue, V extends IValue> Result<U> fieldUpdate(
      String name, Result<V> repl, TypeStore store) {
    IConstructor tree = getValue();

    if (TreeAdapter.isAppl(tree)) {
      int found = -1;
      IConstructor foundType = null;
      IConstructor prod = TreeAdapter.getProduction(tree);
      IList syms = ProductionAdapter.getSymbols(prod);

      // TODO: find deeper into optionals, alternatives and sequences checking the actual arguments
      // for presence/absence of optional trees.
      for (int i = 0; i < syms.length(); i++) {
        IConstructor sym = (IConstructor) syms.get(i);
        if (SymbolAdapter.isLabel(sym)) {
          if (SymbolAdapter.getLabel(sym).equals(name)) {
            found = i;
            foundType = SymbolAdapter.delabel(sym);
            break;
          }
        }
      }

      if (found != -1) {
        Type nont = RascalTypeFactory.getInstance().nonTerminalType(foundType);
        if (repl.getType().isSubtypeOf(nont)) {
          IList args = TreeAdapter.getArgs(tree).put(found, repl.getValue());
          return makeResult(getType(), tree.set("args", args), ctx);
        }
        throw new UnexpectedType(nont, repl.getType(), ctx.getCurrentAST());
      }

      if (Factory.Tree_Appl.hasField(name)) {
        Type fieldType = Factory.Tree_Appl.getFieldType(name);
        if (repl.getType().isSubtypeOf(fieldType)) {
          throw new UnsupportedOperation(
              "changing " + name + " in concrete tree", ctx.getCurrentAST());
        }
        throw new UnexpectedType(fieldType, repl.getType(), ctx.getCurrentAST());
      }

      throw RuntimeExceptionFactory.noSuchField(name, ctx.getCurrentAST(), ctx.getStackTrace());
    }
    throw new UnsupportedOperation("field update", ctx.getCurrentAST());
  }
 public Object findNode(Object ast, int offset) {
   if (ast instanceof ITree) {
     return TreeAdapter.locateLexical((ITree) ast, offset);
   } else if (ast instanceof AbstractAST) {
     return ((AbstractAST) ast).findNode(offset);
   } else if (ast instanceof ModelTreeNode) {
     return findNode(((ModelTreeNode) ast).getASTNode(), offset);
   }
   return null;
 }
  @Override
  public Result<IBool> has(Name name) {
    if (TreeAdapter.isAppl(getValue())) {
      IConstructor prod = TreeAdapter.getProduction(getValue());
      IList syms = ProductionAdapter.getSymbols(prod);
      String tmp = Names.name(name);

      // TODO: find deeper into optionals, checking the actual arguments for presence/absence of
      // optional trees.
      for (IValue sym : syms) {
        if (SymbolAdapter.isLabel((IConstructor) sym)) {
          if (SymbolAdapter.getLabel((IConstructor) sym).equals(tmp)) {
            return ResultFactory.bool(true, ctx);
          }
        }
      }
    }
    return ResultFactory.bool(false, ctx);
  }
  @Override
  public <U extends IValue> Result<U> fieldAccess(String name, TypeStore store) {
    IConstructor tree = getValue();

    if (TreeAdapter.isAppl(tree)) {
      int found = -1;
      IConstructor foundType = null;
      IConstructor prod = TreeAdapter.getProduction(tree);

      if (!ProductionAdapter.isRegular(prod)) {
        IList syms = ProductionAdapter.getSymbols(prod);

        // TODO: find deeper into optionals, checking the actual arguments for presence/absence of
        // optional trees.
        for (int i = 0; i < syms.length(); i++) {
          IConstructor sym = (IConstructor) syms.get(i);

          while (SymbolAdapter.isConditional(sym)) {
            sym = SymbolAdapter.getSymbol(sym);
          }
          if (SymbolAdapter.isLabel(sym)) {
            if (SymbolAdapter.getLabel(sym).equals(name)) {
              found = i;
              foundType = SymbolAdapter.delabel(sym);
            }
          }
        }

        if (found != -1) {
          Type nont = RascalTypeFactory.getInstance().nonTerminalType(foundType);
          IValue child = TreeAdapter.getArgs(tree).get(found);
          return makeResult(nont, child, ctx);
        }
      }
    }

    if (tree.getConstructorType().hasField(name)) {
      return makeResult(tree.getConstructorType().getFieldType(name), tree.get(name), ctx);
    }

    throw RuntimeExceptionFactory.noSuchField(name, ctx.getCurrentAST(), ctx.getStackTrace());
  }
 @SuppressWarnings("unchecked")
 @Override
 protected <U extends IValue> Result<U> addString(StringResult that) {
   // Note the reverse concat.
   return (Result<U>)
       new ConcatStringResult(
           getType(),
           that,
           new StringResult(
               that.getType(), ctx.getValueFactory().string(TreeAdapter.yield(getValue())), ctx),
           ctx);
 }
  public ITree filterAmbiguity(ITree ambCluster, Object environment) {
    ISet alts = (ISet) ambCluster.get("alternatives");

    if (alts.size() == 0) {
      return null;
    }

    Environment env = (Environment) environment;

    Result<IValue> var = env.getFrameVariable("amb");

    if (var != null && var instanceof ICallableValue) {
      Type type = RascalTypeFactory.getInstance().nonTerminalType(ambCluster);
      ICallableValue func = (ICallableValue) var;
      try {
        Result<IValue> result = func.call(new Type[] {TF.setType(type)}, new IValue[] {alts}, null);

        if (result.getType().isBottom()) {
          return ambCluster;
        }
        ITree r = (ITree) result.getValue();
        if (TreeAdapter.isAmb(r)) {
          ISet returnedAlts = TreeAdapter.getAlternatives(r);
          if (returnedAlts.size() == 1) {
            return (ITree) returnedAlts.iterator().next();
          } else if (returnedAlts.size() == 0) {
            return null;
          } else {
            return r;
          }
        }

        return (ITree) result.getValue();
      } catch (ArgumentMismatch e) {
        return ambCluster;
      }
    }

    return ambCluster;
  }
  public Object loadPT(IConstructor[] fileRef, String sourcePath, String sourceName) {
    IConstructor file = fileRef[0];
    ISourceLocation loc = TreeAdapter.getLocation(file);
    int lineNumber = loc.getBeginLine();

    Object ret = null;

    Var.pushThreadBindings(
        RT.map(
            LOADER,
            RT.makeClassLoader(),
            SOURCE_PATH,
            sourcePath,
            SOURCE,
            sourceName,
            METHOD,
            null,
            LOCAL_ENV,
            null,
            LOOP_LOCALS,
            null,
            NEXT_LOCAL_NUM,
            0,
            RT.CURRENT_NS,
            RT.CURRENT_NS.deref(),
            LINE_BEFORE,
            lineNumber,
            LINE_AFTER,
            lineNumber,
            RT.UNCHECKED_MATH,
            RT.UNCHECKED_MATH.deref(),
            RT.WARN_ON_REFLECTION,
            RT.WARN_ON_REFLECTION.deref(),
            RT.DATA_READERS,
            RT.DATA_READERS.deref()));

    UPTRLispReader reader = new UPTRLispReader(vf, errors);

    try {

      if (TreeAdapter.isAmb(file)) {
        System.err.println("Amb");
      }

      // File is start[File], so
      IConstructor file2 = (IConstructor) TreeAdapter.getArgs(file).get(1);
      IList args = TreeAdapter.getArgs(file2);
      // Probably only this is the list of forms; don't forget to fix
      // below.
      IList forms = TreeAdapter.getArgs((IConstructor) args.get(0));

      IListWriter newArgs = vf.listWriter();
      for (int i = 0; i < forms.length(); i++) {
        IConstructor form = (IConstructor) forms.get(i);
        // only forms, no literals at this level.
        UPTRLispReader.Pair p = reader.read(form);
        newArgs.append(p.tree);
        LINE_AFTER.set(TreeAdapter.getLocation(form).getEndLine());
        ret = eval(p.obj, false);
        LINE_BEFORE.set(TreeAdapter.getLocation(form).getBeginLine());
        if (i < forms.length() - 2) {
          i++;
          newArgs.append(forms.get(i)); // layout
        }
      }
      // Fix tree
      file2 = file2.set("args", newArgs.done());
      file =
          file.set(
              "args",
              vf.list(TreeAdapter.getArgs(file).get(0), file2, TreeAdapter.getArgs(file).get(2)));

    } catch (UPTRLispReader.ReaderException e) {
      throw new CompilerException(sourcePath, e.line, e.getCause());
    } finally {
      Var.popThreadBindings();
    }
    fileRef[0] = file;
    return ret;
  }
  @Override
  protected Result<IBool> equalToConcreteSyntax(ConcreteSyntaxResult that) {
    IConstructor left = this.getValue();
    IConstructor right = that.getValue();

    if (TreeAdapter.isLayout(left) && TreeAdapter.isLayout(right)) {
      return bool(true, ctx);
    }

    if (TreeAdapter.isAppl(left) && TreeAdapter.isAppl(right)) {
      IConstructor p1 = TreeAdapter.getProduction(left);
      IConstructor p2 = TreeAdapter.getProduction(right);

      if (!p1.isEqual(p2)) {
        return bool(false, ctx);
      }

      IList l1 = TreeAdapter.getArgs(left);
      IList l2 = TreeAdapter.getArgs(right);

      if (l1.length() != l2.length()) {
        return bool(false, ctx);
      }
      for (int i = 0; i < l1.length(); i++) {
        IValue kid1 = l1.get(i);
        IValue kid2 = l2.get(i);
        // Recurse here on kids to reuse layout handling etc.
        Result<IBool> result =
            makeResult(kid1.getType(), kid1, ctx).equals(makeResult(kid2.getType(), kid2, ctx));
        if (!result.getValue().getValue()) {
          return bool(false, ctx);
        }
        if (TreeAdapter.isContextFree(left)) {
          i++; // skip layout
        }
      }
      return bool(true, ctx);
    }

    if (TreeAdapter.isChar(left) && TreeAdapter.isChar(right)) {
      return bool((TreeAdapter.getCharacter(left) == TreeAdapter.getCharacter(right)), ctx);
    }

    if (TreeAdapter.isAmb(left) && TreeAdapter.isAmb(right)) {
      ISet alts1 = TreeAdapter.getAlternatives(left);
      ISet alts2 = TreeAdapter.getAlternatives(right);

      if (alts1.size() != alts2.size()) {
        return bool(false, ctx);
      }

      // TODO: this is very inefficient
      again:
      for (IValue alt1 : alts1) {
        for (IValue alt2 : alts2) {
          Result<IBool> result =
              makeResult(alt1.getType(), alt1, ctx).equals(makeResult(alt2.getType(), alt2, ctx));
          if (result.getValue().getValue()) {
            // As soon an alt1 is equal to an alt2
            // continue the outer loop.
            continue again;
          }
        }
        // If an alt1 is not equal to any of the the alt2's return false;
        return bool(false, ctx);
      }
      return bool(true, ctx);
    }

    return bool(false, ctx);
  }