Mercurial > hg > truffle
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 } |