Project

General

Profile

Revision 7

Added by Willibald K. over 8 years ago

changing java, cpp, hpp files to unix line endings

View differences:

OoaPrologExpression.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.prolog;
29

  
30
import java.util.ArrayList;
28
package org.momut.ooas.codegen.prolog;
31 29

  
30
import java.util.ArrayList;
31

  
32 32
import org.momut.ooas.ast.expressions.AccessExpression;
33 33
import org.momut.ooas.ast.expressions.BinaryOperator;
34 34
import org.momut.ooas.ast.expressions.CallExpression;
......
62 62
import org.momut.ooas.utils.exceptions.ArgumentException;
63 63
import org.momut.ooas.utils.exceptions.NotImplementedException;
64 64
import org.momut.ooas.visitors.OoaExpressionVisitor;
65

  
66
public class OoaPrologExpression extends OoaExpressionVisitor
67
{
68
	public static class Factory
69
	{
70
		public final OoaPrologExpression create(OoaPrologIdentifier.Factory idFactory, OoaPrologType.Factory typeFactory, Scratchbook sb)
71
		{ return create(idFactory, typeFactory, sb, false); }
72
		public OoaPrologExpression create(OoaPrologIdentifier.Factory idFactory, OoaPrologType.Factory typeFactory, Scratchbook sb, boolean lhs)
73
		{ return new OoaPrologExpression(idFactory, typeFactory, sb, this, lhs); }
74
	}
75

  
76
	protected OoasCodeEmitter m_emitter = new OoasCodeEmitter();
77
	protected ArrayList<String> m_tmpVars = new ArrayList<String>();
78
	protected final Scratchbook m_scratchbook;
79
	private boolean m_LhsExpression = false;
80

  
81

  
82
	public ArrayList<String> tmpVariables() { return m_tmpVars; }
83
	public boolean isLhsExpression() { return m_LhsExpression; }
84

  
85
//	private String GetPrologType(UlyssesType aType)
86
//	{
87
//		OoaPrologType pType = createTypeVisitor();
88
//		aType.Accept(pType);
89
//		return pType.toString();
90
//	}
91

  
92
	protected String GetIdentifierString(Identifier anIdentifier)
93
	{
94
		final OoaPrologIdentifier pIdent = createIdentifierVisitor();
95
		anIdentifier.Accept(pIdent);
96
		return pIdent.toString();
97
	}
98

  
99

  
100
	// following call must not happen
101
	@Override
102
	public void visit(UnresolvedIdentifierExpression unresolvedIdentifierExpression)
103
	{
104
		assert(false);
105
	}
106

  
107
	// call of method that returns a value..
108
	@Override
109
	public /*override*/ void visit(CallExpression callExpression)
110
	{
111
		// we handle only function calls within expressions here (must have non-void return!)
112
		final FunctionType funtype = (FunctionType)callExpression.child().type();
113
		if (funtype.returnType() == null)
114
			throw new ArgumentException("Internal error: Function call in expression with return-type void!");
115

  
116
		String callstatement = "";
117
		final StringBuilder parameter = new StringBuilder();
118

  
119
		final OoaPrologExpression prologexpr = createExpressionVisitor();
120
		callExpression.child().Accept(prologexpr);
121

  
122
		m_emitter.Append(prologexpr.toString());
123
		callstatement = prologexpr.tmpVariables().get(0);
124
		int i = 0;
125
		for (final Expression arg: callExpression.arguments())
126
		{
127
			if (i != 0)
128
				parameter.append(", ");
129
			else
130
				i++;
131
			final OoaPrologExpression paramexpr = createExpressionVisitor();
132
			arg.Accept(paramexpr);
133
			m_emitter.Append(paramexpr.toString());
134
			parameter.append(paramexpr.tmpVariables().get(0));
135
		}
136
		if (parameter.length() > 0)
137
			m_emitter.AppendLine(String.format("%s(%s,%s),", callstatement, parameter, NewTempVariable()));
138
		else
139
			m_emitter.AppendLine(String.format("%s(%s),", callstatement, NewTempVariable()));
140
	}
141

  
142

  
143
	// we need to map all other things to Prolog constructs
144
	private String OperatorString(Expression expression, UlyssesType resultingType)
145
	{
146
		switch (expression.kind())
147
		{
148
		case abs:    // T_ABS:
149
		case card:   // T_CARD:
150
		case dom:    // T_DOM:
151
		case range:  // T_RNG:
152
		case merge:  // T_MERGE:
153
		case elems:  // T_ELEMS:
154
		case head:   // T_HEAD:
155
		case tail:   // T_TAIL:
156
		case conc:   // T_CONC:
157
		case inds:   // T_INDS:
158
		case dinter: // T_DINTER:
159
		case dunion: // T_DUNION:
160
		case domresby:   // T_DOMRESBY:
161
		case domresto:   // T_DOMRESTO:
162
		case rngresby:   // T_RNGRESBY:
163
		case rngresto:   // T_RNGRESTO:
164
		case inter:  // T_INTER:
165
		case union:  // T_UNION:
166
		case diff:   // T_DIFF:
167
		case munion: // T_MUNION:
168
		case seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
169
		case subset:
170
		case elemin:
171
		case notelemin:
172
		case implies:    // T_IMPLIES:
173
		case biimplies:  // T_BIIMPLIES:
174
		case Primed:
175
		case len:    // T_LEN:
176
			throw new NotImplementedException();
177

  
178
		case div:    // T_DIV:
179
			return "/";
180
		case idiv:   // T_IDIV:
181
			return "/";
182
		case mod:    // T_MOD:
183
			return "mod";
184
		case prod:   // T_PROD:
185
			return "*";
186
		case sum:    // T_SUM:
187
			return "+";
188
		case minus:  // T_MINUS:
189
			return "-";
190
		case less:
191
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "<" : "#<";
192
		case lessequal:
193
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "=<" : "#=<";
194
		case greater:
195
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? ">" : "#>";
196
		case greaterequal:
197
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? ">=" : "#>=";
198
		case equal:
199
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "==" : "#=";
200
		case notequal:
201
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "\\=" : "#\\=";
202
		case and:    // T_AND:
203
			throw new NotImplementedException(); // implemented in binaryoperator
204
		case or:     // T_OR:
205
			throw new NotImplementedException(); // implemented in binaryoperator
206
		case not:
207
			throw new NotImplementedException(); // implemented in binaryoperator
208

  
209
		case Cast:
210
			return "";
211

  
212
		default:
213
			return expression.kind().name(); //Enum.GetName(typeof(ExpressionKind), expression.kind);
214
		}
215
	}
216

  
217
	protected boolean isNumericBinary(Expression expression)
218
	{
219
		boolean result = false;
220
		if (expression instanceof BinaryOperator)
221
		{
222
			result = ((BinaryOperator)expression).left().type().kind() == TypeKind.IntType &&
223
					((BinaryOperator)expression).right().type().kind() == TypeKind.IntType;
224
		}
225
		else if (expression instanceof UnaryOperator)
226
		{
227
			result = ((UnaryOperator)expression).child().type().kind() == TypeKind.IntType;
228
		}
229
		else throw new NotImplementedException();
230
		return result;
231
	}
232

  
233
	@SuppressWarnings("unchecked")
234
	@Override
235
	public /*override*/ <T> void visit(ValueExpression<T> valueExpression)
236
	{
237
		assert(m_tmpVars.size() == 0);
238
		final String tmpVar = NewTempVariable();
239
		m_emitter.Append(String.format("%s ", tmpVar));
240

  
241

  
242
		if (valueExpression.value() == null)
243
			m_emitter.Append("= 'null'");
244
		else if (Boolean.class.isAssignableFrom(valueExpression.m_clazz))
245
			m_emitter.Append(((ValueExpression<Boolean>) valueExpression).value() ? " #= true" : " #= fail");
246
		else if (Character.class.isAssignableFrom(valueExpression.m_clazz))
247
			m_emitter.Append(String.format("#= '%s'", valueExpression.toString()));
248
		else if (Integer.class.isAssignableFrom(valueExpression.m_clazz))
249
			m_emitter.Append(String.format("#= %s", valueExpression.toString()));
250
		else
251
			m_emitter.Append(String.format("= %s", valueExpression.value().toString()));
252

  
253
		m_emitter.AppendLine(",");
254
		assert(m_tmpVars.size() == 1);
255
	}
256

  
257
	@Override
258
	public /*override*/ void visit(IdentifierExpression identifierExpression)
259
	{
260
		if (identifierExpression.identifier().kind() == IdentifierKind.LandmarkIdentifier)
261
		{
262
			final LandmarkIdentifier lmid = (LandmarkIdentifier)identifierExpression.identifier();
263
			final OoaPrologIdentifier pid = createIdentifierVisitor();
264
			lmid.Accept(pid);
265
			//m_emitter.Append(pid.ToString());
266
			m_tmpVars.add(pid.toString());
267
			return;
268
		}
269
		else if (identifierExpression.identifier().kind() == IdentifierKind.EnumIdentifier)
270
		{
271
			final EnumIdentifier enumid = (EnumIdentifier)identifierExpression.identifier();
272
			final EnumType enumType = (EnumType)enumid.type();
273
			//m_emitter.Append(enumType.listOfEnumSymbols.IndexOf(enumid));
274
			if (enumType instanceof ValuedEnumType)
275
				m_emitter.AppendLine(String.format("%s #= %s,", NewTempVariable(), enumid.Value()));
276
			else
277
				m_emitter.AppendLine(String.format("%s #= %s,", NewTempVariable(), enumType.listOfEnumSymbols().indexOf(enumid)));
278
		}
279
		else if (identifierExpression.isSelf())
280
		{
281
			m_emitter.AppendLine(String.format("%s = %s,", NewTempVariable(), GetIdentifierString(identifierExpression.identifier())));
282
		}
283
		/*else if (identifierExpression.identifier.kind == IdentifierKind.AttributeIdentifier)
284
        {
285
            m_emitter.AppendLine(String.format("getVal(%s,%s,_),", GetIdentifierString(identifierExpression.identifier), NewTempVariable(), ));
286
        }*/
287
		else
288
		{
289
			m_tmpVars.add(GetIdentifierString(identifierExpression.identifier()));
290
		}
291
	}
292

  
293
	@Override
294
	public /*override*/ void visit(TypeExpression typeExpression)
295
	{
296
		if (typeExpression.type().kind() != TypeKind.QrType &&
297
				typeExpression.type().kind() != TypeKind.EnumeratedType)
298
		{
299
			m_emitter.Append(GetIdentifierString(typeExpression.type().identifier()));
300
		}
301
	}
302

  
303

  
304
	@Override
305
	public /*override*/ void visit(ObjectConstructor objectConstructor)
306
	{
307
		if (objectConstructor.instances().size() > 1)
308
			throw new NotImplementedException();
309

  
310
		m_emitter.AppendLine(String.format("%s = '%s',", NewTempVariable(), objectConstructor.instances().get(0).Name));
311

  
312
		//m_emitter.Append(String.format("new %s(this)", GetIdentifierString(objectConstructor.type.identifier)));
313
	}
314

  
315
	@Override
316
	public /*override*/ void visit(ListConstructor listConstructor)
317
	{
318
		if (listConstructor.hasComprehension())
319
		{
320
			final OoaPrologExpression compr = createExpressionVisitor();
321
			listConstructor.comprehension().Accept(compr);
322
			final OoaPrologExpression elem = createExpressionVisitor();
323
			listConstructor.elements().get(0).Accept(elem);
324

  
325
			final StringBuilder enumvars = new StringBuilder();
326
			int i = 0;
327
			for (final Identifier v: listConstructor.comprehensionVariables().symbolList())
328
			{
329
				final OoaPrologIdentifier ident = createIdentifierVisitor();
330
				v.Accept(ident);
331

  
332
				final OoaPrologType identType = createTypeVisitor();
333
				v.type().Accept(identType);
334

  
335
				enumvars.append(String.format("%s %s: %s", i == 0 ? "" : ",", ident.toString(), identType.toString()));
336
				i++;
337
			}
338

  
339
			m_emitter.AppendLine("% listcomprehension");
340
			m_emitter.AppendLine(String.format("%s = {%s:[%s]:(%s%s,%s%s)}",
341
					NewTempVariable(), elem.tmpVariables().get(0), enumvars.toString(), compr.toString(), compr.tmpVariables().get(0),
342
					elem.toString(), "1=1" /*elem.ToString() == String.Empty ? "1=1" : elem.tmpVariables[0]*/));
343
		}
344
		else
345
		{
346
			m_emitter.AppendLine("% make list");
347
			m_emitter.AppendLine(String.format("%s = []", NewTempVariable()));
348

  
349
			for (final Expression expr: listConstructor.elements())
350
			{
351
				m_emitter.Append(", ");
352

  
353
				final OoaPrologExpression pVal = createExpressionVisitor();
354
				expr.Accept(pVal);
355
				m_emitter.Append(pVal.toString());
356
				assert(pVal.tmpVariables().size() == 1);
357
				m_emitter.AppendLine(String.format("ulyssesListConc(%s,[%s],%s)", m_tmpVars.get(0), pVal.tmpVariables().get(0), NewTempVariable()));
358
				m_tmpVars.remove(0);
359
			}
360
		}
361
		m_emitter.Append(",");
362
		assert(m_tmpVars.size() == 1);
363
	}
364

  
365
	@Override
366
	public /*override*/ void visit(SetConstructor setConstructor)
367
	{
368
		m_emitter.AppendLine("% make set");
369
		// our resulting set.
370
		m_emitter.AppendLine(String.format("%s = []", NewTempVariable()));
371

  
372
		for (final Expression expr: setConstructor.items())
373
		{
374
			m_emitter.Append(", ");
375

  
376
			final OoaPrologExpression pVal = createExpressionVisitor();
377
			expr.Accept(pVal);
378
			m_emitter.Append(pVal.toString());
379
			assert(pVal.tmpVariables().size() == 1);
380
			m_emitter.AppendLine(String.format("ulyssesListConc(%s,[%s],%s)", m_tmpVars.get(0), pVal.tmpVariables().get(0), NewTempVariable()));
381
			m_tmpVars.remove(0);
382
		}
383
		m_emitter.Append(",");
384
		assert(m_tmpVars.size() == 1);
385
	}
386

  
387
	@Override
388
	public /*override*/ void visit(MapConstructor mapConstructor)
389
	{
390
		throw new NotImplementedException();
391
	}
392

  
393
	@Override
394
	public /*override*/ void visit(TupleConstructor tupleConstructor)
395
	{
396
		if (tupleConstructor.isMatcher())
397
		{
398
			// being dealt with in binaryoperator (since we only allow tuple=MyTuple(a,b))
399
			NewTempVariable();
400
			return;
401
		}
402
		else
403
		{
404
			m_emitter.AppendLine("% make tuple");
405
			m_emitter.AppendLine(String.format("%s = []", NewTempVariable()));
406

  
407
			for (final Expression expr: tupleConstructor.values())
408
			{
409
				m_emitter.Append(", ");
410

  
411
				final OoaPrologExpression pVal = createExpressionVisitor();
412
				expr.Accept(pVal);
413
				m_emitter.Append(pVal.toString());
414
				assert(pVal.tmpVariables().size() == 1);
415
				m_emitter.AppendLine(String.format("ulyssesListConc(%s,[%s],%s)", m_tmpVars.get(0), pVal.tmpVariables().get(0), NewTempVariable()));
416
				m_tmpVars.remove(0);
417
			}
418
			m_emitter.Append(",");
419
			assert(m_tmpVars.size() == 1);
420
		}
421
	}
422

  
423
	@Override
424
	public /*override*/ void visit(QValConstructor qValConstructor)
425
	{
426
		final OoaPrologIdentifier pident = createIdentifierVisitor();
427
		qValConstructor.type().identifier().Accept(pident);
428
		final StringBuilder qVal = new StringBuilder();
429
		if (qValConstructor.value() != null || qValConstructor.value().length != 0)
430
		{
431
			final OoaPrologExpression landmark1 = createExpressionVisitor();
432
			qValConstructor.value()[0].Accept(landmark1);
433
			qVal.append(landmark1.toString());
434

  
435
			if (qValConstructor.value().length > 1)
436
			{
437
				final OoaPrologExpression landmark2 = createExpressionVisitor();
438
				qValConstructor.value()[1].Accept(landmark2);
439
				qVal.append("..");
440
				qVal.append(landmark2.toString());
441
			}
442
		}
443
		else
444
			qVal.append("_");
445

  
446
		String deriv = "_";
447
		switch (qValConstructor.valueDeriv())
448
		{
449
		case Dec:
450
			deriv = "dec";
451
			break;
452
		case Inc:
453
			deriv = "inc";
454
			break;
455
		case Steady:
456
			deriv = "std";
457
			break;
458
		default:
459
			throw new NotImplementedException();
460
		}
461
		final String tmpVar = NewTempVariable();
462
		m_emitter.AppendLine(String.format("%s = (%s:%s/%s),", tmpVar, pident.toString(), qVal.toString(), deriv));
463
	}
464

  
465
	@Override
466
	public /*override*/ void visit(AccessExpression accessExpression)
467
	{
468
		if (accessExpression.left().type().kind() != TypeKind.QrType &&
469
				accessExpression.left().type().kind() != TypeKind.EnumeratedType &&
470
				!(accessExpression.right().kind() == ExpressionKind.Identifier &&
471
				((IdentifierExpression)accessExpression.right()).identifier().kind() == IdentifierKind.AttributeIdentifier))
472
		{
473
			assert(m_tmpVars.size() == 0);
474
			// enums and qr types are directly (statically) converted to nums...
475
			VisitSub(accessExpression.left(), accessExpression);
476
			final String leftresult = m_tmpVars.get(0); m_tmpVars.remove(0);
477

  
478
			VisitSub(accessExpression.right(), accessExpression);
479
			final String rightresult = m_tmpVars.get(0); m_tmpVars.remove(0);
480

  
481
			m_tmpVars.add(String.format("%s\\%s", leftresult, rightresult));
482
		}
483
		else
484
			VisitSub(accessExpression.right(), accessExpression);
485
	}
486

  
487
	@Override
488
	public /*override*/ void visit(BinaryOperator binaryOperator)
489
	{
490
		final OoasCodeEmitter origEmitter = m_emitter;
491

  
492

  
493
		// eval stack must be empty
494
		assert(m_tmpVars.size() == 0);
495
		// traverse left
496
		final OoasCodeEmitter leftcode = new OoasCodeEmitter();
497
		m_emitter = leftcode;
498
		VisitSub(binaryOperator.left(), binaryOperator);
499
		final String leftresult = m_tmpVars.get(0); m_tmpVars.remove(0);
500
		assert(m_tmpVars.size() == 0);
501
		// traverse right
502
		final OoasCodeEmitter rightcode = new OoasCodeEmitter();
503
		m_emitter = rightcode;
504
		VisitSub(binaryOperator.right(), binaryOperator);
505
		final String rightresult = m_tmpVars.get(0); m_tmpVars.remove(0);
506
		// eval stack must be empty
507
		assert(m_tmpVars.size() == 0);
508

  
509
		m_emitter = origEmitter;
510

  
511
		// get tmp.var
512
		final String tmpVar = NewTempVariable();
513

  
514
		switch (binaryOperator.kind())
515
		{
516
		case elemin:
517
			m_emitter.Append(leftcode.toString());
518
			m_emitter.Append(rightcode.toString());
519
			m_emitter.AppendLine(String.format(" %s = member(%s,%s),",
520
					tmpVar, leftresult, rightresult));
521
			break;
522
		case and:    // T_AND:
523
			m_emitter.Append(leftcode.toString());
524
			m_emitter.Append(rightcode.toString());
525
			m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
526
					tmpVar, leftresult, ",", rightresult));
527
			break;
528
		case or:     // T_OR:
529
			m_emitter.Append(leftcode.toString());
530
			m_emitter.Append(rightcode.toString());
531
			m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
532
					tmpVar, leftresult, ";", rightresult));
