Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / codegen / prolog / OoaPrologStatement.java @ 7

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.prolog;
29

    
30
import java.util.ArrayList;
31
import java.util.Iterator;
32

    
33
import org.momut.ooas.ast.expressions.AccessExpression;
34
import org.momut.ooas.ast.expressions.CallExpression;
35
import org.momut.ooas.ast.expressions.Expression;
36
import org.momut.ooas.ast.expressions.ExpressionKind;
37
import org.momut.ooas.ast.expressions.IdentifierExpression;
38
import org.momut.ooas.ast.identifiers.Identifier;
39
import org.momut.ooas.ast.identifiers.IdentifierKind;
40
import org.momut.ooas.ast.identifiers.NamedActionIdentifier;
41
import org.momut.ooas.ast.statements.AbortStatement;
42
import org.momut.ooas.ast.statements.Assignment;
43
import org.momut.ooas.ast.statements.Call;
44
import org.momut.ooas.ast.statements.GuardedCommand;
45
import org.momut.ooas.ast.statements.KillStatement;
46
import org.momut.ooas.ast.statements.NondetBlock;
47
import org.momut.ooas.ast.statements.PrioBlock;
48
import org.momut.ooas.ast.statements.QualitativeConstraintStatement;
49
import org.momut.ooas.ast.statements.SeqBlock;
50
import org.momut.ooas.ast.statements.SkipStatement;
51
import org.momut.ooas.ast.statements.Statement;
52
import org.momut.ooas.ast.types.FunctionType;
53
import org.momut.ooas.ast.types.TypeKind;
54
import org.momut.ooas.ast.types.FunctionType.FunctionTypeEnum;
55
import org.momut.ooas.codegen.OoasCodeEmitter;
56
import org.momut.ooas.utils.exceptions.NotImplementedException;
57
import org.momut.ooas.visitors.OoaStatementVisitor;
58

    
59
public class OoaPrologStatement extends OoaStatementVisitor
60
{
61
        public static class Factory
62
        {
63
                public OoaPrologStatement create(
64
                                OoaPrologExpression.Factory exprFactory,
65
                                OoaPrologIdentifier.Factory idFactory,
66
                                OoaPrologType.Factory typeFactory,
67
                                Scratchbook scratchbook)
68
                {
69
                        return new OoaPrologStatement(exprFactory, idFactory, typeFactory, scratchbook);
70
                }
71
        }
72

    
73
        protected final Scratchbook m_scratchbook;
74
        protected OoasCodeEmitter m_emitter = new OoasCodeEmitter();
75

    
76
        @Override
77
        public /*override*/ void visit(NondetBlock nondetBlock)
78
        {
79
                int y = 0;
80
                for (Statement x: nondetBlock.statements())
81
                {
82
                        if (y != 0)
83
                                m_emitter.Append("; ");
84
                        else
85
                                y++;
86
                        m_emitter.Append("(");
87
                        VisitSub(x, nondetBlock);
88
                        m_emitter.Append(")");
89
                }
90
        }
91

    
92
        @Override
93
        public /*override*/ void visit(SeqBlock seqBlock)
94
        {
95
                int y = 0;
96
                if (seqBlock.symbols().symbolList().size() > 0)
97
                {
98
                        m_emitter.Append("([");
99
                        for (Identifier sym: seqBlock.symbols().symbolList())
100
                        {
101
                                if (y != 0)
102
                                        m_emitter.AppendLine(", ");
103
                                else
104
                                        y++;
105

    
106
                                OoaPrologType atype = createTypeVisitor();
107
                                sym.type().Accept(atype);
108
                                OoaPrologIdentifier anIdent = createIdentifierVisitor();
109
                                sym.Accept(anIdent);
110
                                m_emitter.Append(String.format("%s:%s", anIdent.toString(), atype.toString()));
111
                        }
112
                        m_emitter.Append("]: ");
113
                }
114

    
115
                y = 0;
116
                for (Statement x: seqBlock.statements())
117
                {
118
                        if (y != 0)
119
                                m_emitter.AppendLine(", ");
120
                        else
121
                                y++;
122
                        m_emitter.Append("(");
123
                        VisitSub(x, seqBlock);
124
                        m_emitter.Append(")");
125
                }
126

    
127
                if (seqBlock.symbols().symbolList().size() > 0)
128
                        m_emitter.Append(")");
129
        }
130

    
131
        @Override
132
        public /*override*/ void visit(PrioBlock prioBlock)
133
        {
134
                int y = 0;
135
                for (Statement x: prioBlock.statements())
136
                {
137
                        if (y != 0)
138
                                m_emitter.Append("// ");
139
                        else
140
                                y++;
141
                        m_emitter.Append("(");
142
                        VisitSub(x, prioBlock);
143
                        m_emitter.Append(")");
144
                }
145
        }
146

    
147
        @Override
148
        public /*override*/ void visit(GuardedCommand guardedCommand)
149
        {
150
                OoaPrologExpression expr = createExpressionVisitor();
151
                guardedCommand.guard().Accept(expr);
152

    
153
                m_emitter.AppendLineIncIndent(String.format("(%s%s) %s ",
154
                                expr.toString(),
155
                                expr.tmpVariables().get(0),
156
                                guardedCommand.isQualitative() ? "~>" : "=>"));
157
                m_emitter.AppendLineIncIndent("(");
158
                VisitSub(guardedCommand.body(), guardedCommand);
159
                m_emitter.DecIndent();
160
                m_emitter.AppendLine("");
161
                m_emitter.Append(")");
162
        }
163

    
164
        @Override
165
        public /*override*/ void visit(Assignment assignment)
166
        {
167
                if (assignment.nondetExpression() != null)
168
                        throw new NotImplementedException();
169

    
170
                Iterator<Expression> aPlaceIt = assignment.places().iterator();
171
                Iterator<Expression> aValueIt = assignment.values().iterator();
172
                ArrayList<String> assignments = new ArrayList<String>();
173

    
174
                while (aPlaceIt.hasNext())
175
                {
176
                        final Expression aPlace = aPlaceIt.next();
177
                        final Expression aValue = aValueIt.next();
178

    
179
                        OoaPrologExpression prologPlace = createExpressionVisitor(true);
180
                        aPlace.Accept(prologPlace);
181
                        assert(prologPlace.tmpVariables().size() == 1);
182

    
183
                        OoaPrologExpression prologValue = createExpressionVisitor();
184
                        aValue.Accept(prologValue);
185
                        assert(prologValue.tmpVariables().size() == 1);
186

    
187
                        m_emitter.Append(prologValue.toString());
188

    
189
                        if (aPlace.kind() == ExpressionKind.Access &&
190
                                        ((AccessExpression)aPlace).right().kind() == ExpressionKind.Identifier &&
191
                                        ((IdentifierExpression)((AccessExpression)aPlace).right()).identifier().kind() == IdentifierKind.AttributeIdentifier)
192
                        {
193
                                //access to attribute is always 'self.XY'...
194
                                assignments.add(String.format("%s := %s", prologPlace.tmpVariables().get(0), prologValue.tmpVariables().get(0)));
195
                        }
196
                        else
197
                                if (prologPlace.tmpVariables().get(0).equals("RESULT"))
198
                                        assignments.add(String.format("unify( RESULT = %s)", prologValue.tmpVariables().get(0)));
199
                                else if (aPlace.type().kind() == TypeKind.IntType)
200
                                        assignments.add(String.format("%s #= %s", prologPlace.tmpVariables().get(0), prologValue.tmpVariables().get(0)));
201
                                else
202
                                        assignments.add(String.format("%s = %s", prologPlace.tmpVariables().get(0), prologValue.tmpVariables().get(0)));
203

    
204
                        if (prologPlace.toString().length() > 0)
205
                        {
206
                                String place = prologPlace.toString();
207
                                place = place.trim();
208
                                if (place.endsWith(","))
209
                                        place = place.substring(0, place.length() - 1);
210

    
211
                                assignments.add(place);
212
                        }
213
                }
214

    
215
                int pos = 0;
216
                for (String s: assignments)
217
                {
218
                        if (pos != 0)
219
                                m_emitter.Append(",");
220
                        pos++;
221
                        m_emitter.Append(s);
222
                }
223
        }
224

    
225
        @Override
226
        public /*override*/ void visit(Call call)
227
        {
228
                Expression ce = call.callExpression();
229
                String callstatement = "";
230
                StringBuilder parameter = new StringBuilder();
231
                boolean hideCall = false;
232

    
233
                if (ce.kind() == ExpressionKind.Identifier)
234
                        callstatement = ((IdentifierExpression)ce).identifier().tokenText();
235
                else if (ce.kind() == ExpressionKind.Call)
236
                {
237
                        CallExpression parens = (CallExpression)ce;
238

    
239
                        OoaPrologExpression prologexpr = createExpressionVisitor();
240
                        parens.child().Accept(prologexpr);
241

    
242
                        if (parens.child().kind() == ExpressionKind.Identifier &&
243
                                        ((IdentifierExpression)parens.child()).identifier().kind() == IdentifierKind.NamedActionIdentifier)
244
                        {
245
                                // we need to hide internal actions
246
                                NamedActionIdentifier namedactionid = (NamedActionIdentifier)((IdentifierExpression)parens.child()).identifier();
247
                                hideCall = ((FunctionType)namedactionid.type()).functionType() == FunctionTypeEnum.Internal;
248
                        }
249

    
250
                        m_emitter.Append(prologexpr.toString());
251
                        callstatement = prologexpr.tmpVariables().get(0);
252
                        int i = 0;
253
                        for (Expression arg: parens.arguments())
254
                        {
255
                                if (i != 0)
256
                                        parameter.append(", ");
257
                                else
258
                                        i++;
259
                                OoaPrologExpression paramexpr = createExpressionVisitor();
260
                                arg.Accept(paramexpr);
261
                                m_emitter.Append(paramexpr.toString());
262
                                parameter.append(paramexpr.tmpVariables().get(0));
263
                        }
264
                }
265
                else
266
                        throw new NotImplementedException();
267
                if (hideCall)
268
                        m_emitter.Append("i(");
269
                if (parameter.length() > 0)
270
                        m_emitter.AppendLine(String.format("%s(%s)", callstatement, parameter));
271
                else
272
                        m_emitter.AppendLine(String.format("%s", callstatement, parameter));
273
                if (hideCall)
274
                        m_emitter.Append(")");
275
        }
276

    
277
        @Override
278
        public /*override*/ void visit(SkipStatement skipStatement)
279
        {
280
                m_emitter.Append("skip");
281
        }
282

    
283
        @Override
284
        public /*override*/ void visit(AbortStatement abortStatement)
285
        {
286
                throw new NotImplementedException();
287
        }
288

    
289
        @Override
290
        public /*override*/ void visit(KillStatement killStatement)
291
        {
292
                throw new NotImplementedException();
293
        }
294

    
295
        @Override
296
        public /*override*/ void visit(QualitativeConstraintStatement qalitativeConstraintStatement)
297
        {
298
                if (qalitativeConstraintStatement.tag)
299
                {
300
                        m_emitter.Append("% observable assignment in actionhead");
301
                        return;
302
                }
303

    
304
                OoaPrologIdentifier id1 = createIdentifierVisitor();
305
                OoaPrologIdentifier id2 = createIdentifierVisitor();
306
                OoaPrologIdentifier id3 = createIdentifierVisitor();
307

    
308

    
309
                switch (qalitativeConstraintStatement.operation())
310
                {
311
                case Deriv:
312
                        qalitativeConstraintStatement.variable0().Accept(id1);
313
                        qalitativeConstraintStatement.variable1().Accept(id2);
314
                        m_emitter.Append(String.format("%s := dt %s", id1.toString(), id2.toString()));
315
                        break;
316
                case Diff:
317
                        qalitativeConstraintStatement.variable0().Accept(id1);
318
                        qalitativeConstraintStatement.variable1().Accept(id2);
319
                        qalitativeConstraintStatement.variable2().Accept(id3);
320
                        m_emitter.Append(String.format("%s := %s - %s", id1.toString(), id2.toString(), id3.toString()));
321
                        break;
322
                case Equal:
323
                        qalitativeConstraintStatement.variable0().Accept(id1);
324
                        qalitativeConstraintStatement.variable1().Accept(id2);
325
                        m_emitter.Append(String.format("%s := %s", id1.toString(), id2.toString()));
326
                        break;
327

    
328
                case Prod:
329
                        qalitativeConstraintStatement.variable0().Accept(id1);
330
                        qalitativeConstraintStatement.variable1().Accept(id2);
331
                        qalitativeConstraintStatement.variable2().Accept(id3);
332
                        m_emitter.Append(String.format("%s := %s * %s", id1.toString(), id2.toString(), id3.toString()));
333
                        break;
334

    
335
                case Sum:
336
                        qalitativeConstraintStatement.variable0().Accept(id1);
337
                        qalitativeConstraintStatement.variable1().Accept(id2);
338
                        qalitativeConstraintStatement.variable2().Accept(id3);
339
                        m_emitter.Append(String.format("%s := %s + %s", id1.toString(), id2.toString(), id3.toString()));
340
                        break;
341

    
342
                default:
343
                        throw new NotImplementedException();
344
                }
345
        }
346

    
347

    
348
        @Override
349
        public /*override*/ String toString()
350
        {
351
                return m_emitter.toString();
352
        }
353

    
354
        protected OoaPrologExpression createExpressionVisitor() { return m_exprFactory.create(m_idFactory, m_typeFactory, m_scratchbook); }
355
        protected OoaPrologExpression createExpressionVisitor(boolean lhs) { return m_exprFactory.create(m_idFactory, m_typeFactory, m_scratchbook, lhs); }
356
        protected OoaPrologIdentifier createIdentifierVisitor() { return m_idFactory.create(); }
357
        protected OoaPrologType createTypeVisitor() { return m_typeFactory.create(m_idFactory, m_scratchbook); }
358

    
359
        private final OoaPrologExpression.Factory m_exprFactory;
360
        private final OoaPrologIdentifier.Factory m_idFactory;
361
        private final OoaPrologType.Factory m_typeFactory;
362

    
363
        protected OoaPrologStatement(
364
                        OoaPrologExpression.Factory exprFactory,
365
                        OoaPrologIdentifier.Factory idFactory,
366
                        OoaPrologType.Factory typeFactory,
367
                        Scratchbook scratchbook)
368
        {
369
                super();
370
                m_exprFactory = exprFactory;
371
                m_idFactory = idFactory;
372
                m_typeFactory = typeFactory;
373
                m_scratchbook = scratchbook;
374
        }
375
}
376