Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / codegen / cadp / CadpType.java @ 10

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.HashMap;
31
import java.util.HashSet;
32
import java.util.Iterator;
33

    
34
import org.momut.ooas.ast.AstNodeTypeEnum;
35
import org.momut.ooas.ast.IAst;
36
import org.momut.ooas.ast.identifiers.EnumIdentifier;
37
import org.momut.ooas.ast.identifiers.FunctionIdentifier;
38
import org.momut.ooas.ast.identifiers.Identifier;
39
import org.momut.ooas.ast.identifiers.IdentifierKind;
40
import org.momut.ooas.ast.identifiers.MethodIdentifier;
41
import org.momut.ooas.ast.identifiers.TypeIdentifier;
42
import org.momut.ooas.ast.types.BoolType;
43
import org.momut.ooas.ast.types.CharType;
44
import org.momut.ooas.ast.types.EnumType;
45
import org.momut.ooas.ast.types.FloatType;
46
import org.momut.ooas.ast.types.FunctionType;
47
import org.momut.ooas.ast.types.IntType;
48
import org.momut.ooas.ast.types.ListType;
49
import org.momut.ooas.ast.types.MapType;
50
import org.momut.ooas.ast.types.NullType;
51
import org.momut.ooas.ast.types.OoActionSystemInstance;
52
import org.momut.ooas.ast.types.OoActionSystemType;
53
import org.momut.ooas.ast.types.OpaqueType;
54
import org.momut.ooas.ast.types.TupleType;
55
import org.momut.ooas.ast.types.TypeKind;
56
import org.momut.ooas.ast.types.Type;
57
import org.momut.ooas.ast.types.ValuedEnumType;
58
import org.momut.ooas.codegen.OoasCodeEmitter;
59
import org.momut.ooas.parser.SymbolTable;
60
import org.momut.ooas.visitors.OoaCompleteAstTraversalVisitor;
61

    
62
/// <summary>
63
/// Knows how to construct a C-CADP type from a UlyssesType
64
/// (only defined for basic types!)
65
/// </summary>
66
public final class CadpType extends OoaCompleteAstTraversalVisitor
67
{
68
        private static HashMap<String, Integer> m_typesizes;
69
        public static HashMap<String, Integer> sizeOfTypes() {return m_typesizes; }
70

    
71
        private final OoasCodeEmitter m_emitter = new OoasCodeEmitter();
72
//        private int m_typesize;
73

    
74
        public static final String constructorString = "constr_";
75
        public static final String destructorString = "destr_";
76
        public static final String lowString = "low_";
77
        public static final String highString = "count_";
78
        public static final String enumString = "enum_";
79
        public static final String printString = "print_";
80

    
81

    
82
        @Override
83
        public void visit(CharType charType)
84
        {
85
                m_emitter.Append("char");
86
//                m_typesize += m_typesizes.get("char");
87
        }
88

    
89
        @Override
90
        public  void visit(IntType intType)
91
        {
92
                m_emitter.Append("int");
93
//                m_typesize += m_typesizes.get("int");
94
        }
95

    
96
        @Override
97
        public  void visit(BoolType boolType)
98
        {
99
                m_emitter.Append("unsigned char");
100
//                m_typesize += m_typesizes.get("char");
101
        }
102

    
103
        @Override
104
        public  void visit(FloatType floatType)
105
        {
106
                m_emitter.Append("double");
107
//                m_typesize += m_typesizes.get("double");
108
        }
109

    
110
        @Override
111
        public  void visit(EnumType enumType)
112
        {
113
                m_emitter.Append("unsigned int");
114
//                m_typesize += m_typesizes.get("int");
115
        }
116

    
117

    
118
        @Override
119
        public  void visit(TupleType tupleType)
120
        {
121
                // we map a tuple to a struct
122
                m_emitter.Append(GetIdentifierString(tupleType.identifier()));
123
        }
124

    
125
        @Override
126
        public  void visit(ListType listType)
127
        {
128
                m_emitter.Append(GetIdentifierString(listType.identifier()));
129
        }
130

    
131
        @Override
132
        public  void visit(NullType nullType)
133
        {
134
                m_emitter.Append("int");
135
        }
136

    
137
        private static String GetIdentifierString(TypeIdentifier typeIdentifier)
138
        {
139
                return CadpIdentifier.GetIdentifierString(typeIdentifier);
140
        }
141

    
142
        @Override
143
        public  void visit(OoActionSystemType ooActionSystemType)
144
        {
145
                // output: pointer to jump table type
146
                m_emitter.Append(String.format("%s", CadpIdentifier.GetIdentifierString(ooActionSystemType.identifier())));
147
        }
148

    
149

    
150
        // the following types are not supported.
151
        @Override
152
        public  void visit(MapType mapType)
153
        {
154
                throw new UnsupportedOperationException();
155
        }
156

    
157
        @Override
158
        public  void visit(FunctionType functionType)
159
        {
160
                throw new UnsupportedOperationException();
161
        }
162
        @Override
163
        public  void visit(OpaqueType opaqueType)
164
        {
165
                throw new UnsupportedOperationException();
166
        }
167

    
168

    
169
        @Override
170
        protected  void VisitAstElement(IAst element, IAst parent)
171
        {
172
                if (element.nodeType() == AstNodeTypeEnum.type)
173
                        super.VisitAstElement(element, parent);
174
        }
175

    
176
        public  String ToString()
177
        {
178
                return m_emitter.toString();
179
        }
180

    
181
        public CadpType()
182
        {
183
                super(null);
184
        }
185

    
186
        public static String DumpType(Type atype)
187
        {
188
                final CadpType newtype = new CadpType();
189
                atype.Accept(newtype);
190
                return newtype.ToString();
191
        }
192

    
193

    
194
        private static HashSet<String> emittedTypes = new HashSet<String>();
195

    
196
        private static void EmitType(Type aType, OoasCodeEmitter emitter)
197
        {
198
                final String typename = CadpIdentifier.GetIdentifierString(aType.identifier());
199
                if (!emittedTypes.contains(typename))
200
                        switch (aType.kind())
201
                        {
202
                        case BoolType:
203
                                emittedTypes.add(typename);
204
                                EmitDefinition((BoolType)aType, emitter);
205
                                break;
206

    
207
                        case EnumeratedType:
208
                                emittedTypes.add(typename);
209
                                EmitDefinition((EnumType)aType, emitter);
210
                                break;
211

    
212
                        case FloatType:
213
                                emittedTypes.add(typename);
214
                                EmitDefinition((FloatType)aType, emitter);
215
                                break;
216

    
217
                        case IntType:
218
                                emittedTypes.add(typename);
219
                                EmitDefinition((IntType)aType, emitter);
220
                                break;
221

    
222
                        case MapType:
223
                                throw new UnsupportedOperationException();
224

    
225
                        case ListType:
226
                                emittedTypes.add(typename);
227
                                EmitDefinition((ListType)aType, emitter);
228
                                break;
229

    
230
                        case TupleType:
231
                                emittedTypes.add(typename);
232
                                EmitDefinition((TupleType)aType, emitter);
233
                                break;
234

    
235
                        case OoActionSystemType:
236
                                emittedTypes.add(typename);
237
                                EmitDefinition((OoActionSystemType)aType, emitter);
238
                                break;
239

    
240
                        case FunctionType:
241
                                emittedTypes.add(typename);
242
                                EmitDefinition((FunctionType)aType, emitter);
243
                                break;
244

    
245
                        case Null:
246
                        case Any:
247
                        case OpaqueType:
248
                                throw new UnsupportedOperationException(); // should throw invalid args exception
249

    
250
                        default:
251
                                throw new UnsupportedOperationException();
252
                        }
253
        }
254

    
255
        private static void EmitDefinition(FunctionType functionType, OoasCodeEmitter emitter)
256
        {
257
                final String typeName = CadpIdentifier.GetIdentifierString(functionType.identifier());
258
                final String decl = OoaCADPVisitor.FunctionHeader(functionType, String.format("(* %s)", typeName));
259
                m_functionForwardDefinitions.AppendLine(String.format("typedef %s;", decl));
260
        }
261

    
262
        private static void EmitDefinition(IntType intType, OoasCodeEmitter emitter)
263
        {
264
                final String typeName = GetIdentifierString(intType.identifier());
265

    
266
                emitter.AppendLine(String.format("typedef %s %s;", DumpType(intType), typeName));
267

    
268
                // low
269
                emitter.AppendLine(String.format("/*%s%s*/", lowString, typeName));
270
                emitter.Append(String.format("long long int %s%s (void) {", lowString, typeName));
271
                emitter.AppendLine("return 0; }");
272

    
273
                // high
274
                emitter.AppendLine(String.format("/*%s%s*/", highString, typeName));
275
                emitter.Append(String.format("long long int %s%s (void) { return %sLL; }", highString, typeName, ((long)intType.rangeHigh()) - intType.rangeLow() + 1));
276

    
277
                // enumerator
278
                emitter.AppendLine(String.format("/*%s%s*/", enumString, typeName));
279
                emitter.Append(String.format("%s %s%s (long long int value) { ", typeName, enumString, typeName));
280
                emitter.AppendLine(String.format("if (value >= %s%s()) { printf(\"Enum index out of range: %s\\n\"); abort();}", highString, typeName, typeName));
281
                emitter.Append(String.format("return (%s) (%sLL + value);", typeName, intType.rangeLow()));
282
                emitter.AppendLine("}");
283

    
284
                // print
285
                emitter.AppendLine(String.format("/*%s%s*/", printString, typeName));
286
                emitter.AppendLine(String.format("void %s%s (CAESAR_TYPE_FILE CAESAR_FILE, %s A_VALUE)", printString, typeName, typeName));
287
                emitter.AppendLine("{");
288
                emitter.AppendLine("  fprintf(CAESAR_FILE,\"%d\",A_VALUE);");
289
                emitter.AppendLine("}");
290
        }
291

    
292
        private static void EmitDefinition(FloatType floatType, OoasCodeEmitter emitter)
293
        {
294
                final String typeName = GetIdentifierString(floatType.identifier());
295

    
296
                emitter.AppendLine(String.format("typedef %1$s %2$s;", DumpType(floatType), typeName));
297

    
298
                // low
299
                emitter.AppendLine(String.format("/*%1$s%2$s*/", lowString, typeName));
300
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
301

    
302
                // high
303
                emitter.AppendLine(String.format("/*%1$s%2$s*/", highString, typeName));
304
                final long count = (long) (((long)floatType.high() - (long)floatType.low()) / floatType.precision());
305
                emitter.Append(String.format("long long int %2$s%1$s (void) { return %3$sLL; }", typeName, highString, count));
306

    
307
                // enumerator
308
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
309
                emitter.Append(String.format("%1$s %2$s%1$s (long long int value) { ", typeName, enumString));
310
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
311
                emitter.Append(String.format("return %1$sLL + (value * %2$s);", floatType.low(), floatType.precision()));
312
                emitter.AppendLine("}");
313

    
314
                // print
315
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
316
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
317
                emitter.AppendLine("{");
318
                emitter.AppendLine("  fprintf(CAESAR_FILE,\"%lf\",A_VALUE);");
319
                emitter.AppendLine("}");
320
        }
321

    
322
        private static void EmitDefinition(EnumType enumType, OoasCodeEmitter emitter)
323
        {
324
                final String typeName = GetIdentifierString(enumType.identifier());
325

    
326
                emitter.AppendLine(String.format("typedef %1$s %2$s;", DumpType(enumType), typeName));
327

    
328
                // low
329
                emitter.AppendLine(String.format("/*%1$s%2$s*/", lowString, typeName));
330
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
331

    
332
                // high
333
                emitter.AppendLine(String.format("/*%1$s%2$s*/", highString, typeName));
334
                emitter.Append(String.format("int %2$s%1$s (void) { return %3$s; }", typeName, highString, enumType.listOfEnumSymbols().size()));
335

    
336
                if (enumType instanceof ValuedEnumType)
337
                        ValuedEnumType((ValuedEnumType)enumType, emitter, typeName);
338
                else
339
                        NormalEnumType(enumType, emitter, typeName);
340

    
341
        }
342

    
343
        private static void ValuedEnumType(ValuedEnumType enumType, OoasCodeEmitter emitter, String typeName)
344
        {
345
                // enumerator
346
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
347
                emitter.AppendLine(String.format("%3$s %2$s%1$s (long long int value) { ", typeName, enumString, DumpType(enumType)));
348
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
349
                int i = 0;
350
                for (final Identifier sym : enumType.symbolTable().symbolList())
351
                {
352
                        final EnumIdentifier id = (EnumIdentifier)sym;
353
                        emitter.AppendLine(String.format("if (value == %1$s) return (int) %2$s;", i++, id.Value()));
354
                }
355
                emitter.AppendLine("}");
356

    
357

    
358
                // print
359
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
360
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
361
                emitter.AppendLine("{");
362
                i = 0;
363
                for (final Identifier sym : enumType.symbolTable().symbolList())
364
                {
365
                        final EnumIdentifier id = (EnumIdentifier)sym;
366
                        emitter.AppendLine(String.format("  if (A_VALUE == %1$s) fprintf(CAESAR_FILE,\"%2$s\");", id.Value(), id.tokenText()));
367
                }
368
                emitter.AppendLine("}");
369
        }
370

    
371

    
372
        private static void NormalEnumType(EnumType enumType, OoasCodeEmitter emitter, String typeName)
373
        {
374

    
375
                // enumerator
376
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
377
                emitter.AppendLine(String.format("%3$s %2$s%1$s (long long int value) { ", typeName, enumString, DumpType(enumType)));
378
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
379
                emitter.AppendLine(String.format("return (int)value; /*enums are treated like ints*/"));
380
                emitter.AppendLine("}");
381

    
382
                // backtranslation of enum syms
383
                emitter.AppendLine(String.format(" /* backtranslation of enum %1$s */ ", typeName));
384
                emitter.Append(String.format("CAESAR_TYPE_STRING _%1$s_identifiers[%2$s] = {", typeName, enumType.listOfEnumSymbols().size()));
385
                int i = 0;
386
                for (final Identifier x : enumType.listOfEnumSymbols())
387
                {
388
                        if (i != 0)
389
                                emitter.Append(", ");
390
                        else
391
                                i++;
392
                        emitter.Append(String.format("\"%1$s\"", x.tokenText()));
393
                }
394
                emitter.AppendLine("};");
395

    
396
                // print
397
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
398
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
399
                emitter.AppendLine("{");
400
                emitter.AppendLine(String.format("  fprintf(CAESAR_FILE,\"%%s\", _%1$s_identifiers[A_VALUE]);", typeName));
401
                emitter.AppendLine("}");
402

    
403
        }
404

    
405
        private static void EmitDefinition(BoolType boolType, OoasCodeEmitter emitter)
406
        {
407
                final String typeName = GetIdentifierString(boolType.identifier());
408

    
409
                emitter.AppendLine(String.format("typedef %1$s %2$s;", DumpType(boolType), typeName));
410

    
411
                // low
412
                emitter.AppendLine(String.format("/*%1$s%2$s*/", lowString, typeName));
413
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
414

    
415
                // high
416
                emitter.AppendLine(String.format("/*%1$s%2$s*/", highString, typeName));
417
                emitter.Append(String.format("int %2$s%1$s (void) { return 2; }", typeName, highString));
418

    
419
                // enumerator
420
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
421
                emitter.Append(String.format("%1$s %2$s%1$s (long long int value) { ", typeName, enumString));
422
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
423
                emitter.Append("return (int) value;");
424
                emitter.AppendLine("}");
425

    
426
                // print
427
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
428
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
429
                emitter.AppendLine("{");
430
                emitter.AppendLine(String.format("  fprintf(CAESAR_FILE,\"%%s\", A_VALUE ? \"true\" : \"false\");"));
431
                emitter.AppendLine("}");
432
        }
433

    
434
        /// <summary>
435
        /// Emits type definition for list
436
        /// </summary>
437
        private static void EmitDefinition(ListType alistType, OoasCodeEmitter result)
438
        {
439

    
440
                if (alistType.innerType().kind() != TypeKind.Null &&
441
                                !emittedTypes.contains(CadpIdentifier.GetIdentifierString(alistType.innerType().identifier())))
442
                        EmitType(alistType.innerType(), result);
443

    
444
                final OoasCodeEmitter emitter = new OoasCodeEmitter();
445
                final String typeName = GetIdentifierString(alistType.identifier()).replaceAll(" ", "_");
446

    
447
                // include a forward definition
448
                m_typeForwardDefinitions.AppendLine(String.format("typedef struct list_%1$s %1$s;", typeName));
449

    
450
                emitter.AppendLine("#ifdef WINDOWSPACK");
451
                emitter.AppendLine("#pragma pack(1)");
452
                emitter.AppendLine("#endif");
453
                emitter.AppendLine(String.format("struct list_%1$s { int length; %2$s elements[%3$s];} UNIXPACK /*%1$s, * p%1$s*/;"
454
                                , typeName, DumpType(alistType.innerType()), alistType.maxNumberOfElements() == 0 ? 1 : alistType.maxNumberOfElements()));
455
                emitter.AppendLine(String.format("#define MAX_%1$s %2$s", typeName, alistType.maxNumberOfElements()));
456
                emitter.AppendLine("");
457

    
458

    
459
                // -- constructor (non pointer)
460
                emitter.AppendLine(String.format("/*%1$s*/", constructorString));
461
                emitter.Append(String.format("%1$s %2$s%1$s (int length ", typeName, constructorString));
462
                final String internalType = DumpType(alistType.innerType());
463
                int i;
464
                for (i = 0; i < alistType.maxNumberOfElements(); i++)
465
                {
466
                        emitter.Append(", ");
467
                        emitter.Append(String.format("%1$s arg_%2$s", internalType, i));
468
                }
469
                emitter.AppendLineIncIndent(") {");
470
                emitter.AppendLine(String.format("%1$s result;", typeName));
471
                emitter.AppendLine(String.format(String.format("memset(&result,0,sizeof(%1$s));", typeName)));
472
                emitter.AppendLine("result.length = length;");
473
                for (i = 0; i < alistType.maxNumberOfElements(); i++)
474
                {
475
                        emitter.AppendLine(String.format("result.elements[%1$s] = arg_%1$s;", i));
476
                        /*do range checking on ints and floats*/
477
                        switch (alistType.innerType().kind())
478
                        {
479
                        case IntType:
480
                                final IntType placetype_int = (IntType)alistType.innerType();
481
                                emitter.AppendLine(String.format("/*Range of arg_%3$s: %1$s..%2$s*/", placetype_int.rangeLow(), placetype_int.rangeHigh(), i));
482
                                emitter.AppendLine(String.format("if (arg_%1$s < %2$s || arg_%1$s > %3$s)", i, placetype_int.rangeLow(), placetype_int.rangeHigh()));
483
                                emitter.AppendLine(String.format("{CALC_INVALID = 1;}"));
484
                                break;
485
                        case FloatType:
486
                                final FloatType placetype_float = (FloatType)alistType.innerType();
487
                                emitter.AppendLine(String.format("/*Range of arg_%3$s: %1$s..%2$s*/", placetype_float.low(), placetype_float.high(), i));
488
                                emitter.AppendLine(String.format("if (arg_%1$s < %2$s || arg_%1$s > %3$s)", i, placetype_float.low(), placetype_float.high()));
489
                                emitter.AppendLine(String.format("{CALC_INVALID = 1;}"));
490
                                break;
491
                        default:
492
                                break;
493
                        }
494
                }
495
                emitter.AppendLine("return result;");
496
                emitter.AppendLineDecIndent("}");
497
                emitter.AppendLine("");
498

    
499

    
500
                emitter.AppendLine("");
501

    
502
                // low
503
                emitter.AppendLine(String.format("/*%1$s*/", lowString));
504
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
505

    
506
                // high
507
                emitter.AppendLine(String.format("/*%1$s*/", highString));
508
                if (alistType.innerType().kind() == TypeKind.Null)
509
                        emitter.Append(String.format("int %2$s%1$s (void) { return 0; }", typeName, highString));
510
                else
511
                        emitter.Append(String.format("long long int %2$s%1$s (void) { return MAX_%1$s * %2$s%3$s(); }", typeName, highString, GetIdentifierString(alistType.innerType().identifier())));
512

    
513
                // enumerator
514
                //emitter.AppendLine(String.format("/*%1$s*/", enumString));
515
                //emitter.Append(String.format("%1$s %2$s%1$s (int value) { ", typeName, enumString));
516
                //emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
517
                //emitter.AppendLine("abort();");
518
                //emitter.Append("return value;");
519
                //emitter.AppendLine("}");
520

    
521
                // print
522
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
523
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
524
                emitter.AppendLine("{");
525
                emitter.AppendLine(String.format("  fprintf(CAESAR_FILE,\" [len: %%d \", A_VALUE.length);"));
526
                for (i = 0; i < alistType.maxNumberOfElements(); i++)
527
                {
528
                        emitter.AppendLine(String.format("if (A_VALUE.length > %1$s){", i));
529
                        emitter.AppendLine(String.format("fprintf(CAESAR_FILE,\" %1$s: \");", i));
530
                        emitter.AppendLine(String.format("%1$s%2$s (CAESAR_FILE, A_VALUE.elements[%3$s]);", printString, CadpIdentifier.GetIdentifierString(alistType.innerType().identifier()), i));
531
                        emitter.AppendLine("} /*if*/");
532
                }
533
                emitter.AppendLine("  fprintf(CAESAR_FILE,\"]\");");
534
                emitter.AppendLine("}");
535

    
536
                result.Append(emitter.toString());
537
        }
538

    
539
        private static void EmitDefinition(TupleType atupleType, OoasCodeEmitter result)
540
        {
541
                final String typeName = GetIdentifierString(atupleType.identifier());
542
                final OoasCodeEmitter emitter = new OoasCodeEmitter();
543

    
544

    
545
                // include a forward definition
546
                m_typeForwardDefinitions.AppendLine(String.format("typedef struct struct_%1$s %1$s;", typeName));
547

    
548
                emitter.AppendLine("#ifdef WINDOWSPACK");
549
                emitter.AppendLine("#pragma pack(1)");
550
                emitter.AppendLine("#endif");
551
                emitter.AppendLineIncIndent(String.format("struct struct_%1$s {", typeName));
552
                int i = 0;
553
                for (final Type it: atupleType.innerTypes())
554
                {
555
                        EmitType(it);
556
                        emitter.AppendLine(String.format("%1$s elem_%2$s;", DumpType(it), i));
557
                        i++;
558
                }
559
                emitter.AppendLineDecIndent(String.format("} UNIXPACK /*%1$s, * p%1$s*/;", typeName));
560

    
561

    
562

    
563
                emitter.AppendLine("");
564

    
565
                // -- constructor (non pointer)
566
                emitter.AppendLine(String.format("/*%1$s%2$s*/", constructorString, typeName));
567
                emitter.Append(String.format("%1$s %2$s%1$s (", typeName, constructorString));
568
                i = 0;
569
                for (final Type it: atupleType.innerTypes())
570
                {
571
                        if (!emittedTypes.contains(CadpIdentifier.GetIdentifierString(it.identifier())))
572
                                EmitType(it, result);
573
                        if (i != 0)
574
                                emitter.Append(",");
575
                        emitter.Append(String.format("%1$s arg_%2$s", DumpType(it), i));
576
                        i++;
577
                }
578
                emitter.AppendLineIncIndent(") {");
579
                emitter.AppendLine(String.format("%1$s result;", typeName));
580
                i = 0;
581
                for (final Type it:  atupleType.innerTypes())
582
                {
583
                        emitter.AppendLine(String.format("result.elem_%1$s = arg_%1$s;", i));
584
                        /*do range checking on ints and floats*/
585
                        switch (it.kind())
586
                        {
587
                        case IntType:
588
                                final IntType placetype_int = (IntType)it;
589
                                emitter.AppendLine(String.format("/*Range of arg_%3$s: %1$s..%2$s*/", placetype_int.rangeLow(), placetype_int.rangeHigh(), i));
590
                                emitter.AppendLine(String.format("if (arg_%1$s < %2$s || arg_%1$s > %3$s)", i, placetype_int.rangeLow(), placetype_int.rangeHigh()));
591
                                emitter.AppendLine(String.format("{CALC_INVALID = 1;}"));
592
                                break;
593
                        case FloatType:
594
                                final FloatType placetype_float = (FloatType)it;
595
                                emitter.AppendLine(String.format("/*Range of arg_%3$s: %1$s..%2$s*/", placetype_float.low(), placetype_float.high(), i));
596
                                emitter.AppendLine(String.format("if (arg_%1$s < %2$s || arg_%1$s > %3$s)", i, placetype_float.low(), placetype_float.high()));
597
                                emitter.AppendLine(String.format("{CALC_INVALID = 1;}"));
598
                                break;
599
                        default:
600
                                break;
601
                        }
602
                        i++;
603
                }
604
                emitter.AppendLine("return result;");
605
                emitter.AppendLineDecIndent("}");
606
                emitter.AppendLine("");
607

    
608

    
609
                // low
610
                emitter.AppendLine(String.format("/*%1$s%2$s*/", lowString, typeName));
611
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
612

    
613
                // high
614
                emitter.AppendLine(String.format("/*%1$s%2$s*/", highString, typeName));
615
                emitter.Append(String.format("long long int %2$s%1$s (void) { return ", typeName, highString));
616
                i = 0;
617
                for (final Type x : atupleType.innerTypes())
618
                {
619
                        if (i != 0)
620
                                emitter.Append(" * ");
621
                        else
622
                                i++;
623
                        emitter.Append(String.format("%2$s%1$s()", GetIdentifierString(x.identifier()), highString));
624
                }
625
                emitter.AppendLine("; }");
626

    
627
                // enumerator
628
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
629
                emitter.Append(String.format("%1$s %2$s%1$s (long long int value) { ", typeName, enumString));
630
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
631
                emitter.Append(String.format("return %2$s%1$s (", typeName, constructorString));
632
                i = 0;
633
                final StringBuilder divisor = new StringBuilder("value");
634
                for (final Type it: atupleType.innerTypes())
635
                {
636
                        if (i != 0)
637
                                emitter.Append(",");
638
                        else i++;
639
                        emitter.Append(String.format("%2$s%1$s((%4$s) %% %3$s%1$s())", GetIdentifierString(it.identifier()), enumString, highString, divisor.toString()));
640
                        divisor.append(String.format(" / %2$s%1$s() ", GetIdentifierString(it.identifier()), highString));
641
                }
642
                emitter.AppendLine(");}");
643

    
644

    
645
                // print
646
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
647
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
648
                emitter.AppendLine("{");
649
                emitter.AppendLine(String.format("  fprintf(CAESAR_FILE,\" (\");"));
650
                final Iterator<Type> iter = atupleType.innerTypes().iterator();
651
                for (i = 0; i < atupleType.innerTypes().size(); i++)
652
                {
653
                        if (i != 0)
654
                                emitter.AppendLine("fprintf(CAESAR_FILE, \", \");");
655
                        emitter.AppendLine(String.format("%1$s%2$s (CAESAR_FILE, A_VALUE.elem_%3$s);", printString, CadpIdentifier.GetIdentifierString(iter.next().identifier()), i));
656
                }
657
                emitter.AppendLine("  fprintf(CAESAR_FILE,\")\");");
658
                emitter.AppendLine("}");
659

    
660
                emitter.AppendLine("");
661
                result.Append(emitter.toString());
662
        }
663

    
664
        public static String GetNullConstant(OoActionSystemType anActionSystem)
665
        {
666
                return String.format("NULL_%1$s", CadpIdentifier.GetIdentifierString(anActionSystem.identifier()));
667
        }
668

    
669
        private static void EmitObjectJumpTable(OoActionSystemType instance)
670
        {
671

    
672
                final OoasCodeEmitter emitter = new OoasCodeEmitter();
673
                final OoasCodeEmitter forwards = new OoasCodeEmitter();
674

    
675
                // emit null
676
                emitter.AppendLine(String.format("%1$s NULL_%2$s = {0, \"NULL_%2$s\"",
677
                                CadpIdentifier.GetIdentifierString(instance.identifier()),
678
                                CadpIdentifier.GetIdentifierString(instance.identifier())));
679
                emitter.AppendLine(", NULL");
680
                emitter.AppendLine("};");
681

    
682
                // emit standard jump table
683

    
684
                // emit objects
685
                for (final OoActionSystemInstance ooainstance: instance.objects())
686
                {
687
                        forwards.AppendLine(String.format("/* ==> Object %1$s <==*/", ooainstance.Name));
688

    
689
                        emitter.AppendLine(String.format("struct jump_%1$s methods_%2$s = {",
690
                                        CadpIdentifier.GetIdentifierString(instance.identifier()), ooainstance.Name));
691
                        int i = 0;
692
                        final SymbolTable allSyms = instance.getAllSymbols();
693
                        for (final Identifier sym : allSyms.symbolList())
694
                        {
695
                                if (sym.kind() == IdentifierKind.MethodIdentifier)
696
                                {
697
                                        if (i != 0)
698
                                                emitter.AppendLine(", ");
699

    
700
                                        // FIXME: this does not take the shortener into account...
701
                                        final String method = String.format("%s_%s", ooainstance.Name, ((FunctionIdentifier)sym).tokenText());
702
//                                        final String method = OoaObjectInstantiationVisitor.getInstanceFunctionName(ooainstance, (FunctionIdentifier)sym);
703

    
704
                                        final String methoddef = OoaCADPVisitor.FunctionHeader((FunctionIdentifier)sym, method);
705
                                        forwards.AppendLine(String.format("%1$s;", methoddef));
706
                                        emitter.Append(String.format("&%1$s", method));
707
                                        i++;
708
                                }
709
                        }
710
                        emitter.AppendLine();
711
                        emitter.AppendLine("};");
712

    
713

    
714
                        emitter.Append(String.format("%1$s %2$s = {1, \"%2$s\", & methods_%2$s",
715
                                        CadpIdentifier.GetIdentifierString(ooainstance.Type.identifier()), ooainstance.Name));
716
                        emitter.AppendLine("};");
717
                }
718

    
719

    
720

    
721
                // enumerator
722
                final String typeName = String.format("%1$s", CadpIdentifier.GetIdentifierString(instance.identifier()));
723
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
724

    
725
                // extern defs.
726
                for (final OoActionSystemInstance inst: instance.derivedObjects())
727
                        emitter.AppendLine(String.format("extern %1$s %2$s;", CadpIdentifier.GetIdentifierString(inst.Type.identifier()),inst.Name));
728

    
729
                emitter.AppendLine(String.format("%1$s %2$s%1$s (long long int value) { ", typeName, enumString));
730
                m_functionForwardDefinitions.AppendLine(String.format("%1$s %2$s%1$s (long long int value);", typeName, enumString));
731
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
732
                emitter.AppendLine(String.format("switch((int)value){"));
733

    
734
                emitter.AppendLine(String.format(" case 0 : return NULL_%1$s;", CadpIdentifier.GetIdentifierString(instance.identifier())));
735

    
736
                int u = 1;
737
                for (final OoActionSystemInstance inst: instance.objects())
738
                {
739
                        emitter.AppendLine(String.format("case %1$s:", u));
740
                        emitter.AppendLine(String.format("return %1$s;", inst.Name));
741
                        u++;
742
                }
743
                for (final OoActionSystemInstance inst: instance.derivedObjects())
744
                {
745
                        emitter.AppendLine(String.format("case %1$s:", u));
746
                        emitter.AppendLine(String.format("return *(%2$s*)&(%1$s);", inst.Name, typeName));
747
                        u++;
748
                }
749
                emitter.AppendLine("}");
750
                emitter.AppendLine("printf(\"bug during simulation:\\n     unknown object number\\n\"); CAESAR_TERMINATE(1);");
751
                emitter.AppendLine(String.format("return NULL_%1$s;", CadpIdentifier.GetIdentifierString(instance.identifier())));
752
                emitter.AppendLine("}");
753

    
754

    
755
                m_typeDefinitions.AppendLine(forwards.toString());
756
                m_typeDefinitions.AppendLine(emitter.toString());
757
        }
758

    
759

    
760
        private static void EmitDefinition(OoActionSystemType aClass, OoasCodeEmitter result)
761
        {
762
                /* ooa type gets translated into a jump table */
763
                final String typeName = String.format("%1$s", CadpIdentifier.GetIdentifierString(aClass.identifier()));
764
                final OoasCodeEmitter emitter = new OoasCodeEmitter();
765

    
766
                final OoasCodeEmitter classStructure = new OoasCodeEmitter();
767
                classStructure.AppendLine(String.format("/* jump table type for class %1$s */", aClass.identifier().tokenText()));
768

    
769
                classStructure.AppendLine(String.format("struct jump_%1$s {", typeName));
770
//                int i = 0;
771
                final SymbolTable allSyms = aClass.getAllSymbols();
772
                for (final Identifier sym: allSyms.symbolList())
773
                {
774
                        if (sym.kind() == IdentifierKind.MethodIdentifier)
775
                        {
776
                                final MethodIdentifier method = (MethodIdentifier)sym;
777
                                EmitType(method.type());
778
                                classStructure.AppendLine(String.format("%1$s %2$s;", CadpIdentifier.GetIdentifierString(method), method.tokenText()));
779
//                                i++;
780
                        }
781
                }
782
                classStructure.AppendLine("};");
783

    
784
                classStructure.AppendLine("#ifdef WINDOWSPACK");
785
                classStructure.AppendLine("#pragma pack(1)");
786
                classStructure.AppendLine("#endif");
787
                classStructure.AppendLineIncIndent(String.format("struct struct_%1$s {", typeName));
788
                classStructure.AppendLine("char __validinstance;");
789
                classStructure.AppendLine("char* __object_name;");
790
                classStructure.AppendLine(String.format("struct jump_%1$s *methods;", typeName));
791
                classStructure.AppendLineDecIndent(String.format("} UNIXPACK /*%1$s*/;", typeName));
792

    
793
                m_classTypeDefinitions.AppendLine(classStructure.toString());
794

    
795
                emitter.AppendLine("");
796

    
797
                // include a forward definition
798
                m_typeForwardDefinitions.AppendLine(String.format("typedef struct struct_%1$s %1$s;", typeName));
799

    
800
                // low
801
                emitter.AppendLine(String.format("/*%1$s%2$s*/", lowString, typeName));
802
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
803
                m_functionForwardDefinitions.AppendLine(String.format("int %2$s%1$s (void);", typeName, lowString));
804

    
805
                // high
806
                emitter.AppendLine(String.format("/*%1$s%2$s*/", highString, typeName));
807
                emitter.Append(String.format("int %2$s%1$s (void) { return %3$s; }", typeName, highString, aClass.objects().size() + 1 + aClass.derivedObjects().size()));
808
                m_functionForwardDefinitions.AppendLine(String.format("int %2$s%1$s (void);", typeName, highString));
809

    
810
                // print
811
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
812
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
813
                emitter.AppendLine("{");
814
                emitter.AppendLine("  fprintf(CAESAR_FILE,\"object %s\", A_VALUE.__object_name);");
815
                emitter.AppendLine("}");
816
                m_functionForwardDefinitions.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE);", printString, typeName));
817
                result.Append(emitter.toString());
818

    
819
                EmitObjectJumpTable(aClass);
820
        }
