Project

General

Profile

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

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.QValConstructor;
43
import org.momut.ooas.ast.expressions.SetConstructor;
44
import org.momut.ooas.ast.expressions.TernaryOperator;
45
import org.momut.ooas.ast.expressions.TupleConstructor;
46
import org.momut.ooas.ast.expressions.TupleMapAccessExpression;
47
import org.momut.ooas.ast.expressions.TypeExpression;
48
import org.momut.ooas.ast.expressions.UnaryOperator;
49
import org.momut.ooas.ast.expressions.UnresolvedIdentifierExpression;
50
import org.momut.ooas.ast.expressions.ValueExpression;
51
import org.momut.ooas.ast.expressions.QValConstructor.QValDeriv;
52
import org.momut.ooas.ast.identifiers.EnumIdentifier;
53
import org.momut.ooas.ast.identifiers.Identifier;
54
import org.momut.ooas.ast.identifiers.IdentifierKind;
55
import org.momut.ooas.ast.identifiers.LandmarkIdentifier;
56
import org.momut.ooas.ast.types.QrType;
57
import org.momut.ooas.ast.types.TypeKind;
58
import org.momut.ooas.ast.types.UlyssesType;
59
import org.momut.ooas.codegen.OoasCodeEmitter;
60
import org.momut.ooas.utils.UnsignedHelper;
61
import org.momut.ooas.utils.exceptions.NotImplementedException;
62
import org.momut.ooas.utils.exceptions.OoasCompilerRuntimeException;
63
import org.momut.ooas.visitors.OoaExpressionVisitor;
64

    
65
public final class JavaExpression extends OoaExpressionVisitor
66
{
67
        private final OoasCodeEmitter m_emitter = new OoasCodeEmitter();
68
        private final Scratchbook m_data;
69
        private final StringBuilder m_helpers;
70

    
71
        private String GetIdentifierString(String anIdentifier)
72
        {
73
                return JavaIdentifier.GetIdentifierString(anIdentifier);
74
        }
75

    
76
        public ArrayList<ObjectConstructor> constructors() { return m_data.m_constructors; }
77

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

    
91

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

    
157
                case Cast:
158
                        final JavaType ctype = new JavaType();
159
                        expression.type().Accept(ctype);
160
                        return String.format("(%s)", ctype.toString());
161

    
162
                default:
163
                        return expression.kind().name(); //Enum.GetName(typeof(ExpressionKind), expression.kind);
164
                }
165
        }
166
        @Override
167
        public <T> void visit(ValueExpression<T> valueExpression)
168
        {
169
                if (valueExpression.value() == null)
170
                        m_emitter.Append("null");
171
                else if (valueExpression.m_clazz.equals(Boolean.class))
172
                        m_emitter.Append(valueExpression.value().toString().toLowerCase());
173
                else
174
                        m_emitter.Append(valueExpression.value().toString());
175
        }
176
        @Override
177
        public void visit(IdentifierExpression identifierExpression)
178
        {
179
                if (identifierExpression.identifier().kind() == IdentifierKind.LandmarkIdentifier)
180
                {
181
                        final LandmarkIdentifier lmid = (LandmarkIdentifier)identifierExpression.identifier();
182
                        final QrType qr = (QrType)lmid.type();
183
                        m_emitter.Append(qr.landmarks().indexOf(lmid));
184
                        return;
185
                }
186

    
187
                if (identifierExpression.identifier().kind() == IdentifierKind.EnumIdentifier)
188
                {
189
                        m_emitter.Append(GetIdentifierString(((EnumIdentifier)identifierExpression.identifier()).type().identifier().tokenText()));
190
                        m_emitter.Append(".");
191
                }
192

    
193
                m_emitter.Append(GetIdentifierString(identifierExpression.identifier().tokenText()));
194
        }
195

    
196
        @Override
197
        public void visit(TypeExpression typeExpression)
198
        {
199
                if (typeExpression.type().kind() != TypeKind.QrType &&
200
                                typeExpression.type().kind() != TypeKind.EnumeratedType)
201
                        m_emitter.Append(GetIdentifierString(typeExpression.type().identifier().tokenText()));
202
        }
203

    
204

    
205
        @Override
206
        public void visit(ObjectConstructor objectConstructor)
