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 }