Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / codegen / prolog / OoaPrologStatement.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.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.SeqBlock;
49
import org.momut.ooas.ast.statements.SkipStatement;
50
import org.momut.ooas.ast.statements.Statement;
51
import org.momut.ooas.ast.types.FunctionType;
52
import org.momut.ooas.ast.types.TypeKind;
53
import org.momut.ooas.ast.types.FunctionType.FunctionTypeEnum;
54
import org.momut.ooas.codegen.OoasCodeEmitter;
55
import org.momut.ooas.utils.exceptions.NotImplementedException;
56
import org.momut.ooas.visitors.OoaStatementVisitor;
57

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

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

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

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

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

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

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

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

    
146
        @Override
147
        public void visit(GuardedCommand guardedCommand)
148
        {
149
                final OoaPrologExpression expr = createExpressionVisitor();
150
                guardedCommand.guard().Accept(expr);
151

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
294
        @Override
295
        public String toString()
296
        {
297
                return m_emitter.toString();
298
        }
299

    
300
        protected OoaPrologExpression createExpressionVisitor() { return m_exprFactory.create(m_idFactory, m_typeFactory, m_scratchbook); }
301
        protected OoaPrologExpression createExpressionVisitor(boolean lhs) { return m_exprFactory.create(m_idFactory, m_typeFactory, m_scratchbook, lhs); }
302
        protected OoaPrologIdentifier createIdentifierVisitor() { return m_idFactory.create(); }
303
        protected OoaPrologType createTypeVisitor() { return m_typeFactory.create(m_idFactory, m_scratchbook); }
304

    
305
        private final OoaPrologExpression.Factory m_exprFactory;
306
        private final OoaPrologIdentifier.Factory m_idFactory;
307
        private final OoaPrologType.Factory m_typeFactory;
308

    
309
        protected OoaPrologStatement(
310
                        OoaPrologExpression.Factory exprFactory,
311
                        OoaPrologIdentifier.Factory idFactory,
312
                        OoaPrologType.Factory typeFactory,
313
                        Scratchbook scratchbook)
314
        {
315
                super();
316
                m_exprFactory = exprFactory;
317
                m_idFactory = idFactory;
318
                m_typeFactory = typeFactory;
319
                m_scratchbook = scratchbook;
320
        }
321
}
322