Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / codegen / Prolog / ooaPrologStatement.cs

1
/**
2
  *
3
  *                      OOAS Compiler (Deprecated)
4
  *
5
  * Copyright 2015, Institute for Software Technology, Graz University of
6
  * Technology. Portions are copyright 2015 by the AIT Austrian Institute
7
  * of Technology. All rights reserved.
8
  *
9
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
10
  *
11
  * Please notice that this version of the OOAS compiler is considered de-
12
  * precated. Only the Java version is maintained.
13
  *
14
  * Contributors:
15
  *               Willibald Krenn (TU Graz/AIT)
16
  *               Stefan Tiran (TU Graz/AIT)
17
  */
18

    
19
/*
20
 * Prolog Code Generator
21
 */
22

    
23
using System;
24
using System.Collections.Generic;
25
using System.Text;
26
using TUG.Mogentes.Codegen;
27

    
28

    
29
namespace TUG.Mogentes.Codegen.Prolog
30
{
31
    public class OoaPrologStatement : OoaStatementVisitor
32
    {
33
        public class Factory
34
        {
35
            public virtual OoaPrologStatement create(
36
                OoaPrologExpression.Factory exprFactory,
37
                OoaPrologIdentifier.Factory idFactory,
38
                OoaPrologType.Factory typeFactory) 
39
            {
40
                return new OoaPrologStatement(exprFactory, idFactory, typeFactory); 
41
            }
42
        }
43

    
44
        protected OoaCodeEmitter m_emitter = new OoaCodeEmitter();
45

    
46
        public override void visit(NondetBlock nondetBlock)
47
        {
48
            int y = 0;
49
            foreach (var x in nondetBlock.statements)
50
            {
51
                if (y != 0)
52
                    m_emitter.Append("; ");
53
                else
54
                    y++;
55
                m_emitter.Append("(");
56
                VisitSub(x, nondetBlock);
57
                m_emitter.Append(")");
58
            }
59
        }
60

    
61
        public override void visit(SeqBlock seqBlock)
62
        {
63
            int y = 0;
64
            if (seqBlock.symbols.symbolList.Count > 0)
65
            {
66
                m_emitter.Append("([");
67
                foreach (var sym in seqBlock.symbols.symbolList)
68
                {
69
                    if (y != 0)
70
                        m_emitter.AppendLine(", ");
71
                    else
72
                        y++;
73

    
74
                    OoaPrologType atype = createTypeVisitor();
75
                    sym.type.Accept(atype);
76
                    OoaPrologIdentifier anIdent = createIdentifierVisitor();
77
                    sym.Accept(anIdent);
78
                    m_emitter.Append(String.Format("{0}:{1}", anIdent.ToString(), atype.ToString()));
79
                }
80
                m_emitter.Append("]: ");
81
            }
82

    
83
            y = 0;
84
            foreach (var x in seqBlock.statements)
85
            {
86
                if (y != 0)
87
                    m_emitter.AppendLine(", ");
88
                else
89
                    y++;
90
                m_emitter.Append("(");
91
                VisitSub(x, seqBlock);
92
                m_emitter.Append(")");
93
            }
94

    
95
            if (seqBlock.symbols.symbolList.Count > 0)
96
                m_emitter.Append(")");
97
        }
98

    
99
        public override void visit(PrioBlock prioBlock)
100
        {
101
            int y = 0;
102
            foreach (var x in prioBlock.statements)
103
            {
104
                if (y != 0)
105
                    m_emitter.Append("// ");
106
                else
107
                    y++;
108
                m_emitter.Append("(");
109
                VisitSub(x, prioBlock);
110
                m_emitter.Append(")");
111
            }
112
        }
113

    
114
        public override void visit(GuardedCommand guardedCommand)
115
        {
116
            OoaPrologExpression expr = createExpressionVisitor();
117
            guardedCommand.guard.Accept(expr);
118

    
119
            m_emitter.AppendLineIncIndent(String.Format("({0}{2}) {1} ", expr.ToString(), guardedCommand.isQualitative ? "~>" : "=>", expr.tmpVariables[0]));
120
            m_emitter.AppendLineIncIndent("(");
121
            VisitSub(guardedCommand.body, guardedCommand);
122
            m_emitter.DecIndent();
123
            m_emitter.AppendLine("");
124
            m_emitter.Append(")");
125
        }
126

    
127
        public override void visit(Assignment assignment)
128
        {
129
            if (assignment.nondetExpression != null)
130
                throw new NotImplementedException();
131

    
132
            LinkedListNode<Expression> aPlace = assignment.places.First;
133
            LinkedListNode<Expression> aValue = assignment.values.First;
134
            List<string> assignments = new List<string>();
135

    
136
            while (aPlace != null)
137
            {
138
                OoaPrologExpression prologPlace = createExpressionVisitor(true);
139
                aPlace.Value.Accept(prologPlace);
140
                System.Diagnostics.Debug.Assert(prologPlace.tmpVariables.Count == 1);
141

    
142
                OoaPrologExpression prologValue = createExpressionVisitor();
143
                aValue.Value.Accept(prologValue);
144
                System.Diagnostics.Debug.Assert(prologValue.tmpVariables.Count == 1);
145

    
146
                m_emitter.Append(prologValue.ToString());
147

    
148
                if (aPlace.Value.kind == ExpressionKind.Access &&
149
                    ((AccessExpression)aPlace.Value).right.kind == ExpressionKind.Identifier &&
150
                    ((IdentifierExpression)((AccessExpression)aPlace.Value).right).identifier.kind == IdentifierKind.AttributeIdentifier)
151
                {
152
                    //access to attribute is always 'self.XY'...
153
                    assignments.Add(String.Format("{0} := {1}", prologPlace.tmpVariables[0], prologValue.tmpVariables[0]));
154
                }
155
                else
156
                    if (prologPlace.tmpVariables[0] == "RESULT")
157
                        assignments.Add(String.Format("unify( RESULT = {0})", prologValue.tmpVariables[0]));
158
                    else if (aPlace.Value.type.kind == TypeKind.IntType)
159
                        assignments.Add(String.Format("{0} #= {1}", prologPlace.tmpVariables[0], prologValue.tmpVariables[0]));
160
                    else
161
                        assignments.Add(String.Format("{0} = {1}", prologPlace.tmpVariables[0], prologValue.tmpVariables[0]));
162

    
163
                if (prologPlace.ToString().Length > 0)
164
                {
165
                    string place = prologPlace.ToString();
166
                    place = place.Trim();
167
                    if (place.EndsWith(","))
168
                        place = place.Substring(0, place.Length - 1);
169

    
170
                    assignments.Add(place);
171
                }
172

    
173
                aPlace = aPlace.Next;
174
                aValue = aValue.Next;
175
            }
176

    
177
            int pos = 0;
178
            foreach (var s in assignments)
179
            {
180
                if (pos != 0)
181
                    m_emitter.Append(",");
182
                pos++;
183
                m_emitter.Append(s);
184
            }
185
        }
186

    
187
        public override void visit(Call call)
188
        {
189
            Expression ce = call.callExpression;
190
            string callstatement = String.Empty;
191
            StringBuilder parameter = new StringBuilder();
192
            bool hideCall = false;
193

    
194
            if (ce.kind == ExpressionKind.Identifier)
195
                callstatement = ((IdentifierExpression)ce).identifier.tokenText;
196
            else if (ce.kind == ExpressionKind.Call)
197
            {
198
                CallExpression parens = (CallExpression)ce;
199

    
200
                OoaPrologExpression prologexpr = createExpressionVisitor();
201
                parens.child.Accept(prologexpr);
202

    
203
                if (parens.child.kind == ExpressionKind.Identifier &&
204
                    ((IdentifierExpression)parens.child).identifier.kind == IdentifierKind.NamedActionIdentifier)
205
                {
206
                    // we need to hide internal actions
207
                    NamedActionIdentifier namedactionid = (NamedActionIdentifier)((IdentifierExpression)parens.child).identifier;
208
                    hideCall = ((FunctionType)namedactionid.type).functionType == FunctionTypeEnum.Internal;
209
                }
210

    
211
                m_emitter.Append(prologexpr.ToString());
212
                callstatement = prologexpr.tmpVariables[0];
213
                int i = 0;
214
                foreach (var arg in parens.arguments)
215
                {
216
                    if (i != 0)
217
                        parameter.Append(", ");
218
                    else
219
                        i++;
220
                    OoaPrologExpression paramexpr = createExpressionVisitor();
221
                    arg.Accept(paramexpr);
222
                    m_emitter.Append(paramexpr.ToString());
223
                    parameter.Append(paramexpr.tmpVariables[0]);
224
                }
225
            }
226
            else
227
                throw new NotImplementedException();
228
            if (hideCall)
229
                m_emitter.Append("i(");
230
            if (parameter.Length > 0)
231
                m_emitter.AppendLine(String.Format("{0}({1})", callstatement, parameter));
232
            else
233
                m_emitter.AppendLine(String.Format("{0}", callstatement, parameter));
234
            if (hideCall)
235
                m_emitter.Append(")");
236
        }
237

    
238
        public override void visit(SkipStatement skipStatement)
239
        {
240
            m_emitter.Append("skip");
241
        }
242

    
243
        public override void visit(AbortStatement abortStatement)
244
        {
245
            throw new NotImplementedException();
246
        }
247

    
248
        public override void visit(KillStatement killStatement)
249
        {
250
            throw new NotImplementedException();
251
        }
252

    
253
        public override void visit(QualitativeConstraintStatement qalitativeConstraintStatement)
254
        {
255
            if (qalitativeConstraintStatement.tag)
256
            {
257
                m_emitter.Append("% observable assignment in actionhead");
258
                return;
259
            }
260

    
261
            OoaPrologIdentifier id1 = createIdentifierVisitor();
262
            OoaPrologIdentifier id2 = createIdentifierVisitor();
263
            OoaPrologIdentifier id3 = createIdentifierVisitor();
264

    
265

    
266
            switch (qalitativeConstraintStatement.operation)
267
            {
268
                case QualitativeConstraintOperation.Deriv:
269
                    qalitativeConstraintStatement.variable0.Accept(id1);
270
                    qalitativeConstraintStatement.variable1.Accept(id2);
271
                    m_emitter.Append(String.Format("{0} := dt {1}", id1.ToString(), id2.ToString()));
272
                    break;
273
                case QualitativeConstraintOperation.Diff:
274
                    qalitativeConstraintStatement.variable0.Accept(id1);
275
                    qalitativeConstraintStatement.variable1.Accept(id2);
276
                    qalitativeConstraintStatement.variable2.Accept(id3);
277
                    m_emitter.Append(String.Format("{0} := {1} - {2}", id1.ToString(), id2.ToString(), id3.ToString()));
278
                    break;
279
                case QualitativeConstraintOperation.Equal:
280
                    qalitativeConstraintStatement.variable0.Accept(id1);
281
                    qalitativeConstraintStatement.variable1.Accept(id2);
282
                    m_emitter.Append(String.Format("{0} := {1}", id1.ToString(), id2.ToString()));
283
                    break;
284

    
285
                case QualitativeConstraintOperation.Prod:
286
                    qalitativeConstraintStatement.variable0.Accept(id1);
287
                    qalitativeConstraintStatement.variable1.Accept(id2);
288
                    qalitativeConstraintStatement.variable2.Accept(id3);
289
                    m_emitter.Append(String.Format("{0} := {1} * {2}", id1.ToString(), id2.ToString(), id3.ToString()));
290
                    break;
291

    
292
                case QualitativeConstraintOperation.Sum:
293
                    qalitativeConstraintStatement.variable0.Accept(id1);
294
                    qalitativeConstraintStatement.variable1.Accept(id2);
295
                    qalitativeConstraintStatement.variable2.Accept(id3);
296
                    m_emitter.Append(String.Format("{0} := {1} + {2}", id1.ToString(), id2.ToString(), id3.ToString()));
297
                    break;
298

    
299
                default:
300
                    throw new NotImplementedException();
301
            }
302
        }
303

    
304

    
305
        public override string ToString()
306
        {
307
            return m_emitter.ToString();
308
        }
309

    
310
        protected OoaPrologExpression createExpressionVisitor() { return m_exprFactory.create(m_idFactory, m_typeFactory); }
311
        protected OoaPrologExpression createExpressionVisitor(bool lhs) { return m_exprFactory.create(m_idFactory, m_typeFactory, lhs); }
312
        protected OoaPrologIdentifier createIdentifierVisitor() { return m_idFactory.create(); }
313
        protected OoaPrologType createTypeVisitor() { return m_typeFactory.create(m_idFactory); }
314

    
315
        private readonly OoaPrologExpression.Factory m_exprFactory;
316
        private readonly OoaPrologIdentifier.Factory m_idFactory;
317
        private readonly OoaPrologType.Factory m_typeFactory;
318

    
319
        protected OoaPrologStatement(
320
                OoaPrologExpression.Factory exprFactory,
321
                OoaPrologIdentifier.Factory idFactory,
322
                OoaPrologType.Factory typeFactory)
323
            : base()
324
        {
325
            m_exprFactory = exprFactory;
326
            m_idFactory = idFactory;
327
            m_typeFactory = typeFactory;
328
        }
329
    }
330

    
331
}
332