Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / codegen / cadp / CadpType.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.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.QrType;
55
import org.momut.ooas.ast.types.TupleType;
56
import org.momut.ooas.ast.types.TypeKind;
57
import org.momut.ooas.ast.types.UlyssesType;
58
import org.momut.ooas.ast.types.ValuedEnumType;
59
import org.momut.ooas.codegen.OoasCodeEmitter;
60
import org.momut.ooas.parser.SymbolTable;
61
import org.momut.ooas.visitors.OoaCompleteAstTraversalVisitor;
62

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

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

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

    
82

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

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

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

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

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

    
118

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

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

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

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

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

    
150

    
151
        // the following types are not supported.
152
        @Override
153
        public  void visit(MapType mapType)
154
        {
155
                throw new UnsupportedOperationException();
156
        }
157
        @Override
158
        public  void visit(QrType qrType)
159
        {
160
                throw new UnsupportedOperationException();
161
        }
162

    
163
        @Override
164
        public  void visit(FunctionType functionType)
165
        {
166
                throw new UnsupportedOperationException();
167
        }
168
        @Override
169
        public  void visit(OpaqueType opaqueType)
170
        {
171
                throw new UnsupportedOperationException();
172
        }
173

    
174

    
175
        @Override
176
        protected  void VisitAstElement(IAst element, IAst parent)
177
        {
178
                if (element.nodeType() == AstNodeTypeEnum.type)
179
                        super.VisitAstElement(element, parent);
180
        }
181

    
182
        public  String ToString()
183
        {
184
                return m_emitter.toString();
185
        }
186

    
187
        public CadpType()
188
        {
189
                super(null);
190
        }
191

    
192
        public static String DumpType(UlyssesType atype)
193
        {
194
                final CadpType newtype = new CadpType();
195
                atype.Accept(newtype);
196
                return newtype.ToString();
197
        }
198

    
199

    
200
        private static HashSet<String> emittedTypes = new HashSet<String>();
201

    
202
        private static void EmitType(UlyssesType aType, OoasCodeEmitter emitter)
203
        {
204
                final String typename = CadpIdentifier.GetIdentifierString(aType.identifier());
205
                if (!emittedTypes.contains(typename))
206
                        switch (aType.kind())
207
                        {
208
                        case BoolType:
209
                                emittedTypes.add(typename);
210
                                EmitDefinition((BoolType)aType, emitter);
211
                                break;
212

    
213
                        case EnumeratedType:
214
                                emittedTypes.add(typename);
215
                                EmitDefinition((EnumType)aType, emitter);
216
                                break;
217

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

    
223
                        case IntType:
224
                                emittedTypes.add(typename);
225
                                EmitDefinition((IntType)aType, emitter);
226
                                break;
227

    
228
                        case MapType:
229
                                throw new UnsupportedOperationException();
230

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

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

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

    
246
                        case QrType:
247
                                throw new UnsupportedOperationException(); // does not make sense in CADP target.
248

    
249
                        case FunctionType:
250
                                emittedTypes.add(typename);
251
                                EmitDefinition((FunctionType)aType, emitter);
252
                                break;
253

    
254
                        case Null:
255
                        case Any:
256
                        case OpaqueType:
257
                                throw new UnsupportedOperationException(); // should throw invalid args exception
258

    
259
                        default:
260
                                throw new UnsupportedOperationException();
261
                        }
262
        }
263

    
264
        private static void EmitDefinition(FunctionType functionType, OoasCodeEmitter emitter)
265
        {
266
                final String typeName = CadpIdentifier.GetIdentifierString(functionType.identifier());
267
                final String decl = OoaCADPVisitor.FunctionHeader(functionType, String.format("(* %s)", typeName));
268
                m_functionForwardDefinitions.AppendLine(String.format("typedef %s;", decl));
269
        }
270

    
271
        private static void EmitDefinition(IntType intType, OoasCodeEmitter emitter)
