Mercurial > hg > graal-compiler
diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/DSLExpressionGenerator.java @ 19283:08aa0372dad4
Truffle-DSL: implement new guard expression syntax.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Fri, 23 Jan 2015 02:55:23 +0100 |
parents | |
children | 62c43fcf5be2 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/DSLExpressionGenerator.java Fri Jan 23 02:55:23 2015 +0100 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.dsl.processor.generator; + +import java.util.*; + +import javax.lang.model.element.*; + +import com.oracle.truffle.dsl.processor.expression.*; +import com.oracle.truffle.dsl.processor.expression.DSLExpression.Binary; +import com.oracle.truffle.dsl.processor.expression.DSLExpression.Call; +import com.oracle.truffle.dsl.processor.expression.DSLExpression.DSLExpressionVisitor; +import com.oracle.truffle.dsl.processor.expression.DSLExpression.IntLiteral; +import com.oracle.truffle.dsl.processor.expression.DSLExpression.Negate; +import com.oracle.truffle.dsl.processor.expression.DSLExpression.Variable; +import com.oracle.truffle.dsl.processor.java.model.*; + +public class DSLExpressionGenerator implements DSLExpressionVisitor { + + private final Map<Variable, CodeTree> bindings; + private final CodeTree root; + private final Deque<CodeTree> stack = new ArrayDeque<>(); + + public DSLExpressionGenerator(CodeTree root, Map<Variable, CodeTree> bindings) { + this.bindings = bindings; + this.root = root; + } + + public void visitBinary(Binary binary) { + CodeTree right = stack.pop(); + CodeTree left = stack.pop(); + stack.push(combine(left, string(" " + binary.getOperator() + " "), right)); + } + + public void visitCall(Call call) { + ExecutableElement method = call.getResolvedMethod(); + CodeTree[] parameters = new CodeTree[method.getParameters().size()]; + for (int i = 0; i < parameters.length; i++) { + parameters[parameters.length - i - 1] = pop(); + } + + CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); + + if (call.getReceiver() == null) { + if (isStatic(method)) { + builder.startStaticCall(method); + } else { + if (root != null) { + builder.tree(root).string("."); + } + builder.startCall(method.getSimpleName().toString()); + } + } else { + if (isStatic(method)) { + throw new AssertionError("Static calls must not have receivers."); + } + builder.startCall(pop(), method.getSimpleName().toString()); + } + for (CodeTree parameter : parameters) { + builder.tree(parameter); + } + builder.end(); + + push(builder.build()); + } + + public void visitIntLiteral(IntLiteral binary) { + push(string(binary.getLiteral())); + } + + public void visitNegate(Negate negate) { + push(combine(string("!"), pop())); + } + + public void visitVariable(Variable variable) { + VariableElement resolvedVariable = variable.getResolvedVariable(); + CodeTree tree; + if (variable.getReceiver() == null) { + + if (isStatic(resolvedVariable)) { + tree = staticReference(resolvedVariable); + } else { + tree = bindings.get(variable); + boolean bound = true; + if (tree == null) { + tree = string(resolvedVariable.getSimpleName().toString()); + bound = false; + } + if (root != null && !bound) { + tree = combine(root, string("."), tree); + } + } + } else { + if (isStatic(resolvedVariable)) { + throw new AssertionError("Static variables cannot have receivers."); + } + tree = combine(pop(), string("."), string(resolvedVariable.getSimpleName().toString())); + } + push(tree); + } + + private static boolean isStatic(Element element) { + return element.getModifiers().contains(Modifier.STATIC); + } + + private static CodeTree combine(CodeTree tree1, CodeTree tree2) { + return new CodeTreeBuilder(null).startGroup().tree(tree1).tree(tree2).end().build(); + } + + private static CodeTree combine(CodeTree tree1, CodeTree tree2, CodeTree tree3) { + return new CodeTreeBuilder(null).startGroup().tree(tree1).tree(tree2).tree(tree3).end().build(); + } + + private static CodeTree string(String s) { + return CodeTreeBuilder.singleString(s); + } + + private static CodeTree staticReference(VariableElement var) { + return CodeTreeBuilder.createBuilder().staticReference(var.asType(), var.getSimpleName().toString()).build(); + } + + private void push(CodeTree tree) { + stack.push(tree); + } + + private CodeTree pop() { + return stack.pop(); + } + + public static CodeTree write(DSLExpression expression, CodeTree root, Map<Variable, CodeTree> bindings) { + DSLExpressionGenerator writer = new DSLExpressionGenerator(root, bindings); + expression.accept(writer); + return writer.pop(); + } + +}