Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / codegen / cadp / CadpStatement.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.cadp;
29

    
30
import java.util.AbstractMap.SimpleEntry;
31
import java.util.ArrayList;
32
import java.util.Iterator;
33

    
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.expressions.TernaryOperator;
39
import org.momut.ooas.ast.identifiers.FunctionIdentifier;
40
import org.momut.ooas.ast.identifiers.Identifier;
41
import org.momut.ooas.ast.identifiers.ParameterIdentifier;
42
import org.momut.ooas.ast.statements.AbortStatement;
43
import org.momut.ooas.ast.statements.Assignment;
44
import org.momut.ooas.ast.statements.Call;
45
import org.momut.ooas.ast.statements.GuardedCommand;
46
import org.momut.ooas.ast.statements.KillStatement;
47
import org.momut.ooas.ast.statements.NondetBlock;
48
import org.momut.ooas.ast.statements.PrioBlock;
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.FloatType;
53
import org.momut.ooas.ast.types.FunctionType;
54
import org.momut.ooas.ast.types.IntType;
55
import org.momut.ooas.ast.types.ListType;
56
import org.momut.ooas.ast.types.Type;
57
import org.momut.ooas.codegen.OoasCodeEmitter;
58
import org.momut.ooas.visitors.OoaPrintVisitor;
59
import org.momut.ooas.visitors.OoaStatementVisitor;
60

    
61
/// <summary>
62
/// Knows how to construct a C-CADP statement from an AST-statement
63
/// (dumps out, e.g., named actions)
64
/// </summary>
65
public final class CadpStatement extends OoaStatementVisitor
66
{
67
        public final OoasCodeEmitter m_emitter = new OoasCodeEmitter();
68
        private final CadpActionInfo m_procInfo;
69
        private int m_statePosCount = 1;
70
        private static int m_debugPosCount = -1;
71
        private int m_blockCount;
72

    
73
        public int nondetAssignmentsToClose = 0;
74
        public int blockCount() { return m_blockCount; }
75

    
76
        public static String CallHelper(FunctionIdentifier fun, String helperName)
77
        {
78
                final StringBuilder paramStr = new StringBuilder("worklist");
79
                for (final ParameterIdentifier param : fun.parameter())
80
                {
81
                        paramStr.append(", ");
82
                        paramStr.append(String.format("%1$s", CadpIdentifier.GetIdentifierString(param)));
83
                }
84
                if (((FunctionType)fun.type()).returnType() != null)
85
                {
86
                        paramStr.append(", ");
87
                        paramStr.append(String.format("param_result"));
88
                }
89
                return String.format("%1$s(%2$s)", helperName, paramStr.toString());
90
        }
91

    
92
        public static String HelperFunctionHeader(FunctionIdentifier fun, String functionName)
93
        {
94
                final StringBuilder paramStr = new StringBuilder("struct STATE_LIST* worklist");
95
                for (final ParameterIdentifier param: fun.parameter())
96
                {
97
                        //CadpType.EmitType(param.type);
98
                        paramStr.append(", ");
99
                        paramStr.append(String.format("%1$s %2$s", OoaCADPVisitor.DumpType(param.type()), CadpIdentifier.GetIdentifierString(param)));
100
                }
101
                if (((FunctionType)fun.type()).returnType() != null)
102
                {
103
                        //CadpType.EmitType(((FunctionType)fun.type).returnType);
104
                        paramStr.append(", ");
105
                        paramStr.append(String.format("%1$s *param_result", OoaCADPVisitor.DumpType(((FunctionType)fun.type()).returnType())));
106
                }
107
                return String.format("struct STATE_LIST* %1$s (%2$s)", functionName, paramStr.toString());
108
        }
109

    
110

    
111
        @Override
112
        public  void visit(NondetBlock nondetBlock)
113
        {
114
                m_blockCount++;
115
                final int nondetBlocknum = m_blockCount;
116
                m_emitter.AppendLine("{ /* begin nodet-choice block */");
117

    
118
                m_emitter.AppendLine(String.format("struct STATE_LIST *nondetInitial_%1$s = %2$s;", nondetBlocknum, m_procInfo.toDoListString));
119
                m_emitter.AppendLine(String.format("struct STATE_LIST *nondetFinal_%1$s = NULL;", nondetBlocknum));
120
                for (final Statement s : nondetBlock.statements())
121
                {
122
                        s.Accept(this);
123
                        m_emitter.AppendLine("/* nondet-choice block: save result and reset initial states for next choice */");
124
                        m_emitter.AppendLine(String.format("LIST_INSERT_LIST(%3$s,%4$s); %1$s = %2$s; %4$s = NULL;",
125
                                        m_procInfo.toDoListString,
126
                                        String.format("nondetInitial_%1$s", nondetBlocknum),
127
                                        String.format("nondetFinal_%1$s", nondetBlocknum),
128
                                        m_procInfo.doneListString));
129
                }
130
                m_emitter.AppendLine("");
131
                m_emitter.AppendLine(String.format("%1$s = %2$s; /* nondet-choice block end: save all reached final states */",
132
                                m_procInfo.doneListString, String.format("nondetFinal_%1$s", nondetBlocknum)));
133
                m_emitter.AppendLine("} /* end nodet-choice block */");
134
        }
135

    
136
        @Override
137
        public  void visit(SeqBlock seqBlock)
138
        {
139
                int loopcount = 0;
140
                final boolean haveNondeterminism = seqBlock.symbols().symbolList().size() > 0;
141
                final boolean splittingEnabled = m_procInfo.splitBlockSize > 0;
142

    
143
                final int blockNum = haveNondeterminism ? m_blockCount++ : m_blockCount;
144

    
145
                m_emitter.AppendLineIncIndent("{ /* begin seqblock */");
146

    
147
                if (haveNondeterminism)
148
                {
149
                        m_blockCount++;
150
                        m_emitter.AppendLine(String.format("struct STATE_LIST *seqInitial_%1$s = %2$s;", blockNum, m_procInfo.toDoListString));
151
                        m_emitter.AppendLine(String.format("struct STATE_LIST *seqFinal_%1$s = NULL;", blockNum));
152
                        for (final Identifier sym :seqBlock.symbols().symbolList())
153
                        {
154
                                CadpType.EmitType(sym.type());
155
                                final CadpType atype = new CadpType();
156
                                sym.type().Accept(atype);
157
                                final CadpIdentifier anIdent = new CadpIdentifier(OoaCADPVisitor.StateVariablePrefix);
158
                                sym.Accept(anIdent);
159
                                m_emitter.AppendLine("/* local (free) variables of seq block */");
160

    
161
                                m_emitter.AppendLine(String.format("      long long iterator_%1$s;", anIdent.toString()));
162
                                m_emitter.AppendLine(String.format("      for (iterator_%1$s = %2$s; iterator_%1$s <= %3$s; iterator_%1$s++) {",
163
                                                anIdent.toString(), CadpType.GetMinVal(sym.type()), CadpType.GetMaxVal(sym.type())));
164
                                m_emitter.AppendLine(String.format("      %1$s %2$s = %3$s%4$s(iterator_%2$s);",
165
                                                atype.ToString(), anIdent.toString(), CadpType.enumString, CadpIdentifier.GetIdentifierString(sym.type().identifier())));
166

    
167

    
168
                                loopcount++;
169
                        }
170

    
171
                        if (!(seqBlock.filter() == null))
172
                                throw new UnsupportedOperationException();
173
                }
174

    
175
                if (!splittingEnabled || seqBlock.statements().size() < m_procInfo.splitBlockSize)
176
                {
177
                        // no splitting, write out to emitter
178
                        int i = 0;
179
                        for (final Statement s : seqBlock.statements())
180
                        {
181
                                if (i != 0)
182
                                {
183
                                        m_emitter.AppendLine("/* sequential composition: all states reached need to go into todo list */");
184
                                        m_emitter.AppendLine(String.format("%1$s = %2$s; %2$s = NULL;", m_procInfo.toDoListString, m_procInfo.doneListString));
185
                                }
186
                                i++;
187
                                s.Accept(this);
188
                        }
189
                }
190
                else
191
                {
192
                        // splitting, we will create functions that take at max. m_procInfo.splitBlockSize number of children
193
                        int splitCount = 0;
194
                        final Iterator<Statement> enumerator = seqBlock.statements().iterator();
195
                        for (int elemCntr = 0; elemCntr < seqBlock.statements().size(); elemCntr++)
196
                        {
197
                                final CadpStatement stmnt = new CadpStatement(this);
198
                                final Statement currentStatement = enumerator.next();
199
                                currentStatement.Accept(stmnt);
200
                                final boolean newSubGroup = elemCntr % m_procInfo.splitBlockSize == 0;
201
                                if (newSubGroup)
202
                                {
203
                                        splitCount++;
204
                                        final String helperName = String.format("%1$s_%2$s", m_procInfo.action.tokenText(), splitCount);
205
                                        // call the helper
206
                                        if (elemCntr > 0)
207
                                        {
208
                                                m_emitter.AppendLine("/* sequential composition: all states reached need to go into todo list */");
209
                                                m_emitter.AppendLine(String.format("%1$s = %2$s; %2$s = NULL;", m_procInfo.toDoListString, m_procInfo.doneListString));
210
                                        }
211
                                        m_emitter.AppendLine(String.format("%1$s = %2$s;", m_procInfo.doneListString, CallHelper(m_procInfo.action, helperName)));
212
                                        // make a header for the helper
213
                                        m_procInfo.m_helperMethods.AppendLine();
214
                                        m_procInfo.m_helperMethods.AppendLine(HelperFunctionHeader(m_procInfo.action, helperName));
215
                                        m_procInfo.m_helperMethods.IncIndent();
216
                                        m_procInfo.m_helperMethods.AppendLine("{");
217
                                        m_procInfo.m_helperMethods.AppendLine("struct STATE_LIST *newstatelist = NULL;");
218
                                }
219
                                if (!newSubGroup)
220
                                {
221
                                        m_procInfo.m_helperMethods.AppendLine("/* sequential composition: all states reached need to go into todo list */");
222
                                        m_procInfo.m_helperMethods.AppendLine(String.format("%1$s = %2$s; %2$s = NULL;", m_procInfo.toDoListString, m_procInfo.doneListString));
223
                                }
224
                                m_procInfo.m_helperMethods.AppendLine(stmnt.toString());
225
                                if ((elemCntr + 1) % m_procInfo.splitBlockSize == 0 || (elemCntr + 1) >= seqBlock.statements().size())
226
                                {
227
                                        // close the helper
228
                                        m_procInfo.m_helperMethods.AppendLine(String.format("return %1$s;",m_procInfo.doneListString));
229
                                        m_procInfo.m_helperMethods.DecIndent();
230
                                        m_procInfo.m_helperMethods.AppendLine("}");
231
                                }
232
                        }
233
                }
234
                // we need to do some loop-calling here..
235
                if (haveNondeterminism)
236
                {
237

    
238
                        m_emitter.AppendLine("/* save result state and reset initial state for next choice */");
239
                        m_emitter.AppendLine(String.format("LIST_INSERT_LIST(%3$s,%4$s); %1$s = %2$s; %4$s = NULL;",
240
                                        m_procInfo.toDoListString,
241
                                        String.format("seqInitial_%1$s", blockNum),
242
                                        String.format("seqFinal_%1$s", blockNum),
243
                                        m_procInfo.doneListString));
244

    
245
                        while (loopcount > 0)
246
                        {
247
                                m_emitter.AppendLine("      }");
248
                                loopcount--;
249
                        }
250
                        m_emitter.AppendLine("/* all final states reached after the seq-block are on our done list */");
251
                        m_emitter.AppendLine(String.format("%1$s = %2$s;", m_procInfo.doneListString, String.format("seqFinal_%1$s", blockNum)));
252
                }
253
                m_emitter.DecIndent();
254
                m_emitter.AppendLine("} /* end seqblock */");
255
        }
256

    
257
        @Override
258
        public  void visit(PrioBlock prioBlock)
259
        {
260
                m_blockCount++;
261
                final int prioBlocknum = m_blockCount;
262
                m_emitter.AppendLine("{ /* begin prioritized composition block */");
263
                m_emitter.AppendLine(String.format("struct STATE_LIST *prioInitial_%1$s = %2$s;", prioBlocknum, m_procInfo.toDoListString));
264
                m_emitter.AppendLine(String.format("struct STATE_LIST *prioFinal_%1$s = NULL;", prioBlocknum));
265
                for (final Statement s : prioBlock.statements())
266
                {
267
                        s.Accept(this);
268
                        m_emitter.AppendLine("/* prio block: save result and reset initial states for next choice */");
269

    
270
                        m_emitter.AppendLine(String.format("%1$s = GetPrioritizedWorkList(prioInitial_%2$s, %3$s);",
271
                                        m_procInfo.toDoListString, prioBlocknum, m_procInfo.doneListString));
272
                        m_emitter.AppendLine(String.format("LIST_INSERT_LIST(prioFinal_%1$s, %2$s);",
273
                                        prioBlocknum, m_procInfo.doneListString));
274
                        m_emitter.AppendLine(String.format("if (%3$s == NULL) goto prioritizedCompositionExit_%2$s; else %1$s = NULL;",
275
                                        m_procInfo.doneListString, prioBlocknum, m_procInfo.toDoListString));
276
                }
277
                m_emitter.AppendLine("");
278
                m_emitter.AppendLine(String.format("prioritizedCompositionExit_%1$s:", prioBlocknum));
279
                m_emitter.AppendLine(String.format("%1$s = %2$s; /* prioritized composition block end: save all reached final states */",
280
                                m_procInfo.doneListString, String.format("prioFinal_%1$s", prioBlocknum)));
281
                m_emitter.AppendLine("} /* end prioritized composition block */");
282
        }
283

    
284
        @Override
285
        public  void visit(GuardedCommand guardedCommand)
286
        {
287
                String body;
288
                final CadpExpression expr = new CadpExpression(m_procInfo);
289
                final CadpStatement statement = new CadpStatement(this);
290
                guardedCommand.guard().Accept(expr);
291
                guardedCommand.body().Accept(statement);
292
                m_blockCount = statement.blockCount() + 1;
293

    
294
                body = String.format("%3$s if (%1$s) { LIST_INSERT_SINGLELIST(%2$s,elem); };", expr.toString(), m_procInfo.doneListString, expr.VariableDeclarations());
295

    
296
                m_emitter.AppendLineIncIndent("{");
297
                m_emitter.AppendLine("/* guarded command */");
298
                m_emitter.AppendLine(String.format("ITERATE_STATES(%1$s, %2$s );", m_procInfo.toDoListString, body));
299
                m_emitter.AppendLine(String.format("%1$s = %2$s; %2$s = NULL;", m_procInfo.toDoListString, m_procInfo.doneListString));
300
                m_emitter.AppendLine(String.format(" if (%1$s == NULL) goto guardedCommandExit_%2$s;", m_procInfo.toDoListString, OoaCADPVisitor.getUIntHashCode(guardedCommand)));
301
                m_emitter.AppendLineDecIndent("}");
302
                m_emitter.Append(statement.toString());
303
                m_emitter.AppendLine(String.format("guardedCommandExit_%2$s: %1$s = %1$s;", m_procInfo.toDoListString, OoaCADPVisitor.getUIntHashCode(guardedCommand)));
304
        }
305

    
306
        @Override
307
        public  void visit(Assignment assignment)
308
        {
309
                final OoaPrintVisitor pvis = new OoaPrintVisitor(null);
310
                assignment.Accept(pvis);
311
                m_emitter.AppendLine(String.format("{ /* assignment: %1$s */", pvis.toString().replace("/*", "").replace("*/", "")));
312

    
313
                m_emitter.AppendLine(String.format("struct STATE_LIST *elems = %1$s;", m_procInfo.toDoListString));
314
                m_emitter.AppendLine("CAESAR_TYPE_STATE newState = NULL;");
315
                m_emitter.AppendLine("CAESAR_TYPE_STATE oldState;");
316
                m_emitter.AppendLine("while (elems != NULL)");
317
                m_emitter.AppendLineIncIndent("{");
318
                m_emitter.AppendLine("oldState = (CAESAR_TYPE_STATE) elems->aState;");
319

    
320
                final ArrayList<SimpleEntry<String, Type>> nondetEnumerators = new ArrayList<>();
321
                if (assignment.symbols().symbolList().size() > 0)
322
                {
323
                        for (final Identifier sym : assignment.symbols().symbolList())
324
                        {
325
                                final CadpType typevis = new CadpType();
326
                                final CadpIdentifier idvis = new CadpIdentifier("oldState");
327
                                sym.type().Accept(typevis);
328
                                sym.Accept(idvis);
329
                                m_emitter.AppendLine(String.format("%1$s %2$s; /* unbound in expression */", typevis.ToString(), idvis.toString()));
330
                                nondetEnumerators.add(new SimpleEntry<String, Type>(idvis.toString(), sym.type()));
331
                        }
332
                }
333

    
334
                if (assignment.nondetExpression() != null)
335
                {
336
                        for (final SimpleEntry<String, Type> key : nondetEnumerators)
337
                        {
338
                                m_emitter.AppendLine(String.format("for (%1$s = %2$s; %1$s <= %3$s; %1$s++) ",
339
                                                key.getKey(), Type.Low(key.getValue()), Type.High(key.getValue())));
340
                                m_emitter.AppendLineIncIndent("{");
341
                        }
342

    
343
                        final CadpExpression exprvis = new CadpExpression(new CadpActionInfo(null, -1, 0, "", "", "oldState"));
344
                        assignment.nondetExpression().Accept(exprvis);
345
                        m_emitter.AppendLine(String.format("if (%1$s)", exprvis.toString()));
346
                }
347

    
348
                m_emitter.AppendLine("{");
349

    
350
                m_emitter.AppendLine("/* setup new state */");
351
                m_emitter.AppendLine("CAESAR_CREATE_STATE(&newState);");
352
                m_emitter.AppendLine("memcpy(newState,oldState,CAESAR_SIZE_STATE());");
353
                m_emitter.AppendLine("newState->_hidden = 1;");
354
                m_emitter.AppendLine("newState->_predecessor = oldState;");
355
                m_emitter.AppendLine("struct STATE_LIST *newListElem;");
356
                m_emitter.AppendLine("LIST_CREATE(newListElem);");
357
                m_emitter.AppendLine("newListElem->aState = newState;");
358
                m_emitter.AppendLine("newState->_successors = NULL;");
359
                m_emitter.AppendLine(String.format("newState->_statenum = (char*)%1$s;", m_debugPosCount--));
360

    
361

    
362

    
363
                final Iterator<Expression> place = assignment.places().iterator();
364
                final Iterator<Expression> value = assignment.values().iterator();
365
                while (place.hasNext() && value.hasNext())
366
                {
367
                        final Expression currValue = value.next();
368
                        final Expression currPlace = place.next();
369
                        CadpExpression vis = new CadpExpression(new CadpActionInfo(null, -1, 0, "", "", "oldState"));
370
                        currValue.Accept(vis);
371
                        final String from = vis.toString();
372
                        final String fromdecls = vis.VariableDeclarations();
373

    
374
                        vis = new CadpExpression(new CadpActionInfo(null, -1, 0, "", "", "newState"));
375
                        currPlace.Accept(vis);
376
                        final String to = vis.toString();
377
                        /*if (to.Equals("param_result"))
378
                    to = "*param_result";*/
379
                        m_emitter.AppendLine(vis.VariableDeclarations());
380
                        m_emitter.AppendLine(fromdecls);
381
                        m_emitter.AppendLine(String.format("%1$s = %2$s;", to, from));
382

    
383
                        // code that checks wether we're in range..
384
                        switch (currPlace.type().kind())
385
                        {
386
                        case IntType:
387
                                final IntType placetype_int = (IntType)currPlace.type();
388
                                m_emitter.AppendLine(String.format("/*Range of %3$s: %1$s..%2$s*/", placetype_int.rangeLow(), placetype_int.rangeHigh(), to));
389
                                m_emitter.AppendLine(String.format("if (%1$s < %2$sLL || %1$s > %3$sLL)", to, placetype_int.rangeLow(), placetype_int.rangeHigh()));
390
                                m_emitter.AppendLine(String.format("{CAESAR_DELETE(newState); free(newListElem); newListElem = NULL; goto rangeExit_%1$s;}", OoaCADPVisitor.getUIntHashCode(assignment)));
391
                                break;
392
                        case FloatType:
393
                                final FloatType placetype_float = (FloatType)currPlace.type();
394
                                m_emitter.AppendLine(String.format("/*Range of %3$s: %1$s..%2$s*/", placetype_float.low(), placetype_float.high(), to));
395
                                m_emitter.AppendLine(String.format("if (%1$s < %2$s || %1$s > %3$s)", to, placetype_float.low(), placetype_float.high()));
396
                                m_emitter.AppendLine(String.format("{CAESAR_DELETE(newState); free(newListElem); newListElem = NULL; goto rangeExit_%1$s;}", OoaCADPVisitor.getUIntHashCode(assignment)));
397
                                break;
398
                        default:
399
                                m_emitter.AppendLine(String.format("if (CALC_INVALID == 1)"));
400
                                m_emitter.AppendLine(String.format("{ CALC_INVALID = 0; CAESAR_DELETE(newState); free(newListElem); newListElem = NULL; goto rangeExit_%1$s;}", OoaCADPVisitor.getUIntHashCode(assignment)));
401
                                break;
402
                        }
403
                }
404
                m_emitter.AppendLine("LISTLIST_INSERT_LIST(ARGOS_ALL_STATES,newListElem);");
405
                m_emitter.AppendLine(String.format("rangeExit_%1$s:", OoaCADPVisitor.getUIntHashCode(assignment)));
406
                m_emitter.AppendLine(String.format("LIST_INSERT_SINGLELIST(%1$s,newListElem);", m_procInfo.doneListString));
407
                m_emitter.AppendLine("}");
408
                if (assignment.nondetExpression() != null)
409
                        for (@SuppressWarnings("unused") final SimpleEntry<String, Type> key : nondetEnumerators)
410
                                m_emitter.AppendLine("} /* closing nondet assignment for loop */");
411

    
412
                m_emitter.AppendLine("elems = elems->next;");
413
                m_emitter.AppendLineDecIndent("} /*while loop, iterating through all states*/");
414
                m_emitter.AppendLine("} /* end assignment*/");
415
        }
416

    
417
        @Override
418
        public  void visit(Call call)
419
        {
420
                final Expression ce = call.callExpression();
421
                String callstatement = "";
422

    
423
                /*for each state in the worklist..*/
424

    
425
                m_emitter.AppendLineIncIndent("{ /* begin named action call*/");
426
                m_emitter.AppendLine("struct STATE_LIST *callresult = NULL;");
427
                m_emitter.AppendLine(String.format("struct STATE_LIST *elem = %1$s;", m_procInfo.toDoListString));
428
                m_emitter.AppendLine("while(elem != NULL)");
429
                m_emitter.AppendLineIncIndent("{");
430
                m_emitter.AppendLine("struct STATE_LIST *next = elem->next;");
431

    
432
                final StringBuilder parameter = new StringBuilder("(CAESAR_TYPE_STATE)elem->aState");
433

    
434
                if (ce.kind() == ExpressionKind.Identifier)
435
                        callstatement = ((IdentifierExpression)ce).identifier().tokenText();
436
                else if (ce.kind() == ExpressionKind.Call)
437
                {
438
                        final CallExpression parens = (CallExpression)ce;
439

    
440
                        final CadpExpression cadpexpr = new CadpExpression(m_procInfo);
441
                        parens.child().Accept(cadpexpr);
442

    
443
                        m_emitter.Append(cadpexpr.VariableDeclarations());
444

    
445
                        callstatement = cadpexpr.toString();
446
                        for (final Expression arg : parens.arguments())
447
                        {
448
                                parameter.append(", ");
449
                                final CadpExpression paramexpr = new CadpExpression(m_procInfo);
450
                                arg.Accept(paramexpr);
451
                                m_emitter.AppendLine(paramexpr.VariableDeclarations());
452
                                parameter.append(paramexpr.toString());
453
                        }
454
                        if (((FunctionType)parens.child().type()).returnType() != null)
455
                        {
456
                                final String tmpresult = String.format("detcallresult_%1$s", OoaCADPVisitor.getUIntHashCode(parens));
457
                                m_emitter.AppendLine(String.format("%1$s %2$s;", CadpType.DumpType(((FunctionType)parens.child().type()).returnType()), tmpresult));
458
                                parameter.append(String.format(", &(%1$s)", tmpresult));
459
                        }
460

    
461
                }
462
                else if (ce.kind() == ExpressionKind.foldRL
463
                                || ce.kind() == ExpressionKind.foldLR)
464
                {
465
                        // intermediate hack for map..
466
                        final CallExpression callexpr = (CallExpression)((TernaryOperator)ce).left();
467
                        final Expression alist = ((TernaryOperator)ce).right();
468

    
469
                        final CadpExpression cadplist = new CadpExpression(m_procInfo);
470
                        alist.Accept(cadplist);
471
                        final String listname = Integer.toString(OoaCADPVisitor.getUIntHashCode(alist)) + Integer.toString(OoaCADPVisitor.getUIntHashCode(callexpr));
472
                        //m_emitter.AppendLine("struct STATE_LIST *_map_tmp_result = elem;");
473
                        m_emitter.AppendLine(String.format("%1$s list_%2$s = %3$s;",
474
                                        CadpType.DumpType(alist.type()), listname, cadplist.toString()));
475
                        m_emitter.AppendLine(String.format("int list_iterator_%1$s;", listname));
476
                        if (ce.kind() == ExpressionKind.foldLR)
477
                                m_emitter.AppendLine(String.format("for (list_iterator_%1$s = 0; list_iterator_%1$s < list_%1$s.length; list_iterator_%1$s++) {", listname));
478
                        else
479
                                m_emitter.AppendLine(String.format("for (list_iterator_%1$s = list_%1$s.length - 1; list_iterator_%1$s >= 0 ; list_iterator_%1$s--) {", listname));
480

    
481
                        m_emitter.AppendLine(String.format("%1$s list_elem%2$s = list_%2$s.elements[list_iterator_%2$s];", CadpType.DumpType(((ListType)alist.type()).innerType()),
482
                                        listname));
483

    
484

    
485
                        final CadpExpression cadpexpr = new CadpExpression(m_procInfo);
486
                        callexpr.child().Accept(cadpexpr);
487
                        callstatement = cadpexpr.toString();
488
                        for (final Expression arg: callexpr.arguments())
489
                        {
490
                                parameter.append(", ");
491
                                final CadpExpression paramexpr = new CadpExpression(m_procInfo);
492
                                arg.Accept(paramexpr);
493
                                parameter.append(paramexpr.toString());
494
                        }
495
                        parameter.append(String.format(", list_elem%1$s", listname));
496

    
497
                }
498
                else
499
                        throw new UnsupportedOperationException();
500

    
501
                m_emitter.AppendLine(String.format("callresult = %1$s(%2$s);", callstatement, parameter));
502
                if (ce.kind() == ExpressionKind.foldRL || ce.kind() == ExpressionKind.foldLR)
503
                {
504
                        m_emitter.AppendLine("if (callresult == NULL) break; /*if function of map/fold not enabled - abort*/");
505
                        m_emitter.AppendLine("if (callresult->next != NULL) { fprintf(stderr,\"\\nnon-deterministic fold/map not supported!\\n\");  CAESAR_TERMINATE(1); }");
506
                        m_emitter.AppendLine("elem = callresult; }");
507
                }
508
                m_emitter.AppendLine(String.format("LIST_INSERT_LIST(%1$s, callresult);", m_procInfo.doneListString));
509
                m_emitter.AppendLine("elem = next;");
510
                m_emitter.AppendLineDecIndent("}");
511
                m_emitter.AppendLineDecIndent("} /* end named action call*/");
512
        }
513

    
514
        @Override
515
        public  void visit(SkipStatement skipStatement)
516
        {
517
                m_emitter.AppendLine("{ /* skip */");
518
                m_emitter.AppendLine(String.format("struct STATE_LIST *elems = %1$s;", m_procInfo.toDoListString));
519
                m_emitter.AppendLine("CAESAR_TYPE_STATE newState = NULL;");
520
                m_emitter.AppendLine("CAESAR_TYPE_STATE oldState;");
521
                m_emitter.AppendLine("while (elems != NULL)");
522
                m_emitter.AppendLineIncIndent("{");
523
                m_emitter.AppendLine("oldState = (CAESAR_TYPE_STATE) elems->aState;");
524

    
525
                m_emitter.AppendLine("{");
526

    
527
                m_emitter.AppendLine("/* setup new state */");
528
                m_emitter.AppendLine("CAESAR_CREATE_STATE(&newState);");
529
                m_emitter.AppendLine("memcpy(newState,oldState,CAESAR_SIZE_STATE());");
530
                m_emitter.AppendLine("newState->_hidden = 1;");
531
                m_emitter.AppendLine("newState->_predecessor = oldState;");
532
                m_emitter.AppendLine("struct STATE_LIST *newListElem;");
533
                m_emitter.AppendLine("LIST_CREATE(newListElem);");
534
                m_emitter.AppendLine("newListElem->aState = newState;");
535
                m_emitter.AppendLine("newState->_successors = NULL;");
536
                m_emitter.AppendLine(String.format("newState->_statenum = (char*)%1$s;", m_debugPosCount--));
537

    
538
                m_emitter.AppendLine("LISTLIST_INSERT_LIST(ARGOS_ALL_STATES,newListElem);");
539
                m_emitter.AppendLine(String.format("LIST_INSERT_SINGLELIST(%1$s,newListElem);", m_procInfo.doneListString));
540
                m_emitter.AppendLine("}");
541
                m_emitter.AppendLine("elems = elems->next;");
542
                m_emitter.AppendLineDecIndent("} /*while loop, iterating through all states*/");
543
                m_emitter.AppendLine("} /* end skip*/");
544
        }
545

    
546
        @Override
547
        public  void visit(AbortStatement abortStatement)
548
        {
549
                throw new UnsupportedOperationException();
550
        }
551

    
552
        @Override
553
        public  void visit(KillStatement killStatement)
554
        {
555
                throw new UnsupportedOperationException();
556
        }
557

    
558
        @Override
559
        public  String toString()
560
        {
561
                return m_emitter.toString();
562
        }
563

    
564
        public CadpStatement(CadpActionInfo aProcInfo)
565
        {
566
                super();
567
                if (aProcInfo == null)
568
                        throw new IllegalArgumentException();
569
                m_procInfo = aProcInfo;
570
                m_blockCount = 0;
571
        }
572

    
573
        public CadpStatement(CadpActionInfo aProcInfo, boolean labelHiddenStates)
574
        {
575
                this(aProcInfo);
576
                //m_labelHiddenStates = labelHiddenStates;
577
        }
578

    
579

    
580
        public CadpStatement(CadpStatement toCopy)
581
        {
582
                super();
583
                m_procInfo = toCopy.m_procInfo;
584
                m_blockCount = toCopy.m_blockCount;
585
                m_statePosCount = toCopy.m_statePosCount;
586
                //m_labelHiddenStates = toCopy.m_labelHiddenStates;
587
        }
588
}