/*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; }
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); }