272
        {
273
                final String typeName = GetIdentifierString(intType.identifier());
274

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

    
277
                // low
278
                emitter.AppendLine(String.format("/*%s%s*/", lowString, typeName));
279
                emitter.Append(String.format("long long int %s%s (void) {", lowString, typeName));
280
                emitter.AppendLine("return 0; }");
281

    
282
                // high
283
                emitter.AppendLine(String.format("/*%s%s*/", highString, typeName));
284
                emitter.Append(String.format("long long int %s%s (void) { return %sLL; }", highString, typeName, ((long)intType.rangeHigh()) - intType.rangeLow() + 1));
285

    
286
                // enumerator
287
                emitter.AppendLine(String.format("/*%s%s*/", enumString, typeName));
288
                emitter.Append(String.format("%s %s%s (long long int value) { ", typeName, enumString, typeName));
289
                emitter.AppendLine(String.format("if (value >= %s%s()) { printf(\"Enum index out of range: %s\\n\"); abort();}", highString, typeName, typeName));
290
                emitter.Append(String.format("return (%s) (%sLL + value);", typeName, intType.rangeLow()));
291
                emitter.AppendLine("}");
292

    
293
                // print
294
                emitter.AppendLine(String.format("/*%s%s*/", printString, typeName));
295
                emitter.AppendLine(String.format("void %s%s (CAESAR_TYPE_FILE CAESAR_FILE, %s A_VALUE)", printString, typeName, typeName));
296
                emitter.AppendLine("{");
297
                emitter.AppendLine("  fprintf(CAESAR_FILE,\"%d\",A_VALUE);");
298
                emitter.AppendLine("}");
299
        }
300

    
301
        private static void EmitDefinition(FloatType floatType, OoasCodeEmitter emitter)
302
        {
303
                final String typeName = GetIdentifierString(floatType.identifier());
304

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

    
307
                // low
308
                emitter.AppendLine(String.format("/*%1$s%2$s*/", lowString, typeName));
309
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
310

    
311
                // high
312
                emitter.AppendLine(String.format("/*%1$s%2$s*/", highString, typeName));
313
                final long count = (long) (((long)floatType.high() - (long)floatType.low()) / floatType.precision());
314
                emitter.Append(String.format("long long int %2$s%1$s (void) { return %3$sLL; }", typeName, highString, count));
315

    
316
                // enumerator
317
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
318
                emitter.Append(String.format("%1$s %2$s%1$s (long long int value) { ", typeName, enumString));
319
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
320
                emitter.Append(String.format("return %1$sLL + (value * %2$s);", floatType.low(), floatType.precision()));
321
                emitter.AppendLine("}");
322

    
323
                // print
324
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
325
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
326
                emitter.AppendLine("{");
327
                emitter.AppendLine("  fprintf(CAESAR_FILE,\"%lf\",A_VALUE);");
328
                emitter.AppendLine("}");
329
        }
330

    
331
        private static void EmitDefinition(EnumType enumType, OoasCodeEmitter emitter)
332
        {
333
                final String typeName = GetIdentifierString(enumType.identifier());
334

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

    
337
                // low
338
                emitter.AppendLine(String.format("/*%1$s%2$s*/", lowString, typeName));
339
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
340

    
341
                // high
342
                emitter.AppendLine(String.format("/*%1$s%2$s*/", highString, typeName));
343
                emitter.Append(String.format("int %2$s%1$s (void) { return %3$s; }", typeName, highString, enumType.listOfEnumSymbols().size()));
344

    
345
                if (enumType instanceof ValuedEnumType)
346
                        ValuedEnumType((ValuedEnumType)enumType, emitter, typeName);
347
                else
348
                        NormalEnumType(enumType, emitter, typeName);
349

    
350
        }
351

    
352
        private static void ValuedEnumType(ValuedEnumType enumType, OoasCodeEmitter emitter, String typeName)
353
        {
354
                // enumerator
355
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
356
                emitter.AppendLine(String.format("%3$s %2$s%1$s (long long int value) { ", typeName, enumString, DumpType(enumType)));
357
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
358
                int i = 0;
359
                for (final Identifier sym : enumType.symbolTable().symbolList())
360
                {
361
                        final EnumIdentifier id = (EnumIdentifier)sym;
362
                        emitter.AppendLine(String.format("if (value == %1$s) return (int) %2$s;", i++, id.Value()));
363
                }
364
                emitter.AppendLine("}");
365

    
366

    
367
                // print
368
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
369
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
370
                emitter.AppendLine("{");
371
                i = 0;
372
                for (final Identifier sym : enumType.symbolTable().symbolList())
373
                {
374
                        final EnumIdentifier id = (EnumIdentifier)sym;
375
                        emitter.AppendLine(String.format("  if (A_VALUE == %1$s) fprintf(CAESAR_FILE,\"%2$s\");", id.Value(), id.tokenText()));
376
                }
377
                emitter.AppendLine("}");
378
        }
