Project

General

Profile

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

    
30
import java.util.ArrayList;
31

    
32
import org.momut.ooas.ast.IAst;
33
import org.momut.ooas.ast.expressions.AccessExpression;
34
import org.momut.ooas.ast.expressions.BinaryOperator;
35
import org.momut.ooas.ast.expressions.CallExpression;
36
import org.momut.ooas.ast.expressions.Expression;
37
import org.momut.ooas.ast.expressions.ExpressionKind;
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.MapConstructor.MapItem;
52
import org.momut.ooas.ast.identifiers.AttributeIdentifier;
53
import org.momut.ooas.ast.identifiers.EnumIdentifier;
54
import org.momut.ooas.ast.identifiers.ExpressionVariableIdentifier;
55
import org.momut.ooas.ast.identifiers.Identifier;
56
import org.momut.ooas.ast.identifiers.IdentifierKind;
57
import org.momut.ooas.ast.identifiers.LandmarkIdentifier;
58
import org.momut.ooas.ast.identifiers.MainModule;
59
import org.momut.ooas.ast.identifiers.MethodIdentifier;
60
import org.momut.ooas.ast.identifiers.NamedActionIdentifier;
61
import org.momut.ooas.ast.identifiers.NondetIdentifierList;
62
import org.momut.ooas.ast.identifiers.PrioIdentifierList;
63
import org.momut.ooas.ast.identifiers.SeqIdentifierList;
64
import org.momut.ooas.ast.identifiers.TypeIdentifier;
65
import org.momut.ooas.ast.statements.AbortStatement;
66
import org.momut.ooas.ast.statements.Assignment;
67
import org.momut.ooas.ast.statements.Call;
68
import org.momut.ooas.ast.statements.GuardedCommand;
69
import org.momut.ooas.ast.statements.KillStatement;
70
import org.momut.ooas.ast.statements.NondetBlock;
71
import org.momut.ooas.ast.statements.PrioBlock;
72
import org.momut.ooas.ast.statements.SeqBlock;
73
import org.momut.ooas.ast.statements.SkipStatement;
74
import org.momut.ooas.ast.statements.Statement;
75
import org.momut.ooas.ast.types.BoolType;
76
import org.momut.ooas.ast.types.CharType;
77
import org.momut.ooas.ast.types.EnumType;
78
import org.momut.ooas.ast.types.FloatType;
79
import org.momut.ooas.ast.types.FunctionType;
80
import org.momut.ooas.ast.types.IntType;
81
import org.momut.ooas.ast.types.ListType;
82
import org.momut.ooas.ast.types.MapType;
83
import org.momut.ooas.ast.types.NullType;
84
import org.momut.ooas.ast.types.OoActionSystemType;
85
import org.momut.ooas.ast.types.OpaqueType;
86
import org.momut.ooas.ast.types.QrType;
87
import org.momut.ooas.ast.types.TupleType;
88
import org.momut.ooas.ast.types.TypeKind;
89
import org.momut.ooas.ast.types.UlyssesType;
90
import org.momut.ooas.codegen.OoasCodeEmitter;
91
import org.momut.ooas.parser.ParserState;
92
import org.momut.ooas.utils.exceptions.NotImplementedException;
93

    
94
public class OoaPrintVisitor extends OoaCompleteAstTraversalVisitor
95
{
96
        private interface Action {
97
                void doIt();
98
        }
99

    
100
        protected boolean writeTypes;
101
        protected Identifier currentTypeDef;
102
        protected final OoasCodeEmitter output;
103

    
104

    
105

    
106
        private void PrintSubElementOrNull(IAst anElem)
107
        {
108
                if (anElem == null)
109
                        output.Append("<null>");
110
                else
111
                        anElem.Accept(this);
112
        }
113

    
114
        private void PrintEnumeration(Iterable<?> iarg)
115
        {
116
                int i = 0;
117
                @SuppressWarnings("unchecked")
118
                final
119
                Iterable<IAst> arg = (Iterable<IAst>) iarg;
120
                for (final IAst sym: arg)
121
                {
122
                        if (i != 0)
123
                                output.Append(", ");
124
                        i++;
125
                        PrintSubElementOrNull(sym);
126
                }
127
        }
128

    
129
        /*print the type identifier, or the type definition by calling the anAction delegate.*/
130
        private void PrintType(UlyssesType atype, Action anAction)
131
        {
132
                if (   (atype.identifier() != null)
133
                                && (!atype.isAnonymousType())
134
                                && (currentTypeDef != atype.identifier() || !writeTypes)) // ref equ.
135
                {
136
                        final boolean write = writeTypes;
137
                        writeTypes = false;
138
                        atype.identifier().Accept(this);
139
                        writeTypes = write;
140
                }
141
                else
142
                        anAction.doIt();
143
        }
144

    
145

    
146

    
147
        @Override
148
        public void visit(MainModule mainModule)
149
        {
150
                int i = 0;
151
                final boolean haveInstance = mainModule.instance() != null;
152
                /*print all types*/
153
                writeTypes = true;
154
                output.IncIndent();
155
                output.AppendLine("types");
156
                for (final Identifier type: mainModule.symbolTable().symbolList())
157
                {
158
                        if (type.kind() != IdentifierKind.TypeIdentifier)
159
                                continue;
160

    
161
                        if (i != 0)
162
                                output.AppendLine(";");
163
                        i++;
164
                        if (!haveInstance || ((TypeIdentifier)type).type().kind() != TypeKind.OoActionSystemType)
165
                                type.Accept(this);
166
                }
167

    
168
                if (haveInstance)
169
                        mainModule.instance().Accept(this);
170

    
171
                output.DecIndent();
172
                output.AppendLine("");
173
                output.IncIndent();
174
                output.IncIndent();
175
                output.AppendLine("system");
176
                writeTypes = false;
177
                if (!haveInstance)
178
                        mainModule.systemDescription().Accept(this);
179
                else
180
                        output.Append(mainModule.instance().identifier().tokenText());
181
        }
182

    
183
        @Override
184
        public void visit(TypeIdentifier typeIdentifier)
185
        {
186
                output.Append(typeIdentifier.tokenText());
187
                if (writeTypes)
188
                {
189
                        currentTypeDef = typeIdentifier;
190
                        output.Append(" = ");
191
                        PrintSubElementOrNull(typeIdentifier.type());
192
                }
193
        }
194

    
195
        /*write out type definitions*/
196
        @Override
197
        public void visit(BoolType boolType)
198
        {
199
                output.Append("bool");
200
        }
201

    
202
        @Override
203
        public void visit(CharType charType)
204
        {
205
                output.Append("char");
206
        }
207

    
208
        @Override
209
        public void visit(final IntType intType)
210
        {
211
                PrintType(intType, new Action(){
212
                        @Override
213
                        public void doIt() {
214
                                output.Append("int [");
215
                                output.Append(Integer.toString(intType.rangeLow()));
216
                                output.Append(" .. ");
217
                                output.Append(Integer.toString(intType.rangeHigh()));
218
                                output.Append("]");
219
                        }});
220
        }
221

    
222
        @Override
223
        public void visit(final FloatType floatType)
224
        {
225
                PrintType(floatType,  new Action(){
226
                        @Override
227
                        public void doIt() {
228
                                output.Append("float [");
229
                                output.Append(Double.toString(floatType.low()));
230
                                output.Append(" .. ");
231
                                output.Append(Double.toString(floatType.high()));
232
                                output.Append("] /*");
233
                                output.Append(Double.toString(floatType.precision()));
234
                                output.Append("*/");
235
                }});
236
        }
237

    
238

    
239
        @Override
240
        public void visit(EnumIdentifier enumIdentifier)
241
        {
242
                output.Append(enumIdentifier.tokenText());
243
                if (enumIdentifier.HaveValue())
244
                        output.Append(String.format(" = %s", enumIdentifier.Value()));
245
        }
246

    
247
        @Override
248
        public void visit(final EnumType enumType)
249
        {
250
                PrintType(enumType, new Action(){
251
                        @Override
252
                        public void doIt() {
253
                                output.Append("{");
254
                                PrintEnumeration(enumType.listOfEnumSymbols());
255
                                output.Append("}");
256
                        }});
257
        }
258

    
259

    
260
        @Override
261
        public void visit(final ListType listType)
262
        {
263
                PrintType(listType, new Action(){
264
                        @Override
265
                        public void doIt() {
266
                                output.Append("list [");
267
                                output.Append(listType.maxNumberOfElements());
268
                                output.Append("] of ");
269
                                PrintSubElementOrNull(listType.innerType());
270
                        }});
271
        }
272

    
273
        @Override
274
        public void visit(final MapType mapType)
275
        {
276
                PrintType(mapType, new Action(){
277
                        @Override
278
                        public void doIt() {
279
                                output.Append("map [");
280
                                output.Append(mapType.maxNumberOfElements());
281
                                output.Append("] ");
282
                                PrintSubElementOrNull(mapType.fromType());
283
                                output.Append(" to ");
284
                                PrintSubElementOrNull(mapType.toType());
285
                        }});
286
        }
287

    
288
        @Override
289
        public void visit(final TupleType tupleType)
290
        {
291
                PrintType(tupleType, new Action(){
292
                        @Override
293
                        public void doIt() {
294
                                output.Append("(");
295
                                PrintEnumeration(tupleType.innerTypes());
296
                                output.Append(")");
297
                        }});
298
        }
299

    
300
        @Override
301
        public void visit(OpaqueType opaqueType)
302
        {
303
                PrintSubElementOrNull(opaqueType.resolvedType());
304

    
305
                output.Append(" /*opagque*/");
306
        }
307

    
308
        @Override
309
        public void visit(final QrType qrType)
310
        {
311
                PrintType(qrType, new Action(){
312
                        @Override
313
                        public void doIt() {
314
                                output.Append("qspace of [");
315
                                PrintEnumeration(qrType.landmarks());
316
                                output.Append("]");
317
                        }});
318
        }
319

    
320
        @Override
321
        public void visit(LandmarkIdentifier landmarkIdentifier)
322
        {
323
                output.Append(landmarkIdentifier.tokenText());
324
        }
325

    
326
        @Override
327
        public void visit(final OoActionSystemType ooActionSystemType)
328
        {
329
                PrintType(ooActionSystemType, new Action(){
330
                        @Override
331
                        public void doIt() {
332
                                if (ooActionSystemType.autoConstruction())
333
                                        output.Append("autocons ");
334

    
335
                                output.Append("system ");
336
                                if (ooActionSystemType.baseType() != null)
337
                                        output.Append(String.format("(%s)", ooActionSystemType.baseType().identifier().tokenText()));
338
                                output.AppendLine("");
339

    
340
                                output.IncIndent();
341
                                output.AppendLine("|[");
342

    
343
                                // get a list of interesting symbols
344
                                final ArrayList<AttributeIdentifier> attrs = new ArrayList<AttributeIdentifier>();
345
                                final ArrayList<MethodIdentifier> methods = new ArrayList<MethodIdentifier>();
346
                                final ArrayList<NamedActionIdentifier> namedActions = new ArrayList<NamedActionIdentifier>();
347

    
348
                                for(final Identifier sym: ooActionSystemType.symbols().symbolList())
349
                                {
350
                                        if (sym.kind() == IdentifierKind.AttributeIdentifier)
351
                                                attrs.add((AttributeIdentifier)sym);
352
                                        else if (sym.kind() == IdentifierKind.MethodIdentifier)
353
                                                methods.add((MethodIdentifier)sym);
354
                                        else if (sym.kind() == IdentifierKind.NamedActionIdentifier)
355
                                                namedActions.add((NamedActionIdentifier)sym);
356
                                }
357

    
358
                                int i = 0;
359
                                if (attrs.size() > 0)
360
                                {
361
                                        // variables
362
                                        output.IncIndent();
363
                                        output.AppendLine("var");
364
                                        for (final AttributeIdentifier attr : attrs)
365
                                        {
366
                                                if (i != 0)
367
                                                        output.AppendLine(";");
368
                                                i++;
369
                                                PrintSubElementOrNull(attr);
370
                                        }
371
                                        output.DecIndent();
372
                                        output.AppendLine("");
373
                                }
374
                                final boolean writeTypesSave = writeTypes;
375
                                writeTypes = false;
376

    
377
                                i = 0;
378
                                if (methods.size() > 0)
379
                                {
380
                                        output.IncIndent();
381
                                        output.AppendLine("methods");
382
                                        for (final MethodIdentifier method : methods)
383
                                        {
384
                                                if (i != 0)
385
                                                        output.AppendLine(";");
386
                                                i++;
387
                                                PrintSubElementOrNull(method);
388
                                        }
389
                                        output.DecIndent();
390
                                        output.AppendLine("");
391
                                }
392

    
393
                                i = 0;
394
                                if (namedActions.size() > 0)
395
                                {
396
                                        output.IncIndent();
397
                                        output.AppendLine("actions");
398
                                        for (final NamedActionIdentifier action: namedActions)
399
                                        {
400
                                                if (i != 0)
401
                                                        output.AppendLine(";");
402
                                                i++;
403
                                                PrintSubElementOrNull(action);
404
                                        }
405
                                        output.DecIndent();
406
                                        output.AppendLine("");
407
                                }
408

    
409
                                if ((ooActionSystemType.doOdBlock() != null) &&
410
                                    (ooActionSystemType.doOdBlock().statements().size() > 0))
411
                                {
412
                                        output.IncIndent();
413
                                        output.AppendLine("do");
414
                                        PrintSubElementOrNull(ooActionSystemType.doOdBlock());
415
                                        output.DecIndent();
416
                                        output.AppendLine("");
417
                                        output.AppendLine("od");
418
                                }
419
                                output.DecIndent();
420
                                output.AppendLine("");
421
                                output.Append("]|");
422
                                writeTypes = writeTypesSave;
423
                        }});
424
        }
425

    
426
        @Override
427
        public void visit(NullType nullType)
428
        {
429
                output.Append("nil");
430
        }
431

    
432

    
433
        @Override
434
        public void visit(AttributeIdentifier attributeIdentifier)
435
        {
436
                if (attributeIdentifier.isStatic())
437
                        output.Append("static ");
438
                if (attributeIdentifier.isObservable())
439
                        output.Append("obs ");
440
                if (attributeIdentifier.isControllable())
441
                        output.Append("ctr ");
442

    
443
                output.Append(attributeIdentifier.tokenText());
444
                if (writeTypes)
445
                {
446
                        output.Append(": ");
447
                        PrintSubElementOrNull(attributeIdentifier.type());
448
                        output.Append(" = ");
449
                        PrintSubElementOrNull(attributeIdentifier.initializer());
450
                }
451
        }
452

    
453

    
454
        @Override
455
        public <T>void visit(ValueExpression<T> valueExpression)
456
        {
457
                if (valueExpression.value() != null)
458
                        output.Append(valueExpression.value().toString());
459
                else
460
                        output.Append("nil");
461
        }
462

    
463
        @Override
464
        public void visit(AbortStatement abortStatement)
465
        {
466
                output.Append("abort");
467
        }
468

    
469
        @Override
470
        public void visit(Assignment assignment)
471
        {
472
                PrintEnumeration(assignment.places());
473
                output.Append(" := ");
474
                PrintEnumeration(assignment.values());
475
                if (assignment.nondetExpression() != null)
476
                {
477
                        output.IncIndent();
478
                        output.AppendLine("");
479
                        output.Append("with ");
480
                        assignment.nondetExpression().Accept(this);
481

    
482
                        if (assignment.symbols().symbolList().size() > 0)
483
                        {
484
                                output.Append(" /* vars: ");
485
                                for (final Identifier localVar: assignment.symbols().symbolList())
486
                                {
487
                                        localVar.Accept(this);
488
                                        output.Append(" ");
489
                                }
490
                                output.Append("*/");
491
                        }
492
                        output.DecIndent();
493
                        output.AppendLine("");
494
                }
495
        }
496

    
497
        @Override
498
        public void visit(KillStatement killStatement)
499
        {
500
                output.Append("kill (");
501
                PrintSubElementOrNull(killStatement.someOne);
502
                output.Append(")");
503
        }
504

    
505
        @Override
506
        public void visit(AccessExpression accessExpression)
507
        {
508
                if (accessExpression.right() != null)
509
                {
510
                        output.Append("(");
511
                        PrintSubElementOrNull(accessExpression.left());
512
                        output.Append(").");
513
                        PrintSubElementOrNull(accessExpression.right());
514
                }
515
                else
516
                {
517
                        output.Append("(");
518
                        PrintSubElementOrNull(accessExpression.left());
519
                        output.Append(")");
520
                }
521
        }
522

    
523
        private void PrintOperator(Expression expression)
524
        {
525
                switch (expression.kind())
526
                {
527
                case abs:    // T_ABS:
528
                        output.Append("abs");
529
                        break;
530
                case card:   // T_CARD:
531
                        output.Append("card");
532
                        break;
533
                case dom:    // T_DOM:
534
                        output.Append("dom");
535
                        break;
536
                case range:  // T_RNG:
537
                        output.Append("range");
538
                        break;
539
                case merge:  // T_MERGE:
540
                        output.Append("merge");
541
                        break;
542
                case len:    // T_LEN:
543
                        output.Append("len");
544
                        break;
545
                case elems:  // T_ELEMS:
546
                        output.Append("elems");
547
                        break;
548
                case head:   // T_HEAD:
549
                        output.Append("head");
550
                        break;
551
                case tail:   // T_TAIL:
552
                        output.Append("tail");
553
                        break;
554
                case conc:   // T_CONC:
555
                        output.Append("conc");
556
                        break;
557
                case inds:   // T_INDS:
558
                        output.Append("inds");
559
                        break;
560
                case dinter: // T_DINTER:
561
                        output.Append("dinter");
562
                        break;
563
                case dunion: // T_DUNION:
564
                        output.Append("dunion");
565
                        break;
566
                case domresby:   // T_DOMRESBY:
567
                        output.Append("domresby");
568
                        break;
569
                case domresto:   // T_DOMRESTO:
570
                        output.Append("domresto");
571
                        break;
572
                case rngresby:   // T_RNGRESBY:
573
                        output.Append("rngresby");
574
                        break;
575
                case rngresto:   // T_RNGRESTO:
576
                        output.Append("rngresto");
577
                        break;
578
                case div:    // T_DIV:
579
                        output.Append("div");
580
                        break;
581
                case idiv:   // T_IDIV:
582
                        output.Append("idiv");
583
                        break;
584
                case mod:    // T_MOD:
585
                        output.Append("mod");
586
                        break;
587
                case prod:   // T_PROD:
588
                        output.Append("*");
589
                        break;
590
                case inter:  // T_INTER:
591
                        output.Append("inter");
592
                        break;
593
                case sum:    // T_SUM:
594
                        output.Append("+");
595
                        break;
596
                case minus:  // T_MINUS:
597
                        output.Append("-");
598
                        break;
599
                case union:  // T_UNION:
600
                        output.Append("union");
601
                        break;
602
                case diff:   // T_DIFF:
603
                        output.Append("diff");
604
                        break;
605
                case munion: // T_MUNION:
606
                        output.Append("munion");
607
                        break;
608
                case seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
609
                        output.Append("seqmod_mapoverride");
610
                        break;
611
                case less:
612
                        output.Append("<");
613
                        break;
614
                case lessequal:
615
                        output.Append("<=");
616
                        break;
617
                case greater:
618
                        output.Append(">");
619
                        break;
620
                case greaterequal:
621
                        output.Append(">=");
622
                        break;
623
                case equal:
624
                        output.Append("=");
625
                        break;
626
                case notequal:
627
                        output.Append("<>");
628
                        break;
629
                case subset:
630
                        output.Append("subset");
631
                        break;
632
                case elemin:
633
                        output.Append("in");
634
                        break;
635
                case notelemin:
636
                        output.Append("not in");
637
                        break;
638
                case and:    // T_AND:
639
                        output.Append("and");
640
                        break;
641

    
642
                case or:     // T_OR:
643
                        output.Append("or");
644
                        break;
645
                case implies:    // T_IMPLIES:
646
                        output.Append("=>");
647
                        break;
648
                case biimplies:  // T_BIIMPLIES:
649
                        output.Append("<=>");
650
                        break;
651

    
652
                case Primed:
653
                        output.Append("'");
654
                        break;
655

    
656

    
657
                case Cast:
658
                        output.Append("(");
659
                        if (expression.type() != null)
660
                                output.Append(expression.type().toString());
661
                        else
662
                                output.Append("Cast??");
663
                        output.Append(")");
664
                        break;
665

    
666
                default:
667
                        output.Append(expression.kind().toString()); //Enum.GetName(typeof(ExpressionKind), expression.kind));
668
                        break;
669
                }
670
        }
671

    
672
        @Override
673
        public void visit(TypeExpression typeExpression)
674
        {
675
                PrintSubElementOrNull(typeExpression.type());
676
        }
677

    
678
        @Override
679
        public void visit(BinaryOperator binaryOperator)
680
        {
681
                output.IncIndent();
682
                output.AppendLine("(");
683
                PrintSubElementOrNull(binaryOperator.left());
684
                output.DecIndent();
685
                output.AppendLine("");
686
                output.AppendLine(")");
687

    
688
                PrintOperator(binaryOperator); output.AppendLine("");
689

    
690
                output.IncIndent();
691
                output.AppendLine("(");
692
                PrintSubElementOrNull(binaryOperator.right());
693
                output.DecIndent();
694
                output.AppendLine("");
695
                output.AppendLine(")");
696
        }
697

    
698
        @Override
699
        public void visit(UnaryOperator unaryOperator)
700
        {
701
                PrintOperator(unaryOperator);
702
                output.Append("(");
703
                PrintSubElementOrNull(unaryOperator.child());
704
                output.Append(")");
705
        }
706

    
707
        @Override
708
        public void visit(UnresolvedIdentifierExpression unresolvedIdentifierExpression)
709
        {
710
                output.Append(unresolvedIdentifierExpression.tokenText());
711
        }
712

    
713
        @Override
714
        public void visit(CallExpression callExpression)
715
        {
716
                if (callExpression.child() != null)
717
                        callExpression.child().Accept(this);
718
                if ((callExpression.arguments() != null) && (callExpression.arguments().size() > 0))
719
                {
720
                        output.Append("(");
721
                        PrintEnumeration(callExpression.arguments());
722
                        output.Append(")");
723
                }
724
                else
725
                {
726
                        output.Append("()");
727
                }
728
        }
729

    
730
        @Override
731
        public void visit(TupleMapAccessExpression tupleMapAccessExpression)
732
        {
733
                if (tupleMapAccessExpression.child() != null)
734
                        tupleMapAccessExpression.child().Accept(this);
735
                output.Append("[");
736
                PrintSubElementOrNull(tupleMapAccessExpression.argument());
737
                output.Append("]");
738
        }
739

    
740
        @Override
741
        public void visit(TupleConstructor tupleConstructor)
742
        {
743
                output.Append(tupleConstructor.tupleType().tokenText());
744
                output.Append("(");
745
                PrintEnumeration(tupleConstructor.values());
746
                output.Append(")");
747
        }
748

    
749
        @Override
750
        public void visit(ListConstructor listConstructor)
751
        {
752
                output.Append("[");
753
                PrintEnumeration(listConstructor.elements());
754
                if (listConstructor.hasComprehension())
755
                {
756
                        output.Append("| var ");
757
                        int i = 0;
758
                        for (final Identifier element: listConstructor.comprehensionVariables().symbolList())
759
                        {
760
                                if (i != 0)
761
                                        output.Append("; ");
762
                                i++;
763
                                PrintSubElementOrNull(element);
764
                        }
765
                        output.AppendLine(" &");
766
                        PrintSubElementOrNull(listConstructor.comprehension());
767
                }
768
                output.Append("]");
769
        }
770

    
771
        @Override
772
        public void visit(QValConstructor qValConstructor)
773
        {
774
                output.Append("qval(");
775
                PrintSubElementOrNull(qValConstructor.value()[0]);
776
                if (qValConstructor.value().length == 2)
777
                {
778
                        output.Append(" .. ");
779
                        PrintSubElementOrNull(qValConstructor.value()[1]);
780
                }
781
                output.Append(",");
782
                output.Append(qValConstructor.valueDeriv().toString());
783
                output.Append(")");
784
        }
785

    
786

    
787
        private boolean make_parens = false;
788

    
789
        @Override
790
        public void visit(NondetBlock nondetBlock)
791
        {
792
                int i = 0;
793
                if (make_parens)
794
                {
795
                        output.IncIndent();
796
                        output.AppendLine("(");
797
                }
798
                for (final Statement smt: nondetBlock.statements())
799
                {
800
                        if (i != 0)
801
                        {
802
                                output.DecIndent();
803
                                output.AppendLine("");
804
                                output.IncIndent();
805
                                output.AppendLine("[] ");
806
                        }
807
                        i++;
808
                        smt.Accept(this);
809
                }
810
                if (make_parens)
811
                {
812
                        output.DecIndent();
813
                        output.AppendLine("");
814
                        output.AppendLine(")");
815
                }
816
        }
817

    
818
        @Override
819
        public void visit(PrioBlock prioBlock)
820
        {
821
                int i = 0;
822
                if (make_parens)
823
                {
824
                        output.IncIndent();
825
                        output.AppendLine("(");
826
                }
827
                for (final Statement smt: prioBlock.statements())
828
                {
829
                        if (i != 0)
830
                        {
831
                                output.DecIndent();
832
                                output.AppendLine("");
833
                                output.IncIndent();
834
                                output.AppendLine("// ");
835
                        }
836
                        i++;
837
                        smt.Accept(this);
838
                }
839
                if (make_parens)
840
                {
841
                        output.DecIndent();
842
                        output.AppendLine("");
843
                        output.AppendLine(")");
844
                }
845
        }
846

    
847
        @Override
848
        public void visit(SeqBlock seqBlock)
849
        {
850
                int i = 0;
851
                final boolean old_makeparens = make_parens;
852
                output.IncIndent();
853
                output.AppendLine("(");
854
                if (seqBlock.symbols().symbolList().size() > 0)
855
                {
856
                        output.Append("var ");
857
                        for (final Identifier id: seqBlock.symbols().symbolList())
858
                        {
859
                                output.Append(id.tokenText());
860
                                output.Append(": ");
861
                                PrintSubElementOrNull(id);
862
                        }
863
                        output.Append(": ");
864
                }
865
                for (final Statement smt: seqBlock.statements())
866
                {
867
                        if (smt == null)
868
                                continue;
869
                        if (i != 0)
870
                        {
871
                                output.DecIndent();
872
                                output.AppendLine("");
873
                                output.IncIndent();
874
                                output.AppendLine("; ");
875
                        }
876
                        i++;
877
                        make_parens = true;
878
                        smt.Accept(this);
879
                        make_parens = old_makeparens;
880
                }
881
                output.DecIndent();
882
                output.AppendLine("");
883
                output.AppendLine(")");
884
        }
885

    
886
        @Override
887
        public void visit(Call call)
888
        {
889
                call.callExpression().Accept(this);
890
        }
891

    
892
        @Override
893
        public void visit(GuardedCommand guardedCommand)
894
        {
895
                output.Append("requires ");
896
                PrintSubElementOrNull(guardedCommand.guard());
897
                output.IncIndent();
898
                output.AppendLine(" :");
899

    
900
                guardedCommand.body().Accept(this);
901

    
902
                output.DecIndent();
903
                output.AppendLine("");
904
                output.AppendLine("end");
905
        }
906

    
907
        @Override
908
        public void visit(IdentifierExpression identifierExpression)
909
        {
910
                output.Append(identifierExpression.identifier().tokenText());
911
        }
912

    
913
        @Override
914
        public void visit(NondetIdentifierList nondetIdentifierList)
915
        {
916
                int i = 0;
917
                for (final Identifier smt: nondetIdentifierList.identifiers())
918
                {
919
                        if (i != 0)
920
                        {
921
                                output.DecIndent();
922
                                output.AppendLine("");
923
                                output.IncIndent();
924
                                output.AppendLine("[] ");
925
                        }
926
                        i++;
927
                        smt.Accept(this);
928
                }
929
        }
930

    
931
        @Override
932
        public void visit(PrioIdentifierList prioIdentifierList)
933
        {
934
                int i = 0;
935
                for (final Identifier smt: prioIdentifierList.identifiers())
936
                {
937
                        if (i != 0)
938
                        {
939
                                output.DecIndent();
940
                                output.AppendLine("");
941
                                output.IncIndent();
942
                                output.AppendLine("//");
943
                        }
944
                        i++;
945
                        smt.Accept(this);
946
                }
947
        }
948

    
949

    
950
        @Override
951
        public void visit(SeqIdentifierList seqIdentifierList)
952
        {
953
                int i = 0;
954
                output.IncIndent();
955
                output.AppendLine("(");
956
                for (final Identifier smt: seqIdentifierList.identifiers())
957
                {
958
                        if (i != 0)
959
                        {
960
                                output.AppendLine("; ");
961
                        }
962
                        i++;
963
                        smt.Accept(this);
964
                }
965
                output.DecIndent();
966
                output.AppendLine("");
967
                output.AppendLine(")");
968
        }
969

    
970
        @Override
971
        public void visit(SkipStatement skipStatement)
972
        {
973
                output.Append("skip");
974
        }
975

    
976
        @Override
977
        public void visit(TernaryOperator ternaryOperator)
978
        {
979
                if (ternaryOperator.kind() == ExpressionKind.conditional)
980
                {
981
                        output.Append("if");
982
                        PrintSubElementOrNull(ternaryOperator.left());
983
                        output.IncIndent();
984
                        output.AppendLine("then");
985
                        PrintSubElementOrNull(ternaryOperator.mid());
986
                        output.DecIndent();
987
                        output.AppendLine("");
988
                        output.IncIndent();
989
                        output.AppendLine("else");
990
                        PrintSubElementOrNull(ternaryOperator.right());
991
                        output.DecIndent();
992
                        output.AppendLine("");
993
                        output.Append("end");
994
                }
995
                else if (ternaryOperator.kind() == ExpressionKind.foldLR ||
996
                                ternaryOperator.kind() == ExpressionKind.foldRL)
997
                {
998
                        PrintSubElementOrNull(ternaryOperator.left());
999
                        if (ternaryOperator.mid() != null)
1000
                        {
1001
                                output.Append(" :: (");
1002
                                PrintSubElementOrNull(ternaryOperator.mid());
1003
                                output.Append(")");
1004
                        }
1005
                        if (ternaryOperator.kind() == ExpressionKind.foldLR)
1006
                                output.Append(" :>: (");
1007
                        else
1008
                                output.Append(" :<: (");
1009
                        PrintSubElementOrNull(ternaryOperator.right());
1010
                        output.Append(")");
1011
                }
1012
                else
1013
                        throw new NotImplementedException();
1014
        }
1015

    
1016
        @Override
1017
        public void visit(MethodIdentifier methodIdentifier)
1018
        {
1019
                final Boolean safe = ((FunctionType)methodIdentifier.type()).isMiracleSafe();
1020
                if ( safe == null || safe == false)
1021
                        output.Append("/*BASIC*/ ");
1022

    
1023

    
1024
                final FunctionType atype = (FunctionType)methodIdentifier.type();
1025

    
1026
                output.Append(methodIdentifier.tokenText());
1027
                output.Append("(");
1028
                int j = 0;
1029
                for (final Identifier x: methodIdentifier.parameter())
1030
                {
1031
                        if (j != 0)
1032
                                output.Append(", ");
1033
                        else
1034
                                j++;
1035
                        output.Append(x.tokenText());
1036
                        output.Append(": ");
1037
                        PrintSubElementOrNull(x.type());
1038
                }
1039
                output.Append(")");
1040
                if (atype.returnType() != null)
1041
                {
1042
                        output.Append(": ");
1043
                        PrintSubElementOrNull(atype.returnType());
1044
                }
1045
                output.AppendLine("");
1046

    
1047
                output.IncIndent();
1048
                output.AppendLine("var");
1049
                int i = 0;
1050
                for (final Identifier sym: methodIdentifier.symbolTable().symbolList())
1051
                {
1052
                        if (i != 0)
1053
                                output.AppendLine(";");
1054
                        i++;
1055
                        output.Append(sym.tokenText()); output.Append(": "); PrintSubElementOrNull(sym.type());
1056
                }
1057
                output.DecIndent();
1058
                output.AppendLine("");
1059

    
1060
                PrintSubElementOrNull(methodIdentifier.body());
1061
                output.Append("end");
1062
        }
1063

    
1064
        @Override
1065
        public void visit(NamedActionIdentifier namedActionIdentifier)
1066
        {
1067
                final Boolean safe = ((FunctionType)namedActionIdentifier.type()).isMiracleSafe();
1068
                if ( safe == null || safe == false)
1069
                        output.Append("/*BASIC*/ ");
1070

    
1071
                output.Append(namedActionIdentifier.tokenText());
1072
                output.Append("(");
1073
                final FunctionType atype = (FunctionType)namedActionIdentifier.type();
1074
                PrintEnumeration(atype.parameter());
1075
                output.Append(")");
1076
                output.AppendLine("");
1077

    
1078
                output.IncIndent();
1079
                output.AppendLine("var");
1080
                int i = 0;
1081
                for (final Identifier sym: namedActionIdentifier.symbolTable().symbolList())
1082
                {
1083
                        if (i != 0)
1084
                                output.AppendLine(";");
1085
                        i++;
1086
                        output.Append(sym.tokenText()); output.Append(": "); PrintSubElementOrNull(sym.type());
1087
                }
1088
                output.DecIndent();
1089
                output.AppendLine("");
1090

    
1091
                PrintSubElementOrNull(namedActionIdentifier.body());
1092
                output.Append("end");
1093
        }
1094

    
1095
        @Override
1096
        public void visit(MapConstructor mapConstructor)
1097
        {
1098
                output.Append("{");
1099
                int i = 0;
1100
                for (final MapItem x: mapConstructor.items())
1101
                {
1102
                        if (i != 0)
1103
                                output.Append(", ");
1104
                        i++;
1105
                        PrintSubElementOrNull(x.key);
1106
                        output.Append(" -> ");
1107
                        PrintSubElementOrNull(x.value);
1108
                }
1109
                output.Append("}");
1110
        }
1111

    
1112
        @Override
1113
        public void visit(SetConstructor setConstructor)
1114
        {
1115
                output.Append("[");
1116
                PrintEnumeration(setConstructor.items());
1117
                if (setConstructor.hasComprehension())
1118
                {
1119
                        output.Append("| var ");
1120
                        int i = 0;
1121
                        for(final Identifier elem: setConstructor.comprehensionVariables().symbolList())
1122
                        {
1123
                                if (i != 0)
1124
                                        output.Append("; ");
1125
                                i++;
1126
                                PrintSubElementOrNull(elem);
1127
                        }
1128
                        output.AppendLine(" &");
1129
                        PrintSubElementOrNull(setConstructor.comprehension());
1130
                }
1131
                output.Append("]");
1132
        }
1133

    
1134
        @Override
1135
        public void visit(ExpressionVariableIdentifier expressionVariableIdentifier)
1136
        {
1137
                output.Append(expressionVariableIdentifier.tokenText()); output.Append(": ");
1138
                PrintSubElementOrNull(expressionVariableIdentifier.type());
1139
        }
1140

    
1141

    
1142
        @Override
1143
        public void visit(ObjectConstructor objectConstructor)
1144
        {
1145
                output.Append("new (");
1146
                PrintSubElementOrNull(objectConstructor.type());
1147
                output.Append(")");
1148
        }
1149

    
1150
        @Override
1151
        public String toString()
1152
        {
1153
                return output.toString();
1154
        }
1155

    
1156
        public OoaPrintVisitor(ParserState aState)
1157
        {
1158
                super(aState);
1159
                writeTypes = true;
1160
                output = new OoasCodeEmitter();
1161
        }
1162
}