Mercurial > hg > graal-compiler
comparison 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 |
comparison
equal
deleted
inserted
replaced
19282:ae81dd154fb6 | 19283:08aa0372dad4 |
---|---|
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 | |
29 import com.oracle.truffle.dsl.processor.expression.*; | |
30 import com.oracle.truffle.dsl.processor.expression.DSLExpression.Binary; | |
31 import com.oracle.truffle.dsl.processor.expression.DSLExpression.Call; | |
32 import com.oracle.truffle.dsl.processor.expression.DSLExpression.DSLExpressionVisitor; | |
33 import com.oracle.truffle.dsl.processor.expression.DSLExpression.IntLiteral; | |
34 import com.oracle.truffle.dsl.processor.expression.DSLExpression.Negate; | |
35 import com.oracle.truffle.dsl.processor.expression.DSLExpression.Variable; | |
36 import com.oracle.truffle.dsl.processor.java.model.*; | |
37 | |
38 public class DSLExpressionGenerator implements DSLExpressionVisitor { | |
39 | |
40 private final Map<Variable, CodeTree> bindings; | |
41 private final CodeTree root; | |
42 private final Deque<CodeTree> stack = new ArrayDeque<>(); | |
43 | |
44 public DSLExpressionGenerator(CodeTree root, Map<Variable, CodeTree> bindings) { | |
45 this.bindings = bindings; | |
46 this.root = root; | |
47 } | |
48 | |
49 public void visitBinary(Binary binary) { | |
50 CodeTree right = stack.pop(); | |
51 CodeTree left = stack.pop(); | |
52 stack.push(combine(left, string(" " + binary.getOperator() + " "), right)); | |
53 } | |
54 | |
55 public void visitCall(Call call) { | |
56 ExecutableElement method = call.getResolvedMethod(); | |
57 CodeTree[] parameters = new CodeTree[method.getParameters().size()]; | |
58 for (int i = 0; i < parameters.length; i++) { | |
59 parameters[parameters.length - i - 1] = pop(); | |
60 } | |
61 | |
62 CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); | |
63 | |
64 if (call.getReceiver() == null) { | |
65 if (isStatic(method)) { | |
66 builder.startStaticCall(method); | |
67 } else { | |
68 if (root != null) { | |
69 builder.tree(root).string("."); | |
70 } | |
71 builder.startCall(method.getSimpleName().toString()); | |
72 } | |
73 } else { | |
74 if (isStatic(method)) { | |
75 throw new AssertionError("Static calls must not have receivers."); | |
76 } | |
77 builder.startCall(pop(), method.getSimpleName().toString()); | |
78 } | |
79 for (CodeTree parameter : parameters) { | |
80 builder.tree(parameter); | |
81 } | |
82 builder.end(); | |
83 | |
84 push(builder.build()); | |
85 } | |
86 | |
87 public void visitIntLiteral(IntLiteral binary) { | |
88 push(string(binary.getLiteral())); | |
89 } | |
90 | |
91 public void visitNegate(Negate negate) { | |
92 push(combine(string("!"), pop())); | |
93 } | |
94 | |
95 public void visitVariable(Variable variable) { | |
96 VariableElement resolvedVariable = variable.getResolvedVariable(); | |
97 CodeTree tree; | |
98 if (variable.getReceiver() == null) { | |
99 | |
100 if (isStatic(resolvedVariable)) { | |
101 tree = staticReference(resolvedVariable); | |
102 } else { | |
103 tree = bindings.get(variable); | |
104 boolean bound = true; | |
105 if (tree == null) { | |
106 tree = string(resolvedVariable.getSimpleName().toString()); | |
107 bound = false; | |
108 } | |
109 if (root != null && !bound) { | |
110 tree = combine(root, string("."), tree); | |
111 } | |
112 } | |
113 } else { | |
114 if (isStatic(resolvedVariable)) { | |
115 throw new AssertionError("Static variables cannot have receivers."); | |
116 } | |
117 tree = combine(pop(), string("."), string(resolvedVariable.getSimpleName().toString())); | |
118 } | |
119 push(tree); | |
120 } | |
121 | |
122 private static boolean isStatic(Element element) { | |
123 return element.getModifiers().contains(Modifier.STATIC); | |
124 } | |
125 | |
126 private static CodeTree combine(CodeTree tree1, CodeTree tree2) { | |
127 return new CodeTreeBuilder(null).startGroup().tree(tree1).tree(tree2).end().build(); | |
128 } | |
129 | |
130 private static CodeTree combine(CodeTree tree1, CodeTree tree2, CodeTree tree3) { | |
131 return new CodeTreeBuilder(null).startGroup().tree(tree1).tree(tree2).tree(tree3).end().build(); | |
132 } | |
133 | |
134 private static CodeTree string(String s) { | |
135 return CodeTreeBuilder.singleString(s); | |
136 } | |
137 | |
138 private static CodeTree staticReference(VariableElement var) { | |
139 return CodeTreeBuilder.createBuilder().staticReference(var.asType(), var.getSimpleName().toString()).build(); | |
140 } | |
141 | |
142 private void push(CodeTree tree) { | |
143 stack.push(tree); | |
144 } | |
145 | |
146 private CodeTree pop() { | |
147 return stack.pop(); | |
148 } | |
149 | |
150 public static CodeTree write(DSLExpression expression, CodeTree root, Map<Variable, CodeTree> bindings) { | |
151 DSLExpressionGenerator writer = new DSLExpressionGenerator(root, bindings); | |
152 expression.accept(writer); | |
153 return writer.pop(); | |
154 } | |
155 | |
156 } |