comparison truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/DSLExpressionGenerator.java @ 21951:9c8c0937da41

Moving all sources into truffle subdirectory
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 17 Jun 2015 10:58:08 +0200
parents graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/DSLExpressionGenerator.java@f83fd99b2962
children dc83cc1f94f2
comparison
equal deleted inserted replaced
21950:2a5011c7e641 21951:9c8c0937da41
1 /*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.truffle.dsl.processor.generator;
24
25 import java.util.*;
26
27 import javax.lang.model.element.*;
28 import javax.lang.model.type.*;
29
30 import com.oracle.truffle.dsl.processor.expression.*;
31 import com.oracle.truffle.dsl.processor.expression.DSLExpression.Binary;
32 import com.oracle.truffle.dsl.processor.expression.DSLExpression.Call;
33 import com.oracle.truffle.dsl.processor.expression.DSLExpression.DSLExpressionVisitor;
34 import com.oracle.truffle.dsl.processor.expression.DSLExpression.IntLiteral;
35 import com.oracle.truffle.dsl.processor.expression.DSLExpression.Negate;
36 import com.oracle.truffle.dsl.processor.expression.DSLExpression.Variable;
37 import com.oracle.truffle.dsl.processor.java.model.*;
38
39 public class DSLExpressionGenerator implements DSLExpressionVisitor {
40
41 private final Map<Variable, CodeTree> bindings;
42 private final CodeTree root;
43 private final Deque<CodeTree> stack = new ArrayDeque<>();
44
45 public DSLExpressionGenerator(CodeTree root, Map<Variable, CodeTree> bindings) {
46 this.bindings = bindings;
47 this.root = root;
48 }
49
50 public void visitBinary(Binary binary) {
51 CodeTree right = stack.pop();
52 CodeTree left = stack.pop();
53 stack.push(combine(left, string(" " + binary.getOperator() + " "), right));
54 }
55
56 public void visitCall(Call call) {
57 ExecutableElement method = call.getResolvedMethod();
58 CodeTree[] parameters = new CodeTree[method.getParameters().size()];
59 for (int i = 0; i < parameters.length; i++) {
60 parameters[parameters.length - i - 1] = pop();
61 }
62
63 CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
64
65 if (call.getResolvedMethod().getKind() == ElementKind.CONSTRUCTOR) {
66 builder.startNew(call.getResolvedType());
67 } else if (call.getReceiver() == null) {
68 if (isStatic(method)) {
69 builder.startStaticCall(method);
70 } else {
71 if (root != null) {
72 builder.tree(root).string(".");
73 }
74 builder.startCall(method.getSimpleName().toString());
75 }
76 } else {
77 if (isStatic(method)) {
78 throw new AssertionError("Static calls must not have receivers.");
79 }
80 builder.startCall(pop(), method.getSimpleName().toString());
81 }
82 for (CodeTree parameter : parameters) {
83 builder.tree(parameter);
84 }
85 builder.end();
86
87 push(builder.build());
88 }
89
90 public void visitIntLiteral(IntLiteral binary) {
91 push(string(binary.getLiteral()));
92 }
93
94 public void visitNegate(Negate negate) {
95 push(combine(string("!"), combine(string("("), pop(), string(")"))));
96 }
97
98 public void visitVariable(Variable variable) {
99 VariableElement resolvedVariable = variable.getResolvedVariable();
100 CodeTree tree;
101 if (variable.getResolvedType().getKind() == TypeKind.NULL) {
102 tree = CodeTreeBuilder.singleString("null");
103 } else if (variable.getReceiver() == null) {
104
105 if (isStatic(resolvedVariable)) {
106 tree = staticReference(resolvedVariable);
107 } else {
108 tree = bindings.get(variable);
109 boolean bound = true;
110 if (tree == null) {
111 tree = string(resolvedVariable.getSimpleName().toString());
112 bound = false;
113 }
114 if (root != null && !bound) {
115 tree = combine(root, string("."), tree);
116 }
117 }
118 } else {
119 if (isStatic(resolvedVariable)) {
120 throw new AssertionError("Static variables cannot have receivers.");
121 }
122 tree = combine(pop(), string("."), string(resolvedVariable.getSimpleName().toString()));
123 }
124 push(tree);
125 }
126
127 private static boolean isStatic(Element element) {
128 return element.getModifiers().contains(Modifier.STATIC);
129 }
130
131 private static CodeTree combine(CodeTree tree1, CodeTree tree2) {
132 return new CodeTreeBuilder(null).startGroup().tree(tree1).tree(tree2).end().build();
133 }
134
135 private static CodeTree combine(CodeTree tree1, CodeTree tree2, CodeTree tree3) {
136 return new CodeTreeBuilder(null).startGroup().tree(tree1).tree(tree2).tree(tree3).end().build();
137 }
138
139 private static CodeTree string(String s) {
140 return CodeTreeBuilder.singleString(s);
141 }
142
143 private static CodeTree staticReference(VariableElement var) {
144 return CodeTreeBuilder.createBuilder().staticReference(var.getEnclosingElement().asType(), var.getSimpleName().toString()).build();
145 }
146
147 private void push(CodeTree tree) {
148 stack.push(tree);
149 }
150
151 private CodeTree pop() {
152 return stack.pop();
153 }
154
155 public static CodeTree write(DSLExpression expression, CodeTree root, Map<Variable, CodeTree> bindings) {
156 DSLExpressionGenerator writer = new DSLExpressionGenerator(root, bindings);
157 expression.accept(writer);
158 return combine(string("("), writer.pop(), string(")"));
159 }
160
161 }