Project

General

Profile

Revision 7

Added by Willibald K. over 8 years ago

changing java, cpp, hpp files to unix line endings

View differences:

CadpType.java
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
  */

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 26

  
27 27

  
28
package org.momut.ooas.codegen.cadp;
29

  
30
import java.util.HashMap;
31
import java.util.HashSet;
32
import java.util.Iterator;
28
package org.momut.ooas.codegen.cadp;
33 29

  
30
import java.util.HashMap;
31
import java.util.HashSet;
32
import java.util.Iterator;
33

  
34 34
import org.momut.ooas.ast.AstNodeTypeEnum;
35 35
import org.momut.ooas.ast.IAst;
36 36
import org.momut.ooas.ast.identifiers.EnumIdentifier;
......
59 59
import org.momut.ooas.codegen.OoasCodeEmitter;
60 60
import org.momut.ooas.parser.SymbolTable;
61 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
	}
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
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff