1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9
|
|
10
|
|
11
|
|
12
|
|
13
|
|
14
|
|
15
|
|
16
|
|
17
|
|
18
|
|
19
|
|
20
|
|
21
|
|
22
|
|
23
|
|
24
|
|
25
|
|
26
|
|
27
|
|
28
|
package org.momut.ooas.codegen.cadp;
|
29
|
|
30
|
import java.util.ArrayList;
|
31
|
import java.util.HashSet;
|
32
|
import java.util.Iterator;
|
33
|
import java.util.List;
|
34
|
|
35
|
import org.momut.ooas.ast.expressions.AccessExpression;
|
36
|
import org.momut.ooas.ast.expressions.BinaryOperator;
|
37
|
import org.momut.ooas.ast.expressions.CallExpression;
|
38
|
import org.momut.ooas.ast.expressions.ExistsQuantifier;
|
39
|
import org.momut.ooas.ast.expressions.Expression;
|
40
|
import org.momut.ooas.ast.expressions.ExpressionKind;
|
41
|
import org.momut.ooas.ast.expressions.ForallQuantifier;
|
42
|
import org.momut.ooas.ast.expressions.IdentifierExpression;
|
43
|
import org.momut.ooas.ast.expressions.ListConstructor;
|
44
|
import org.momut.ooas.ast.expressions.MapConstructor;
|
45
|
import org.momut.ooas.ast.expressions.ObjectConstructor;
|
46
|
import org.momut.ooas.ast.expressions.SetConstructor;
|
47
|
import org.momut.ooas.ast.expressions.TernaryOperator;
|
48
|
import org.momut.ooas.ast.expressions.TupleConstructor;
|
49
|
import org.momut.ooas.ast.expressions.TupleMapAccessExpression;
|
50
|
import org.momut.ooas.ast.expressions.TypeExpression;
|
51
|
import org.momut.ooas.ast.expressions.UnaryOperator;
|
52
|
import org.momut.ooas.ast.expressions.UnresolvedIdentifierExpression;
|
53
|
import org.momut.ooas.ast.expressions.ValueExpression;
|
54
|
import org.momut.ooas.ast.expressions.LeafExpression.LeafTypeEnum;
|
55
|
import org.momut.ooas.ast.identifiers.ExpressionVariableIdentifier;
|
56
|
import org.momut.ooas.ast.identifiers.FunctionIdentifier;
|
57
|
import org.momut.ooas.ast.identifiers.Identifier;
|
58
|
import org.momut.ooas.ast.identifiers.IdentifierKind;
|
59
|
import org.momut.ooas.ast.types.FunctionType;
|
60
|
import org.momut.ooas.ast.types.ListType;
|
61
|
import org.momut.ooas.ast.types.MapType;
|
62
|
import org.momut.ooas.ast.types.OoActionSystemInstance;
|
63
|
import org.momut.ooas.ast.types.OoActionSystemType;
|
64
|
import org.momut.ooas.ast.types.TupleType;
|
65
|
import org.momut.ooas.ast.types.TypeKind;
|
66
|
import org.momut.ooas.ast.types.Type;
|
67
|
import org.momut.ooas.codegen.OoasCodeEmitter;
|
68
|
import org.momut.ooas.parser.SymbolTable;
|
69
|
import org.momut.ooas.visitors.OoaExpressionVisitor;
|
70
|
|
71
|
|
72
|
|
73
|
|
74
|
|
75
|
public final class CadpExpression extends OoaExpressionVisitor
|
76
|
{
|
77
|
private OoasCodeEmitter m_emitter = new OoasCodeEmitter();
|
78
|
private final CadpActionInfo m_procInfo;
|
79
|
private final ArrayList<Identifier> m_usedIdentifier = new ArrayList<Identifier>();
|
80
|
private static OoasCodeEmitter m_helperCode = new OoasCodeEmitter();
|
81
|
private static OoasCodeEmitter m_resetCode = new OoasCodeEmitter();
|
82
|
|
83
|
public static HashSet<String> emittedOperations = new HashSet<String>();
|
84
|
public List<Identifier> usedIdentifiers() { return m_usedIdentifier; }
|
85
|
|
86
|
private String OperatorString(Expression expression)
|
87
|
{
|
88
|
switch (expression.kind())
|
89
|
{
|
90
|
case abs:
|
91
|
case card:
|
92
|
case dom:
|
93
|
case range:
|
94
|
case merge:
|
95
|
case elems:
|
96
|
case inds:
|
97
|
case dinter:
|
98
|
case dunion:
|
99
|
case domresby:
|
100
|
case domresto:
|
101
|
case rngresby:
|
102
|
case rngresto:
|
103
|
case inter:
|
104
|
case union:
|
105
|
case munion:
|
106
|
case seqmod_mapoverride:
|
107
|
case subset:
|
108
|
case biimplies:
|
109
|
case Primed:
|
110
|
throw new UnsupportedOperationException();
|
111
|
|
112
|
case notelemin:
|
113
|
case elemin:
|
114
|
case implies:
|
115
|
case conc:
|
116
|
case head:
|
117
|
case tail:
|
118
|
case len:
|
119
|
throw new IllegalArgumentException();
|
120
|
|
121
|
|
122
|
case div:
|
123
|
return "/";
|
124
|
case idiv:
|
125
|
return "/";
|
126
|
case mod:
|
127
|
return "%";
|
128
|
case prod:
|
129
|
return "*";
|
130
|
case sum:
|
131
|
return "+";
|
132
|
case minus:
|
133
|
return "-";
|
134
|
case less:
|
135
|
return "<";
|
136
|
case lessequal:
|
137
|
return "<=";
|
138
|
case greater:
|
139
|
return ">";
|
140
|
case greaterequal:
|
141
|
return ">=";
|
142
|
case equal:
|
143
|
return "==";
|
144
|
case notequal:
|
145
|
return "!=";
|
146
|
case and:
|
147
|
return "&&";
|
148
|
case or:
|
149
|
return "||";
|
150
|
case not:
|
151
|
return "!";
|
152
|
|
153
|
case Cast:
|
154
|
throw new IllegalArgumentException();
|
155
|
|
156
|
|
157
|
|
158
|
|
159
|
|
160
|
default:
|
161
|
return expression.kind().toString();
|
162
|
}
|
163
|
}
|
164
|
@Override
|
165
|
public <T>void visit(ValueExpression<T> valueExpression)
|
166
|
{
|
167
|
if (valueExpression.value() == null)
|
168
|
{
|
169
|
m_emitter.Append("NULL");
|
170
|
}
|
171
|
else if (valueExpression.valueType() == LeafTypeEnum.bool)
|
172
|
{
|
173
|
|
174
|
final boolean aboolval = (Boolean)valueExpression.value();
|
175
|
m_emitter.AppendLine(aboolval ? "1" : "0");
|
176
|
}
|
177
|
else if (valueExpression.valueType() == LeafTypeEnum.chr)
|
178
|
m_emitter.Append(String.format("'%1$s'", valueExpression.toString()));
|
179
|
else
|
180
|
m_emitter.Append(valueExpression.value().toString());
|
181
|
}
|
182
|
@Override
|
183
|
public void visit(UnresolvedIdentifierExpression unresolvedIdentifierExpression)
|
184
|
{
|
185
|
throw new IllegalArgumentException();
|
186
|
}
|
187
|
|
188
|
@Override
|
189
|
public void visit(IdentifierExpression identifierExpression)
|
190
|
{
|
191
|
final CadpIdentifier idvis = new CadpIdentifier(m_procInfo.stateVariableString);
|
192
|
identifierExpression.Accept(idvis);
|
193
|
m_emitter.Append(idvis.toString());
|
194
|
|
195
|
if (identifierExpression.identifier().kind() == IdentifierKind.ExpressionVariableIdentifier)
|
196
|
{
|
197
|
|
198
|
|
199
|
final ExpressionVariableIdentifier id = (ExpressionVariableIdentifier)identifierExpression.identifier();
|
200
|
if (!emittedVariabes.contains(id))
|
201
|
{
|
202
|
emittedVariabes.add(id);
|
203
|
final CadpType atype = new CadpType();
|
204
|
id.type().Accept(atype);
|
205
|
varDecl.Append(String.format("%1$s %2$s; ", atype.ToString(), idvis.toString()));
|
206
|
}
|
207
|
}
|
208
|
|
209
|
if (!m_usedIdentifier.contains(identifierExpression.identifier()))
|
210
|
m_usedIdentifier.add(identifierExpression.identifier());
|
211
|
}
|
212
|
|
213
|
@Override
|
214
|
public void visit(TypeExpression typeExpression)
|
215
|
{
|
216
|
m_emitter.Append(typeExpression.type().identifier().tokenText());
|
217
|
}
|
218
|
|
219
|
@Override
|
220
|
public void visit(ListConstructor listConstructor)
|
221
|
{
|
222
|
final ListType aListType = (ListType)listConstructor.type();
|
223
|
if (!listConstructor.hasComprehension())
|
224
|
{
|
225
|
CadpType.EmitType(aListType);
|
226
|
|
227
|
m_emitter.Append(String.format("%1$s%2$s(%3$s", CadpType.constructorString, CadpIdentifier.GetIdentifierString(aListType.identifier()), listConstructor.elements().size()));
|
228
|
int i;
|
229
|
for (i = 0; i < aListType.maxNumberOfElements(); i++)
|
230
|
{
|
231
|
m_emitter.Append(", ");
|
232
|
if (i < listConstructor.elements().size())
|
233
|
listConstructor.elements().get(i).Accept(this);
|
234
|
else
|
235
|
m_emitter.Append(String.format("%1$s%2$s(%3$s%2$s())", CadpType.enumString, CadpIdentifier.GetIdentifierString(aListType.innerType().identifier()), CadpType.lowString));
|
236
|
}
|
237
|
m_emitter.Append(")");
|
238
|
}
|
239
|
else
|
240
|
{
|
241
|
final CadpExpression compExpr = new CadpExpression(new CadpActionInfo(null, -1, 0, m_procInfo.toDoListString, m_procInfo.doneListString, "aState"), emittedVariabes);
|
242
|
if (listConstructor.comprehension() != null)
|
243
|
listConstructor.comprehension().Accept(compExpr);
|
244
|
else
|
245
|
new ValueExpression<Integer>(1, 0, 0, Integer.class).Accept(compExpr);
|
246
|
|
247
|
final CadpExpression listElementExpr = new CadpExpression(m_procInfo, emittedVariabes);
|
248
|
listConstructor.elements().get(0).Accept(listElementExpr);
|
249
|
|
250
|
|
251
|
compExpr.usedIdentifiers().addAll(listElementExpr.usedIdentifiers());
|
252
|
final List<Identifier> importVars = getListOfAccessedIdentifiers(compExpr, listConstructor.comprehensionVariables());
|
253
|
|
254
|
|
255
|
|
256
|
|
257
|
|
258
|
|
259
|
final List<Identifier> varsToRemove = new ArrayList<Identifier>();
|
260
|
|
261
|
for (final Identifier id : importVars)
|
262
|
{
|
263
|
final CadpType atype = new CadpType();
|
264
|
id.type().Accept(atype);
|
265
|
final String typeAndName = (String.format("%1$s %2$s; ", atype.ToString(), id.tokenText()));
|
266
|
|
267
|
if (compExpr.VariableDeclarations().contains(typeAndName))
|
268
|
varsToRemove.add(id);
|
269
|
}
|
270
|
int tmpcntr = importVars.size() -1;
|
271
|
for (tmpcntr = importVars.size() -1; tmpcntr>=0; tmpcntr--)
|
272
|
if (varsToRemove.contains(importVars.get(tmpcntr)))
|
273
|
importVars.remove(tmpcntr);
|
274
|
|
275
|
|
276
|
final String functionName = String.format("create_dyn_list_%1$s", OoaCADPVisitor.getUIntHashCode(listConstructor));
|
277
|
m_emitter.Append(functionName);
|
278
|
m_emitter.Append(String.format("( %1$s", this.m_procInfo.stateVariableString));
|
279
|
for (final Identifier x : importVars)
|
280
|
{
|
281
|
m_emitter.Append(",");
|
282
|
m_emitter.Append(String.format("%1$s", CadpIdentifier.GetIdentifierString(x)));
|
283
|
}
|
284
|
m_emitter.Append(")");
|
285
|
|
286
|
|
287
|
final ListType listType = (ListType)listConstructor.type();
|
288
|
CadpType.EmitType(listType.innerType());
|
289
|
final OoasCodeEmitter helper = new OoasCodeEmitter();
|
290
|
final String listtypename = String.format("struct_list_%1$s", CadpType.DumpType(listType.innerType()).replaceAll(" ", "_"));
|
291
|
|
292
|
|
293
|
final StringBuilder typedefbuilder = new StringBuilder();
|
294
|
typedefbuilder.append("#ifdef WINDOWSPACK" + System.lineSeparator());
|
295
|
typedefbuilder.append("#pragma pack(1)" + System.lineSeparator());
|
296
|
typedefbuilder.append("#endif" + System.lineSeparator());
|
297
|
typedefbuilder.append(String.format("struct %2$s { struct %2$s *next; %1$s element;} UNIXPACK;", CadpType.DumpType(listType.innerType()), listtypename));
|
298
|
typedefbuilder.append(System.lineSeparator());
|
299
|
final String listStruct = typedefbuilder.toString();
|
300
|
CadpType.AddTypeDefinition(listStruct);
|
301
|
|
302
|
helper.AppendLine(String.format("struct %1$s* %2$s(CAESAR_TYPE_STATE aState", listtypename, functionName));
|
303
|
for (final Identifier x : importVars)
|
304
|
{
|
305
|
helper.Append(", ");
|
306
|
helper.Append(String.format("%1$s %2$s", CadpType.DumpType(x.type()), CadpIdentifier.GetIdentifierString(x)));
|
307
|
}
|
308
|
helper.AppendLine("){");
|
309
|
|
310
|
helper.AppendLine(String.format("struct %1$s* result = NULL;", listtypename));
|
311
|
helper.AppendLine(String.format("struct %1$s* __currhead = NULL;", listtypename));
|
312
|
helper.AppendLine(compExpr.VariableDeclarations());
|
313
|
|
314
|
int loops = 0;
|
315
|
for (final Identifier enumvar : listConstructor.comprehensionVariables().symbolList())
|
316
|
{
|
317
|
helper.AppendLine(String.format("long long iterator_%1$s;", CadpIdentifier.GetIdentifierString(enumvar)));
|
318
|
helper.AppendLine(String.format("for (iterator_%1$s = %2$s; iterator_%1$s <= %3$s; iterator_%1$s++) {",
|
319
|
CadpIdentifier.GetIdentifierString(enumvar), CadpType.GetMinVal(enumvar.type()), CadpType.GetMaxVal(enumvar.type())));
|
320
|
|
321
|
if (compExpr.VariableDeclarations().contains(String.format(" %1$s;", CadpIdentifier.GetIdentifierString(enumvar))))
|
322
|
helper.AppendLine(String.format("/*%1$s*/ %2$s = %3$s(iterator_%2$s);",
|
323
|
CadpType.DumpType(enumvar.type()), CadpIdentifier.GetIdentifierString(enumvar), CadpType.GetEnumVal(enumvar.type())));
|
324
|
else
|
325
|
helper.AppendLine(String.format("%1$s %2$s = %3$s(iterator_%2$s);",
|
326
|
CadpType.DumpType(enumvar.type()), CadpIdentifier.GetIdentifierString(enumvar), CadpType.GetEnumVal(enumvar.type())));
|
327
|
loops++;
|
328
|
}
|
329
|
|
330
|
helper.AppendLine(String.format("%1$s __newElem;", CadpType.DumpType(listType.innerType())));
|
331
|
|
332
|
|
333
|
helper.AppendLine(String.format("if ((%1$s) && (CALC_INVALID == 0)) { __newElem = %2$s; ", compExpr.toString(), listElementExpr.toString()));
|
334
|
|
335
|
helper.AppendLine(String.format("struct %1$s* __listelem = (struct %1$s*) malloc(sizeof(struct %1$s));", listtypename));
|
336
|
helper.AppendLine(String.format("if (__listelem == NULL) { fprintf(stderr,\"malloc failure\"); exit(1);}"));
|
337
|
helper.AppendLine(String.format("memset((char*)__listelem,0,sizeof(struct %1$s));", listtypename));
|
338
|
|
339
|
helper.AppendLine(String.format(String.format("memcpy(&(__listelem->element),&__newElem, sizeof(%1$s));", CadpType.DumpType(listType.innerType()))));
|
340
|
helper.AppendLine(String.format("if (result == NULL) result = __listelem; else __currhead->next = __listelem; __currhead = __listelem;"));
|
341
|
|
342
|
helper.AppendLine("} /*if*/");
|
343
|
helper.AppendLine("if (CALC_INVALID == 1) CALC_INVALID = 0;");
|
344
|
while (loops > 0)
|
345
|
{
|
346
|
helper.AppendLine("}");
|
347
|
loops--;
|
348
|
}
|
349
|
helper.AppendLine("return result; }");
|
350
|
|
351
|
m_helperCode.Append(helper.toString());
|
352
|
}
|
353
|
}
|
354
|
|
355
|
@Override
|
356
|
public void visit(SetConstructor setConstructor)
|
357
|
{
|
358
|
final ListType aSetType = (ListType)setConstructor.type();
|
359
|
m_emitter.Append(String.format(" /*set constr*/ %1$s%2$s(", CadpType.constructorString, CadpIdentifier.GetIdentifierString(aSetType.identifier())));
|
360
|
m_emitter.Append(setConstructor.items().size());
|
361
|
for (final Expression x : setConstructor.items())
|
362
|
{
|
363
|
m_emitter.Append(", ");
|
364
|
x.Accept(this);
|
365
|
}
|
366
|
m_emitter.Append(")");
|
367
|
}
|
368
|
|
369
|
@Override
|
370
|
public void visit(MapConstructor mapConstructor)
|
371
|
{
|
372
|
throw new UnsupportedOperationException();
|
373
|
}
|
374
|
|
375
|
@Override
|
376
|
public void visit(TupleConstructor tupleConstructor)
|
377
|
{
|
378
|
final TupleType aTupleType = (TupleType)tupleConstructor.type();
|
379
|
|
380
|
if (tupleConstructor.isMatcher())
|
381
|
{
|
382
|
|
383
|
throw new IllegalArgumentException();
|
384
|
}
|
385
|
else
|
386
|
{
|
387
|
m_emitter.Append(String.format("%1$s%2$s(", CadpType.constructorString, CadpIdentifier.GetIdentifierString(aTupleType.identifier())));
|
388
|
int i = 0;
|
389
|
for (final Expression x : tupleConstructor.values())
|
390
|
{
|
391
|
if (i != 0)
|
392
|
m_emitter.Append(", ");
|
393
|
else
|
394
|
i++;
|
395
|
x.Accept(this);
|
396
|
}
|
397
|
m_emitter.Append(")");
|
398
|
}
|
399
|
}
|
400
|
|
401
|
@Override
|
402
|
public void visit(ObjectConstructor objectConstructor)
|
403
|
{
|
404
|
final OoActionSystemInstance instance = objectConstructor.GetNextInstance();
|
405
|
CadpType.EmitType(instance.Type);
|
406
|
if (objectConstructor.instances().size() == 1)
|
407
|
{
|
408
|
m_emitter.Append(String.format("%1$s", instance.Name));
|
409
|
}
|
410
|
else
|
411
|
{
|
412
|
final String helpername = String.format("obj_constr_%1$s", OoaCADPVisitor.getUIntHashCode(objectConstructor));
|
413
|
m_emitter.Append(String.format("%1$s()", helpername));
|
414
|
|
415
|
|
416
|
|
417
|
final OoasCodeEmitter helper = new OoasCodeEmitter();
|
418
|
helper.AppendLine(String.format("int %1$s_counter = 0;", helpername));
|
419
|
m_resetCode.AppendLine(String.format("%1$s_counter = 0;", helpername));
|
420
|
helper.AppendLine(String.format("%1$s %2$s(){", CadpType.DumpType(objectConstructor.type()), helpername));
|
421
|
int i = 0;
|
422
|
for (final OoActionSystemInstance x : objectConstructor.instances())
|
423
|
{
|
424
|
CadpType.EmitType(x.Type);
|
425
|
helper.AppendLine(String.format("if (%1$s_counter == %2$s) {%1$s_counter++; return %3$s;}",
|
426
|
helpername, i, x.Name));
|
427
|
i++;
|
428
|
}
|
429
|
helper.AppendLine(String.format("fprintf(stderr,\"constructor called too often: %1$s\"); exit(1);", helpername));
|
430
|
helper.Append("}");
|
431
|
m_helperCode.AppendLine(helper.toString());
|
432
|
}
|
433
|
}
|
434
|
|
435
|
|
436
|
@Override
|
437
|
public void visit(AccessExpression accessExpression)
|
438
|
{
|
439
|
|
440
|
if (accessExpression.left().kind() == ExpressionKind.Type &&
|
441
|
((TypeExpression)accessExpression.left()).type().kind() == TypeKind.EnumeratedType )
|
442
|
{
|
443
|
accessExpression.right().Accept(this);
|
444
|
return;
|
445
|
}
|
446
|
|
447
|
|
448
|
|
449
|
if (accessExpression.left().kind() == ExpressionKind.Identifier &&
|
450
|
((IdentifierExpression)accessExpression.left()).isSelf())
|
451
|
{
|
452
|
if (accessExpression.right().kind() != ExpressionKind.Identifier ||
|
453
|
((IdentifierExpression)accessExpression.right()).identifier().kind() != IdentifierKind.MethodIdentifier)
|
454
|
{
|
455
|
accessExpression.right().Accept(this);
|
456
|
return;
|
457
|
}
|
458
|
}
|
459
|
|
460
|
accessExpression.left().Accept(this);
|
461
|
m_emitter.Append(".");
|
462
|
|
463
|
if (((IdentifierExpression)accessExpression.right()).identifier().kind() == IdentifierKind.MethodIdentifier ||
|
464
|
((IdentifierExpression)accessExpression.right()).identifier().kind() == IdentifierKind.NamedActionIdentifier)
|
465
|
m_emitter.Append("methods->");
|
466
|
accessExpression.right().Accept(this);
|
467
|
}
|
468
|
|
469
|
|
470
|
OoasCodeEmitter varDecl = new OoasCodeEmitter();
|
471
|
HashSet<Identifier> emittedVariabes = new HashSet<Identifier>();
|
472
|
|
473
|
public void addEmittedVariables(HashSet<Identifier> elementsToAdd)
|
474
|
{
|
475
|
emittedVariabes.addAll(elementsToAdd);
|
476
|
}
|
477
|
|
478
|
private void EmitMatcher(TupleConstructor tupleConstructor, Expression expression)
|
479
|
{
|
480
|
final OoasCodeEmitter tmp = m_emitter;
|
481
|
|
482
|
m_emitter = new OoasCodeEmitter();
|
483
|
expression.Accept(this);
|
484
|
final OoasCodeEmitter expr = m_emitter;
|
485
|
m_emitter = tmp;
|
486
|
|
487
|
|
488
|
final Iterator<Type> elem = ((TupleType)tupleConstructor.type()).innerTypes().iterator();
|
489
|
int i = 0;
|
490
|
m_emitter.Append("(");
|
491
|
while (elem.hasNext())
|
492
|
{
|
493
|
final Expression var = tupleConstructor.values().get(i);
|
494
|
|
495
|
if (i != 0)
|
496
|
m_emitter.Append(" , ");
|
497
|
|
498
|
var.Accept(this);
|
499
|
m_emitter.Append(String.format(" = (%1$s).elem_%2$s ", expr.toString(), i));
|
500
|
|
501
|
i++;
|
502
|
}
|
503
|
m_emitter.Append(", 1==1)");
|
504
|
}
|
505
|
|
506
|
private void EmitDefaultBinaryOperator(BinaryOperator binaryOperator)
|
507
|
{
|
508
|
m_emitter.Append("(");
|
509
|
VisitSub(binaryOperator.left(), binaryOperator);
|
510
|
m_emitter.Append(") ");
|
511
|
m_emitter.Append(OperatorString(binaryOperator));
|
512
|
m_emitter.Append(" (");
|
513
|
VisitSub(binaryOperator.right(), binaryOperator);
|
514
|
m_emitter.Append(")");
|
515
|
}
|
516
|
|
517
|
@Override
|
518
|
public void visit(BinaryOperator binaryOperator)
|
519
|
{
|
520
|
switch (binaryOperator.kind())
|
521
|
{
|
522
|
case equal:
|
523
|
|
524
|
if (binaryOperator.left().kind() == ExpressionKind.TupleConstr &&
|
525
|
((TupleConstructor)binaryOperator.left()).isMatcher())
|
526
|
{
|
527
|
EmitMatcher((TupleConstructor)binaryOperator.left(), binaryOperator.right());
|
528
|
}
|
529
|
else if (binaryOperator.right().kind() == ExpressionKind.TupleConstr &&
|
530
|
((TupleConstructor)binaryOperator.right()).isMatcher())
|
531
|
{
|
532
|
EmitMatcher((TupleConstructor)binaryOperator.right(), binaryOperator.left());
|
533
|
}
|
534
|
else if (!CadpType.IsNumeric(binaryOperator.left().type()))
|
535
|
{
|
536
|
m_emitter.Append("0 == ");
|
537
|
EmitComplexEqual(binaryOperator);
|
538
|
}
|
539
|
else
|
540
|
EmitDefaultBinaryOperator(binaryOperator);
|
541
|
break;
|
542
|
case notequal:
|
543
|
if (!CadpType.IsNumeric(binaryOperator.left().type()))
|
544
|
{
|
545
|
m_emitter.Append("0 != ");
|
546
|
EmitComplexEqual(binaryOperator);
|
547
|
}
|
548
|
else
|
549
|
EmitDefaultBinaryOperator(binaryOperator);
|
550
|
break;
|
551
|
case conc:
|
552
|
final String conc = EmitConcOperation(binaryOperator);
|
553
|
m_emitter.Append(String.format("%1$s(", conc));
|
554
|
VisitSub(binaryOperator.left(), binaryOperator);
|
555
|
m_emitter.Append(",");
|
556
|
VisitSub(binaryOperator.right(), binaryOperator);
|
557
|
m_emitter.Append(")");
|
558
|
break;
|
559
|
case implies:
|
560
|
m_emitter.Append("!(");
|
561
|
VisitSub(binaryOperator.left(), binaryOperator);
|
562
|
m_emitter.Append(") || (");
|
563
|
VisitSub(binaryOperator.right(), binaryOperator);
|
564
|
m_emitter.Append(")");
|
565
|
break;
|
566
|
case elemin:
|
567
|
EmitInOperator(binaryOperator);
|
568
|
break;
|
569
|
case notelemin:
|
570
|
EmitNotInOperator(binaryOperator);
|
571
|
break;
|
572
|
case diff:
|
573
|
final String diff = EmitSetDifference(binaryOperator);
|
574
|
m_emitter.Append(String.format("%1$s(", diff));
|
575
|
VisitSub(binaryOperator.left(), binaryOperator);
|
576
|
m_emitter.Append(",");
|
577
|
VisitSub(binaryOperator.right(), binaryOperator);
|
578
|
m_emitter.Append(")");
|
579
|
break;
|
580
|
default:
|
581
|
EmitDefaultBinaryOperator(binaryOperator);
|
582
|
break;
|
583
|
}
|
584
|
}
|
585
|
|
586
|
private String EmitSetDifference(BinaryOperator binaryOperator)
|
587
|
{
|
588
|
final String childBTypeName = CadpIdentifier.GetIdentifierString(binaryOperator.right().type().identifier());
|
589
|
final String childATypeName = CadpIdentifier.GetIdentifierString(binaryOperator.left().type().identifier());
|
590
|
final String result = String.format("op_listdiff_%1$s_%2$s", childATypeName, childBTypeName);
|
591
|
if (emittedOperations.contains(result))
|
592
|
return result;
|
593
|
|
594
|
CadpType.EmitType(binaryOperator.type());
|
595
|
final ListType alist = (ListType)binaryOperator.type();
|
596
|
final Type innerType = alist.innerType();
|
597
|
final String resultTypeName = CadpIdentifier.GetIdentifierString(binaryOperator.type().identifier());
|
598
|
|
599
|
m_helperCode.AppendLine(String.format("%4$s %3$s(%1$s listA, %2$s listB){", childATypeName, childBTypeName, result, resultTypeName));
|
600
|
m_helperCode.AppendLine(String.format("%1$s result;", resultTypeName));
|
601
|
m_helperCode.AppendLine(String.format("int len = 0; int i; int j;"));
|
602
|
|
603
|
m_helperCode.AppendLine(String.format("for (i = 0; i < listA.length; i++) {"));
|
604
|
m_helperCode.AppendLine(String.format("for (j = 0; j < listB.length; j++) {"));
|
605
|
m_helperCode.AppendLine(String.format("if (memcmp(&listA.elements[i],&listB.elements[j],sizeof(%1$s))==0)", CadpType.DumpType(innerType)));
|
606
|
m_helperCode.AppendLine("goto NotCopy;");
|
607
|
m_helperCode.AppendLine("}");
|
608
|
m_helperCode.AppendLine(String.format("memcpy(&result.elements[len],&listA.elements[i],sizeof(%1$s));", CadpType.DumpType(innerType)));
|
609
|
m_helperCode.AppendLine("len++;");
|
610
|
m_helperCode.AppendLine("NotCopy:");
|
611
|
m_helperCode.AppendLine("len = len;");
|
612
|
m_helperCode.AppendLine("}");
|
613
|
m_helperCode.AppendLine("result.length = len;");
|
614
|
|
615
|
|
616
|
m_helperCode.AppendLine(String.format("int counter;"));
|
617
|
m_helperCode.AppendLine(String.format("for (counter = %1$s; counter >= result.length; counter--) {", ((ListType)binaryOperator.type()).maxNumberOfElements() - 1));
|
618
|
m_helperCode.AppendLine(String.format("result.elements[counter] = %1$s%2$s(%3$s%2$s());}",
|
619
|
CadpType.enumString, CadpIdentifier.GetIdentifierString(alist.innerType().identifier()), CadpType.lowString));
|
620
|
|
621
|
m_helperCode.AppendLine("return result; }");
|
622
|
|
623
|
emittedOperations.add(result);
|
624
|
return result;
|
625
|
}
|
626
|
|
627
|
private void EmitInOperator(BinaryOperator binop)
|
628
|
{
|
629
|
m_emitter.Append(String.format("0 != setin_%1$s(", OoaCADPVisitor.getUIntHashCode(binop)));
|
630
|
VisitSub(binop.left(), binop);
|
631
|
m_emitter.Append(",");
|
632
|
VisitSub(binop.right(), binop);
|
633
|
m_emitter.Append(")");
|
634
|
|
635
|
CadpType.EmitType(binop.left().type());
|
636
|
CadpType.EmitType(binop.right().type());
|
637
|
final OoasCodeEmitter helper = new OoasCodeEmitter();
|
638
|
helper.Append(String.format("int setin_%1$s(", OoaCADPVisitor.getUIntHashCode(binop)));
|
639
|
helper.AppendLine(String.format("%1$s arg1, %2$s arg2){", CadpType.DumpType(binop.left().type()), CadpType.DumpType(binop.right().type())));
|
640
|
helper.AppendLine("int __counter;");
|
641
|
helper.AppendLine(String.format("for (__counter = 0; __counter < arg2.length; __counter++)"));
|
642
|
helper.AppendLine(String.format("if (memcmp(&arg1,&(arg2.elements[__counter]),sizeof(%1$s))==0) return 1;", CadpType.DumpType(binop.left().type())));
|
643
|
helper.AppendLine("return 0;}");
|
644
|
m_helperCode.Append(helper.toString());
|
645
|
}
|
646
|
|
647
|
|
648
|
private void EmitNotInOperator(BinaryOperator binop)
|
649
|
{
|
650
|
m_emitter.Append(String.format("0 == setin_%1$s(", OoaCADPVisitor.getUIntHashCode(binop)));
|
651
|
VisitSub(binop.left(), binop);
|
652
|
m_emitter.Append(",");
|
653
|
VisitSub(binop.right(), binop);
|
654
|
m_emitter.Append(")");
|
655
|
|
656
|
CadpType.EmitType(binop.left().type());
|
657
|
CadpType.EmitType(binop.right().type());
|
658
|
final OoasCodeEmitter helper = new OoasCodeEmitter();
|
659
|
helper.Append(String.format("int setin_%1$s(", OoaCADPVisitor.getUIntHashCode(binop)));
|
660
|
helper.AppendLine(String.format("%1$s arg1, %2$s arg2){", CadpType.DumpType(binop.left().type()), CadpType.DumpType(binop.right().type())));
|
661
|
helper.AppendLine("int __counter;");
|
662
|
helper.AppendLine(String.format("for (__counter = 0; __counter < arg2.length; __counter++)"));
|
663
|
helper.AppendLine(String.format("if (memcmp(&arg1,&(arg2.elements[__counter]),sizeof(%1$s))==0) return 1;", CadpType.DumpType(binop.left().type())));
|
664
|
helper.AppendLine("return 0;}");
|
665
|
m_helperCode.Append(helper.toString());
|
666
|
}
|
667
|
|
668
|
|
669
|
|
670
|
private void EmitComplexEqual(BinaryOperator binop)
|
671
|
{
|
672
|
m_emitter.Append(String.format("complex_equal_%1$s(", OoaCADPVisitor.getUIntHashCode(binop)));
|
673
|
VisitSub(binop.left(), binop);
|
674
|
m_emitter.Append(",");
|
675
|
VisitSub(binop.right(), binop);
|
676
|
m_emitter.Append(")");
|
677
|
|
678
|
CadpType.EmitType(binop.left().type());
|
679
|
CadpType.EmitType(binop.right().type());
|
680
|
final OoasCodeEmitter helper = new OoasCodeEmitter();
|
681
|
helper.Append(String.format("int complex_equal_%1$s(", OoaCADPVisitor.getUIntHashCode(binop)));
|
682
|
helper.AppendLine(String.format("%1$s arg1, %2$s arg2){", CadpType.DumpType(binop.left().type()), CadpType.DumpType(binop.right().type())));
|
683
|
helper.AppendLine(String.format("return memcmp(&arg1, &arg2, sizeof(%1$s));}", CadpIdentifier.GetIdentifierString(binop.left().type().identifier())));
|
684
|
m_helperCode.Append(helper.toString());
|
685
|
}
|
686
|
|
687
|
private String EmitConcOperation(BinaryOperator binaryOperator)
|
688
|
{
|
689
|
final String childBTypeName = CadpIdentifier.GetIdentifierString(binaryOperator.right().type().identifier());
|
690
|
final String childATypeName = CadpIdentifier.GetIdentifierString(binaryOperator.left().type().identifier());
|
691
|
final String result = String.format("op_conc_%1$s_%2$s", childATypeName, childBTypeName);
|
692
|
if (emittedOperations.contains(result))
|
693
|
return result;
|
694
|
|
695
|
CadpType.EmitType(binaryOperator.type());
|
696
|
final ListType alist = (ListType)binaryOperator.type();
|
697
|
final Type innerType = alist.innerType();
|
698
|
final String resultTypeName = CadpIdentifier.GetIdentifierString(binaryOperator.type().identifier());
|
699
|
|
700
|
m_helperCode.AppendLine(String.format("%4$s %3$s(%1$s listA, %2$s listB){", childATypeName, childBTypeName, result, resultTypeName));
|
701
|
m_helperCode.AppendLine(String.format("%1$s result;", resultTypeName));
|
702
|
m_helperCode.AppendLine(String.format("result.length = listA.length + listB.length;"));
|
703
|
|
704
|
m_helperCode.AppendLine(String.format("if (result.length > %1$s) { printf(\"Concatenation result too long! %2$s\\n\"); abort();}", alist.maxNumberOfElements(), result));
|
705
|
m_helperCode.AppendLine(String.format("memcpy(&result.elements[0],&listA.elements[0],listA.length * sizeof(%1$s));", CadpType.DumpType(innerType)));
|
706
|
m_helperCode.AppendLine(String.format("memcpy(&result.elements[listA.length],&listB.elements[0],listB.length * sizeof(%1$s));", CadpType.DumpType(innerType)));
|
707
|
m_helperCode.AppendLine(String.format("int counter;"));
|
708
|
m_helperCode.AppendLine(String.format("for (counter = %1$s; counter >= (listA.length + listB.length); counter--) {", alist.maxNumberOfElements() - 1));
|
709
|
m_helperCode.AppendLine(String.format("result.elements[counter] = %1$s%2$s(%3$s%2$s());}",
|
710
|
CadpType.enumString, CadpIdentifier.GetIdentifierString(alist.innerType().identifier()), CadpType.lowString));
|
711
|
m_helperCode.AppendLine("return result; }");
|
712
|
|
713
|
emittedOperations.add(result);
|
714
|
return result;
|
715
|
}
|
716
|
|
717
|
@Override
|
718
|
public void visit(TernaryOperator ternaryOperator)
|
719
|
{
|
720
|
if (ternaryOperator.kind() == ExpressionKind.conditional)
|
721
|
{
|
722
|
m_emitter.Append("(");
|
723
|
VisitSub(ternaryOperator.left(), ternaryOperator);
|
724
|
m_emitter.Append(" ? ");
|
725
|
|
726
|
VisitSub(ternaryOperator.mid(), ternaryOperator);
|
727
|
m_emitter.Append(" : ");
|
728
|
|
729
|
VisitSub(ternaryOperator.right(), ternaryOperator);
|
730
|
m_emitter.Append(")");
|
731
|
}
|
732
|
else if (ternaryOperator.kind() == ExpressionKind.foldLR ||
|
733
|
ternaryOperator.kind() == ExpressionKind.foldRL)
|
734
|
{
|
735
|
final CallExpression leftcall = (CallExpression)ternaryOperator.left();
|
736
|
final Expression initializer = ternaryOperator.mid();
|
737
|
final Expression listgetter = ternaryOperator.right();
|
738
|
|
739
|
m_emitter.Append(String.format("fold_%1$s(%2$s", OoaCADPVisitor.getUIntHashCode(ternaryOperator), m_procInfo.stateVariableString));
|
740
|
|
741
|
|
742
|
final CadpExpression cadpexpr = new CadpExpression(m_procInfo, emittedVariabes);
|
743
|
leftcall.child().Accept(cadpexpr);
|
744
|
final List<String> paramtypes = new ArrayList<String>();
|
745
|
final List<String> parameters = new ArrayList<String>();
|
746
|
for (int i = 0; i < leftcall.arguments().size() - 2; i++)
|
747
|
{
|
748
|
final Expression arg = leftcall.arguments().get(i);
|
749
|
final CadpExpression paramexpr = new CadpExpression(m_procInfo, emittedVariabes);
|
750
|
arg.Accept(paramexpr);
|
751
|
m_emitter.Append(",");
|
752
|
m_emitter.Append(paramexpr.toString());
|
753
|
}
|
754
|
|
755
|
final FunctionType fun = (FunctionType)leftcall.child().type();
|
756
|
final FunctionIdentifier funid = (FunctionIdentifier) fun.identifier();
|
757
|
final Iterator<Type> node = fun.parameter().iterator();
|
758
|
for (int i = 0; i < fun.parameter().size() - 2; i++)
|
759
|
{
|
760
|
final Type nodeValue = node.next();
|
761
|
paramtypes.add(CadpType.DumpType(nodeValue));
|
762
|
final CadpIdentifier paramid = new CadpIdentifier(m_procInfo.stateVariableString);
|
763
|
funid.parameter().get(i).Accept(paramid);
|
764
|
parameters.add(paramid.toString());
|
765
|
}
|
766
|
|
767
|
m_emitter.Append(")");
|
768
|
|
769
|
|
770
|
CadpType.EmitType(initializer.type());
|
771
|
CadpType.EmitType(listgetter.type());
|
772
|
final ListType thelist = (ListType)listgetter.type();
|
773
|
CadpType.EmitType(thelist.innerType());
|
774
|
final OoasCodeEmitter helper = new OoasCodeEmitter();
|
775
|
helper.Append(String.format("%2$s fold_%1$s(CAESAR_TYPE_STATE oldState", OoaCADPVisitor.getUIntHashCode(ternaryOperator), CadpType.DumpType(leftcall.type())));
|
776
|
if (paramtypes.size() > 0)
|
777
|
{
|
778
|
for (int i = 0; i < paramtypes.size(); i++)
|
779
|
{
|
780
|
helper.Append(",");
|
781
|
helper.Append(paramtypes.get(i));
|
782
|
helper.Append(" ");
|
783
|
helper.Append(parameters.get(i));
|
784
|
}
|
785
|
}
|
786
|
helper.AppendLine("){");
|
787
|
|
788
|
helper.AppendLine(String.format("int __iterator;"));
|
789
|
helper.AppendLine(String.format("%1$s param__result;", CadpType.DumpType(leftcall.type())));
|
790
|
helper.AppendLine(String.format("%1$s __thelist;", CadpType.DumpType(listgetter.type())));
|
791
|
helper.AppendLine(String.format("%1$s param__elem;", CadpType.DumpType(thelist.innerType())));
|
792
|
|
793
|
final CadpActionInfo actionInfo = new CadpActionInfo(m_procInfo.action, -1, 0, m_procInfo.toDoListString, m_procInfo.doneListString, "oldState");
|
794
|
|
795
|
final CadpExpression initvizcode = new CadpExpression(actionInfo, emittedVariabes);
|
796
|
initializer.Accept(initvizcode);
|
797
|
helper.AppendLine(initvizcode.VariableDeclarations());
|
798
|
helper.AppendLine(String.format("param__result = %1$s;", initvizcode.toString()));
|
799
|
|
800
|
final CadpExpression listgettercode = new CadpExpression(actionInfo, emittedVariabes);
|
801
|
listgetter.Accept(listgettercode);
|
802
|
helper.AppendLine(listgettercode.VariableDeclarations());
|
803
|
helper.AppendLine(String.format("__thelist = %1$s;", listgettercode.toString()));
|
804
|
|
805
|
final CadpExpression filtercall = new CadpExpression(actionInfo, emittedVariabes);
|
806
|
leftcall.Accept(filtercall);
|
807
|
helper.AppendLine(filtercall.VariableDeclarations());
|
808
|
|
809
|
if (ternaryOperator.kind() == ExpressionKind.foldLR)
|
810
|
helper.AppendLine(String.format("for (__iterator = 0; __iterator < __thelist.length; __iterator++) {"));
|
811
|
else
|
812
|
helper.AppendLine(String.format("for (__iterator = __thelist.length - 1; __iterator >= 0; __iterator--) {"));
|
813
|
|
814
|
helper.AppendLine(String.format("param__elem = __thelist.elements[__iterator];"));
|
815
|
helper.AppendLine(String.format("param__result = %1$s;", filtercall.toString()));
|
816
|
|
817
|
|
818
|
helper.AppendLine("}");
|
819
|
helper.AppendLine("return param__result;}");
|
820
|
m_helperCode.Append(helper.toString());
|
821
|
}
|
822
|
else
|
823
|
throw new UnsupportedOperationException();
|
824
|
}
|
825
|
|
826
|
@Override
|
827
|
public void visit(TupleMapAccessExpression tupleMapAccessExpression)
|
828
|
{
|
829
|
VisitSub(tupleMapAccessExpression.child(), tupleMapAccessExpression);
|
830
|
if (tupleMapAccessExpression.child().type().kind() == TypeKind.TupleType)
|
831
|
{
|
832
|
|
833
|
@SuppressWarnings("unchecked")
|
834
|
final ValueExpression<Integer> accessValue = (ValueExpression<Integer>)tupleMapAccessExpression.argument();
|
835
|
m_emitter.Append(String.format(".elem_%1$s", accessValue.value()));
|
836
|
}
|
837
|
else if (tupleMapAccessExpression.child().type().kind() == TypeKind.ListType)
|
838
|
{
|
839
|
m_emitter.Append(".elements[");
|
840
|
VisitSub(tupleMapAccessExpression.argument(), tupleMapAccessExpression);
|
841
|
m_emitter.Append("]");
|
842
|
}
|
843
|
else
|
844
|
throw new UnsupportedOperationException();
|
845
|
}
|
846
|
@Override
|
847
|
public void visit(CallExpression callExpression)
|
848
|
{
|
849
|
|
850
|
|
851
|
|
852
|
|
853
|
|
854
|
final FunctionType funtype = (FunctionType)callExpression.child().type();
|
855
|
if (funtype.returnType() == null)
|
856
|
throw new IllegalArgumentException("Internal error: Function call in expression with return-type void!");
|
857
|
|
858
|
|
859
|
final String tmpresult = String.format("detcallresult_%1$s", OoaCADPVisitor.getUIntHashCode(callExpression));
|
860
|
final String tmpaftercallstates = String.format("callresult_%1$s", OoaCADPVisitor.getUIntHashCode(callExpression));
|
861
|
|
862
|
varDecl.AppendLine(String.format("%1$s %2$s;", CadpType.DumpType(funtype.returnType()), tmpresult));
|
863
|
varDecl.AppendLine(String.format("struct STATE_LIST * %1$s;", tmpaftercallstates));
|
864
|
|
865
|
final CadpExpression cadpexpr = new CadpExpression(m_procInfo, emittedVariabes);
|
866
|
callExpression.child().Accept(cadpexpr);
|
867
|
final String callstatement = cadpexpr.toString();
|
868
|
varDecl.Append(cadpexpr.VariableDeclarations());
|
869
|
m_usedIdentifier.addAll(cadpexpr.usedIdentifiers());
|
870
|
final StringBuilder parameter = new StringBuilder(m_procInfo.stateVariableString);
|
871
|
for (final Expression arg : callExpression.arguments())
|
872
|
{
|
873
|
parameter.append(", ");
|
874
|
final CadpExpression paramexpr = new CadpExpression(m_procInfo, emittedVariabes);
|
875
|
arg.Accept(paramexpr);
|
876
|
parameter.append(paramexpr.toString());
|
877
|
}
|
878
|
parameter.append(String.format(", &(%1$s)", tmpresult));
|
879
|
|
880
|
m_emitter.Append("(");
|
881
|
m_emitter.Append(String.format("%3$s = %1$s(%2$s)", callstatement, parameter, tmpaftercallstates));
|
882
|
m_emitter.Append(",");
|
883
|
m_emitter.Append(String.format(" CALC_INVALID = %1$s == NULL ? (fprintf(stderr,\"call to %2$s returns NULL!\\n\"), 1) : (%1$s->next == NULL ? CALC_INVALID : (fprintf(stderr,\"call to %2$s non-deterministic!\\n\"), 1))", tmpaftercallstates, callstatement.replaceAll("\"", "'")));
|
884
|
if (!funtype.isPureFunction())
|
885
|
{
|
886
|
m_emitter.Append(",");
|
887
|
m_emitter.Append(String.format(" elem = %1$s == NULL ? elem : (list_insert_list(%2$s, %1$s),%1$s)", tmpaftercallstates, m_procInfo.doneListString));
|
888
|
}
|
889
|
m_emitter.Append(",");
|
890
|
m_emitter.Append(String.format("%1$s", tmpresult));
|
891
|
m_emitter.Append(")");
|
892
|
}
|
893
|
|
894
|
|
895
|
private interface IFilter<T> {
|
896
|
boolean apply (T input);
|
897
|
}
|
898
|
|
899
|
private static <T> void removeAll(List<T> list, IFilter<T> filter) {
|
900
|
int max;
|
901
|
for (max = list.size() - 1; max >= 0; max --) {
|
902
|
if (filter.apply(list.get(max)))
|
903
|
list.remove(max);
|
904
|
}
|
905
|
}
|
906
|
|
907
|
private List<Identifier> getListOfAccessedIdentifiers(CadpExpression child, final SymbolTable currentScopeSymbols)
|
908
|
{
|
909
|
final List<Identifier> importVars = new ArrayList<Identifier>(child.usedIdentifiers());
|
910
|
if (currentScopeSymbols != null)
|
911
|
removeAll(importVars, new IFilter<Identifier>(){
|
912
|
@Override
|
913
|
public boolean apply(Identifier input) {
|
914
|
return currentScopeSymbols.symbolList().contains(input);
|
915
|
}});
|
916
|
|
917
|
removeAll(importVars, new IFilter<Identifier>(){
|
918
|
@Override
|
919
|
public boolean apply(Identifier input) {
|
920
|
return input.kind() == IdentifierKind.AttributeIdentifier ||
|
921
|
input.kind() == IdentifierKind.EnumIdentifier ||
|
922
|
input.kind() == IdentifierKind.MethodIdentifier ||
|
923
|
input.kind() == IdentifierKind.NamedActionIdentifier;
|
924
|
}
|
925
|
});
|
926
|
return importVars;
|
927
|
}
|
928
|
|
929
|
|
930
|
@Override
|
931
|
public void visit(ForallQuantifier quantifier)
|
932
|
{
|
933
|
final CadpActionInfo info = new CadpActionInfo(null, -1, -1, m_procInfo.toDoListString, m_procInfo.doneListString, "oldstate");
|
934
|
final CadpExpression compExpr = new CadpExpression(info, emittedVariabes);
|
935
|
quantifier.child().Accept(compExpr);
|
936
|
|
937
|
|
938
|
final List<Identifier> importVars = getListOfAccessedIdentifiers(compExpr, quantifier.symbols());
|
939
|
|
940
|
final String functionName = String.format("forall_%1$s", OoaCADPVisitor.getUIntHashCode(quantifier));
|
941
|
m_emitter.Append(String.format("1 == %1$s", functionName));
|
942
|
m_emitter.Append(String.format("( %1$s", this.m_procInfo.stateVariableString));
|
943
|
for (final Identifier x : importVars)
|
944
|
{
|
945
|
m_emitter.Append(",");
|
946
|
m_emitter.Append(String.format("%1$s", CadpIdentifier.GetIdentifierString(x)));
|
947
|
}
|
948
|
m_emitter.Append(")");
|
949
|
|
950
|
|
951
|
final OoasCodeEmitter helper = new OoasCodeEmitter();
|
952
|
helper.AppendLine(String.format("int %1$s(CAESAR_TYPE_STATE %2$s", functionName, "oldstate"));
|
953
|
for (final Identifier x : importVars)
|
954
|
{
|
955
|
helper.Append(", ");
|
956
|
helper.Append(String.format("%1$s %2$s", CadpType.DumpType(x.type()), CadpIdentifier.GetIdentifierString(x)));
|
957
|
}
|
958
|
helper.AppendLine("){");
|
959
|
|
960
|
helper.AppendLine(compExpr.VariableDeclarations());
|
961
|
|
962
|
int loops = 0;
|
963
|
for (final Identifier enumvar : quantifier.symbols().symbolList())
|
964
|
{
|
965
|
CadpType.EmitType(enumvar.type());
|
966
|
helper.AppendLine(String.format("long long iterator_%1$s;", CadpIdentifier.GetIdentifierString(enumvar)));
|
967
|
helper.AppendLine(String.format("for (iterator_%1$s = %2$s; iterator_%1$s <= %3$s; iterator_%1$s++) {",
|
968
|
CadpIdentifier.GetIdentifierString(enumvar), CadpType.GetMinVal(enumvar.type()), CadpType.GetMaxVal(enumvar.type())));
|
969
|
helper.AppendLine(String.format("/*%1$s*/ %2$s = %3$s(iterator_%2$s);",
|
970
|
CadpType.DumpType(enumvar.type()), CadpIdentifier.GetIdentifierString(enumvar), CadpType.GetEnumVal(enumvar.type())));
|
971
|
if (enumvar.type().kind() == TypeKind.OoActionSystemType)
|
972
|
{
|
973
|
|
974
|
helper.AppendLine(String.format("if (memcmp(&%1$s, &%2$s, sizeof(%3$s)) == 0) continue;",
|
975
|
CadpIdentifier.GetIdentifierString(enumvar), CadpType.GetNullConstant((OoActionSystemType)enumvar.type()), CadpType.DumpType(enumvar.type())));
|
976
|
}
|
977
|
loops++;
|
978
|
}
|
979
|
|
980
|
helper.AppendLine(String.format("if (!("));
|
981
|
helper.AppendLine(compExpr.toString());
|
982
|
helper.AppendLine(String.format(") ) return 0;"));
|
983
|
|
984
|
|
985
|
while (loops > 0)
|
986
|
{
|
987
|
helper.AppendLine("}");
|
988
|
loops--;
|
989
|
}
|
990
|
helper.AppendLine("return 1; }");
|
991
|
|
992
|
m_helperCode.Append(helper.toString());
|
993
|
}
|
994
|
|
995
|
@Override
|
996
|
public void visit(ExistsQuantifier quantifier)
|
997
|
{
|
998
|
final CadpActionInfo info = new CadpActionInfo(null, -1, -1, m_procInfo.toDoListString, m_procInfo.doneListString, "oldstate");
|
999
|
final CadpExpression compExpr = new CadpExpression(info, emittedVariabes);
|
1000
|
quantifier.child().Accept(compExpr);
|
1001
|
|
1002
|
|
1003
|
final List<Identifier> importVars = getListOfAccessedIdentifiers(compExpr, quantifier.symbols());
|
1004
|
|
1005
|
final String functionName = String.format("exists_%1$s", OoaCADPVisitor.getUIntHashCode(quantifier));
|
1006
|
m_emitter.Append(String.format("1 == %1$s", functionName));
|
1007
|
m_emitter.Append(String.format("( %1$s", this.m_procInfo.stateVariableString));
|
1008
|
for (final Identifier x : importVars)
|
1009
|
{
|
1010
|
m_emitter.Append(",");
|
1011
|
m_emitter.Append(String.format("%1$s", CadpIdentifier.GetIdentifierString(x)));
|
1012
|
}
|
1013
|
m_emitter.Append(")");
|
1014
|
|
1015
|
|
1016
|
final OoasCodeEmitter helper = new OoasCodeEmitter();
|
1017
|
helper.Append(String.format("int %1$s(CAESAR_TYPE_STATE %2$s", functionName, "oldstate"));
|
1018
|
for (final Identifier x : importVars)
|
1019
|
{
|
1020
|
helper.Append(", ");
|
1021
|
helper.Append(String.format("%1$s %2$s", CadpType.DumpType(x.type()), CadpIdentifier.GetIdentifierString(x)));
|
1022
|
}
|
1023
|
helper.AppendLine("){");
|
1024
|
|
1025
|
helper.AppendLine(compExpr.VariableDeclarations());
|
1026
|
|
1027
|
int loops = 0;
|
1028
|
for (final Identifier enumvar : quantifier.symbols().symbolList())
|
1029
|
{
|
1030
|
CadpType.EmitType(enumvar.type());
|
1031
|
helper.AppendLine(String.format("long long iterator_%1$s;", CadpIdentifier.GetIdentifierString(enumvar)));
|
1032
|
helper.AppendLine(String.format("for (iterator_%1$s = %2$s; iterator_%1$s <= %3$s; iterator_%1$s++) {",
|
1033
|
CadpIdentifier.GetIdentifierString(enumvar), CadpType.GetMinVal(enumvar.type()), CadpType.GetMaxVal(enumvar.type())));
|
1034
|
helper.AppendLine(String.format("/*%1$s*/ %2$s = %3$s(iterator_%2$s);",
|
1035
|
CadpType.DumpType(enumvar.type()), CadpIdentifier.GetIdentifierString(enumvar), CadpType.GetEnumVal(enumvar.type())));
|
1036
|
if (enumvar.type().kind() == TypeKind.OoActionSystemType)
|
1037
|
{
|
1038
|
|
1039
|
helper.AppendLine(String.format("if (memcmp(&%1$s, &%2$s, sizeof(%3$s)) == 0) continue;",
|
1040
|
CadpIdentifier.GetIdentifierString(enumvar), CadpType.GetNullConstant((OoActionSystemType)enumvar.type()), CadpType.DumpType(enumvar.type())));
|
1041
|
}
|
1042
|
loops++;
|
1043
|
}
|
1044
|
|
1045
|
helper.AppendLine(String.format("if (("));
|
1046
|
helper.AppendLine(compExpr.toString());
|
1047
|
helper.AppendLine(String.format(") ) return 1;"));
|
1048
|
|
1049
|
|
1050
|
while (loops > 0)
|
1051
|
{
|
1052
|
helper.AppendLine("}");
|
1053
|
loops--;
|
1054
|
}
|
1055
|
helper.AppendLine("return 0; }");
|
1056
|
|
1057
|
m_helperCode.Append(helper.toString());
|
1058
|
}
|
1059
|
|
1060
|
private static final class RefBool {
|
1061
|
boolean value = false;
|
1062
|
}
|
1063
|
|
1064
|
@Override
|
1065
|
public void visit(UnaryOperator unaryOperator)
|
1066
|
{
|
1067
|
switch (unaryOperator.kind())
|
1068
|
{
|
1069
|
case tail:
|
1070
|
final String tail = EmitTailOperation(unaryOperator);
|
1071
|
m_emitter.Append(String.format("%1$s(", tail));
|
1072
|
VisitSub(unaryOperator.child(), unaryOperator);
|
1073
|
m_emitter.Append(")");
|
1074
|
break;
|
1075
|
case head:
|
1076
|
m_emitter.Append("(");
|
1077
|
VisitSub(unaryOperator.child(), unaryOperator);
|
1078
|
m_emitter.Append(String.format(").elements[0]"));
|
1079
|
break;
|
1080
|
case len:
|
1081
|
m_emitter.Append("(");
|
1082
|
VisitSub(unaryOperator.child(), unaryOperator);
|
1083
|
m_emitter.Append(String.format(").length"));
|
1084
|
break;
|
1085
|
case Cast:
|
1086
|
m_emitter.Append("/*cast*/");
|
1087
|
final RefBool doSub = new RefBool();
|
1088
|
final String cast = EmitCastOperation(unaryOperator, doSub);
|
1089
|
if (doSub.value)
|
1090
|
{
|
1091
|
m_emitter.Append(String.format("(%1$s(", cast));
|
1092
|
VisitSub(unaryOperator.child(), unaryOperator);
|
1093
|
m_emitter.Append("))");
|
1094
|
}
|
1095
|
break;
|
1096
|
default:
|
1097
|
m_emitter.Append(" ");
|
1098
|
m_emitter.Append(OperatorString(unaryOperator));
|
1099
|
m_emitter.Append("(");
|
1100
|
VisitSub(unaryOperator.child(), unaryOperator);
|
1101
|
m_emitter.Append(")");
|
1102
|
break;
|
1103
|
}
|
1104
|
}
|
1105
|
|
1106
|
|
1107
|
|
1108
|
|
1109
|
private boolean CADPCastEquivalent(Type type1, Type type2)
|
1110
|
{
|
1111
|
if ((type1 == null) || (type2 == null))
|
1112
|
return false;
|
1113
|
|
1114
|
final TypeKind tk1 = type1.kind();
|
1115
|
final TypeKind tk2 = type2.kind();
|
1116
|
|
1117
|
|
1118
|
if (tk1 != tk2)
|
1119
|
return false;
|
1120
|
|
1121
|
|
1122
|
switch (tk1)
|
1123
|
{
|
1124
|
case IntType:
|
1125
|
return true;
|
1126
|
case BoolType:
|
1127
|
return true;
|
1128
|
case FloatType:
|
1129
|
throw new UnsupportedOperationException();
|
1130
|
case EnumeratedType:
|
1131
|
return type1 == type2;
|
1132
|
case ListType:
|
1133
|
final ListType listt1 = (ListType)type1;
|
1134
|
final ListType listt2 = (ListType)type2;
|
1135
|
return CADPCastEquivalent(listt1.innerType(), listt2.innerType()) &&
|
1136
|
listt1.maxNumberOfElements() == listt2.maxNumberOfElements();
|
1137
|
case MapType:
|
1138
|
final MapType mapt1 = (MapType)type1;
|
1139
|
final MapType mapt2 = (MapType)type2;
|
1140
|
return CADPCastEquivalent(mapt1.fromType(), mapt2.fromType()) &&
|
1141
|
CADPCastEquivalent(mapt1.toType(), mapt2.toType()) &&
|
1142
|
mapt1.maxNumberOfElements() == mapt2.maxNumberOfElements();
|
1143
|
case TupleType:
|
1144
|
final TupleType tuplet1 = (TupleType)type1;
|
1145
|
final TupleType tuplet2 = (TupleType)type2;
|
1146
|
if (tuplet1.innerTypes().size() != tuplet2.innerTypes().size())
|
1147
|
return false;
|
1148
|
final Iterator<Type> innert1 = tuplet1.innerTypes().iterator();
|
1149
|
final Iterator<Type> innert2 = tuplet2.innerTypes().iterator();
|
1150
|
while (innert1.hasNext())
|
1151
|
{
|
1152
|
final Type innert1Value = innert1.next();
|
1153
|
final Type innert2Value = innert2.next();
|
1154
|
|
1155
|
if (!CADPCastEquivalent(innert1Value, innert2Value))
|
1156
|
return false;
|
1157
|
}
|
1158
|
return true;
|
1159
|
case OoActionSystemType:
|
1160
|
return type1 == type2 ||
|
1161
|
Type.Covariance((OoActionSystemType)type2, (OoActionSystemType)type1);
|
1162
|
case OpaqueType:
|
1163
|
throw new IllegalArgumentException();
|
1164
|
case Null:
|
1165
|
case Any:
|
1166
|
return true;
|
1167
|
default:
|
1168
|
throw new UnsupportedOperationException();
|
1169
|
}
|
1170
|
}
|
1171
|
|
1172
|
|
1173
|
private String EmitCastOperation(UnaryOperator unaryOperator, RefBool doSub)
|
1174
|
{
|
1175
|
doSub.value = true;
|
1176
|
if (unaryOperator.child().kind() == ExpressionKind.ListConstr &&
|
1177
|
((ListConstructor)unaryOperator.child()).hasComprehension())
|
1178
|
{
|
1179
|
|
1180
|
final String childTypeName = CadpIdentifier.GetIdentifierString(unaryOperator.child().type().identifier());
|
1181
|
final String resultTypeName = CadpIdentifier.GetIdentifierString(unaryOperator.type().identifier());
|
1182
|
final String result = String.format("op_cast_malloc_%1$s_%2$s", childTypeName, resultTypeName);
|
1183
|
|
1184
|
if (emittedOperations.contains(result))
|
1185
|
return result;
|
1186
|
|
1187
|
|
1188
|
CadpType.EmitType(unaryOperator.type());
|
1189
|
|
1190
|
switch (unaryOperator.type().kind())
|
1191
|
{
|
1192
|
case ListType:
|
1193
|
final ListType toType = (ListType)unaryOperator.type();
|
1194
|
final ListType fromType = (ListType)unaryOperator.child().type();
|
1195
|
final String listStruct = String.format("struct struct_list_%1$s", CadpType.DumpType(fromType.innerType()).replaceAll(" ", "_"));
|
1196
|
|
1197
|
if (!(fromType.innerType().kind() == TypeKind.Null || CADPCastEquivalent(fromType.innerType(), toType.innerType())))
|
1198
|
throw new UnsupportedOperationException(String.format("CADP Target does not support this type of cast: '%1$s' to '%2$s'", fromType.innerType().toString(), toType.innerType().toString()));
|
1199
|
m_helperCode.AppendLine(String.format("%3$s %2$s(%1$s *toCast){", listStruct, result, resultTypeName));
|
1200
|
m_helperCode.AppendLine(String.format("%1$s result;", resultTypeName));
|
1201
|
m_helperCode.AppendLine(String.format("%1$s *tmp = toCast;", listStruct));
|
1202
|
m_helperCode.AppendLine(String.format("int len = 0;"));
|
1203
|
m_helperCode.AppendLine(String.format("result.length = 0;"));
|
1204
|
|
1205
|
m_helperCode.AppendLine("while (toCast != NULL)");
|
1206
|
m_helperCode.AppendLine("{");
|
1207
|
m_helperCode.AppendLine(String.format(" if (len < %1$s)", toType.maxNumberOfElements()));
|
1208
|
m_helperCode.AppendLine(" {");
|
1209
|
m_helperCode.AppendLine(String.format("memcpy(&result.elements[len],&(toCast->element),sizeof(%1$s));", CadpType.DumpType(toType.innerType())));
|
1210
|
m_helperCode.AppendLine(String.format("result.length = len+1;"));
|
1211
|
m_helperCode.AppendLine(" }");
|
1212
|
m_helperCode.AppendLine(" else ");
|
1213
|
m_helperCode.AppendLine(" CALC_INVALID = 1;");
|
1214
|
m_helperCode.AppendLine(" len++;");
|
1215
|
m_helperCode.AppendLine(" tmp = toCast->next;");
|
1216
|
m_helperCode.AppendLine(" free(toCast);");
|
1217
|
m_helperCode.AppendLine(" toCast = tmp;");
|
1218
|
m_helperCode.AppendLine("}");
|
1219
|
m_helperCode.AppendLine(" if (CALC_INVALID == 1)");
|
1220
|
m_helperCode.AppendLine(String.format(" printf(\"\\n\\nCalculation invalid: Cast to smaller list in %1$s\\n\\n\");", result));
|
1221
|
|
1222
|
|
1223
|
m_helperCode.AppendLine(String.format("int counter;"));
|
1224
|
m_helperCode.AppendLine(String.format("for (counter = %1$s; counter >= result.length; counter--) {", toType.maxNumberOfElements() - 1));
|
1225
|
m_helperCode.AppendLine(String.format("result.elements[counter] = %1$s%2$s(%3$s%2$s());}",
|
1226
|
CadpType.enumString, CadpIdentifier.GetIdentifierString(toType.innerType().identifier()), CadpType.lowString));
|
1227
|
m_helperCode.AppendLine("return result; }");
|
1228
|
|
1229
|
|
1230
|
break;
|
1231
|
default:
|
1232
|
|
1233
|
return "";
|
1234
|
}
|
1235
|
emittedOperations.add(result);
|
1236
|
return result;
|
1237
|
|
1238
|
|
1239
|
}
|
1240
|
else
|
1241
|
{
|
1242
|
final String childTypeName = CadpIdentifier.GetIdentifierString(unaryOperator.child().type().identifier());
|
1243
|
final String resultTypeName = CadpIdentifier.GetIdentifierString(unaryOperator.type().identifier());
|
1244
|
final String result = String.format("op_cast_%1$s_%2$s", childTypeName, resultTypeName);
|
1245
|
|
1246
|
if (emittedOperations.contains(result))
|
1247
|
return result;
|
1248
|
|
1249
|
|
1250
|
CadpType.EmitType(unaryOperator.type());
|
1251
|
|
1252
|
switch (unaryOperator.type().kind())
|
1253
|
{
|
1254
|
case ListType:
|
1255
|
final ListType toType = (ListType)unaryOperator.type();
|
1256
|
final ListType fromType = (ListType)unaryOperator.child().type();
|
1257
|
if (!(fromType.innerType().kind() == TypeKind.Null || CADPCastEquivalent(fromType.innerType(), toType.innerType())))
|
1258
|
throw new UnsupportedOperationException(String.format("CADP Target does not support this type of cast: '%1$s' to '%2$s'", fromType.innerType().toString(), toType.innerType().toString()));
|
1259
|
m_helperCode.AppendLine(String.format("%3$s %2$s(%1$s toCast){", childTypeName, result, resultTypeName));
|
1260
|
m_helperCode.AppendLine(String.format("%1$s result;", resultTypeName));
|
1261
|
m_helperCode.AppendLine(String.format("if (toCast.length > %1$s) { printf(\"Cast to smaller list! %2$s\\n\"); ", toType.maxNumberOfElements(), result));
|
1262
|
m_helperCode.AppendLine(String.format("%1$s%2$s(stdout, toCast); fflush(stdout); CALC_INVALID=1; result.length = %3$s;} else", CadpType.printString, childTypeName, toType.maxNumberOfElements()));
|
1263
|
m_helperCode.AppendLine(String.format("result.length = toCast.length;"));
|
1264
|
m_helperCode.AppendLine(String.format("if (result.length > 0)"));
|
1265
|
m_helperCode.AppendLine(String.format("memcpy(result.elements,toCast.elements,result.length * sizeof(%1$s));", CadpType.DumpType(toType.innerType())));
|
1266
|
m_helperCode.AppendLine(String.format("int counter;"));
|
1267
|
m_helperCode.AppendLine(String.format("for (counter = %1$s; counter >= result.length; counter--) {", toType.maxNumberOfElements() - 1));
|
1268
|
m_helperCode.AppendLine(String.format("result.elements[counter] = %1$s%2$s(%3$s%2$s());}",
|
1269
|
CadpType.enumString, CadpIdentifier.GetIdentifierString(toType.innerType().identifier()), CadpType.lowString));
|
1270
|
m_helperCode.AppendLine("return result; }");
|
1271
|
|
1272
|
|
1273
|
break;
|
1274
|
case OoActionSystemType:
|
1275
|
if (unaryOperator.child().kind() == ExpressionKind.Value &&
|
1276
|
(unaryOperator.child() instanceof ValueExpression<?>) &&
|
1277
|
((ValueExpression<?>)unaryOperator.child()).value() == null)
|
1278
|
{
|
1279
|
m_emitter.Append(String.format("NULL_%1$s", CadpIdentifier.GetIdentifierString(unaryOperator.type().identifier())));
|
1280
|
doSub.value = false;
|
1281
|
}
|
1282
|
else
|
1283
|
{
|
1284
|
doSub.value = true;
|
1285
|
final CadpType targetType = new CadpType();
|
1286
|
unaryOperator.type().Accept(targetType);
|
1287
|
final CadpType sourceType = new CadpType();
|
1288
|
unaryOperator.child().type().Accept(sourceType);
|
1289
|
if (!(Type.Covariance((OoActionSystemType)unaryOperator.child().type(), (OoActionSystemType)unaryOperator.type())))
|
1290
|
{
|
1291
|
|
1292
|
return String.format("/* up-cast: %1$s as %2$s */ *(%2$s*)&", sourceType.ToString(), targetType.ToString());
|
1293
|
}
|
1294
|
else
|
1295
|
{
|
1296
|
return String.format(" /* down-cast: %1$s as %2$s */ *(%2$s*)&", sourceType.ToString(), targetType.ToString());
|
1297
|
}
|
1298
|
|
1299
|
}
|
1300
|
return "";
|
1301
|
default:
|
1302
|
|
1303
|
return "";
|
1304
|
}
|
1305
|
emittedOperations.add(result);
|
1306
|
return result;
|
1307
|
}
|
1308
|
}
|
1309
|
|
1310
|
private String EmitTailOperation(UnaryOperator unaryOperator)
|
1311
|
{
|
1312
|
final String childTypeName = CadpIdentifier.GetIdentifierString(unaryOperator.child().type().identifier());
|
1313
|
final String result = String.format("op_tail_%1$s", childTypeName);
|
1314
|
if (emittedOperations.contains(result))
|
1315
|
return result;
|
1316
|
|
1317
|
final ListType alist = (ListType)unaryOperator.child().type();
|
1318
|
CadpType.EmitType(unaryOperator.type());
|
1319
|
final String resultType = CadpIdentifier.GetIdentifierString(unaryOperator.type().identifier());
|
1320
|
final ListType resultList = (ListType)unaryOperator.type();
|
1321
|
|
1322
|
|
1323
|
m_helperCode.AppendLine(String.format("%3$s %2$s(%1$s toCopy){", childTypeName, result, resultType));
|
1324
|
m_helperCode.AppendLine(String.format("%1$s result;", resultType));
|
1325
|
m_helperCode.AppendLine(String.format("if (toCopy.length == 0) { printf(\"Tail from empty list! %1$s\\n\"); abort();}", childTypeName));
|
1326
|
m_helperCode.AppendLine(String.format("result.length = toCopy.length - 1;"));
|
1327
|
m_helperCode.AppendLine(String.format("if (result.length == 0)"));
|
1328
|
m_helperCode.AppendLine(String.format("memset(&result,0,sizeof(%1$s));", resultType));
|
1329
|
m_helperCode.AppendLine(String.format("else"));
|
1330
|
m_helperCode.AppendLine(String.format("memcpy(&result.elements[0],&toCopy.elements[1],result.length * sizeof(%1$s));", CadpType.DumpType(alist.innerType()), alist.maxNumberOfElements() - 1));
|
1331
|
|
1332
|
|
1333
|
m_helperCode.AppendLine(String.format("int counter;"));
|
1334
|
m_helperCode.AppendLine(String.format("for (counter = %1$s; counter >= result.length; counter--) {", resultList.maxNumberOfElements() - 1));
|
1335
|
m_helperCode.AppendLine(String.format("result.elements[counter] = %1$s%2$s(%3$s%2$s());}",
|
1336
|
CadpType.enumString, CadpIdentifier.GetIdentifierString(alist.innerType().identifier()), CadpType.lowString));
|
1337
|
|
1338
|
|
1339
|
m_helperCode.AppendLine("return result; }");
|
1340
|
|
1341
|
|
1342
|
emittedOperations.add(result);
|
1343
|
return result;
|
1344
|
}
|
1345
|
|
1346
|
public String VariableDeclarations()
|
1347
|
{
|
1348
|
return varDecl.toString();
|
1349
|
}
|
1350
|
|
1351
|
@Override
|
1352
|
public String toString()
|
1353
|
{
|
1354
|
return m_emitter.toString();
|
1355
|
}
|
1356
|
|
1357
|
public static String GetHelperCode()
|
1358
|
{
|
1359
|
final StringBuilder result = new StringBuilder(m_helperCode.toString());
|
1360
|
result.append("void Model_Reset() {");
|
1361
|
result.append(System.lineSeparator());
|
1362
|
result.append(m_resetCode.toString());
|
1363
|
result.append("}");
|
1364
|
result.append(System.lineSeparator());
|
1365
|
return result.toString();
|
1366
|
}
|
1367
|
|
1368
|
public CadpExpression(CadpActionInfo aProcInfo)
|
1369
|
{
|
1370
|
if (aProcInfo == null)
|
1371
|
throw new IllegalArgumentException();
|
1372
|
m_procInfo = aProcInfo;
|
1373
|
}
|
1374
|
|
1375
|
|
1376
|
public CadpExpression(CadpActionInfo aProcInfo, HashSet<Identifier> varDecls)
|
1377
|
{
|
1378
|
if (aProcInfo == null)
|
1379
|
throw new IllegalArgumentException();
|
1380
|
m_procInfo = aProcInfo;
|
1381
|
emittedVariabes.addAll(varDecls);
|
1382
|
}
|
1383
|
}
|