821

    
822

    
823

    
824

    
825
        public static String GetMaxVal(Type atype)
826
        {
827
                return String.format(" (%2$s%1$s() - 1) ", GetIdentifierString(atype.identifier()), highString);
828
        }
829

    
830
        public static String GetMinVal(Type atype)
831
        {
832
                return String.format(" %2$s%1$s() ", GetIdentifierString(atype.identifier()), lowString);
833
        }
834

    
835
        public static String GetEnumVal(Type atype, String indexvar)
836
        {
837
                return String.format(" %2$s%1$s(%3$s)", GetIdentifierString(atype.identifier()), enumString, indexvar);
838
        }
839
        public static String GetEnumVal(Type atype)
840
        {
841
                return String.format(" %2$s%1$s", GetIdentifierString(atype.identifier()), enumString);
842
        }
843

    
844

    
845
        private static OoasCodeEmitter m_typeForwardDefinitions = new OoasCodeEmitter();
846
        private static OoasCodeEmitter m_functionForwardDefinitions = new OoasCodeEmitter();
847
        private static OoasCodeEmitter m_classTypeDefinitions = new OoasCodeEmitter();
848
        private static OoasCodeEmitter m_typeDefinitions = new OoasCodeEmitter();
849

    
850
        public static void EmitType(Type aType)