533
			break;
534

  
535
		case implies:
536
			m_emitter.Append(leftcode.toString());
537
			m_emitter.AppendLine(String.format(" %s = (%s -> (%s%s); true), ", // {0} = (({1} -> ({2}{3}); true))
538
					tmpVar, leftresult, rightcode.toString(), rightresult));
539
			break;
540

  
541
		case equal:
542
			m_emitter.Append(leftcode.toString());
543
			m_emitter.Append(rightcode.toString());
544
			/*check if we have tupleconstructors as matchers*/
545
			TupleConstructor matcher = null;
546
			String aTuple = null;
547
			if (binaryOperator.left().kind() == ExpressionKind.TupleConstr &&
548
					((TupleConstructor)binaryOperator.left()).isMatcher())
549
			{
550
				matcher = (TupleConstructor)binaryOperator.left();
551
				aTuple = rightresult;
552
			}
553
			else if (binaryOperator.right().kind() == ExpressionKind.TupleConstr &&
554
					((TupleConstructor)binaryOperator.right()).isMatcher())
555
			{
556
				matcher = (TupleConstructor)binaryOperator.right();
557
				aTuple = leftresult;
558
			}
559

  
560
			if (matcher == null)
561
				m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
562
				tmpVar, leftresult, OperatorString(binaryOperator, binaryOperator.left().type()), rightresult));
