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);
}
if (TreeAdapter.isLexical(tree)) {
return cache(tree, new Tree.Lexical(tree, kids));
}
else if (TreeAdapter.isList(tree)) {
// TODO: splice element lists (can happen in case of ambiguous lists)
return cache(tree, new Tree.List(tree, kids));
}
else if (TreeAdapter.isOpt(tree)) {
return cache(tree, new Tree.Optional(tree, kids));
}
else {
return cache(tree, new Tree.Appl(tree, kids));
}
}
else if (TreeAdapter.isCycle(tree)) {
return new Tree.Cycle(TreeAdapter.getCycleType(tree), TreeAdapter.getCycleLength(tree));
}
else if (TreeAdapter.isAmb(tree)) {
ISet args = TreeAdapter.getAlternatives(tree);
java.util.List<Expression> kids = new ArrayList<Expression>(args.size());
for (IValue arg : args) {
kids.add(liftRec((IConstructor) arg, lexicalFather, layoutOfFather));
}