207
        {
208
                final int num = m_data.m_constructors.size();
209
                m_data.m_constructors.add(objectConstructor);
210
                if (objectConstructor.givenObjectName() != null)
211
                        m_emitter.Append(String.format("new %s(this,%s,\"%s\")",
212
                                        GetIdentifierString(objectConstructor.type().identifier().tokenText()),
213
                                        num,
214
                                        objectConstructor.givenObjectName()));
215
                else
216
                        m_emitter.Append(String.format("new %s(this,%s)",
217
                                        GetIdentifierString(objectConstructor.type().identifier().tokenText()),
218
                                        num));
219
        }
220

    
221
        @Override
222
        public void visit(ListConstructor listConstructor)
223
        {
224
                if (listConstructor.hasComprehension())
225
                {
226
                        final String helpername = String.format("list_constr_helper_%s", UnsignedHelper.toString(listConstructor.hashCode()));
227
                        m_emitter.Append(String.format("%s(new org.momut.ooas.codegen.java.runtime.CustomList<Object>())",
228
                                        helpername));
229
                        final OoasCodeEmitter helperEmitter = new OoasCodeEmitter();
230
                        helperEmitter.AppendLine(String.format(
231
                                        "public org.momut.ooas.codegen.java.runtime.CustomList<Object> %s (org.momut.ooas.codegen.java.runtime.CustomList<Object> newList){",
232
                                        helpername));
233

    
234

    
235
                        for (final Identifier sym: listConstructor.comprehensionVariables().symbolList())
236
                        {
237
                                final JavaType atype = new JavaType();
238
                                sym.type().Accept(atype);
239

    
240
                                if (sym.type().IsNumeric())
241
                                        helperEmitter.AppendLine(String.format("for (%s %s = %s; %s <= %s; %s++) {",
242
                                                        atype.toString(),
243
                                                        JavaIdentifier.GetIdentifierString(sym.tokenText()),
244
                                                        UlyssesType.Low(sym.type()),
245
                                                        JavaIdentifier.GetIdentifierString(sym.tokenText()),
246
                                                        UlyssesType.High(sym.type()),
247
                                                        JavaIdentifier.GetIdentifierString(sym.tokenText())));
248
                                else
249
                                        throw new NotImplementedException();
250
                        }
251

    
252
                        final StringBuilder helperhelper = new StringBuilder();
253

    
254

    
255
                        String guardexpr = "true";
256
                        if (listConstructor.comprehension() != null)
257
                        {
258
                                final JavaExpression expr = new JavaExpression(helperhelper, m_data);
259
                                listConstructor.comprehension().Accept(expr);
260
                                guardexpr = expr.toString();
261
                        }
262

    
263
                        final JavaExpression expr2 = new JavaExpression(helperhelper, m_data);
264
                        listConstructor.elements().get(0).Accept(expr2);
265

    
266
                        helperEmitter.AppendLine(String.format("if (%s) {", guardexpr));
267
                        helperEmitter.AppendLine(String.format("newList.Add(%s);", expr2.toString()));
268
                        helperEmitter.AppendLine("}");
269

    
270
                        final int count = listConstructor.comprehensionVariables().symbolList().size();
271
                        for (int i = 0; i< count; i++)
272
                                helperEmitter.AppendLine("}");
273

    
274
                        helperEmitter.AppendLineIncIndent("return newList;");
275
                        helperEmitter.AppendLine("}");
276
                        m_helpers.append(helperEmitter.toString());
277
                        m_helpers.append(helperhelper.toString());
278
                }
279
                else
280
                {
281
                        m_emitter.Append("new org.momut.ooas.codegen.java.runtime.CustomList<Object>(");
282
                        int i = 0;
283
                        if (listConstructor.elements().size() > 0)
284
                        {
285
                                m_emitter.Append("new Object[] { ");
286
                                for (final Expression x: listConstructor.elements())
287
                                {
288
                                        if (i != 0)
289
                                                m_emitter.Append(",");
290
                                        else
291
                                                i++;
292
                                        x.Accept(this);
293
                                }
294
                                m_emitter.Append(" }");
295
                        }
296
                        m_emitter.Append(")");
297
                }
298
        }
299

    
300
        @Override
301
        public void visit(SetConstructor setConstructor)
302
        {
303
                throw new NotImplementedException();
304
        }
305

    
306
        @Override
307
        public void visit(MapConstructor mapConstructor)
308
        {
309
                throw new NotImplementedException();
310
        }
311

    
312
        @Override
313
        public void visit(TupleConstructor tupleConstructor)