563
			else
564
			{
565
				m_emitter.Append(String.format("%s = unify(%s = [", tmpVar, aTuple));
566
				int cntr = 0;
567
				for(final Expression x: matcher.values())
568
				{
569
					if (cntr != 0)
570
						m_emitter.Append(", ");
571
					else
572
						cntr++;
573

  
574
					if (x.kind() != ExpressionKind.Identifier)
575
						throw new ArgumentException();
576

  
577
					final IdentifierExpression ident = (IdentifierExpression)x;
578
					final OoaPrologIdentifier avisitor = createIdentifierVisitor();
579
					ident.Accept(avisitor);
580
					m_emitter.Append(avisitor.toString());
581
				}
582
				m_emitter.AppendLine("]),");
583
			}
584
			break;
585

  
586

  
587

  
588
		case conc:
589
			m_emitter.Append(leftcode.toString());
590
			m_emitter.Append(rightcode.toString());
591
			m_emitter.AppendLine(String.format("ulyssesListConc(%s,%s,%s),", leftresult, rightresult, tmpVar));
592
			break;
593

  
594
		default:
595
			m_emitter.Append(leftcode.toString());
596
			m_emitter.Append(rightcode.toString());
597
			if (binaryOperator.left().type().kind() == TypeKind.QrType)
598
				m_emitter.Append("qEval");
599
			//m_emitter.Append("(");
600
			if (binaryOperator.type().kind() == TypeKind.IntType)
601
				m_emitter.AppendLine(String.format(" %s #= (%s %s %s), ",
602
						tmpVar, leftresult, OperatorString(binaryOperator, binaryOperator.left().type()), rightresult));
603
			else
604
				m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
605
						tmpVar, leftresult, OperatorString(binaryOperator, binaryOperator.left().type()), rightresult));
606
			//m_emitter.Append(")");
