comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemCodeGenerator.java @ 11545:2fb276f5e3e9

Truffle-DSL: implemented implicit casts.
author Christian Humer <christian.humer@gmail.com>
date Fri, 06 Sep 2013 16:16:40 +0200
parents b7f90ff38d4b
children 8e8347ecabbc
comparison
equal deleted inserted replaced
11544:e5b5a5cb0ac7 11545:2fb276f5e3e9
42 42
43 public static String isTypeMethodName(TypeData type) { 43 public static String isTypeMethodName(TypeData type) {
44 return "is" + Utils.getTypeId(type.getBoxedType()); 44 return "is" + Utils.getTypeId(type.getBoxedType());
45 } 45 }
46 46
47 public static String isImplicitTypeMethodName(TypeData type) {
48 return "isImplicit" + Utils.getTypeId(type.getBoxedType());
49 }
50
47 public static String asTypeMethodName(TypeData type) { 51 public static String asTypeMethodName(TypeData type) {
48 return "as" + Utils.getTypeId(type.getBoxedType()); 52 return "as" + Utils.getTypeId(type.getBoxedType());
53 }
54
55 public static String asImplicitTypeMethodName(TypeData type) {
56 return "asImplicit" + Utils.getTypeId(type.getBoxedType());
57 }
58
59 public static String getImplicitClass(TypeData type) {
60 return "getImplicit" + Utils.getTypeId(type.getBoxedType()) + "Class";
49 } 61 }
50 62
51 public static String expectTypeMethodName(TypeData type) { 63 public static String expectTypeMethodName(TypeData type) {
52 return "expect" + Utils.getTypeId(type.getBoxedType()); 64 return "expect" + Utils.getTypeId(type.getBoxedType());
53 } 65 }
98 CodeExecutableElement expect = createExpectTypeMethod(type, sourceType); 110 CodeExecutableElement expect = createExpectTypeMethod(type, sourceType);
99 if (expect != null) { 111 if (expect != null) {
100 clazz.add(expect); 112 clazz.add(expect);
101 } 113 }
102 } 114 }
115
116 CodeExecutableElement asImplicit = createAsImplicitTypeMethod(type);
117 if (asImplicit != null) {
118 clazz.add(asImplicit);
119 }
120 CodeExecutableElement isImplicit = createIsImplicitTypeMethod(type);
121 if (isImplicit != null) {
122 clazz.add(isImplicit);
123 }
124
125 CodeExecutableElement typeIndex = createGetTypeIndex(type);
126 if (typeIndex != null) {
127 clazz.add(typeIndex);
128 }
103 } 129 }
104 } 130 }
105 131
106 return clazz; 132 return clazz;
107 } 133 }
131 CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(getModel().getTemplateType().asType())); 157 CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(getModel().getTemplateType().asType()));
132 field.createInitBuilder().startNew(clazz.asType()).end(); 158 field.createInitBuilder().startNew(clazz.asType()).end();
133 return field; 159 return field;
134 } 160 }
135 161
162 private CodeExecutableElement createIsImplicitTypeMethod(TypeData type) {
163 TypeSystemData typeSystem = getModel();
164 List<ImplicitCastData> casts = typeSystem.lookupByTargetType(type);
165 if (casts.isEmpty()) {
166 return null;
167 }
168 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type));
169 method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE));
170 CodeTreeBuilder builder = method.createBuilder();
171
172 List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type);
173
174 builder.startReturn();
175 String sep = "";
176 for (TypeData sourceType : sourceTypes) {
177 builder.string(sep);
178 builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
179 sep = " || ";
180 }
181 builder.end();
182 return method;
183 }
184
185 private CodeExecutableElement createAsImplicitTypeMethod(TypeData type) {
186 TypeSystemData typeSystem = getModel();
187 List<ImplicitCastData> casts = typeSystem.lookupByTargetType(type);
188 if (casts.isEmpty()) {
189 return null;
190 }
191 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asImplicitTypeMethodName(type));
192 method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE));
193
194 List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type);
195
196 CodeTreeBuilder builder = method.createBuilder();
197 boolean elseIf = false;
198 for (TypeData sourceType : sourceTypes) {
199 elseIf = builder.startIf(elseIf);
200 builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
201 builder.end().startBlock();
202
203 builder.startReturn();
204 ImplicitCastData cast = typeSystem.lookupCast(sourceType, type);
205 if (cast != null) {
206 builder.startCall(cast.getMethodName());
207 }
208 builder.startCall(asTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
209 if (cast != null) {
210 builder.end();
211 }
212 builder.end();
213 builder.end();
214 }
215
216 builder.startElseBlock();
217 builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end().end();
218 builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end();
219 builder.end();
220 return method;
221 }
222
223 private CodeExecutableElement createGetTypeIndex(TypeData type) {
224 TypeSystemData typeSystem = getModel();
225 List<ImplicitCastData> casts = typeSystem.lookupByTargetType(type);
226 if (casts.isEmpty()) {
227 return null;
228 }
229 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type));
230 method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE));
231
232 List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type);
233 CodeTreeBuilder builder = method.createBuilder();
234 boolean elseIf = false;
235 for (TypeData sourceType : sourceTypes) {
236 elseIf = builder.startIf(elseIf);
237 builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
238 builder.end().startBlock();
239 builder.startReturn().typeLiteral(sourceType.getPrimitiveType()).end();
240 builder.end();
241 }
242
243 builder.startElseBlock();
244 builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end().end();
245 builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end();
246 builder.end();
247
248 return method;
249 }
250
136 private CodeExecutableElement createIsTypeMethod(TypeData type) { 251 private CodeExecutableElement createIsTypeMethod(TypeData type) {
137 if (!type.getTypeChecks().isEmpty()) { 252 if (!type.getTypeChecks().isEmpty()) {
138 return null; 253 return null;
139 } 254 }
140 255
172 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType)); 287 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType));
173 method.addParameter(new CodeVariableElement(sourceType.getPrimitiveType(), LOCAL_VALUE)); 288 method.addParameter(new CodeVariableElement(sourceType.getPrimitiveType(), LOCAL_VALUE));
174 method.addThrownType(getContext().getTruffleTypes().getUnexpectedValueException()); 289 method.addThrownType(getContext().getTruffleTypes().getUnexpectedValueException());
175 290
176 CodeTreeBuilder body = method.createBuilder(); 291 CodeTreeBuilder body = method.createBuilder();
177 body.startIf().startCall(null, TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock(); 292 body.startIf().startCall(TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock();
178 body.startReturn().startCall(null, TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end(); 293 body.startReturn().startCall(TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end();
179 body.end(); // if-block 294 body.end(); // if-block
180 body.startThrow().startNew(getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end(); 295 body.startThrow().startNew(getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end();
181 296
182 return method; 297 return method;
183 } 298 }