Method: consInterface(AMethodTypeIR, List)

1: /*
2: * #%~
3: * VDM Code Generator
4: * %%
5: * Copyright (C) 2008 - 2014 Overture
6: * %%
7: * This program is free software: you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation, either version 3 of the
10: * License, or (at your option) any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public
18: * License along with this program. If not, see
19: * <http://www.gnu.org/licenses/gpl-3.0.html>.
20: * #~%
21: */
22: package org.overture.codegen.trans.funcvalues;
23:
24: import java.util.LinkedList;
25: import java.util.List;
26:
27: import org.overture.ast.types.AFunctionType;
28: import org.overture.ast.types.PType;
29: import org.overture.codegen.ir.IRConstants;
30: import org.overture.codegen.ir.SPatternIR;
31: import org.overture.codegen.ir.STypeIR;
32: import org.overture.codegen.ir.analysis.AnalysisException;
33: import org.overture.codegen.ir.analysis.DepthFirstAnalysisAdaptor;
34: import org.overture.codegen.ir.declarations.AFormalParamLocalParamIR;
35: import org.overture.codegen.ir.declarations.AInterfaceDeclIR;
36: import org.overture.codegen.ir.declarations.AMethodDeclIR;
37: import org.overture.codegen.ir.expressions.AAnonymousClassExpIR;
38: import org.overture.codegen.ir.expressions.ALambdaExpIR;
39: import org.overture.codegen.ir.expressions.AMethodInstantiationExpIR;
40: import org.overture.codegen.ir.expressions.SVarExpIR;
41: import org.overture.codegen.ir.patterns.AIdentifierPatternIR;
42: import org.overture.codegen.ir.statements.ABlockStmIR;
43: import org.overture.codegen.ir.statements.AReturnStmIR;
44: import org.overture.codegen.ir.types.AInterfaceTypeIR;
45: import org.overture.codegen.ir.types.AMethodTypeIR;
46: import org.overture.codegen.ir.types.ATemplateTypeIR;
47: import org.overture.codegen.trans.assistants.TransAssistantIR;
48:
49: public class FuncValTrans extends DepthFirstAnalysisAdaptor
50: {
51:         private TransAssistantIR transformationAssistant;
52:         private FuncValAssistant functionValueAssistant;
53:         private FuncValPrefixes funcValPrefixes;
54:
55:         public FuncValTrans(TransAssistantIR transformationAssistant,
56:                         FuncValAssistant functionValueAssistant,
57:                         FuncValPrefixes funcValPrefixes)
58:         {
59:                 this.transformationAssistant = transformationAssistant;
60:                 this.functionValueAssistant = functionValueAssistant;
61:                 this.funcValPrefixes = funcValPrefixes;
62:         }
63:
64:         public FuncValAssistant getFunctionValueAssistant()
65:         {
66:                 return functionValueAssistant;
67:         }
68:
69:         @Override
70:         public void inAMethodTypeIR(AMethodTypeIR node) throws AnalysisException
71:         {
72:                 if (node.parent() instanceof AMethodDeclIR)
73:                 {
74:                         return;
75:                 }
76:
77:                 if (node.parent() instanceof SVarExpIR)
78:                 {
79:                         return;
80:                 }
81:
82:                 if (node.parent() instanceof AMethodInstantiationExpIR)
83:                 {
84:                         return;
85:                 }
86:
87:                 PType vdmType = node.getEquivalent();
88:
89:                 if (!(vdmType instanceof AFunctionType))
90:                 {
91:                         // vdmType == null:
92:                         // Can be the case if the default constructor in the IR AST has been manually
93:                         // constructed. In this case it is not needed to construct the
94:                         // interface
95:
96:                         // vdmType can also be an operation type, but operations cannot be used as values
97:                         return;
98:                 }
99:
100:                 AInterfaceDeclIR info = functionValueAssistant.findInterface(node);
101:
102:                 if (info == null)
103:                 {
104:                         info = consInterface(node);
105:                         functionValueAssistant.registerInterface(info);
106:                 }
107:         }
108:
109:         @Override
110:         public void inALambdaExpIR(ALambdaExpIR node) throws AnalysisException
111:         {
112:                 AMethodTypeIR methodType = (AMethodTypeIR) node.getType().clone();
113:                 AInterfaceDeclIR lambdaInterface = functionValueAssistant.findInterface(methodType);
114:
115:                 if (lambdaInterface == null)
116:                 {
117:                         @SuppressWarnings("unchecked")
118:                         List<? extends AFormalParamLocalParamIR> formalParams = (List<? extends AFormalParamLocalParamIR>) node.getParams().clone();
119:                         lambdaInterface = consInterface(methodType, formalParams);
120:
121:                         functionValueAssistant.registerInterface(lambdaInterface);
122:                 }
123:
124:                 LinkedList<AFormalParamLocalParamIR> params = node.getParams();
125:
126:                 AInterfaceTypeIR classType = new AInterfaceTypeIR();
127:                 classType.setName(lambdaInterface.getName());
128:
129:                 AMethodDeclIR lambdaDecl = lambdaInterface.getMethodSignatures().get(0).clone();
130:                 lambdaDecl.setAbstract(false);
131:
132:                 for (int i = 0; i < params.size(); i++)
133:                 {
134:                         AFormalParamLocalParamIR paramLocalDeclIR = params.get(i);
135:                         STypeIR paramType = paramLocalDeclIR.getType();
136:                         SPatternIR pattern = paramLocalDeclIR.getPattern();
137:
138:                         classType.getTypes().add(paramType.clone());
139:                         lambdaDecl.getFormalParams().get(i).setType(paramType.clone());
140:                         lambdaDecl.getFormalParams().get(i).setPattern(pattern.clone());
141:                 }
142:
143:                 classType.getTypes().add(methodType.getResult().clone());
144:                 lambdaDecl.getMethodType().setResult(methodType.getResult().clone());
145:
146:                 AReturnStmIR lambdaReturn = new AReturnStmIR();
147:                 lambdaReturn.setExp(node.getExp().clone());
148:
149:                 ABlockStmIR lambdaBody = new ABlockStmIR();
150:                 lambdaBody.getStatements().add(lambdaReturn);
151:
152:                 lambdaDecl.setAbstract(false);
153:                 lambdaDecl.setBody(lambdaBody);
154:
155:                 AAnonymousClassExpIR classExp = new AAnonymousClassExpIR();
156:                 classExp.setType(classType);
157:                 classExp.getMethods().add(lambdaDecl);
158:
159:                 transformationAssistant.replaceNodeWithRecursively(node, classExp, this);
160:         }
161:
162:         private AInterfaceDeclIR consInterface(AMethodTypeIR methodType)
163:         {
164:                 List<AFormalParamLocalParamIR> params = new LinkedList<AFormalParamLocalParamIR>();
165:
166:                 List<STypeIR> paramTypes = methodType.getParams();
167:
168:                 for (int i = 0; i < paramTypes.size(); i++)
169:                 {
170:                         STypeIR paramType = paramTypes.get(i);
171:
172:                         AFormalParamLocalParamIR param = new AFormalParamLocalParamIR();
173:
174:                         String nextParamName = funcValPrefixes.param() + (i + 1);
175:                         AIdentifierPatternIR idPattern = new AIdentifierPatternIR();
176:                         idPattern.setName(nextParamName);
177:
178:                         param.setType(paramType.clone());
179:                         param.setPattern(idPattern);
180:
181:                         params.add(param);
182:                 }
183:
184:                 return consInterface(methodType, params);
185:         }
186:
187:         private AInterfaceDeclIR consInterface(AMethodTypeIR methodType,
188:                         List<? extends AFormalParamLocalParamIR> params)
189:         {
190:                 AInterfaceDeclIR methodTypeInterface = new AInterfaceDeclIR();
191:
192:                 methodTypeInterface.setPackage(null);
193:                 methodTypeInterface.setName(transformationAssistant.getInfo().getTempVarNameGen().nextVarName(funcValPrefixes.funcInterface()));
194:
195:                 AMethodDeclIR evalMethod = new AMethodDeclIR();
196:                 evalMethod.setImplicit(false);
197:                 evalMethod.setAbstract(true);
198:                 evalMethod.setAccess(IRConstants.PUBLIC);
199:                 evalMethod.setBody(null);
200:                 evalMethod.setIsConstructor(false);
201:                 evalMethod.setMethodType(methodType.clone());
202:                 evalMethod.setName(funcValPrefixes.evalMethod());
203:                 evalMethod.setStatic(false);
204:
205:                 AMethodTypeIR evalMethodType = new AMethodTypeIR();
206:
207:•                for (int i = 0; i < params.size(); i++)
208:                 {
209:                         ATemplateTypeIR templateType = new ATemplateTypeIR();
210:                         templateType.setName(funcValPrefixes.templateType() + (i + 1));
211:
212:                         AFormalParamLocalParamIR formalParam = new AFormalParamLocalParamIR();
213:                         formalParam.setType(templateType);
214:                         formalParam.setPattern(params.get(i).getPattern().clone());
215:
216:                         evalMethod.getFormalParams().add(formalParam);
217:                         methodTypeInterface.getTemplateTypes().add(templateType.clone());
218:                         evalMethodType.getParams().add(templateType.clone());
219:                 }
220:
221:                 methodTypeInterface.getMethodSignatures().add(evalMethod);
222:
223:                 ATemplateTypeIR templateTypeResult = new ATemplateTypeIR();
224:                 templateTypeResult.setName(funcValPrefixes.templateType()
225:                                 + (methodType.getParams().size() + 1));
226:                 methodTypeInterface.getTemplateTypes().add(templateTypeResult);
227:                 evalMethodType.setResult(templateTypeResult.clone());
228:
229:                 evalMethod.setMethodType(evalMethodType);
230:
231:                 return methodTypeInterface;
232:         }
233: }