Skip to content

Instantly share code, notes, and snippets.

@josejuan
Created July 10, 2018 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josejuan/7b32918abb08ac0d51418c742a324950 to your computer and use it in GitHub Desktop.
Save josejuan/7b32918abb08ac0d51418c742a324950 to your computer and use it in GitHub Desktop.
private static NodeList<Statement> reduceDoExpression(final NodeList<Statement> xs) {
final NodeList<Statement> rs = new NodeList<>();
int i = 0;
while (i < xs.size()) {
final Statement s = xs.get(i);
if (s.isExpressionStmt()) {
final Expression e = s.asExpressionStmt().getExpression();
if (e.isVariableDeclarationExpr()) {
final VariableDeclarationExpr vde = e.asVariableDeclarationExpr();
if (vde.getVariables().size() == 1) {
final VariableDeclarator vd = vde.getVariable(0);
if (vd.getInitializer().map(Expression::isMethodCallExpr).orElse(false)) {
final MethodCallExpr mce = vd.getInitializer().get().asMethodCallExpr();
final List<Node> nodes = mce.getChildNodes();
if (!nodes.isEmpty()) {
final Node n = nodes.get(nodes.size() - 1);
if (n instanceof SimpleName) {
final SimpleName sn = (SimpleName) n;
if ("yield".equals(sn.asString())) {
// Transformamos:
//
// A...;
// T x = E.yield();
// B...;
//
// En:
//
// A...;
// return E.bind((T x) -> { B...; });
//
// A...
final NodeList<Statement> zs = new NodeList<>();
while(++i < xs.size())
zs.add(xs.get(i));
// T x
final Parameter param = new Parameter();
param.setName(vd.getName());
param.setType(vd.getType());
final NodeList<Parameter> params = new NodeList<>();
params.add(param);
// B...
final BlockStmt block = new BlockStmt();
block.setStatements(reduceDoExpression(zs));
// bind
final LambdaExpr lambda = new LambdaExpr();
lambda.setEnclosingParameters(true);
lambda.setParameters(params);
lambda.setBody(block);
final NodeList<Expression> args = new NodeList<>();
args.add(lambda);
mce.setName("bind");
mce.setArguments(args);
// return
final ReturnStmt rstmt = new ReturnStmt();
rstmt.setExpression(mce);
rs.add(rstmt);
return rs;
}
}
}
}
}
}
}
rs.add(xs.get(i));
i += 1;
}
// no yield statement
return xs;
}
/*
Por ejemplo, dado un código parseado se puede transformar como:
parser.findAll(BlockStmt.class).forEach(block -> block.setStatements(reduceDoExpression(block.getStatements())));
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment