constructorCache.putUnsafe(in, out);
return out;
}
private Expression liftRec(IConstructor tree, boolean lexicalFather, String layoutOfFather) {
Expression cached = constructorCache.get(tree);
if (cached != null) {
return cached;
}
if (layoutOfFather == null) {
throw new ImplementationError("layout is null");
}
if (TreeAdapter.isAppl(tree)) {
String cons = TreeAdapter.getConstructorName(tree);
if (cons != null && (cons.equals("hole"))) { // TODO: this is unsafe, what if somebody named their own production "hole"??
return liftHole(tree);
}
boolean lex = lexicalFather ? !TreeAdapter.isSort(tree) : TreeAdapter.isLexical(tree);
IList args = TreeAdapter.getArgs(tree);
String layout = layoutOfFather;
if (cons != null && !lex) {
String newLayout = getLayoutName(TreeAdapter.getProduction(tree));
// this approximation is possibly harmfull. Perhaps there is a chain rule defined in another module, which nevertheless
// switched the applicable layout. Until we have a proper type-analysis there is nothing we can do here.
if (newLayout != null) {
layout = newLayout;
}
}
java.util.List<Expression> kids = new ArrayList<Expression>(args.length());
for (IValue arg : args) {
Expression ast = liftRec((IConstructor) arg, lex, layout);
if (ast == null) {
return null;
}
kids.add(ast);
}