607
			break;
608
		}
609
		assert(m_tmpVars.size() == 1);
610
	}
611

  
612
	@Override
613
	public /*override*/ void visit(TernaryOperator ternaryOperator)
614
	{
615
		if (ternaryOperator.kind() == ExpressionKind.conditional)
616
		{
617
			VisitSub(ternaryOperator.left(), ternaryOperator);
618
			final String leftresult = m_tmpVars.get(0); m_tmpVars.remove(0);
619
			VisitSub(ternaryOperator.mid(), ternaryOperator);
620
			final String midresult = m_tmpVars.get(0); m_tmpVars.remove(0);
621
			VisitSub(ternaryOperator.right(), ternaryOperator);
622
			final String rightresult = m_tmpVars.get(0); m_tmpVars.remove(0);
623

  
624
			final String varname = NewTempVariable();
625

  
626
			// (cond, expr #= var; #\ (cond), expr #= var)
627
			m_emitter.Append("((");
628
			m_emitter.Append(leftresult);
629
			m_emitter.Append(", unify(");
630
			m_emitter.Append(midresult);
631
			m_emitter.Append(String.format(" = %s) );( call(\\+(%s)), unify(", varname, leftresult));
632
			m_emitter.Append(rightresult);
633
			m_emitter.Append(String.format(" = %s) )),", varname));
634
		}
635
		else if (ternaryOperator.kind() == ExpressionKind.foldRL)
636
			throw new NotImplementedException();
637
		else if (ternaryOperator.kind() == ExpressionKind.foldLR)
638
		{
639
			VisitSub(ternaryOperator.mid(), ternaryOperator);
640
			final String midresult = m_tmpVars.get(0); m_tmpVars.remove(0);
641
			VisitSub(ternaryOperator.right(), ternaryOperator);
642
			final String rightresult = m_tmpVars.get(0); m_tmpVars.remove(0);
643

  
644

  
645
			// make vars unique
646
			final int uniqueNumer = GetUniqueNumber();
647
			final CallExpression leftcall = (CallExpression)ternaryOperator.left();
648
			final IdentifierExpression elemId = (IdentifierExpression)leftcall.arguments().get(leftcall.arguments().size() - 1);
649
			elemId.identifier().SetTokenText(String.format("Elem_%s", uniqueNumer));
650
			final IdentifierExpression currentResultId = (IdentifierExpression)leftcall.arguments().get(leftcall.arguments().size() - 2);
651
			currentResultId.identifier().SetTokenText(String.format("In_%s", uniqueNumer));
652

  
653
			final String elemVarName = GetIdentifierString(elemId.identifier());
654
			final String inVarName = GetIdentifierString(currentResultId.identifier());
655

  
656
			m_emitter.Append(String.format("fun_fold(%s,%s,(%s, %s, Out_%s,(",
657
					midresult, rightresult, elemVarName, inVarName, uniqueNumer));
658
			VisitSub(leftcall, ternaryOperator);
659
			final String leftresult = m_tmpVars.get(0); m_tmpVars.remove(0);
660
			final String tmpresult = NewTempVariable();
661
			m_emitter.Append(String.format(" Out_%s = %s)),%s),", uniqueNumer, leftresult, tmpresult));
662
		}
663

  
664
		else
665
			throw new NotImplementedException();
666
	}
667

  
668
	@Override
669
	public /*override*/ void visit(TupleMapAccessExpression tupleMapAccessExpression)
670
	{
671
		assert(m_tmpVars.size() == 0);
672
		VisitSub(tupleMapAccessExpression.child(), tupleMapAccessExpression);
673
		final String childresult = m_tmpVars.get(0); m_tmpVars.remove(0);
674

  
675
		VisitSub(tupleMapAccessExpression.argument(), tupleMapAccessExpression);
676
		final String accessresult = m_tmpVars.get(0); m_tmpVars.remove(0);
677
		assert(m_tmpVars.size() == 0);
678

  
679
		final String tmpresult = NewTempVariable();
680

  
681
		if (!m_LhsExpression)
682
		{
683
			switch (tupleMapAccessExpression.child().type().kind())
684
			{
685
			case TupleType:
686
				m_emitter.AppendLine(String.format("ulyssesTupleAccess(%s,%s,%s),", childresult, accessresult, tmpresult));
687
				break;
688
			case MapType:
689
				m_emitter.AppendLine(String.format("ulyssesMapAccess(%s,%s,%s),", childresult, accessresult, tmpresult));
690
				break;
691
			case ListType:
692
				m_emitter.AppendLine(String.format("ulyssesListAccess(%s,%s,%s),", childresult, accessresult, tmpresult));
693
				break;
694
			default:
695
				throw new NotImplementedException();
696
			}
697
			assert(m_tmpVars.size() == 1);
698
		}
699
		else
700
		{
701
			/*>>>>> See comment in ooaTypeCheckVisitor on method CheckPlace! <<<<<<<<<*/
702
			switch (tupleMapAccessExpression.child().type().kind())
703
			{
704
			case ListType:
705
				boolean isAttribute;
706
				isAttribute = tupleMapAccessExpression.child().kind() == ExpressionKind.Identifier &&
707
						((IdentifierExpression)tupleMapAccessExpression.child()).identifier().kind() == IdentifierKind.AttributeIdentifier;
708

  
709
				isAttribute = isAttribute || tupleMapAccessExpression.child().kind() == ExpressionKind.Access
710
						&& ((AccessExpression)tupleMapAccessExpression.child()).left().kind() == ExpressionKind.Identifier
711
						&& ((IdentifierExpression)((AccessExpression)tupleMapAccessExpression.child()).left()).isSelf()
712
						&& ((AccessExpression)tupleMapAccessExpression.child()).right().kind() == ExpressionKind.Identifier
713
						&& ((IdentifierExpression)((AccessExpression)tupleMapAccessExpression.child()).right()).identifier().kind()
714
						== IdentifierKind.AttributeIdentifier;
715

  
716

  
717
				final String newlist = String.format("RESVAR_%s", m_scratchbook.getNewTmpVarCntrValue());
718

  
719
				m_emitter.AppendLine(String.format("ulyssesListWrite(%s,%s,%s,%s),", childresult, accessresult, tmpresult, newlist));
720

  
721
				if (isAttribute)
722
				{ m_emitter.AppendLine(String.format("%s := %s,", childresult, newlist)); }
723
				else
724
				{ throw new NotImplementedException(); }
725

  
726
				break;
727
			default:
728
				throw new NotImplementedException();
729
			}
730

  
731

  
732
		}
733
	}
734

  
735

  
736
	@Override
737
	public /*override*/ void visit(ForallQuantifier quantifier)
738
	{
739
		final OoaPrologExpression pExpr = createExpressionVisitor();
740
		quantifier.child().Accept(pExpr);
741

  
742
		// TEMPXY = forall(enumerate1([var:type,...]),pred(var..))
743
		final StringBuilder Generator = new StringBuilder();
744
		final StringBuilder nullGuard = new StringBuilder();
745
		int i = 0;
746
		for (final Identifier v: quantifier.symbols().symbolList())
747
		{
748
			final OoaPrologIdentifier ident = createIdentifierVisitor();
749
			v.Accept(ident);
750

  
751
			final OoaPrologType identType = createTypeVisitor();
752
			v.type().Accept(identType);
753

  
754
			Generator.append(String.format("%s %s: %s", i == 0 ? "" : ",", ident.toString(), identType.toString()));
755
			if (v.type().kind() == TypeKind.OoActionSystemType)
756
				nullGuard.append(String.format("(%s == null) ; ", ident.toString()));
757
			i++;
758
		}
759

  
760
		m_emitter.AppendLine(String.format("%s = forall([%s], (%s(%s%s))),",
761
				NewTempVariable(), Generator.toString(), nullGuard.toString(), pExpr.toString(), pExpr.tmpVariables().get(0)));
762
	}