379

    
380

    
381
        private static void NormalEnumType(EnumType enumType, OoasCodeEmitter emitter, String typeName)
382
        {
383

    
384
                // enumerator
385
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
386
                emitter.AppendLine(String.format("%3$s %2$s%1$s (long long int value) { ", typeName, enumString, DumpType(enumType)));
387
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
388
                emitter.AppendLine(String.format("return (int)value; /*enums are treated like ints*/"));
389
                emitter.AppendLine("}");
390

    
391
                // backtranslation of enum syms
392
                emitter.AppendLine(String.format(" /* backtranslation of enum %1$s */ ", typeName));
393
                emitter.Append(String.format("CAESAR_TYPE_STRING _%1$s_identifiers[%2$s] = {", typeName, enumType.listOfEnumSymbols().size()));
394
                int i = 0;
395
                for (final Identifier x : enumType.listOfEnumSymbols())
396
                {
397
                        if (i != 0)
398
                                emitter.Append(", ");
399
                        else
400
                                i++;
401
                        emitter.Append(String.format("\"%1$s\"", x.tokenText()));
402
                }
403
                emitter.AppendLine("};");
404

    
405
                // print
406
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
407
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
408
                emitter.AppendLine("{");
409
                emitter.AppendLine(String.format("  fprintf(CAESAR_FILE,\"%%s\", _%1$s_identifiers[A_VALUE]);", typeName));
410
                emitter.AppendLine("}");
411

    
412
        }
413

    
414
        private static void EmitDefinition(BoolType boolType, OoasCodeEmitter emitter)
415
        {
416
                final String typeName = GetIdentifierString(boolType.identifier());
417

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

    
420
                // low
421
                emitter.AppendLine(String.format("/*%1$s%2$s*/", lowString, typeName));
422
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
423

    
424
                // high
425
                emitter.AppendLine(String.format("/*%1$s%2$s*/", highString, typeName));
426
                emitter.Append(String.format("int %2$s%1$s (void) { return 2; }", typeName, highString));
427

    
428
                // enumerator
429
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
430
                emitter.Append(String.format("%1$s %2$s%1$s (long long int value) { ", typeName, enumString));
431
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
432
                emitter.Append("return (int) value;");
433
                emitter.AppendLine("}");
434

    
435
                // print
436
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
437
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
438
                emitter.AppendLine("{");
439
                emitter.AppendLine(String.format("  fprintf(CAESAR_FILE,\"%%s\", A_VALUE ? \"true\" : \"false\");"));
440
                emitter.AppendLine("}");
441
        }
442

    
443
        /// <summary>
444
        /// Emits type definition for list
445
        /// </summary>
446
        private static void EmitDefinition(ListType alistType, OoasCodeEmitter result)
447
        {
448

    
449
                if (alistType.innerType().kind() != TypeKind.Null &&
450
                                !emittedTypes.contains(CadpIdentifier.GetIdentifierString(alistType.innerType().identifier())))
451
                        EmitType(alistType.innerType(), result);
452

    
453
                final OoasCodeEmitter emitter = new OoasCodeEmitter();
454
                final String typeName = GetIdentifierString(alistType.identifier()).replaceAll(" ", "_");
455

    
456
                // include a forward definition
457
                m_typeForwardDefinitions.AppendLine(String.format("typedef struct list_%1$s %1$s;", typeName));
458

    
459
                emitter.AppendLine("#ifdef WINDOWSPACK");
460
                emitter.AppendLine("#pragma pack(1)");
461
                emitter.AppendLine("#endif");
462
                emitter.AppendLine(String.format("struct list_%1$s { int length; %2$s elements[%3$s];} UNIXPACK /*%1$s, * p%1$s*/;"
463
                                , typeName, DumpType(alistType.innerType()), alistType.maxNumberOfElements() == 0 ? 1 : alistType.maxNumberOfElements()));
464
                emitter.AppendLine(String.format("#define MAX_%1$s %2$s", typeName, alistType.maxNumberOfElements()));
465
                emitter.AppendLine("");
466

    
467

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

    
508

    
509
                emitter.AppendLine("");
510

    
511
                // low
512
                emitter.AppendLine(String.format("/*%1$s*/", lowString));
513
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
514

    
515
                // high
516
                emitter.AppendLine(String.format("/*%1$s*/", highString));
517
                if (alistType.innerType().kind() == TypeKind.Null)
518
                        emitter.Append(String.format("int %2$s%1$s (void) { return 0; }", typeName, highString));
519
                else
520
                        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())));
521

    
522
                // enumerator
523
                //emitter.AppendLine(String.format("/*%1$s*/", enumString));
524
                //emitter.Append(String.format("%1$s %2$s%1$s (int value) { ", typeName, enumString));
525
                //emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
526
                //emitter.AppendLine("abort();");
527
                //emitter.Append("return value;");
528
                //emitter.AppendLine("}");
529

    
530
                // print
531
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
532
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
533
                emitter.AppendLine("{");
534
                emitter.AppendLine(String.format("  fprintf(CAESAR_FILE,\" [len: %%d \", A_VALUE.length);"));
535
                for (i = 0; i < alistType.maxNumberOfElements(); i++)
536
                {
537
                        emitter.AppendLine(String.format("if (A_VALUE.length > %1$s){", i));
538
                        emitter.AppendLine(String.format("fprintf(CAESAR_FILE,\" %1$s: \");", i));
539
                        emitter.AppendLine(String.format("%1$s%2$s (CAESAR_FILE, A_VALUE.elements[%3$s]);", printString, CadpIdentifier.GetIdentifierString(alistType.innerType().identifier()), i));
540
                        emitter.AppendLine("} /*if*/");
541
                }
542
                emitter.AppendLine("  fprintf(CAESAR_FILE,\"]\");");
543
                emitter.AppendLine("}");
544

    
545
                result.Append(emitter.toString());
546
        }
547

    
548
        private static void EmitDefinition(TupleType atupleType, OoasCodeEmitter result)
549
        {
550
                final String typeName = GetIdentifierString(atupleType.identifier());
551
                final OoasCodeEmitter emitter = new OoasCodeEmitter();
552

    
553

    
554
                // include a forward definition
555
                m_typeForwardDefinitions.AppendLine(String.format("typedef struct struct_%1$s %1$s;", typeName));
556

    
557
                emitter.AppendLine("#ifdef WINDOWSPACK");
558
                emitter.AppendLine("#pragma pack(1)");
559
                emitter.AppendLine("#endif");
560
                emitter.AppendLineIncIndent(String.format("struct struct_%1$s {", typeName));
561
                int i = 0;
562
                for (final UlyssesType it: atupleType.innerTypes())
563
                {
564
                        EmitType(it);
565
                        emitter.AppendLine(String.format("%1$s elem_%2$s;", DumpType(it), i));
566
                        i++;
567
                }
568
                emitter.AppendLineDecIndent(String.format("} UNIXPACK /*%1$s, * p%1$s*/;", typeName));
569

    
570

    
571

    
572
                emitter.AppendLine("");
573

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

    
617

    
618
                // low
619
                emitter.AppendLine(String.format("/*%1$s%2$s*/", lowString, typeName));
620
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
621

    
622
                // high
623
                emitter.AppendLine(String.format("/*%1$s%2$s*/", highString, typeName));
624
                emitter.Append(String.format("long long int %2$s%1$s (void) { return ", typeName, highString));
625
                i = 0;
626
                for (final UlyssesType x : atupleType.innerTypes())
627
                {
628
                        if (i != 0)
629
                                emitter.Append(" * ");
630
                        else
631
                                i++;
632
                        emitter.Append(String.format("%2$s%1$s()", GetIdentifierString(x.identifier()), highString));
633
                }
634
                emitter.AppendLine("; }");
635

    
636
                // enumerator
637
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
638
                emitter.Append(String.format("%1$s %2$s%1$s (long long int value) { ", typeName, enumString));
639
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
640
                emitter.Append(String.format("return %2$s%1$s (", typeName, constructorString));
641
                i = 0;
642
                final StringBuilder divisor = new StringBuilder("value");
643
                for (final UlyssesType it: atupleType.innerTypes())
644
                {
645
                        if (i != 0)
646
                                emitter.Append(",");
647
                        else i++;
648
                        emitter.Append(String.format("%2$s%1$s((%4$s) %% %3$s%1$s())", GetIdentifierString(it.identifier()), enumString, highString, divisor.toString()));
649
                        divisor.append(String.format(" / %2$s%1$s() ", GetIdentifierString(it.identifier()), highString));
650
                }
651
                emitter.AppendLine(");}");
652

    
653

    
654
                // print
655
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
656
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
657
                emitter.AppendLine("{");
658
                emitter.AppendLine(String.format("  fprintf(CAESAR_FILE,\" (\");"));
659
                final Iterator<UlyssesType> iter = atupleType.innerTypes().iterator();
660
                for (i = 0; i < atupleType.innerTypes().size(); i++)
661
                {
662
                        if (i != 0)
663
                                emitter.AppendLine("fprintf(CAESAR_FILE, \", \");");
664
                        emitter.AppendLine(String.format("%1$s%2$s (CAESAR_FILE, A_VALUE.elem_%3$s);", printString, CadpIdentifier.GetIdentifierString(iter.next().identifier()), i));
665
                }
666
                emitter.AppendLine("  fprintf(CAESAR_FILE,\")\");");
667
                emitter.AppendLine("}");
668

    
669
                emitter.AppendLine("");
670
                result.Append(emitter.toString());
671
        }
672

    
673
        public static String GetNullConstant(OoActionSystemType anActionSystem)
674
        {
675
                return String.format("NULL_%1$s", CadpIdentifier.GetIdentifierString(anActionSystem.identifier()));
676
        }
677

    
678
        private static void EmitObjectJumpTable(OoActionSystemType instance)
679
        {
680

    
681
                final OoasCodeEmitter emitter = new OoasCodeEmitter();
682
                final OoasCodeEmitter forwards = new OoasCodeEmitter();
683

    
684
                // emit null
685
                emitter.AppendLine(String.format("%1$s NULL_%2$s = {0, \"NULL_%2$s\"",
686
                                CadpIdentifier.GetIdentifierString(instance.identifier()),
687
                                CadpIdentifier.GetIdentifierString(instance.identifier())));
688
                emitter.AppendLine(", NULL");
689
                emitter.AppendLine("};");
690

    
691
                // emit standard jump table
692

    
693
                // emit objects
694
                for (final OoActionSystemInstance ooainstance: instance.objects())
695
                {
696
                        forwards.AppendLine(String.format("/* ==> Object %1$s <==*/", ooainstance.Name));
697

    
698
                        emitter.AppendLine(String.format("struct jump_%1$s methods_%2$s = {",
699
                                        CadpIdentifier.GetIdentifierString(instance.identifier()), ooainstance.Name));
700
                        int i = 0;
701
                        final SymbolTable allSyms = instance.getAllSymbols();
702
                        for (final Identifier sym : allSyms.symbolList())
703
                        {
704
                                if (sym.kind() == IdentifierKind.MethodIdentifier)
705
                                {
706
                                        if (i != 0)
707
                                                emitter.AppendLine(", ");
708

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

    
713
                                        final String methoddef = OoaCADPVisitor.FunctionHeader((FunctionIdentifier)sym, method);
714
                                        forwards.AppendLine(String.format("%1$s;", methoddef));
715
                                        emitter.Append(String.format("&%1$s", method));
716
                                        i++;
717
                                }
718
                        }
719
                        emitter.AppendLine();
720
                        emitter.AppendLine("};");
721

    
722

    
723
                        emitter.Append(String.format("%1$s %2$s = {1, \"%2$s\", & methods_%2$s",
724
                                        CadpIdentifier.GetIdentifierString(ooainstance.Type.identifier()), ooainstance.Name));
725
                        emitter.AppendLine("};");
726
                }
727

    
728

    
729

    
730
                // enumerator
731
                final String typeName = String.format("%1$s", CadpIdentifier.GetIdentifierString(instance.identifier()));
732
                emitter.AppendLine(String.format("/*%1$s%2$s*/", enumString, typeName));
733

    
734
                // extern defs.
735
                for (final OoActionSystemInstance inst: instance.derivedObjects())
736
                        emitter.AppendLine(String.format("extern %1$s %2$s;", CadpIdentifier.GetIdentifierString(inst.Type.identifier()),inst.Name));
737

    
738
                emitter.AppendLine(String.format("%1$s %2$s%1$s (long long int value) { ", typeName, enumString));
739
                m_functionForwardDefinitions.AppendLine(String.format("%1$s %2$s%1$s (long long int value);", typeName, enumString));
740
                emitter.AppendLine(String.format("if (value >= %2$s%1$s()) { printf(\"Enum index out of range: %1$s\\n\"); abort();}", typeName, highString));
741
                emitter.AppendLine(String.format("switch((int)value){"));
742

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

    
745
                int u = 1;
746
                for (final OoActionSystemInstance inst: instance.objects())
747
                {
748
                        emitter.AppendLine(String.format("case %1$s:", u));
749
                        emitter.AppendLine(String.format("return %1$s;", inst.Name));
750
                        u++;
751
                }
752
                for (final OoActionSystemInstance inst: instance.derivedObjects())
753
                {
754
                        emitter.AppendLine(String.format("case %1$s:", u));
755
                        emitter.AppendLine(String.format("return *(%2$s*)&(%1$s);", inst.Name, typeName));
756
                        u++;
757
                }
758
                emitter.AppendLine("}");
759
                emitter.AppendLine("printf(\"bug during simulation:\\n     unknown object number\\n\"); CAESAR_TERMINATE(1);");
760
                emitter.AppendLine(String.format("return NULL_%1$s;", CadpIdentifier.GetIdentifierString(instance.identifier())));
761
                emitter.AppendLine("}");
762

    
763

    
764
                m_typeDefinitions.AppendLine(forwards.toString());
765
                m_typeDefinitions.AppendLine(emitter.toString());
766
        }