851
        {
852
                EmitType(aType, m_typeDefinitions);
853
        }
854

    
855
        public static String GetTypeDefintions()
856
        {
857
                final StringBuilder result = new StringBuilder();
858
                result.append(m_typeForwardDefinitions.toString());
859
                result.append(System.lineSeparator());
860
                result.append(m_functionForwardDefinitions.toString());
861
                result.append(System.lineSeparator());
862
                result.append(m_classTypeDefinitions.toString());
863
                result.append(System.lineSeparator());
864
                result.append(m_typeDefinitions.toString());
865
                result.append(System.lineSeparator());
866
                return result.toString();
867
        }
868

    
869
        public static boolean IsNumeric(Type ulyssesType)
870
        {
871
                switch (ulyssesType.kind())
872
                {
873
                case BoolType:
874
                case EnumeratedType:
875
                case FloatType:
876
                case IntType:
877
                        return true;
878
                default:
879
                        return false;
880
                }
881
        }
882

    
883

    
884
        static
885
        {
886
                // populate typesizes.
887
                m_typesizes = new HashMap<String, Integer>();
888
                m_typesizes.put("char", 1);
889
                m_typesizes.put("int", 4);
890
                m_typesizes.put("double", 8);
891
                m_typesizes.put("pointer", 4);
892
        }
893

    
894

    
895

    
896
        public static void AddTypeDefinition(String listStruct)
897
        {
898
                if (!emittedTypes.contains(listStruct))
899
                {
900
                        m_typeDefinitions.AppendLine(listStruct);
901
                        emittedTypes.add(listStruct);
902
                }
903
        }
904
}