root / trunk / compiler / ooasCompiler / src / org / momut / ooas / codegen / prolog / OoaPrologVisitor.java @ 10
1 |
/**
|
---|---|
2 |
*
|
3 |
* OOAS Compiler
|
4 |
*
|
5 |
* Copyright 2015, AIT Austrian Institute of Technology.
|
6 |
* This code is based on the C# Version of the OOAS Compiler, which is
|
7 |
* copyright 2015 by the Institute of Software Technology, Graz University
|
8 |
* of Technology with portions copyright by the AIT Austrian Institute of
|
9 |
* Technology. All rights reserved.
|
10 |
*
|
11 |
* SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
|
12 |
*
|
13 |
* If you modify the file please update the list of contributors below to in-
|
14 |
* clude your name. Please also stick to the coding convention of using TABs
|
15 |
* to do the basic (block-level) indentation and spaces for anything after
|
16 |
* that. (Enable the display of special chars and it should be pretty obvious
|
17 |
* what this means.) Also, remove all trailing whitespace.
|
18 |
*
|
19 |
* Contributors:
|
20 |
* Willibald Krenn (AIT)
|
21 |
* Stephan Zimmerer (AIT)
|
22 |
* Markus Demetz (AIT)
|
23 |
* Christoph Czurda (AIT)
|
24 |
*
|
25 |
*/
|
26 |
|
27 |
|
28 |
package org.momut.ooas.codegen.prolog; |
29 |
|
30 |
import java.util.ArrayList; |
31 |
import java.util.Date; |
32 |
|
33 |
import org.momut.ooas.ast.identifiers.AttributeIdentifier; |
34 |
import org.momut.ooas.ast.identifiers.Identifier; |
35 |
import org.momut.ooas.ast.identifiers.IdentifierKind; |
36 |
import org.momut.ooas.ast.identifiers.MainModule; |
37 |
import org.momut.ooas.ast.identifiers.MethodIdentifier; |
38 |
import org.momut.ooas.ast.identifiers.NamedActionIdentifier; |
39 |
import org.momut.ooas.ast.identifiers.ParameterIdentifier; |
40 |
import org.momut.ooas.ast.identifiers.TypeIdentifier; |
41 |
import org.momut.ooas.ast.statements.Block; |
42 |
import org.momut.ooas.ast.types.FunctionType; |
43 |
import org.momut.ooas.ast.types.FunctionType.FunctionTypeEnum; |
44 |
import org.momut.ooas.codegen.OoasCodeEmitter; |
45 |
import org.momut.ooas.parser.ParserState; |
46 |
import org.momut.ooas.utils.OoasCompilerHashMap; |
47 |
import org.momut.ooas.visitors.OoaCompleteAstTraversalVisitor; |
48 |
|
49 |
public class OoaPrologVisitor extends OoaCompleteAstTraversalVisitor |
50 |
{ |
51 |
protected OoasCodeEmitter m_emitter;
|
52 |
protected final Scratchbook m_scratchbook = new Scratchbook(); |
53 |
|
54 |
// private String PrologIdentifier(Identifier id)
|
55 |
// {
|
56 |
// OoaPrologIdentifier identifierVisitor = m_idFactory.create();
|
57 |
// id.Accept(identifierVisitor);
|
58 |
// return identifierVisitor.toString();
|
59 |
// }
|
60 |
|
61 |
protected void ExportMethodsAndActions(MainModule mainModule) |
62 |
{ |
63 |
final StringBuilder varActions = new StringBuilder(); |
64 |
m_emitter.AppendLine(); |
65 |
m_emitter.AppendLine("% action system");
|
66 |
m_emitter.AppendLineIncIndent("as :- ");
|
67 |
|
68 |
/* export methods */
|
69 |
m_emitter.AppendLine("methods (");
|
70 |
ExportMethods(mainModule); |
71 |
m_emitter.AppendLine("), ");
|
72 |
m_emitter.AppendLine("actions (");
|
73 |
ExportNamedActions(mainModule, varActions); |
74 |
m_emitter.AppendLine("), ");
|
75 |
m_emitter.AppendLine("dood (");
|
76 |
|
77 |
ExportDoOdBlock(mainModule.instance().doOdBlock(), m_emitter); |
78 |
|
79 |
|
80 |
m_emitter.AppendLine("), qdes (none)");
|
81 |
m_emitter.DecIndent(); |
82 |
m_emitter.AppendLine(".");
|
83 |
m_emitter.AppendLine("");
|
84 |
|
85 |
m_emitter.Append(varActions.toString()); |
86 |
} |
87 |
|
88 |
private void ExportMethods(MainModule mainModule) |
89 |
{ |
90 |
int y = 0; |
91 |
for (final Identifier x: mainModule.instance().symbols().symbolList()) |
92 |
{ |
93 |
if (x.kind() == IdentifierKind.MethodIdentifier)
|
94 |
{ |
95 |
if (y != 0) |
96 |
m_emitter.AppendLine(", ");
|
97 |
else
|
98 |
y++; |
99 |
|
100 |
final MethodIdentifier theMethod = (MethodIdentifier)x;
|
101 |
final OoaPrologIdentifier pIdent = m_idFactory.create();
|
102 |
theMethod.Accept(pIdent); |
103 |
|
104 |
/* method */
|
105 |
final StringBuilder parameter = new StringBuilder(); |
106 |
if (theMethod.parameter().size() > 0 || ((FunctionType)theMethod.type()).returnType() != null) |
107 |
{ |
108 |
parameter.append("(");
|
109 |
int z = 0; |
110 |
for (final ParameterIdentifier param: theMethod.parameter()) |
111 |
{ |
112 |
if (z != 0) |
113 |
{ |
114 |
parameter.append(", ");
|
115 |
} |
116 |
else
|
117 |
z++; |
118 |
final OoaPrologIdentifier pParamIdent = m_idFactory.create();
|
119 |
param.Accept(pParamIdent); |
120 |
parameter.append(pParamIdent.toString()); |
121 |
} |
122 |
|
123 |
|
124 |
if (((FunctionType)theMethod.type()).returnType() != null) |
125 |
{ |
126 |
if (z != 0) |
127 |
parameter.append(", ");
|
128 |
parameter.append("RESULT");
|
129 |
} |
130 |
parameter.append(")");
|
131 |
} |
132 |
m_emitter.AppendLineIncIndent(String.format("%s%s = (", pIdent.toString(), parameter.toString())); |
133 |
|
134 |
final OoaPrologStatement pBody = createStatementVisitor();
|
135 |
((MethodIdentifier)x).body().Accept(pBody); |
136 |
m_emitter.Append(pBody.toString()); |
137 |
m_emitter.Append(")");
|
138 |
m_emitter.DecIndent(); |
139 |
} |
140 |
} |
141 |
if (y == 0) |
142 |
m_emitter.Append(" none ");
|
143 |
} |
144 |
|
145 |
private void ExportNamedActions(MainModule mainModule, StringBuilder varActions) |
146 |
{ |
147 |
int y = 0; |
148 |
for (final Identifier x: mainModule.instance().symbols().symbolList()) |
149 |
{ |
150 |
if (x.kind() == IdentifierKind.NamedActionIdentifier)
|
151 |
{ |
152 |
if (y != 0) |
153 |
m_emitter.AppendLine(", ");
|
154 |
else
|
155 |
y++; |
156 |
final NamedActionIdentifier action = (NamedActionIdentifier)x;
|
157 |
final OoaPrologIdentifier pIdent = m_idFactory.create();
|
158 |
action.Accept(pIdent); |
159 |
|
160 |
if (((FunctionType)action.type()).functionType() != FunctionTypeEnum.Continuous)
|
161 |
{ |
162 |
/* discrete actions */
|
163 |
final StringBuilder parameter = new StringBuilder(); |
164 |
final StringBuilder parametertype = new StringBuilder(); |
165 |
if (action.parameter().size() > 0) |
166 |
{ |
167 |
parameter.append("(");
|
168 |
parametertype.append("(");
|
169 |
int z = 0; |
170 |
for (final ParameterIdentifier param: action.parameter()) |
171 |
{ |
172 |
if (z != 0) |
173 |
{ |
174 |
parameter.append(", ");
|
175 |
parametertype.append(", ");
|
176 |
} |
177 |
else
|
178 |
z++; |
179 |
final OoaPrologIdentifier pParamIdent = m_idFactory.create();
|
180 |
param.Accept(pParamIdent); |
181 |
parameter.append(pParamIdent.toString()); |
182 |
|
183 |
final OoaPrologType pParamType = createTypeVisitor(); // bugfix me! |
184 |
param.type().Accept(pParamType); |
185 |
parametertype.append(pParamType.toString()); |
186 |
|
187 |
} |
188 |
parametertype.append(")");
|
189 |
parameter.append(")");
|
190 |
} |
191 |
//if (parametertype.Length > 0)
|
192 |
// varActions.AppendLine(String.format("%s%s.", pIdent.toString(), parametertype.toString()));
|
193 |
m_emitter.AppendLineIncIndent(String.format("%s%s::", pIdent.toString(), parameter.toString())); |
194 |
} |
195 |
else
|
196 |
{ |
197 |
// we do not support continuous actions anymore.
|
198 |
throw new UnsupportedOperationException(); |
199 |
// /* observable state vars outside... */
|
200 |
// final StringBuilder parameter = new StringBuilder();
|
201 |
// int z = 0;
|
202 |
// for (final Statement stmt : ((GuardedCommand)action.body().statements().peekFirst()).body().statements())
|
203 |
// {
|
204 |
// final QualitativeConstraintStatement qstmt = (QualitativeConstraintStatement)stmt;
|
205 |
// if (qstmt.operation() == QualitativeConstraintOperation.Equal
|
206 |
// && qstmt.variable1().kind() == IdentifierKind.AttributeIdentifier
|
207 |
// && ((AttributeIdentifier)qstmt.variable1()).isObservable())
|
208 |
// {
|
209 |
// if (z != 0)
|
210 |
// parameter.append(", ");
|
211 |
// else
|
212 |
// z++;
|
213 |
// qstmt.tag = true;
|
214 |
// final OoaPrologIdentifier pParamIdent1 = m_idFactory.create();
|
215 |
// final OoaPrologIdentifier pParamIdent2 = m_idFactory.create();
|
216 |
// qstmt.variable0().Accept(pParamIdent1);
|
217 |
// qstmt.variable1().Accept(pParamIdent2);
|
218 |
// parameter.append(String.format("%s(%s)", pParamIdent2.toString(), pParamIdent1.toString()));
|
219 |
// }
|
220 |
// }
|
221 |
// m_emitter.AppendLineIncIndent(String.format("[%s]::", parameter.toString()));
|
222 |
} |
223 |
|
224 |
final OoaPrologStatement pBody = createStatementVisitor();
|
225 |
((NamedActionIdentifier)x).body().Accept(pBody); |
226 |
m_emitter.Append(pBody.toString()); |
227 |
m_emitter.DecIndent(); |
228 |
|
229 |
} |
230 |
} |
231 |
} |
232 |
|
233 |
private void ExportDoOdBlock(Block block, OoasCodeEmitter m_emitter) |
234 |
{ |
235 |
final OoaPrologStatement statement = createStatementVisitor();
|
236 |
block.Accept(statement); |
237 |
m_emitter.Append(statement.toString()); |
238 |
} |
239 |
|
240 |
protected int ExportActions(MainModule mainModule, String predName, FunctionTypeEnum actionKind) |
241 |
{ |
242 |
m_emitter.AppendLine("");
|
243 |
m_emitter.AppendLine("%emit " + actionKind.toString() + " actions"); |
244 |
m_emitter.Append(predName + "([");
|
245 |
int y = 0; |
246 |
for (final Identifier x: mainModule.instance().symbols().symbolList()) |
247 |
{ |
248 |
if (x.kind() == IdentifierKind.NamedActionIdentifier)
|
249 |
{ |
250 |
if (((FunctionType)((NamedActionIdentifier)x).type()).functionType() == actionKind)
|
251 |
{ |
252 |
if (y != 0) |
253 |
m_emitter.Append(", ");
|
254 |
else
|
255 |
y++; |
256 |
final OoaPrologIdentifier pIdent = m_idFactory.create();
|
257 |
|
258 |
((NamedActionIdentifier)x).Accept(pIdent); |
259 |
m_emitter.Append(pIdent.toString()); |
260 |
} |
261 |
} |
262 |
} |
263 |
m_emitter.AppendLine("]).");
|
264 |
return y;
|
265 |
} |
266 |
|
267 |
protected int ExportControllableActions(MainModule mainModule) { |
268 |
return ExportActions(mainModule, "input", FunctionTypeEnum.Controllable); |
269 |
} |
270 |
|
271 |
protected int ExportObservableActions(MainModule mainModule) { |
272 |
return ExportActions(mainModule, "output", FunctionTypeEnum.Observable); |
273 |
} |
274 |
|
275 |
protected void ExportInitialState(MainModule mainModule) |
276 |
{ |
277 |
m_emitter.AppendLine("");
|
278 |
m_emitter.AppendLine("%emit initial state");
|
279 |
final ArrayList<String> initPreds = new ArrayList<String>(); |
280 |
final ArrayList<String> initVars = new ArrayList<String>(); |
281 |
int y = 0; |
282 |
for (final Identifier x: mainModule.instance().symbols().symbolList()) |
283 |
{ |
284 |
if (x.kind() == IdentifierKind.AttributeIdentifier)
|
285 |
{ |
286 |
final OoaPrologExpression anExprVis = createExpressionVisitor();
|
287 |
((AttributeIdentifier)x).initializer().Accept(anExprVis); |
288 |
assert(anExprVis.tmpVariables().size() == 1); |
289 |
final String initPredName = String.format("attr_%s_init(%s)", x.tokenText(), anExprVis.tmpVariables().get(0)); |
290 |
m_emitter.AppendLine(String.format("%s :- %s 1=1.", initPredName, anExprVis.toString())); |
291 |
initPreds.add(initPredName); |
292 |
initVars.add(anExprVis.tmpVariables().get(0));
|
293 |
} |
294 |
} |
295 |
|
296 |
|
297 |
m_emitter.Append("init([");
|
298 |
y = 0;
|
299 |
for (final String x: initVars) |
300 |
{ |
301 |
if (y != 0) |
302 |
m_emitter.Append(",");
|
303 |
else
|
304 |
y++; |
305 |
m_emitter.Append(x); |
306 |
} |
307 |
m_emitter.Append("]) :-");
|
308 |
y = 0;
|
309 |
for (final String x: initPreds) |
310 |
{ |
311 |
if (y != 0) |
312 |
m_emitter.Append(",");
|
313 |
else
|
314 |
y++; |
315 |
m_emitter.Append(x); |
316 |
} |
317 |
m_emitter.AppendLine(".");
|
318 |
} |
319 |
|
320 |
protected int ExportState(MainModule mainModule) |
321 |
{ |
322 |
m_emitter.AppendLine("");
|
323 |
m_emitter.AppendLine("%emit state definition");
|
324 |
m_emitter.Append("state_def([");
|
325 |
int y = 0; |
326 |
for (final Identifier x: mainModule.instance().symbols().symbolList()) |
327 |
{ |
328 |
if (x.kind() == IdentifierKind.AttributeIdentifier)
|
329 |
{ |
330 |
if (y != 0) |
331 |
m_emitter.Append(", ");
|
332 |
else
|
333 |
y++; |
334 |
final OoaPrologIdentifier pid = m_idFactory.create();
|
335 |
x.Accept(pid); |
336 |
m_emitter.Append(pid.toString()); |
337 |
} |
338 |
} |
339 |
m_emitter.AppendLine("]).");
|
340 |
return y;
|
341 |
} |
342 |
|
343 |
protected void ExportVariables(MainModule mainModule) |
344 |
{ |
345 |
m_emitter.AppendLine("");
|
346 |
m_emitter.AppendLine("%emit type of state variables");
|
347 |
final OoasCompilerHashMap<String, StringBuilder> varlist = new OoasCompilerHashMap<String, StringBuilder>(); |
348 |
for (final Identifier x: mainModule.instance().symbols().symbolList()) |
349 |
{ |
350 |
if (x.kind() == IdentifierKind.AttributeIdentifier)
|
351 |
{ |
352 |
final OoaPrologIdentifier pid = m_idFactory.create();
|
353 |
final OoaPrologType ptype = createTypeVisitor();
|
354 |
x.Accept(pid); |
355 |
x.type().Accept(ptype); |
356 |
|
357 |
final String key = ptype.toString(); |
358 |
if (varlist.containsKey(key))
|
359 |
{ |
360 |
varlist.get(key).append(String.format(", %s", pid.toString())); |
361 |
} |
362 |
else
|
363 |
{ |
364 |
varlist.putSafe(key, new StringBuilder(String.format("[%s", pid.toString()))); |
365 |
} |
366 |
} |
367 |
} |
368 |
for (final String key: varlist.keySet()) |
369 |
m_emitter.AppendLine(String.format("var(%s], %s).", varlist.get(key), key)); |
370 |
} |
371 |
|
372 |
protected void ExportTypes(MainModule mainModule) |
373 |
{ |
374 |
for (final Identifier x: mainModule.symbolTable().symbolList()) |
375 |
{ |
376 |
if (x.kind() == IdentifierKind.TypeIdentifier)
|
377 |
OoaPrologType.EmitType(((TypeIdentifier)x).type(), m_idFactory, m_scratchbook); |
378 |
} |
379 |
} |
380 |
|
381 |
|
382 |
@Override
|
383 |
public /*override*/ void visit(MainModule mainModule) |
384 |
{ |
385 |
m_emitter.AppendLine("% OOAS Compiler Generated");
|
386 |
// m_emitter.AppendLine(String.format("%%%s", Mogentes.Program.GetProgramVersion().toString().Replace(Environment.NewLine, Environment.NewLine + "%")));
|
387 |
m_emitter.AppendLine("% Code-Gen Version: 0.2");
|
388 |
m_emitter.Append("% Generated: "); m_emitter.AppendLine(new Date().toString()); |
389 |
m_emitter.AppendLine("%------------------------------------------------------------------------");
|
390 |
m_emitter.AppendLine("");
|
391 |
m_emitter.AppendLine(String.format(":- module(%s, [var/2, input/1, searchDepth/1, qspace/2]).", m_nameSpace)); |
392 |
m_emitter.AppendLine(":- use_module(library(file_systems)).");
|
393 |
m_emitter.AppendLine(":- use_module(library(process)).");
|
394 |
m_emitter.AppendLine(":- use_module(library(clpfd)).");
|
395 |
m_emitter.AppendLine(":- use_module(library(clpb)).");
|
396 |
m_emitter.AppendLine(":- use_module(library(lists)).");
|
397 |
m_emitter.AppendLine(":- use_module(library(avl)).");
|
398 |
m_emitter.AppendLine(":- use_module(library(ordsets)).");
|
399 |
m_emitter.AppendLine(":- use_module(library(system)).");
|
400 |
m_emitter.AppendLine("% :- use_module(library(gauge)). % this is a debug lib not supported on Win.");
|
401 |
m_emitter.AppendLine(":- use_module(library(terms)).");
|
402 |
m_emitter.AppendLine(":- use_module(library(sets)).");
|
403 |
m_emitter.AppendLine(":- use_module(library(random)).");
|
404 |
|
405 |
m_emitter.AppendLine(":- use_module(ulysseslib, _, [ulyssesListHead/2, ulyssesListLength/2, ulyssesListTail/2, ulyssesListConc/3, ulyssesTupleAccess/3, ulyssesListAccess/3, ulyssesListWrite/4, ulyssesMapAccess/3]).");
|
406 |
|
407 |
m_emitter.AppendLine(":- public(as/0).");
|
408 |
m_emitter.AppendLine(":- dynamic(as/0).");
|
409 |
m_emitter.AppendLine(":- dynamic(qstate_init/1).");
|
410 |
m_emitter.AppendLine(":- dynamic(qstate_constraints/1).");
|
411 |
m_emitter.AppendLine(":- public(qstate_init/1).");
|
412 |
m_emitter.AppendLine(":- public(qstate_constraints/1).");
|
413 |
|
414 |
/*definition of search depth*/
|
415 |
m_emitter.AppendLine("");
|
416 |
m_emitter.AppendLine("% maximal search depth (change at will)");
|
417 |
// FIXME: HACK
|
418 |
m_emitter.AppendLine(String.format("searchDepth(%s).", m_maxSearchDepth)); |
419 |
m_emitter.AppendLine("");
|
420 |
|
421 |
/*definition of types*/
|
422 |
ExportTypes(mainModule); |
423 |
/* variable definition */
|
424 |
ExportVariables(mainModule); |
425 |
|
426 |
/* state definition */
|
427 |
ExportState(mainModule); |
428 |
/* initial state */
|
429 |
ExportInitialState(mainModule); |
430 |
/* input actions (controllables) */
|
431 |
ExportControllableActions(mainModule); |
432 |
/* output actions (observables) */
|
433 |
ExportObservableActions(mainModule); |
434 |
/* named actions */
|
435 |
ExportMethodsAndActions(mainModule); |
436 |
|
437 |
/* all types */
|
438 |
m_emitter.AppendLine("%definition of types");
|
439 |
m_emitter.AppendLine(m_scratchbook.typeDefinitions().toString()); |
440 |
m_emitter.AppendLine(createTypeVisitor().GetInternalTypeDefinitions()); |
441 |
|
442 |
for(final String line: m_ParserState.mappingInformation) |
443 |
m_emitter.AppendLine("% " + line);
|
444 |
} |
445 |
|
446 |
|
447 |
@Override
|
448 |
public /*override*/ String toString() |
449 |
{ |
450 |
return m_emitter.toString();
|
451 |
} |
452 |
|
453 |
protected OoaPrologIdentifier createIdentifierVisitor() { return m_idFactory.create(); } |
454 |
protected OoaPrologType createTypeVisitor() { return m_typeFactory.create(m_idFactory, m_scratchbook); } |
455 |
protected OoaPrologExpression createExpressionVisitor() { return m_exprFactory.create(m_idFactory, m_typeFactory, m_scratchbook); } |
456 |
protected OoaPrologStatement createStatementVisitor() { return m_stmtFactory.create(m_exprFactory, m_idFactory, m_typeFactory, m_scratchbook); } |
457 |
protected final String m_nameSpace; |
458 |
protected final int m_maxSearchDepth; |
459 |
|
460 |
|
461 |
private final OoaPrologExpression.Factory m_exprFactory; |
462 |
private final OoaPrologIdentifier.Factory m_idFactory; |
463 |
private final OoaPrologStatement.Factory m_stmtFactory; |
464 |
private final OoaPrologType.Factory m_typeFactory; |
465 |
|
466 |
protected OoaPrologVisitor(
|
467 |
ParserState aState, |
468 |
int maxSearchDepth,
|
469 |
String nameSpace,
|
470 |
OoaPrologExpression.Factory exprFactory, |
471 |
OoaPrologIdentifier.Factory idFactory, |
472 |
OoaPrologStatement.Factory stmtFactory, |
473 |
OoaPrologType.Factory tpeFactory) |
474 |
{ |
475 |
super(aState);
|
476 |
m_maxSearchDepth = maxSearchDepth; |
477 |
m_nameSpace = nameSpace; |
478 |
m_emitter = new OoasCodeEmitter();
|
479 |
m_exprFactory = exprFactory; |
480 |
m_idFactory = idFactory; |
481 |
m_stmtFactory = stmtFactory; |
482 |
m_typeFactory = tpeFactory; |
483 |
} |
484 |
|
485 |
public OoaPrologVisitor(ParserState aState, int maxSearchDepth, String nameSpace) { |
486 |
this(
|
487 |
aState, |
488 |
maxSearchDepth, |
489 |
nameSpace, |
490 |
new OoaPrologExpression.Factory(),
|
491 |
new OoaPrologIdentifier.Factory(),
|
492 |
new OoaPrologStatement.Factory(),
|
493 |
new OoaPrologType.Factory());
|
494 |
} |
495 |
} |