767

    
768

    
769
        private static void EmitDefinition(OoActionSystemType aClass, OoasCodeEmitter result)
770
        {
771
                /* ooa type gets translated into a jump table */
772
                final String typeName = String.format("%1$s", CadpIdentifier.GetIdentifierString(aClass.identifier()));
773
                final OoasCodeEmitter emitter = new OoasCodeEmitter();
774

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

    
778
                classStructure.AppendLine(String.format("struct jump_%1$s {", typeName));
779
//                int i = 0;
780
                final SymbolTable allSyms = aClass.getAllSymbols();
781
                for (final Identifier sym: allSyms.symbolList())
782
                {
783
                        if (sym.kind() == IdentifierKind.MethodIdentifier)
784
                        {
785
                                final MethodIdentifier method = (MethodIdentifier)sym;
786
                                EmitType(method.type());
787
                                classStructure.AppendLine(String.format("%1$s %2$s;", CadpIdentifier.GetIdentifierString(method), method.tokenText()));
788
//                                i++;
789
                        }
790
                }
791
                classStructure.AppendLine("};");
792

    
793
                classStructure.AppendLine("#ifdef WINDOWSPACK");
794
                classStructure.AppendLine("#pragma pack(1)");
795
                classStructure.AppendLine("#endif");
796
                classStructure.AppendLineIncIndent(String.format("struct struct_%1$s {", typeName));
797
                classStructure.AppendLine("char __validinstance;");
798
                classStructure.AppendLine("char* __object_name;");
799
                classStructure.AppendLine(String.format("struct jump_%1$s *methods;", typeName));
800
                classStructure.AppendLineDecIndent(String.format("} UNIXPACK /*%1$s*/;", typeName));
801

    
802
                m_classTypeDefinitions.AppendLine(classStructure.toString());
803

    
804
                emitter.AppendLine("");
805

    
806
                // include a forward definition
807
                m_typeForwardDefinitions.AppendLine(String.format("typedef struct struct_%1$s %1$s;", typeName));
808

    
809
                // low
810
                emitter.AppendLine(String.format("/*%1$s%2$s*/", lowString, typeName));
811
                emitter.Append(String.format("int %2$s%1$s (void) {", typeName, lowString)); emitter.AppendLine("return 0; }");
812
                m_functionForwardDefinitions.AppendLine(String.format("int %2$s%1$s (void);", typeName, lowString));
813

    
814
                // high
815
                emitter.AppendLine(String.format("/*%1$s%2$s*/", highString, typeName));
816
                emitter.Append(String.format("int %2$s%1$s (void) { return %3$s; }", typeName, highString, aClass.objects().size() + 1 + aClass.derivedObjects().size()));
817
                m_functionForwardDefinitions.AppendLine(String.format("int %2$s%1$s (void);", typeName, highString));
818

    
819
                // print
820
                emitter.AppendLine(String.format("/*%1$s%2$s*/", printString, typeName));
821
                emitter.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE)", printString, typeName));
