Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / codegen / java / JavaExpression.java @ 9

1
/**
2
  *
3
  *                      OOAS Compiler
4
  *
5
  *       Copyright 2015, AIT Austrian Institute of Technology.
6
  * This code is based on the C# Version of the OOAS Compiler, which is
7
  * copyright 2015 by the Institute of Software Technology, Graz University
8
  * of Technology with portions copyright by the AIT Austrian Institute of
9
  * Technology. All rights reserved.
10
  *
11
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
12
  *
13
  * If you modify the file please update the list of contributors below to in-
14
  * clude your name. Please also stick to the coding convention of using TABs
15
  * to do the basic (block-level) indentation and spaces for anything after
16
  * that. (Enable the display of special chars and it should be pretty obvious
17
  * what this means.) Also, remove all trailing whitespace.
18
  *
19
  * Contributors:
20
  *               Willibald Krenn (AIT)
21
  *               Stephan Zimmerer (AIT)
22
  *               Markus Demetz (AIT)
23
  *               Christoph Czurda (AIT)
24
  *
25
  */
26

    
27

    
28
package org.momut.ooas.codegen.java;
29

    
30
import java.util.ArrayList;
31

    
32
import org.momut.ooas.ast.expressions.AccessExpression;
33
import org.momut.ooas.ast.expressions.BinaryOperator;
34
import org.momut.ooas.ast.expressions.CallExpression;
35
import org.momut.ooas.ast.expressions.ExistsQuantifier;
36
import org.momut.ooas.ast.expressions.Expression;
37
import org.momut.ooas.ast.expressions.ForallQuantifier;
38
import org.momut.ooas.ast.expressions.IdentifierExpression;
39
import org.momut.ooas.ast.expressions.ListConstructor;
40
import org.momut.ooas.ast.expressions.MapConstructor;
41
import org.momut.ooas.ast.expressions.ObjectConstructor;
42
import org.momut.ooas.ast.expressions.SetConstructor;
43
import org.momut.ooas.ast.expressions.TernaryOperator;
44
import org.momut.ooas.ast.expressions.TupleConstructor;
45
import org.momut.ooas.ast.expressions.TupleMapAccessExpression;
46
import org.momut.ooas.ast.expressions.TypeExpression;
47
import org.momut.ooas.ast.expressions.UnaryOperator;
48
import org.momut.ooas.ast.expressions.UnresolvedIdentifierExpression;
49
import org.momut.ooas.ast.expressions.ValueExpression;
50
import org.momut.ooas.ast.identifiers.EnumIdentifier;
51
import org.momut.ooas.ast.identifiers.Identifier;
52
import org.momut.ooas.ast.identifiers.IdentifierKind;
53
import org.momut.ooas.ast.types.TypeKind;
54
import org.momut.ooas.ast.types.Type;
55
import org.momut.ooas.codegen.OoasCodeEmitter;
56
import org.momut.ooas.utils.UnsignedHelper;
57
import org.momut.ooas.utils.exceptions.NotImplementedException;
58
import org.momut.ooas.utils.exceptions.OoasCompilerRuntimeException;
59
import org.momut.ooas.visitors.OoaExpressionVisitor;
60

    
61
public final class JavaExpression extends OoaExpressionVisitor
62
{
63
        private final OoasCodeEmitter m_emitter = new OoasCodeEmitter();
64
        private final Scratchbook m_data;
65
        private final StringBuilder m_helpers;
66

    
67
        private String GetIdentifierString(String anIdentifier)
68
        {
69
                return JavaIdentifier.GetIdentifierString(anIdentifier);
70
        }
71

    
72
        public ArrayList<ObjectConstructor> constructors() { return m_data.m_constructors; }
73

    
74
        // following calls must not happen
75
        @Override
76
        public void visit(UnresolvedIdentifierExpression unresolvedIdentifierExpression)
77
        {
78
                throw new OoasCompilerRuntimeException();
79
        }
80
        @Override
81
        public void visit(CallExpression callExpression)
82
        {
83
                throw new OoasCompilerRuntimeException();
84
//                System.Diagnostics.Debug.Assert(false);
85
        }
86

    
87

    
88
        // we need to map all other things to Java constructs
89
        private String OperatorString(Expression expression)
90
        {
91
                switch (expression.kind())
92
                {
93
                case abs:    // T_ABS:
94
                case card:   // T_CARD:
95
                case dom:    // T_DOM:
96
                case range:  // T_RNG:
97
                case merge:  // T_MERGE:
98
                case len:    // T_LEN:
99
                case elems:  // T_ELEMS:
100
                case head:   // T_HEAD:
101
                case tail:   // T_TAIL:
102
                case conc:   // T_CONC:
103
                case inds:   // T_INDS:
104
                case dinter: // T_DINTER:
105
                case dunion: // T_DUNION:
106
                case domresby:   // T_DOMRESBY:
107
                case domresto:   // T_DOMRESTO:
108
                case rngresby:   // T_RNGRESBY:
109
                case rngresto:   // T_RNGRESTO:
110
                case inter:  // T_INTER:
111
                case union:  // T_UNION:
112
                case diff:   // T_DIFF:
113
                case munion: // T_MUNION:
114
                case seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
115
                case subset:
116
                case elemin:
117
                case notelemin:
118
                case implies:    // T_IMPLIES:
119
                case biimplies:  // T_BIIMPLIES:
120
                case Primed:
121
                        throw new NotImplementedException();
122
                case div:    // T_DIV:
123
                        return "/";
124
                case idiv:   // T_IDIV:
125
                        return "/";
126
                case mod:    // T_MOD:
127
                        return "%";
128
                case prod:   // T_PROD:
129
                        return "*";
130
                case sum:    // T_SUM:
131
                        return "+";
132
                case minus:  // T_MINUS:
133
                        return "-";
134
                case less:
135
                        return "<";
136
                case lessequal:
137
                        return "<=";
138
                case greater:
139
                        return ">";
140
                case greaterequal:
141
                        return ">=";
142
                case equal:
143
                        return "==";
144
                case notequal:
145
                        return "!=";
146
                case and:    // T_AND:
147
                        return "&&";
148
                case or:     // T_OR:
149
                        return "||";
150
                case not:
151
                        return "!";
152

    
153
                case Cast:
154
                        final JavaType ctype = new JavaType();
155
                        expression.type().Accept(ctype);
156
                        return String.format("(%s)", ctype.toString());
157

    
158
                default:
159
                        return expression.kind().name(); //Enum.GetName(typeof(ExpressionKind), expression.kind);
160
                }
161
        }
162
        @Override
163
        public <T> void visit(ValueExpression<T> valueExpression)
164
        {
165
                if (valueExpression.value() == null)
166
                        m_emitter.Append("null");
167
                else if (valueExpression.m_clazz.equals(Boolean.class))
168
                        m_emitter.Append(valueExpression.value().toString().toLowerCase());
169
                else
170
                        m_emitter.Append(valueExpression.value().toString());
171
        }
172
        @Override
173
        public void visit(IdentifierExpression identifierExpression)
174
        {
175
                if (identifierExpression.identifier().kind() == IdentifierKind.EnumIdentifier)
176
                {
177
                        m_emitter.Append(GetIdentifierString(((EnumIdentifier)identifierExpression.identifier()).type().identifier().tokenText()));
178
                        m_emitter.Append(".");
179
                }
180

    
181
                m_emitter.Append(GetIdentifierString(identifierExpression.identifier().tokenText()));
182
        }
183

    
184
        @Override
185
        public void visit(TypeExpression typeExpression)
186
        {
187
                if (typeExpression.type().kind() != TypeKind.QrType &&
188
                                typeExpression.type().kind() != TypeKind.EnumeratedType)
189
                        m_emitter.Append(GetIdentifierString(typeExpression.type().identifier().tokenText()));
190
        }
191

    
192

    
193
        @Override
194
        public void visit(ObjectConstructor objectConstructor)
195
        {
196
                final int num = m_data.m_constructors.size();
197
                m_data.m_constructors.add(objectConstructor);
198
                if (objectConstructor.givenObjectName() != null)
199
                        m_emitter.Append(String.format("new %s(this,%s,\"%s\")",
200
                                        GetIdentifierString(objectConstructor.type().identifier().tokenText()),
201
                                        num,
202
                                        objectConstructor.givenObjectName()));
203
                else
204
                        m_emitter.Append(String.format("new %s(this,%s)",
205
                                        GetIdentifierString(objectConstructor.type().identifier().tokenText()),
206
                                        num));
207
        }
208

    
209
        @Override
210
        public void visit(ListConstructor listConstructor)
211
        {
212
                if (listConstructor.hasComprehension())
213
                {
214
                        final String helpername = String.format("list_constr_helper_%s", UnsignedHelper.toString(listConstructor.hashCode()));
215
                        m_emitter.Append(String.format("%s(new org.momut.ooas.codegen.java.runtime.CustomList<Object>())",
216
                                        helpername));
217
                        final OoasCodeEmitter helperEmitter = new OoasCodeEmitter();
218
                        helperEmitter.AppendLine(String.format(
219
                                        "public org.momut.ooas.codegen.java.runtime.CustomList<Object> %s (org.momut.ooas.codegen.java.runtime.CustomList<Object> newList){",
220
                                        helpername));
221

    
222

    
223
                        for (final Identifier sym: listConstructor.comprehensionVariables().symbolList())
224
                        {
225
                                final JavaType atype = new JavaType();
226
                                sym.type().Accept(atype);
227

    
228
                                if (sym.type().IsNumeric())
229
                                        helperEmitter.AppendLine(String.format("for (%s %s = %s; %s <= %s; %s++) {",
230
                                                        atype.toString(),
231
                                                        JavaIdentifier.GetIdentifierString(sym.tokenText()),
232
                                                        Type.Low(sym.type()),
233
                                                        JavaIdentifier.GetIdentifierString(sym.tokenText()),
234
                                                        Type.High(sym.type()),
235
                                                        JavaIdentifier.GetIdentifierString(sym.tokenText())));
236
                                else
237
                                        throw new NotImplementedException();
238
                        }
239

    
240
                        final StringBuilder helperhelper = new StringBuilder();
241

    
242

    
243
                        String guardexpr = "true";
244
                        if (listConstructor.comprehension() != null)
245
                        {
246
                                final JavaExpression expr = new JavaExpression(helperhelper, m_data);
247
                                listConstructor.comprehension().Accept(expr);
248
                                guardexpr = expr.toString();
249
                        }
250

    
251
                        final JavaExpression expr2 = new JavaExpression(helperhelper, m_data);
252
                        listConstructor.elements().get(0).Accept(expr2);
253

    
254
                        helperEmitter.AppendLine(String.format("if (%s) {", guardexpr));
255
                        helperEmitter.AppendLine(String.format("newList.Add(%s);", expr2.toString()));
256
                        helperEmitter.AppendLine("}");
257

    
258
                        final int count = listConstructor.comprehensionVariables().symbolList().size();
259
                        for (int i = 0; i< count; i++)
260
                                helperEmitter.AppendLine("}");
261

    
262
                        helperEmitter.AppendLineIncIndent("return newList;");
263
                        helperEmitter.AppendLine("}");
264
                        m_helpers.append(helperEmitter.toString());
265
                        m_helpers.append(helperhelper.toString());
266
                }
267
                else
268
                {
269
                        m_emitter.Append("new org.momut.ooas.codegen.java.runtime.CustomList<Object>(");
270
                        int i = 0;
271
                        if (listConstructor.elements().size() > 0)
272
                        {
273
                                m_emitter.Append("new Object[] { ");
274
                                for (final Expression x: listConstructor.elements())
275
                                {
276
                                        if (i != 0)
277
                                                m_emitter.Append(",");
278
                                        else
279
                                                i++;
280
                                        x.Accept(this);
281
                                }
282
                                m_emitter.Append(" }");
283
                        }
284
                        m_emitter.Append(")");
285
                }
286
        }
287

    
288
        @Override
289
        public void visit(SetConstructor setConstructor)
290
        {
291
                throw new NotImplementedException();
292
        }
293

    
294
        @Override
295
        public void visit(MapConstructor mapConstructor)
296
        {
297
                throw new NotImplementedException();
298
        }
299

    
300
        @Override
301
        public void visit(TupleConstructor tupleConstructor)
302
        {
303
                m_emitter.Append(String.format("new %s(", GetIdentifierString(tupleConstructor.tupleType().tokenText())));
304
                int i = 0;
305
                for (final Expression arg: tupleConstructor.values())
306
                {
307
                        if (i != 0)
308
                                m_emitter.Append(",");
309
                        else
310
                                i++;
311
                        arg.Accept(this);
312
                }
313
                m_emitter.Append(")");
314
        }
315

    
316
        @Override
317
        public void visit(AccessExpression accessExpression)
318
        {
319
                if (accessExpression.left().type().kind() != TypeKind.QrType &&
320
                                accessExpression.left().type().kind() != TypeKind.EnumeratedType)
321
                {
322
                        // enums and qr types are directly (statically) converted to nums...
323
                        VisitSub(accessExpression.left(), accessExpression);
324
                        m_emitter.Append(".");
325
                }
326
                VisitSub(accessExpression.right(), accessExpression);
327
        }
328

    
329
        @Override
330
        public void visit(BinaryOperator binaryOperator)
331
        {
332
                m_emitter.Append("(");
333
                VisitSub(binaryOperator.left(), binaryOperator);
334
                m_emitter.Append(") ");
335
                m_emitter.Append(OperatorString(binaryOperator));
336
                m_emitter.Append(" (");
337
                VisitSub(binaryOperator.right(), binaryOperator);
338
                m_emitter.Append(")");
339
        }
340

    
341
        @Override
342
        public void visit(TernaryOperator ternaryOperator)
343
        {
344
                m_emitter.Append("(");
345
                VisitSub(ternaryOperator.left(), ternaryOperator);
346
                m_emitter.Append(" ? ");
347

    
348
                VisitSub(ternaryOperator.mid(), ternaryOperator);
349
                m_emitter.Append(" : ");
350

    
351
                VisitSub(ternaryOperator.right(), ternaryOperator);
352
                m_emitter.Append(")");
353
        }
354
        @Override
355
        public void visit(TupleMapAccessExpression tupleMapAccessExpression)
356
        {
357
                throw new NotImplementedException();
358
        }
359
        @Override
360
        public void visit(ForallQuantifier quantifier)
361
        {
362
                throw new NotImplementedException();
363
        }
364
        @Override
365
        public void visit(ExistsQuantifier quantifier)
366
        {
367
                throw new NotImplementedException();
368
        }
369
        @Override
370
        public void visit(UnaryOperator unaryOperator)
371
        {
372
                m_emitter.Append(" ");
373
                m_emitter.Append(OperatorString(unaryOperator));
374
                m_emitter.Append("(");
375
                VisitSub(unaryOperator.child(), unaryOperator);
376
                m_emitter.Append(")");
377
        }
378

    
379
        @Override
380
        public String toString()
381
        {
382
                return m_emitter.toString();
383
        }
384

    
385
        public JavaExpression(StringBuilder helpers, Scratchbook data)
386
        {
387
                super ();
388
                m_helpers = helpers;
389
                m_data = data;
390
        }
391
}