763

  
764

  
765

  
766
	@Override
767
	public /*override*/ void visit(ExistsQuantifier quantifier)
768
	{
769
		final OoaPrologExpression pExpr = createExpressionVisitor();
770
		quantifier.child().Accept(pExpr);
771

  
772
		// TEMPXY = exists(enumerate1([var:type,...]),pred(var..))
773
		final StringBuilder Generator = new StringBuilder();
774
		final StringBuilder nullGuard = new StringBuilder();
775
		int i = 0;
776
		for (final Identifier v: quantifier.symbols().symbolList())
777
		{
778
			final OoaPrologIdentifier ident = createIdentifierVisitor();
779
			v.Accept(ident);
780

  
781
			final OoaPrologType identType = createTypeVisitor();
782
			v.type().Accept(identType);
783

  
784
			Generator.append(String.format("%s %s: %s", i == 0 ? "" : ",", ident.toString(), identType.toString()));
785
			if (v.type().kind() == TypeKind.OoActionSystemType)
786
				nullGuard.append(String.format("(%s \\= null), ", ident.toString()));
787
			i++;
788
		}
789

  
790
		m_emitter.AppendLine(String.format("%s = exists([%s], (%s(%s%s))),",
791
				NewTempVariable(), Generator.toString(), nullGuard.toString(), pExpr.toString(), pExpr.tmpVariables().get(0)));
792
	}
793
	@Override
794
	public /*override*/ void visit(UnaryOperator unaryOperator)
795
	{
796
		assert(m_tmpVars.size() == 0);
797
		VisitSub(unaryOperator.child(), unaryOperator);
798

  
799
		if (unaryOperator.kind() == ExpressionKind.Cast)
800
			return;
801

  
802
		final String childresult = m_tmpVars.get(0); m_tmpVars.remove(0);
803
		assert(m_tmpVars.size() == 0);
804

  
805
		final String tmpresult = NewTempVariable();
806

  
807
		switch (unaryOperator.kind())
808
		{
809
		case head:
810
			m_emitter.AppendLine(String.format("ulyssesListHead(%s,%s),", childresult, tmpresult));
811
			break;
812

  
813
		case tail:
814
			m_emitter.AppendLine(String.format("ulyssesListTail(%s,%s),", childresult, tmpresult));
815
			break;
816

  
817
		case len:    // T_LEN:
818
			m_emitter.AppendLine(String.format("ulyssesListLength(%s,%s),", childresult, tmpresult));
819
			break;
820

  
821
		case not:
822

  
823
			if (unaryOperator.type().kind() == TypeKind.IntType)
824
				m_emitter.Append(String.format(" %s #= call(\\+", tmpresult));
825
			else
826
				m_emitter.Append(String.format(" %s = call(\\+", tmpresult));
827
			m_emitter.Append("(");
828
			m_emitter.Append(childresult);
829
			m_emitter.AppendLine(")),");
830

  
831

  
832
			break;
833

  
834
		case Cast:
835
			// todo
836
			break;
837

  
838
		default:
839
			if (unaryOperator.type().kind() == TypeKind.IntType)
840
				m_emitter.Append(String.format(" %s #= (%s", tmpresult, OperatorString(unaryOperator, unaryOperator.child().type())));
841
			else
842
				m_emitter.Append(String.format(" %s = (%s", tmpresult, OperatorString(unaryOperator, unaryOperator.child().type())));
843
			m_emitter.Append("(");
844
			m_emitter.Append(childresult);
845
			m_emitter.AppendLine(")),");
846
			break;
847
		}
848
		assert(m_tmpVars.size() == 1);
849
	}
850

  
851
	@Override
852
	public /*override*/ String toString()
853
	{
854
		return m_emitter.toString();
855
	}
856

  
857
	protected OoaPrologType createTypeVisitor() { return m_typeFactory.create(m_idFactory, m_scratchbook); }
858
	protected OoaPrologIdentifier createIdentifierVisitor() { return m_idFactory.create(); }
859
	protected OoaPrologExpression createExpressionVisitor() { return m_exprFactory.create(m_idFactory, m_typeFactory, m_scratchbook); }
860

  
861
	protected final OoaPrologIdentifier.Factory m_idFactory;
862
	protected final OoaPrologType.Factory m_typeFactory;
863
	protected final OoaPrologExpression.Factory m_exprFactory;
864

  
865
	protected OoaPrologExpression(
866
			OoaPrologIdentifier.Factory idFactory,
867
			OoaPrologType.Factory typeFactory,
868
			Scratchbook scratchbook,
869
			OoaPrologExpression.Factory expressionFactory)
870
	{
871
		this(idFactory, typeFactory, scratchbook, expressionFactory, false);
872
	}
873

  
874
	protected OoaPrologExpression(
875
			OoaPrologIdentifier.Factory idFactory,
876
			OoaPrologType.Factory typeFactory,
877
			Scratchbook scratchbook,
878
			OoaPrologExpression.Factory expressionFactory,
879
			boolean isLHS)
880
	{
881
		super();
882
		m_LhsExpression = isLHS;
883
		m_idFactory = idFactory;
884
		m_typeFactory = typeFactory;
885
		m_exprFactory = expressionFactory;
886
		m_scratchbook = scratchbook;
887
	}
888

  
889

  
890
	public String NewTempVariable()
891
	{
892
		final String result = String.format("TMPVAR_%s", m_scratchbook.getNewTmpVarCntrValue());
893
		m_tmpVars.add(result);
894
		return result;
895
	}
896

  
897
	public int GetUniqueNumber()
898
	{
899
		return m_scratchbook.getNewTmpVarCntrValue();
900
	}