822
                emitter.AppendLine("{");
823
                emitter.AppendLine("  fprintf(CAESAR_FILE,\"object %s\", A_VALUE.__object_name);");
824
                emitter.AppendLine("}");
825
                m_functionForwardDefinitions.AppendLine(String.format("void %1$s%2$s (CAESAR_TYPE_FILE CAESAR_FILE, %2$s A_VALUE);", printString, typeName));
826
                result.Append(emitter.toString());
827

    
828
                EmitObjectJumpTable(aClass);
829
        }
830

    
831

    
832

    
833

    
834
        public static String GetMaxVal(UlyssesType atype)
835
        {
836
                return String.format(" (%2$s%1$s() - 1) ", GetIdentifierString(atype.identifier()), highString);
837
        }
838

    
839
        public static String GetMinVal(UlyssesType atype)
840
        {
841
                return String.format(" %2$s%1$s() ", GetIdentifierString(atype.identifier()), lowString);
842
        }
843

    
844
        public static String GetEnumVal(UlyssesType atype, String indexvar)
845
        {
846
                return String.format(" %2$s%1$s(%3$s)", GetIdentifierString(atype.identifier()), enumString, indexvar);
847
        }
848
        public static String GetEnumVal(UlyssesType atype)
849
        {
850
                return String.format(" %2$s%1$s", GetIdentifierString(atype.identifier()), enumString);
851
        }
852

    
853

    
854
        private static OoasCodeEmitter m_typeForwardDefinitions = new OoasCodeEmitter();
855
        private static OoasCodeEmitter m_functionForwardDefinitions = new OoasCodeEmitter();
856
        private static OoasCodeEmitter m_classTypeDefinitions = new OoasCodeEmitter();
857
        private static OoasCodeEmitter m_typeDefinitions = new OoasCodeEmitter();
858

    
859
        public static void EmitType(UlyssesType aType)
860
        {
861
                EmitType(aType, m_typeDefinitions);
862
        }
863

    
864
        public static String GetTypeDefintions()
865
        {
866
                final StringBuilder result = new StringBuilder();
867
                result.append(m_typeForwardDefinitions.toString());
868
                result.append(System.lineSeparator());
869
                result.append(m_functionForwardDefinitions.toString());
870
                result.append(System.lineSeparator());
871
                result.append(m_classTypeDefinitions.toString());
872
                result.append(System.lineSeparator());
873
                result.append(m_typeDefinitions.toString());
874
                result.append(System.lineSeparator());
875
                return result.toString();
876
        }
877

    
878
        public static boolean IsNumeric(UlyssesType ulyssesType)
879
        {
880
                switch (ulyssesType.kind())
881
                {
882
                case BoolType:
883
                case EnumeratedType:
884
                case FloatType:
885
                case IntType:
886
                        return true;
887
                default:
888
                        return false;
889
                }
890
        }
891

    
892

    
893
        static
894
        {
895
                // populate typesizes.
896
                m_typesizes = new HashMap<String, Integer>();
897
                m_typesizes.put("char", 1);
898
                m_typesizes.put("int", 4);
899
                m_typesizes.put("double", 8);
900
                m_typesizes.put("pointer", 4);
901
        }
902

    
903

    
904

    
905
        public static void AddTypeDefinition(String listStruct)
906
        {
907
                if (!emittedTypes.contains(listStruct))
908
                {
909
                        m_typeDefinitions.AppendLine(listStruct);
910
                        emittedTypes.add(listStruct);
911
                }
912
        }
913
}