Revision 7
Added by Willibald K. over 8 years ago
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
Also available in: Unified diff
changing java, cpp, hpp files to unix line endings