314
        {
315
                m_emitter.Append(String.format("new %s(", GetIdentifierString(tupleConstructor.tupleType().tokenText())));
316
                int i = 0;
317
                for (final Expression arg: tupleConstructor.values())
318
                {
319
                        if (i != 0)
320
                                m_emitter.Append(",");
321
                        else
322
                                i++;
323
                        arg.Accept(this);
324
                }
325
                m_emitter.Append(")");
326
        }
327

    
328
        @Override
329
        public void visit(QValConstructor qValConstructor)
330
        {
331
                final StringBuilder helpers = new StringBuilder();
332

    
333
                String landmarkOne = "null";
334
                if (qValConstructor.value().length >= 1 && qValConstructor.value()[0] != null)
335
                {
336
                        final JavaExpression lndmrk1 = new JavaExpression(helpers, m_data);
337
                        qValConstructor.value()[0].Accept(lndmrk1);
338
                        landmarkOne = lndmrk1.toString();
339
                }
340
                String landmarkTwo = "null";
341
                if (qValConstructor.value().length >= 2 && qValConstructor.value()[1] != null)
342
                {
343
                        final JavaExpression lndmrk = new JavaExpression(helpers, m_data);
344
                        qValConstructor.value()[1].Accept(lndmrk);
345
                        landmarkTwo = lndmrk.toString();
346
                }
347
                String derivation = "null";
348
                if (qValConstructor.valueDeriv() != QValDeriv.DonTCare)
349
                {
350
                        derivation = Integer.toString(qValConstructor.valueDeriv().ordinal());
351
                        //derivation = Enum.Format(typeof(QValDeriv), qValConstructor.valueDeriv, "d");
352
                }
353

    
354
                m_helpers.append(helpers.toString());
355
                m_emitter.Append(String.format("new QualitativeValue(%s,%s,%s)", landmarkOne, landmarkTwo, derivation));
356
        }
357

    
358
        @Override
359
        public void visit(AccessExpression accessExpression)
360
        {
361
                if (accessExpression.left().type().kind() != TypeKind.QrType &&
362
                                accessExpression.left().type().kind() != TypeKind.EnumeratedType)
363
                {
364
                        // enums and qr types are directly (statically) converted to nums...
365
                        VisitSub(accessExpression.left(), accessExpression);
366
                        m_emitter.Append(".");
367
                }
368
                VisitSub(accessExpression.right(), accessExpression);
369
        }
370

    
371
        @Override
372
        public void visit(BinaryOperator binaryOperator)
373
        {
374
                m_emitter.Append("(");
375
                VisitSub(binaryOperator.left(), binaryOperator);
376
                m_emitter.Append(") ");
377
                m_emitter.Append(OperatorString(binaryOperator));
378
                m_emitter.Append(" (");
379
                VisitSub(binaryOperator.right(), binaryOperator);
380
                m_emitter.Append(")");
381
        }
382

    
383
        @Override
384
        public void visit(TernaryOperator ternaryOperator)
385
        {
386
                m_emitter.Append("(");
387
                VisitSub(ternaryOperator.left(), ternaryOperator);
388
                m_emitter.Append(" ? ");
389

    
390
                VisitSub(ternaryOperator.mid(), ternaryOperator);
391
                m_emitter.Append(" : ");
392

    
393
                VisitSub(ternaryOperator.right(), ternaryOperator);
394
                m_emitter.Append(")");
395
        }
396
        @Override
397
        public void visit(TupleMapAccessExpression tupleMapAccessExpression)
398
        {
399
                throw new NotImplementedException();
400
        }
401
        @Override
402
        public void visit(ForallQuantifier quantifier)
403
        {
404
                throw new NotImplementedException();
405
        }
406
        @Override
407
        public void visit(ExistsQuantifier quantifier)
408
        {
409
                throw new NotImplementedException();
410
        }
411
        @Override
412
        public void visit(UnaryOperator unaryOperator)
413
        {
414
                m_emitter.Append(" ");
415
                m_emitter.Append(OperatorString(unaryOperator));
416
                m_emitter.Append("(");
417
                VisitSub(unaryOperator.child(), unaryOperator);
418
                m_emitter.Append(")");
419
        }
420

    
421
        @Override
422
        public String toString()
423
        {
424
                return m_emitter.toString();
425
        }
426

    
427
        public JavaExpression(StringBuilder helpers, Scratchbook data)
428
        {
429
                super ();
430
                m_helpers = helpers;
431
                m_data = data;
432
        }
433
}