65

  
66
public class OoaPrologExpression extends OoaExpressionVisitor
67
{
68
	public static class Factory
69
	{
70
		public final OoaPrologExpression create(OoaPrologIdentifier.Factory idFactory, OoaPrologType.Factory typeFactory, Scratchbook sb)
71
		{ return create(idFactory, typeFactory, sb, false); }
72
		public OoaPrologExpression create(OoaPrologIdentifier.Factory idFactory, OoaPrologType.Factory typeFactory, Scratchbook sb, boolean lhs)
73
		{ return new OoaPrologExpression(idFactory, typeFactory, sb, this, lhs); }
74
	}
75

  
76
	protected OoasCodeEmitter m_emitter = new OoasCodeEmitter();
77
	protected ArrayList<String> m_tmpVars = new ArrayList<String>();
78
	protected final Scratchbook m_scratchbook;
79
	private boolean m_LhsExpression = false;
80

  
81

  
82
	public ArrayList<String> tmpVariables() { return m_tmpVars; }
83
	public boolean isLhsExpression() { return m_LhsExpression; }
84

  
85
//	private String GetPrologType(UlyssesType aType)
86
//	{
87
//		OoaPrologType pType = createTypeVisitor();
88
//		aType.Accept(pType);
89
//		return pType.toString();
90
//	}
91

  
92
	protected String GetIdentifierString(Identifier anIdentifier)
93
	{
94
		final OoaPrologIdentifier pIdent = createIdentifierVisitor();
95
		anIdentifier.Accept(pIdent);
96
		return pIdent.toString();
97
	}
98

  
99

  
100
	// following call must not happen
101
	@Override
102
	public void visit(UnresolvedIdentifierExpression unresolvedIdentifierExpression)
103
	{
104
		assert(false);
105
	}
106

  
107
	// call of method that returns a value..
108
	@Override
109
	public /*override*/ void visit(CallExpression callExpression)
110
	{
111
		// we handle only function calls within expressions here (must have non-void return!)
112
		final FunctionType funtype = (FunctionType)callExpression.child().type();
113
		if (funtype.returnType() == null)
114
			throw new ArgumentException("Internal error: Function call in expression with return-type void!");
115

  
116
		String callstatement = "";
117
		final StringBuilder parameter = new StringBuilder();
118

  
119
		final OoaPrologExpression prologexpr = createExpressionVisitor();
120
		callExpression.child().Accept(prologexpr);
121

  
122
		m_emitter.Append(prologexpr.toString());
123
		callstatement = prologexpr.tmpVariables().get(0);
124
		int i = 0;
125
		for (final Expression arg: callExpression.arguments())
126
		{
127
			if (i != 0)
128
				parameter.append(", ");
129
			else
130
				i++;
131
			final OoaPrologExpression paramexpr = createExpressionVisitor();
132
			arg.Accept(paramexpr);
133
			m_emitter.Append(paramexpr.toString());
134
			parameter.append(paramexpr.tmpVariables().get(0));
135
		}
136
		if (parameter.length() > 0)
137
			m_emitter.AppendLine(String.format("%s(%s,%s),", callstatement, parameter, NewTempVariable()));
138
		else
139
			m_emitter.AppendLine(String.format("%s(%s),", callstatement, NewTempVariable()));
140
	}
141

  
142

  
143
	// we need to map all other things to Prolog constructs
144
	private String OperatorString(Expression expression, UlyssesType resultingType)
145
	{
146
		switch (expression.kind())
147
		{
148
		case abs:    // T_ABS:
149
		case card:   // T_CARD:
150
		case dom:    // T_DOM:
151
		case range:  // T_RNG:
152
		case merge:  // T_MERGE:
153
		case elems:  // T_ELEMS:
154
		case head:   // T_HEAD:
155
		case tail:   // T_TAIL:
156
		case conc:   // T_CONC:
157
		case inds:   // T_INDS:
158
		case dinter: // T_DINTER:
159
		case dunion: // T_DUNION:
160
		case domresby:   // T_DOMRESBY:
161
		case domresto:   // T_DOMRESTO:
162
		case rngresby:   // T_RNGRESBY:
163
		case rngresto:   // T_RNGRESTO:
164
		case inter:  // T_INTER:
165
		case union:  // T_UNION:
166
		case diff:   // T_DIFF:
167
		case munion: // T_MUNION:
168
		case seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
169
		case subset:
170
		case elemin:
171
		case notelemin:
172
		case implies:    // T_IMPLIES:
173
		case biimplies:  // T_BIIMPLIES:
174
		case Primed:
175
		case len:    // T_LEN:
176
			throw new NotImplementedException();
177

  
178
		case div:    // T_DIV:
179
			return "/";
180
		case idiv:   // T_IDIV:
181
			return "/";
182
		case mod:    // T_MOD:
183
			return "mod";
184
		case prod:   // T_PROD:
185
			return "*";
186
		case sum:    // T_SUM:
187
			return "+";
188
		case minus:  // T_MINUS:
189
			return "-";
190
		case less:
191
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "<" : "#<";
192
		case lessequal:
193
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "=<" : "#=<";
194
		case greater:
195
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? ">" : "#>";
196
		case greaterequal:
197
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? ">=" : "#>=";
198
		case equal:
199
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "==" : "#=";
200
		case notequal:
201
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "\\=" : "#\\=";
202
		case and:    // T_AND:
203
			throw new NotImplementedException(); // implemented in binaryoperator
204
		case or:     // T_OR:
205
			throw new NotImplementedException(); // implemented in binaryoperator
206
		case not:
207
			throw new NotImplementedException(); // implemented in binaryoperator
208

  
209
		case Cast:
210
			return "";
211

  
212
		default:
213
			return expression.kind().name(); //Enum.GetName(typeof(ExpressionKind), expression.kind);
214
		}
215
	}
216

  
217
	protected boolean isNumericBinary(Expression expression)
218
	{
219
		boolean result = false;
220
		if (expression instanceof BinaryOperator)
221
		{
222
			result = ((BinaryOperator)expression).left().type().kind() == TypeKind.IntType &&
223
					((BinaryOperator)expression).right().type().kind() == TypeKind.IntType;
224
		}
225
		else if (expression instanceof UnaryOperator)
226
		{
227
			result = ((UnaryOperator)expression).child().type().kind() == TypeKind.IntType;
228
		}
229
		else throw new NotImplementedException();
230
		return result;
231
	}
232

  
233
	@SuppressWarnings("unchecked")
234
	@Override
235
	public /*override*/ <T> void visit(ValueExpression<T> valueExpression)
236
	{
237
		assert(m_tmpVars.size() == 0);
238
		final String tmpVar = NewTempVariable();
239
		m_emitter.Append(String.format("%s ", tmpVar));
240

  
241

  
242
		if (valueExpression.value() == null)
243
			m_emitter.Append("= 'null'");
244
		else if (Boolean.class.isAssignableFrom(valueExpression.m_clazz))
245
			m_emitter.Append(((ValueExpression<Boolean>) valueExpression).value() ? " #= true" : " #= fail");
246
		else if (Character.class.isAssignableFrom(valueExpression.m_clazz))
247
			m_emitter.Append(String.format("#= '%s'", valueExpression.toString()));
248
		else if (Integer.class.isAssignableFrom(valueExpression.m_clazz))
249
			m_emitter.Append(String.format("#= %s", valueExpression.toString()));
250
		else
251
			m_emitter.Append(String.format("= %s", valueExpression.value().toString()));
252

  
253
		m_emitter.AppendLine(",");
254
		assert(m_tmpVars.size() == 1);
255
	}
256

  
257
	@Override
258
	public /*override*/ void visit(IdentifierExpression identifierExpression)
259
	{
260
		if (identifierExpression.identifier().kind() == IdentifierKind.LandmarkIdentifier)
261
		{
262
			final LandmarkIdentifier lmid = (LandmarkIdentifier)identifierExpression.identifier();
263
			final OoaPrologIdentifier pid = createIdentifierVisitor();
264
			lmid.Accept(pid);
265
			//m_emitter.Append(pid.ToString());
266
			m_tmpVars.add(pid.toString());
267
			return;
268
		}
269
		else if (identifierExpression.identifier().kind() == IdentifierKind.EnumIdentifier)
270
		{
271
			final EnumIdentifier enumid = (EnumIdentifier)identifierExpression.identifier();
272
			final EnumType enumType = (EnumType)enumid.type();
273
			//m_emitter.Append(enumType.listOfEnumSymbols.IndexOf(enumid));
274
			if (enumType instanceof ValuedEnumType)
275
				m_emitter.AppendLine(String.format("%s #= %s,", NewTempVariable(), enumid.Value()));
276
			else
277
				m_emitter.AppendLine(String.format("%s #= %s,", NewTempVariable(), enumType.listOfEnumSymbols().indexOf(enumid)));
278
		}
279
		else if (identifierExpression.isSelf())
280
		{
281
			m_emitter.AppendLine(String.format("%s = %s,", NewTempVariable(), GetIdentifierString(identifierExpression.identifier())));
282
		}
283
		/*else if (identifierExpression.identifier.kind == IdentifierKind.AttributeIdentifier)
284
        {
285
            m_emitter.AppendLine(String.format("getVal(%s,%s,_),", GetIdentifierString(identifierExpression.identifier), NewTempVariable(), ));
286
        }*/
287
		else
288
		{
289
			m_tmpVars.add(GetIdentifierString(identifierExpression.identifier()));
290
		}
291
	}
292

  
293
	@Override
294
	public /*override*/ void visit(TypeExpression typeExpression)
295
	{
296
		if (typeExpression.type().kind() != TypeKind.QrType &&
297
				typeExpression.type().kind() != TypeKind.EnumeratedType)
298
		{
299
			m_emitter.Append(GetIdentifierString(typeExpression.type().identifier()));
300
		}
301
	}
302

  
303

  
304
	@Override
305
	public /*override*/ void visit(ObjectConstructor objectConstructor)
306
	{
307
		if (objectConstructor.instances().size() > 1)
308
			throw new NotImplementedException();
309

  
310
		m_emitter.AppendLine(String.format("%s = '%s',", NewTempVariable(), objectConstructor.instances().get(0).Name));
311

  
312
		//m_emitter.Append(String.format("new %s(this)", GetIdentifierString(objectConstructor.type.identifier)));
313
	}
314

  
315
	@Override
316
	public /*override*/ void visit(ListConstructor listConstructor)
317
	{
318
		if (listConstructor.hasComprehension())
319
		{
320
			final OoaPrologExpression compr = createExpressionVisitor();
321
			listConstructor.comprehension().Accept(compr);
322
			final OoaPrologExpression elem = createExpressionVisitor();
323
			listConstructor.elements().get(0).Accept(elem);
324

  
325
			final StringBuilder enumvars = new StringBuilder();
326
			int i = 0;
327
			for (final Identifier v: listConstructor.comprehensionVariables().symbolList())
328
			{
329
				final OoaPrologIdentifier ident = createIdentifierVisitor();
330
				v.Accept(ident);
331

  
332
				final OoaPrologType identType = createTypeVisitor();
333
				v.type().Accept(identType);
334

  
335
				enumvars.append(String.format("%s %s: %s", i == 0 ? "" : ",", ident.toString(), identType.toString()));
336
				i++;
337
			}
338

  
339
			m_emitter.AppendLine("% listcomprehension");
340
			m_emitter.AppendLine(String.format("%s = {%s:[%s]:(%s%s,%s%s)}",
341
					NewTempVariable(), elem.tmpVariables().get(0), enumvars.toString(), compr.toString(), compr.tmpVariables().get(0),
342
					elem.toString(), "1=1" /*elem.ToString() == String.Empty ? "1=1" : elem.tmpVariables[0]*/));
343
		}
344
		else
345
		{
346
			m_emitter.AppendLine("% make list");
347
			m_emitter.AppendLine(String.format("%s = []", NewTempVariable()));
348

  
349
			for (final Expression expr: listConstructor.elements())
350
			{
351
				m_emitter.Append(", ");
352

  
353
				final OoaPrologExpression pVal = createExpressionVisitor();
354
				expr.Accept(pVal);
355
				m_emitter.Append(pVal.toString());
356
				assert(pVal.tmpVariables().size() == 1);
357
				m_emitter.AppendLine(String.format("ulyssesListConc(%s,[%s],%s)", m_tmpVars.get(0), pVal.tmpVariables().get(0), NewTempVariable()));
358
				m_tmpVars.remove(0);
359
			}
360
		}
361
		m_emitter.Append(",");
362
		assert(m_tmpVars.size() == 1);
363
	}
364

  
365
	@Override
366
	public /*override*/ void visit(SetConstructor setConstructor)
367
	{
368
		m_emitter.AppendLine("% make set");
369
		// our resulting set.
370
		m_emitter.AppendLine(String.format("%s = []", NewTempVariable()));
371

  
372
		for (final Expression expr: setConstructor.items())
373
		{
374
			m_emitter.Append(", ");
375

  
376
			final OoaPrologExpression pVal = createExpressionVisitor();
377
			expr.Accept(pVal);
378
			m_emitter.Append(pVal.toString());
379
			assert(pVal.tmpVariables().size() == 1);
380
			m_emitter.AppendLine(String.format("ulyssesListConc(%s,[%s],%s)", m_tmpVars.get(0), pVal.tmpVariables().get(0), NewTempVariable()));
381
			m_tmpVars.remove(0);
382
		}
383
		m_emitter.Append(",");
384
		assert(m_tmpVars.size() == 1);
385
	}
386

  
387
	@Override
388
	public /*override*/ void visit(MapConstructor mapConstructor)
389
	{
390
		throw new NotImplementedException();
391
	}
392

  
393
	@Override
394
	public /*override*/ void visit(TupleConstructor tupleConstructor)
395
	{
396
		if (tupleConstructor.isMatcher())
397
		{
398
			// being dealt with in binaryoperator (since we only allow tuple=MyTuple(a,b))
399
			NewTempVariable();
400
			return;
401
		}
402
		else
403
		{
404
			m_emitter.AppendLine("% make tuple");
405
			m_emitter.AppendLine(String.format("%s = []", NewTempVariable()));
406

  
407
			for (final Expression expr: tupleConstructor.values())
408
			{
409
				m_emitter.Append(", ");
410

  
411
				final OoaPrologExpression pVal = createExpressionVisitor();
412
				expr.Accept(pVal);
413
				m_emitter.Append(pVal.toString());
414
				assert(pVal.tmpVariables().size() == 1);
415
				m_emitter.AppendLine(String.format("ulyssesListConc(%s,[%s],%s)", m_tmpVars.get(0), pVal.tmpVariables().get(0), NewTempVariable()));
416
				m_tmpVars.remove(0);
417
			}
418
			m_emitter.Append(",");
419
			assert(m_tmpVars.size() == 1);
420
		}
421
	}
422

  
423
	@Override
424
	public /*override*/ void visit(QValConstructor qValConstructor)
425
	{
426
		final OoaPrologIdentifier pident = createIdentifierVisitor();
427
		qValConstructor.type().identifier().Accept(pident);
428
		final StringBuilder qVal = new StringBuilder();
429
		if (qValConstructor.value() != null || qValConstructor.value().length != 0)
430
		{
431
			final OoaPrologExpression landmark1 = createExpressionVisitor();
432
			qValConstructor.value()[0].Accept(landmark1);
433
			qVal.append(landmark1.toString());
434

  
435
			if (qValConstructor.value().length > 1)
436
			{
437
				final OoaPrologExpression landmark2 = createExpressionVisitor();
438
				qValConstructor.value()[1].Accept(landmark2);
439
				qVal.append("..");
440
				qVal.append(landmark2.toString());
441
			}
442
		}
443
		else
444
			qVal.append("_");
445

  
446
		String deriv = "_";
447
		switch (qValConstructor.valueDeriv())
448
		{
449
		case Dec:
450
			deriv = "dec";
451
			break;
452
		case Inc:
453
			deriv = "inc";
454
			break;
455
		case Steady:
456
			deriv = "std";
457
			break;
458
		default:
459
			throw new NotImplementedException();
460
		}
461
		final String tmpVar = NewTempVariable();
462
		m_emitter.AppendLine(String.format("%s = (%s:%s/%s),", tmpVar, pident.toString(), qVal.toString(), deriv));
463
	}
464

  
465
	@Override
466
	public /*override*/ void visit(AccessExpression accessExpression)
467
	{
468
		if (accessExpression.left().type().kind() != TypeKind.QrType &&
469
				accessExpression.left().type().kind() != TypeKind.EnumeratedType &&
470
				!(accessExpression.right().kind() == ExpressionKind.Identifier &&
471
				((IdentifierExpression)accessExpression.right()).identifier().kind() == IdentifierKind.AttributeIdentifier))
472
		{
473
			assert(m_tmpVars.size() == 0);
474
			// enums and qr types are directly (statically) converted to nums...
475
			VisitSub(accessExpression.left(), accessExpression);
476
			final String leftresult = m_tmpVars.get(0); m_tmpVars.remove(0);
477

  
478
			VisitSub(accessExpression.right(), accessExpression);
479
			final String rightresult = m_tmpVars.get(0); m_tmpVars.remove(0);
480

  
481
			m_tmpVars.add(String.format("%s\\%s", leftresult, rightresult));
482
		}
483
		else
484
			VisitSub(accessExpression.right(), accessExpression);
485
	}
486

  
487
	@Override
488
	public /*override*/ void visit(BinaryOperator binaryOperator)
489
	{
490
		final OoasCodeEmitter origEmitter = m_emitter;
491

  
492

  
493
		// eval stack must be empty
494
		assert(m_tmpVars.size() == 0);
495
		// traverse left
496
		final OoasCodeEmitter leftcode = new OoasCodeEmitter();
497
		m_emitter = leftcode;
498
		VisitSub(binaryOperator.left(), binaryOperator);
499
		final String leftresult = m_tmpVars.get(0); m_tmpVars.remove(0);
500
		assert(m_tmpVars.size() == 0);
501
		// traverse right
502
		final OoasCodeEmitter rightcode = new OoasCodeEmitter();
503
		m_emitter = rightcode;
504
		VisitSub(binaryOperator.right(), binaryOperator);
505
		final String rightresult = m_tmpVars.get(0); m_tmpVars.remove(0);
506
		// eval stack must be empty
507
		assert(m_tmpVars.size() == 0);
508

  
509
		m_emitter = origEmitter;
510

  
511
		// get tmp.var
512
		final String tmpVar = NewTempVariable();
513

  
514
		switch (binaryOperator.kind())
515
		{
516
		case elemin:
517
			m_emitter.Append(leftcode.toString());
518
			m_emitter.Append(rightcode.toString());
519
			m_emitter.AppendLine(String.format(" %s = member(%s,%s),",
520
					tmpVar, leftresult, rightresult));
521
			break;
522
		case and:    // T_AND:
523
			m_emitter.Append(leftcode.toString());
524
			m_emitter.Append(rightcode.toString());
525
			m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
526
					tmpVar, leftresult, ",", rightresult));
527
			break;
528
		case or:     // T_OR:
529
			m_emitter.Append(leftcode.toString());
530
			m_emitter.Append(rightcode.toString());
531
			m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
532
					tmpVar, leftresult, ";", rightresult));
533
			break;
534

  
535
		case implies:
536
			m_emitter.Append(leftcode.toString());
537
			m_emitter.AppendLine(String.format(" %s = (%s -> (%s%s); true), ", // {0} = (({1} -> ({2}{3}); true))
538
					tmpVar, leftresult, rightcode.toString(), rightresult));
539
			break;
540

  
541
		case equal:
542
			m_emitter.Append(leftcode.toString());
543
			m_emitter.Append(rightcode.toString());
544
			/*check if we have tupleconstructors as matchers*/
545
			TupleConstructor matcher = null;
546
			String aTuple = null;
547
			if (binaryOperator.left().kind() == ExpressionKind.TupleConstr &&
548
					((TupleConstructor)binaryOperator.left()).isMatcher())
549
			{
550
				matcher = (TupleConstructor)binaryOperator.left();
551
				aTuple = rightresult;
552
			}
553
			else if (binaryOperator.right().kind() == ExpressionKind.TupleConstr &&
554
					((TupleConstructor)binaryOperator.right()).isMatcher())
555
			{
556
				matcher = (TupleConstructor)binaryOperator.right();
557
				aTuple = leftresult;
558
			}
559

  
560
			if (matcher == null)
561
				m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
562
				tmpVar, leftresult, OperatorString(binaryOperator, binaryOperator.left().type()), rightresult));
563
			else
564
			{
565
				m_emitter.Append(String.format("%s = unify(%s = [", tmpVar, aTuple));
566
				int cntr = 0;
567
				for(final Expression x: matcher.values())
568
				{
569
					if (cntr != 0)
570
						m_emitter.Append(", ");
571
					else
572
						cntr++;
573

  
574
					if (x.kind() != ExpressionKind.Identifier)
575
						throw new ArgumentException();
576

  
577
					final IdentifierExpression ident = (IdentifierExpression)x;
578
					final OoaPrologIdentifier avisitor = createIdentifierVisitor();
579
					ident.Accept(avisitor);
580
					m_emitter.Append(avisitor.toString());
581
				}
582
				m_emitter.AppendLine("]),");
583
			}
584
			break;
585

  
586

  
587

  
588
		case conc:
589
			m_emitter.Append(leftcode.toString());
590
			m_emitter.Append(rightcode.toString());
591
			m_emitter.AppendLine(String.format("ulyssesListConc(%s,%s,%s),", leftresult, rightresult, tmpVar));
592
			break;
593

  
594
		default:
595
			m_emitter.Append(leftcode.toString());
596
			m_emitter.Append(rightcode.toString());
597
			if (binaryOperator.left().type().kind() == TypeKind.QrType)
598
				m_emitter.Append("qEval");
599
			//m_emitter.Append("(");
600
			if (binaryOperator.type().kind() == TypeKind.IntType)
601
				m_emitter.AppendLine(String.format(" %s #= (%s %s %s), ",
602
						tmpVar, leftresult, OperatorString(binaryOperator, binaryOperator.left().type()), rightresult));
603
			else
604
				m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
605
						tmpVar, leftresult, OperatorString(binaryOperator, binaryOperator.left().type()), rightresult));
606
			//m_emitter.Append(")");
607
			break;
608
		}
609
		assert(m_tmpVars.size() == 1);
610
	}
611

  
612
	@Override
613
	public /*override*/ void visit(TernaryOperator ternaryOperator)
614
	{
615
		if (ternaryOperator.kind() == ExpressionKind.conditional)
616
		{
617
			VisitSub(ternaryOperator.left(), ternaryOperator);
618
			final String leftresult = m_tmpVars.get(0); m_tmpVars.remove(0);
619
			VisitSub(ternaryOperator.mid(), ternaryOperator);
620
			final String midresult = m_tmpVars.get(0); m_tmpVars.remove(0);
621
			VisitSub(ternaryOperator.right(), ternaryOperator);
622
			final String rightresult = m_tmpVars.get(0); m_tmpVars.remove(0);
623

  
624
			final String varname = NewTempVariable();
625

  
626
			// (cond, expr #= var; #\ (cond), expr #= var)
627
			m_emitter.Append("((");
628
			m_emitter.Append(leftresult);
629
			m_emitter.Append(", unify(");
630
			m_emitter.Append(midresult);
631
			m_emitter.Append(String.format(" = %s) );( call(\\+(%s)), unify(", varname, leftresult));
632
			m_emitter.Append(rightresult);
633
			m_emitter.Append(String.format(" = %s) )),", varname));
634
		}
635
		else if (ternaryOperator.kind() == ExpressionKind.foldRL)
636
			throw new NotImplementedException();
637
		else if (ternaryOperator.kind() == ExpressionKind.foldLR)
638
		{
639
			VisitSub(ternaryOperator.mid(), ternaryOperator);
640
			final String midresult = m_tmpVars.get(0); m_tmpVars.remove(0);
641
			VisitSub(ternaryOperator.right(), ternaryOperator);
642
			final String rightresult = m_tmpVars.get(0); m_tmpVars.remove(0);
643

  
644

  
645
			// make vars unique
646
			final int uniqueNumer = GetUniqueNumber();
647
			final CallExpression leftcall = (CallExpression)ternaryOperator.left();
648
			final IdentifierExpression elemId = (IdentifierExpression)leftcall.arguments().get(leftcall.arguments().size() - 1);
649
			elemId.identifier().SetTokenText(String.format("Elem_%s", uniqueNumer));
650
			final IdentifierExpression currentResultId = (IdentifierExpression)leftcall.arguments().get(leftcall.arguments().size() - 2);
651
			currentResultId.identifier().SetTokenText(String.format("In_%s", uniqueNumer));
652

  
653
			final String elemVarName = GetIdentifierString(elemId.identifier());
654
			final String inVarName = GetIdentifierString(currentResultId.identifier());
655

  
656
			m_emitter.Append(String.format("fun_fold(%s,%s,(%s, %s, Out_%s,(",
657
					midresult, rightresult, elemVarName, inVarName, uniqueNumer));
658
			VisitSub(leftcall, ternaryOperator);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff