Project

General

Profile

Revision 7

Added by Willibald K. over 8 years ago

changing java, cpp, hpp files to unix line endings

View differences:

OoaPrologSymbolicExpression.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.prologsymbolic;

29

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

  
30 30
import org.momut.ooas.ast.expressions.BinaryOperator;
31 31
import org.momut.ooas.ast.expressions.Expression;
32 32
import org.momut.ooas.ast.expressions.ExpressionKind;
......
48 48
import org.momut.ooas.codegen.prolog.Scratchbook;
49 49
import org.momut.ooas.utils.exceptions.ArgumentException;
50 50
import org.momut.ooas.utils.exceptions.NotImplementedException;
51

  
52
public class OoaPrologSymbolicExpression extends OoaPrologExpression
53
{
54
	public static class Factory extends OoaPrologExpression.Factory
55
	{
56
		@Override
57
		public /*override*/ OoaPrologExpression create(OoaPrologIdentifier.Factory idFactory, OoaPrologType.Factory typeFactory, Scratchbook scratchbook, boolean lhs)
58
		{ return new OoaPrologSymbolicExpression(idFactory, typeFactory, scratchbook, this, lhs); }
59
	}
60

  
61
	/*Also treats bools and enums as ints..*/
62
	@Override
63
	protected boolean isNumericBinary(Expression expression)
64
	{
65
		boolean result = false;
66
		if (expression instanceof BinaryOperator)
67
		{
68
			final TypeKind leftKind = ((BinaryOperator)expression).left().type().kind();
69
			final TypeKind rightKind = ((BinaryOperator)expression).right().type().kind();
70
			result = (leftKind == TypeKind.IntType || leftKind == TypeKind.BoolType || leftKind == TypeKind.EnumeratedType) &&
71
					(rightKind == TypeKind.IntType || rightKind == TypeKind.BoolType || rightKind == TypeKind.EnumeratedType);
72
		}
73
		else if (expression instanceof UnaryOperator)
74
		{
75
			final TypeKind childKind = ((UnaryOperator)expression).child().type().kind();
76
			result = childKind == TypeKind.IntType || childKind == TypeKind.BoolType || childKind == TypeKind.EnumeratedType;
77
		}
78
		else throw new NotImplementedException();
79
		return result;
80
	}
81

  
82
	// we need to map all other things to Prolog constructs
83
	private String operatorString(Expression expression, UlyssesType resultingType)
84
	{
85
		switch (expression.kind())
86
		{
87
		case abs:    // T_ABS:
88
		case card:   // T_CARD:
89
		case dom:    // T_DOM:
90
		case range:  // T_RNG:
91
		case merge:  // T_MERGE:
92
		case elems:  // T_ELEMS:
93
		case head:   // T_HEAD:
94
		case tail:   // T_TAIL:
95
		case conc:   // T_CONC:
96
		case inds:   // T_INDS:
97
		case dinter: // T_DINTER:
98
		case dunion: // T_DUNION:
99
		case domresby:   // T_DOMRESBY:
100
		case domresto:   // T_DOMRESTO:
101
		case rngresby:   // T_RNGRESBY:
102
		case rngresto:   // T_RNGRESTO:
103
		case inter:  // T_INTER:
104
		case union:  // T_UNION:
105
		case diff:   // T_DIFF:
106
		case munion: // T_MUNION:
107
		case seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
108
		case subset:
109
		case elemin:
110
		case notelemin:
111
		case implies:    // T_IMPLIES:
112
		case biimplies:  // T_BIIMPLIES:
113
		case Primed:
114
		case len:    // T_LEN:
115
			throw new NotImplementedException();
116

  
117
		case div:    // T_DIV:
118
			return "/";
119
		case idiv:   // T_IDIV:
120
			return "/";
121
		case mod:    // T_MOD:
122
			return "mod";
123
		case prod:   // T_PROD:
124
			return "*";
125
		case sum:    // T_SUM:
126
			return "+";
127
		case minus:  // T_MINUS:
128
			return "-";
129
		case less:
130
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "<" : "#<";
131
		case lessequal:
132
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "=<" : "#=<";
133
		case greater:
134
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? ">" : "#>";
135
		case greaterequal:
136
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? ">=" : "#>=";
137
		case equal:
138
			return resultingType.kind() == TypeKind.QrType ? "==" : "#=";
139
		case notequal:
140
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "\\=" : "#\\=";
141
		case and:    // T_AND:
142
			throw new NotImplementedException(); // implemented in binaryoperator
143
		case or:     // T_OR:
144
			throw new NotImplementedException(); // implemented in binaryoperator
145
		case not:
146
			throw new NotImplementedException(); // implemented in binaryoperator
147

  
148
		case Cast:
149
			return "";
150

  
151
		default:
152
			return expression.kind().name(); //Enum.GetName(typeof(ExpressionKind), expression.kind);
153
		}
154
	}
155

  
156
	@SuppressWarnings("unchecked")
157
	@Override
158
	public /*override*/ <T> void visit(ValueExpression<T> valueExpression)
159
	{
160
		assert(m_tmpVars.size() == 0);
161
		final String tmpVar = NewTempVariable();
162
		m_emitter.Append(String.format("%s ", tmpVar));
163

  
164

  
165
		if (valueExpression.value() == null)
166
			m_emitter.Append("= 'null'");
167
		else if (Boolean.class.isAssignableFrom(valueExpression.m_clazz))
168
			m_emitter.Append(((ValueExpression<Boolean>)valueExpression).value() ? " = true" : " = false");
169
		else if (Character.class.isAssignableFrom(valueExpression.m_clazz))
170
			m_emitter.Append(String.format("= '%s'", valueExpression.toString()));
171
		else if (Integer.class.isAssignableFrom(valueExpression.m_clazz))
172
			m_emitter.Append(String.format("= %s", valueExpression.toString()));
173
		else
174
			m_emitter.Append(String.format("= %s", valueExpression.value().toString()));
175

  
176
		m_emitter.AppendLine(",");
177
		assert(m_tmpVars.size() == 1);
178
	}
179

  
180
	@Override
181
	public /*override*/ void visit(IdentifierExpression identifierExpression)
182
	{
183
		if (identifierExpression.identifier().kind() == IdentifierKind.LandmarkIdentifier)
184
		{
185
			final LandmarkIdentifier lmid = (LandmarkIdentifier)identifierExpression.identifier();
186
			final OoaPrologIdentifier pid = createIdentifierVisitor();
187
			lmid.Accept(pid);
188
			//m_emitter.Append(pid.ToString());
189
			m_tmpVars.add(pid.toString());
190
			return;
191
		}
192
		else if (identifierExpression.identifier().kind() == IdentifierKind.EnumIdentifier)
193
		{
194
			final EnumIdentifier enumid = (EnumIdentifier)identifierExpression.identifier();
195
			final EnumType enumType = (EnumType)enumid.type();
196
			//m_emitter.Append(enumType.listOfEnumSymbols.IndexOf(enumid));
197
			if (enumType instanceof ValuedEnumType)
198
				m_emitter.AppendLine(String.format("%s = %s,", NewTempVariable(), enumid.Value()));
199
			else
200
				m_emitter.AppendLine(String.format("%s = %s,", NewTempVariable(), enumType.listOfEnumSymbols().indexOf(enumid)));
201
		}
202
		else if (identifierExpression.isSelf())
203
		{
204
			m_emitter.AppendLine(String.format("%s = %s,", NewTempVariable(), GetIdentifierString(identifierExpression.identifier())));
205
		}
206
		else
207
		{
208
			m_tmpVars.add(GetIdentifierString(identifierExpression.identifier()));
209
		}
210
	}
211

  
212
	@Override
213
	public /*override*/ void visit(UnaryOperator unaryOperator)
214
	{
215
		assert(m_tmpVars.size() == 0);
216
		VisitSub(unaryOperator.child(), unaryOperator);
217

  
218
		if (unaryOperator.kind() == ExpressionKind.Cast)
219
			return;
220

  
221
		final String childresult = m_tmpVars.get(0); m_tmpVars.remove(0);
222
		assert(m_tmpVars.size() == 0);
223

  
224
		final String tmpresult = NewTempVariable();
225

  
226
		switch (unaryOperator.kind())
227
		{
228
		case head:
229
			m_emitter.AppendLine(String.format("ulyssesListHead(%s,%s),", childresult, tmpresult));
230
			break;
231

  
232
		case tail:
233
			m_emitter.AppendLine(String.format("ulyssesListTail(%s,%s),", childresult, tmpresult));
234
			break;
235

  
236
		case len:    // T_LEN:
237
			m_emitter.AppendLine(String.format("ulyssesListLength(%s,%s),", childresult, tmpresult));
238
			break;
239

  
240
		case not:
241
			m_emitter.Append(String.format(" %s = ( #\\", tmpresult));
242
			m_emitter.Append("(");
243
			m_emitter.Append(childresult);
244
			m_emitter.AppendLine(")),");
245
			break;
246

  
247
		case Cast:
248
			// todo
249
			break;
250

  
251
		default:
252
			//do not use #= for assignments in the symbolic backend
253
			m_emitter.Append(String.format(" %s = (%s", tmpresult, operatorString(unaryOperator, unaryOperator.child().type())));
254
			m_emitter.Append("(");
255
			m_emitter.Append(childresult);
256
			m_emitter.AppendLine(")),");
257
			break;
258
		}
259
		assert(m_tmpVars.size() == 1);
260
	}
261

  
262
	@Override
263
	public /*override*/ void visit(BinaryOperator binaryOperator)
264
	{
265
		// eval stack must be empty
266
		assert(m_tmpVars.size() == 0);
267

  
268
		final OoasCodeEmitter origEmitter = m_emitter;
269
		final OoasCodeEmitter leftcode = new OoasCodeEmitter();
270
		final OoasCodeEmitter rightcode = new OoasCodeEmitter();
271

  
272

  
273
		// traverse left
274
		m_emitter = leftcode;
275
		VisitSub(binaryOperator.left(), binaryOperator);
276
		final String leftresult = m_tmpVars.get(0); m_tmpVars.remove(0);
277
		assert(m_tmpVars.size() == 0);
278

  
279
		// traverse right
280
		m_emitter = rightcode;
281
		VisitSub(binaryOperator.right(), binaryOperator);
282
		final String rightresult = m_tmpVars.get(0); m_tmpVars.remove(0);
283
		// eval stack must be empty
284
		assert(m_tmpVars.size() == 0);
285

  
286
		// restore original emitter and get tmp.var
287
		m_emitter = origEmitter;
288
		final String tmpVar = NewTempVariable();
289

  
290
		switch (binaryOperator.kind())
291
		{
292
		case elemin:
293
			m_emitter.Append(leftcode.toString());
294
			m_emitter.Append(rightcode.toString());
295
			m_emitter.AppendLine(String.format(" %s = member(%s,%s),",
296
					tmpVar, leftresult, rightresult));
297
			break;
298
		case and:    // T_AND:
299
			m_emitter.Append(leftcode.toString());
300
			m_emitter.Append(rightcode.toString());
301
			m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
302
					tmpVar, leftresult, "#/\\", rightresult));
303
			break;
304
		case or:     // T_OR:
305
			m_emitter.Append(leftcode.toString());
306
			m_emitter.Append(rightcode.toString());
307
			m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
308
					tmpVar, leftresult, "#\\/", rightresult));
309
			break;
310

  
311
		case implies:
312
			m_emitter.Append(leftcode.toString());
313
			m_emitter.AppendLine(String.format(" %s = (%s -> (%s%s); true), ", // {0} = (({1} -> ({2}{3}); true))
314
					tmpVar, leftresult, rightcode.toString(), rightresult));
315
			break;
316

  
317
		case equal:
318
			m_emitter.Append(leftcode.toString());
319
			m_emitter.Append(rightcode.toString());
320
			/*check if we have tupleconstructors as matchers*/
321
			TupleConstructor matcher = null;
322
			String aTuple = null;
323
			if (binaryOperator.left().kind() == ExpressionKind.TupleConstr &&
324
					((TupleConstructor)binaryOperator.left()).isMatcher())
325
			{
326
				matcher = (TupleConstructor)binaryOperator.left();
327
				aTuple = rightresult;
328
			}
329
			else if (binaryOperator.right().kind() == ExpressionKind.TupleConstr &&
330
					((TupleConstructor)binaryOperator.right()).isMatcher())
331
			{
332
				matcher = (TupleConstructor)binaryOperator.right();
333
				aTuple = leftresult;
334
			}
335

  
336
			if (matcher == null)
337
				m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
338
				tmpVar, leftresult, operatorString(binaryOperator, binaryOperator.left().type()), rightresult));
339
			else
340
			{
341
				m_emitter.Append(String.format("%s = unify(%s = [", tmpVar, aTuple));
342
				int cntr = 0;
343
				for (final Expression x: matcher.values())
344
				{
345
					if (cntr != 0)
346
						m_emitter.Append(", ");
347
					else
348
						cntr++;
349

  
350
					if (x.kind() != ExpressionKind.Identifier)
351
						throw new ArgumentException();
352

  
353
					final IdentifierExpression ident = (IdentifierExpression)x;
354
					final OoaPrologIdentifier avisitor = createIdentifierVisitor();
355
					ident.Accept(avisitor);
356
					m_emitter.Append(avisitor.toString());
357
				}
358
				m_emitter.AppendLine("]),");
359
			}
360
			break;
361

  
362

  
363

  
364
		case conc:
365
			m_emitter.Append(leftcode.toString());
366
			m_emitter.Append(rightcode.toString());
367
			m_emitter.AppendLine(String.format("ulyssesListConc(%s,%s,%s),", leftresult, rightresult, tmpVar));
368
			break;
369

  
370
		default:
371
			m_emitter.Append(leftcode.toString());
372
			m_emitter.Append(rightcode.toString());
373
			if (binaryOperator.left().type().kind() == TypeKind.QrType)
374
				m_emitter.Append("qEval");
375

  
376
			//do not use #= for assignments in the symbolic backend
377
			m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
378
					tmpVar, leftresult, operatorString(binaryOperator, binaryOperator.left().type()), rightresult));
379
			break;
380
		}
381
		assert(m_tmpVars.size() == 1);
382
	}
383

  
384

  
385

  
386
	protected OoaPrologSymbolicExpression(
387
			OoaPrologIdentifier.Factory idFactory,
388
			OoaPrologType.Factory typeFactory,
389
			Scratchbook scratchbook,
390
			OoaPrologExpression.Factory expressionFactory,
391
			boolean lhs)
392
	{
393
		super (idFactory, typeFactory, scratchbook, expressionFactory,  lhs);
394
	}
395

  
396
}
51

  
52
public class OoaPrologSymbolicExpression extends OoaPrologExpression
53
{
54
	public static class Factory extends OoaPrologExpression.Factory
55
	{
56
		@Override
57
		public /*override*/ OoaPrologExpression create(OoaPrologIdentifier.Factory idFactory, OoaPrologType.Factory typeFactory, Scratchbook scratchbook, boolean lhs)
58
		{ return new OoaPrologSymbolicExpression(idFactory, typeFactory, scratchbook, this, lhs); }
59
	}
60

  
61
	/*Also treats bools and enums as ints..*/
62
	@Override
63
	protected boolean isNumericBinary(Expression expression)
64
	{
65
		boolean result = false;
66
		if (expression instanceof BinaryOperator)
67
		{
68
			final TypeKind leftKind = ((BinaryOperator)expression).left().type().kind();
69
			final TypeKind rightKind = ((BinaryOperator)expression).right().type().kind();
70
			result = (leftKind == TypeKind.IntType || leftKind == TypeKind.BoolType || leftKind == TypeKind.EnumeratedType) &&
71
					(rightKind == TypeKind.IntType || rightKind == TypeKind.BoolType || rightKind == TypeKind.EnumeratedType);
72
		}
73
		else if (expression instanceof UnaryOperator)
74
		{
75
			final TypeKind childKind = ((UnaryOperator)expression).child().type().kind();
76
			result = childKind == TypeKind.IntType || childKind == TypeKind.BoolType || childKind == TypeKind.EnumeratedType;
77
		}
78
		else throw new NotImplementedException();
79
		return result;
80
	}
81

  
82
	// we need to map all other things to Prolog constructs
83
	private String operatorString(Expression expression, UlyssesType resultingType)
84
	{
85
		switch (expression.kind())
86
		{
87
		case abs:    // T_ABS:
88
		case card:   // T_CARD:
89
		case dom:    // T_DOM:
90
		case range:  // T_RNG:
91
		case merge:  // T_MERGE:
92
		case elems:  // T_ELEMS:
93
		case head:   // T_HEAD:
94
		case tail:   // T_TAIL:
95
		case conc:   // T_CONC:
96
		case inds:   // T_INDS:
97
		case dinter: // T_DINTER:
98
		case dunion: // T_DUNION:
99
		case domresby:   // T_DOMRESBY:
100
		case domresto:   // T_DOMRESTO:
101
		case rngresby:   // T_RNGRESBY:
102
		case rngresto:   // T_RNGRESTO:
103
		case inter:  // T_INTER:
104
		case union:  // T_UNION:
105
		case diff:   // T_DIFF:
106
		case munion: // T_MUNION:
107
		case seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
108
		case subset:
109
		case elemin:
110
		case notelemin:
111
		case implies:    // T_IMPLIES:
112
		case biimplies:  // T_BIIMPLIES:
113
		case Primed:
114
		case len:    // T_LEN:
115
			throw new NotImplementedException();
116

  
117
		case div:    // T_DIV:
118
			return "/";
119
		case idiv:   // T_IDIV:
120
			return "/";
121
		case mod:    // T_MOD:
122
			return "mod";
123
		case prod:   // T_PROD:
124
			return "*";
125
		case sum:    // T_SUM:
126
			return "+";
127
		case minus:  // T_MINUS:
128
			return "-";
129
		case less:
130
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "<" : "#<";
131
		case lessequal:
132
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "=<" : "#=<";
133
		case greater:
134
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? ">" : "#>";
135
		case greaterequal:
136
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? ">=" : "#>=";
137
		case equal:
138
			return resultingType.kind() == TypeKind.QrType ? "==" : "#=";
139
		case notequal:
140
			return resultingType.kind() == TypeKind.QrType || !isNumericBinary(expression) ? "\\=" : "#\\=";
141
		case and:    // T_AND:
142
			throw new NotImplementedException(); // implemented in binaryoperator
143
		case or:     // T_OR:
144
			throw new NotImplementedException(); // implemented in binaryoperator
145
		case not:
146
			throw new NotImplementedException(); // implemented in binaryoperator
147

  
148
		case Cast:
149
			return "";
150

  
151
		default:
152
			return expression.kind().name(); //Enum.GetName(typeof(ExpressionKind), expression.kind);
153
		}
154
	}
155

  
156
	@SuppressWarnings("unchecked")
157
	@Override
158
	public /*override*/ <T> void visit(ValueExpression<T> valueExpression)
159
	{
160
		assert(m_tmpVars.size() == 0);
161
		final String tmpVar = NewTempVariable();
162
		m_emitter.Append(String.format("%s ", tmpVar));
163

  
164

  
165
		if (valueExpression.value() == null)
166
			m_emitter.Append("= 'null'");
167
		else if (Boolean.class.isAssignableFrom(valueExpression.m_clazz))
168
			m_emitter.Append(((ValueExpression<Boolean>)valueExpression).value() ? " = true" : " = false");
169
		else if (Character.class.isAssignableFrom(valueExpression.m_clazz))
170
			m_emitter.Append(String.format("= '%s'", valueExpression.toString()));
171
		else if (Integer.class.isAssignableFrom(valueExpression.m_clazz))
172
			m_emitter.Append(String.format("= %s", valueExpression.toString()));
173
		else
174
			m_emitter.Append(String.format("= %s", valueExpression.value().toString()));
175

  
176
		m_emitter.AppendLine(",");
177
		assert(m_tmpVars.size() == 1);
178
	}
179

  
180
	@Override
181
	public /*override*/ void visit(IdentifierExpression identifierExpression)
182
	{
183
		if (identifierExpression.identifier().kind() == IdentifierKind.LandmarkIdentifier)
184
		{
185
			final LandmarkIdentifier lmid = (LandmarkIdentifier)identifierExpression.identifier();
186
			final OoaPrologIdentifier pid = createIdentifierVisitor();
187
			lmid.Accept(pid);
188
			//m_emitter.Append(pid.ToString());
189
			m_tmpVars.add(pid.toString());
190
			return;
191
		}
192
		else if (identifierExpression.identifier().kind() == IdentifierKind.EnumIdentifier)
193
		{
194
			final EnumIdentifier enumid = (EnumIdentifier)identifierExpression.identifier();
195
			final EnumType enumType = (EnumType)enumid.type();
196
			//m_emitter.Append(enumType.listOfEnumSymbols.IndexOf(enumid));
197
			if (enumType instanceof ValuedEnumType)
198
				m_emitter.AppendLine(String.format("%s = %s,", NewTempVariable(), enumid.Value()));
199
			else
200
				m_emitter.AppendLine(String.format("%s = %s,", NewTempVariable(), enumType.listOfEnumSymbols().indexOf(enumid)));
201
		}
202
		else if (identifierExpression.isSelf())
203
		{
204
			m_emitter.AppendLine(String.format("%s = %s,", NewTempVariable(), GetIdentifierString(identifierExpression.identifier())));
205
		}
206
		else
207
		{
208
			m_tmpVars.add(GetIdentifierString(identifierExpression.identifier()));
209
		}
210
	}
211

  
212
	@Override
213
	public /*override*/ void visit(UnaryOperator unaryOperator)
214
	{
215
		assert(m_tmpVars.size() == 0);
216
		VisitSub(unaryOperator.child(), unaryOperator);
217

  
218
		if (unaryOperator.kind() == ExpressionKind.Cast)
219
			return;
220

  
221
		final String childresult = m_tmpVars.get(0); m_tmpVars.remove(0);
222
		assert(m_tmpVars.size() == 0);
223

  
224
		final String tmpresult = NewTempVariable();
225

  
226
		switch (unaryOperator.kind())
227
		{
228
		case head:
229
			m_emitter.AppendLine(String.format("ulyssesListHead(%s,%s),", childresult, tmpresult));
230
			break;
231

  
232
		case tail:
233
			m_emitter.AppendLine(String.format("ulyssesListTail(%s,%s),", childresult, tmpresult));
234
			break;
235

  
236
		case len:    // T_LEN:
237
			m_emitter.AppendLine(String.format("ulyssesListLength(%s,%s),", childresult, tmpresult));
238
			break;
239

  
240
		case not:
241
			m_emitter.Append(String.format(" %s = ( #\\", tmpresult));
242
			m_emitter.Append("(");
243
			m_emitter.Append(childresult);
244
			m_emitter.AppendLine(")),");
245
			break;
246

  
247
		case Cast:
248
			// todo
249
			break;
250

  
251
		default:
252
			//do not use #= for assignments in the symbolic backend
253
			m_emitter.Append(String.format(" %s = (%s", tmpresult, operatorString(unaryOperator, unaryOperator.child().type())));
254
			m_emitter.Append("(");
255
			m_emitter.Append(childresult);
256
			m_emitter.AppendLine(")),");
257
			break;
258
		}
259
		assert(m_tmpVars.size() == 1);
260
	}
261

  
262
	@Override
263
	public /*override*/ void visit(BinaryOperator binaryOperator)
264
	{
265
		// eval stack must be empty
266
		assert(m_tmpVars.size() == 0);
267

  
268
		final OoasCodeEmitter origEmitter = m_emitter;
269
		final OoasCodeEmitter leftcode = new OoasCodeEmitter();
270
		final OoasCodeEmitter rightcode = new OoasCodeEmitter();
271

  
272

  
273
		// traverse left
274
		m_emitter = leftcode;
275
		VisitSub(binaryOperator.left(), binaryOperator);
276
		final String leftresult = m_tmpVars.get(0); m_tmpVars.remove(0);
277
		assert(m_tmpVars.size() == 0);
278

  
279
		// traverse right
280
		m_emitter = rightcode;
281
		VisitSub(binaryOperator.right(), binaryOperator);
282
		final String rightresult = m_tmpVars.get(0); m_tmpVars.remove(0);
283
		// eval stack must be empty
284
		assert(m_tmpVars.size() == 0);
285

  
286
		// restore original emitter and get tmp.var
287
		m_emitter = origEmitter;
288
		final String tmpVar = NewTempVariable();
289

  
290
		switch (binaryOperator.kind())
291
		{
292
		case elemin:
293
			m_emitter.Append(leftcode.toString());
294
			m_emitter.Append(rightcode.toString());
295
			m_emitter.AppendLine(String.format(" %s = member(%s,%s),",
296
					tmpVar, leftresult, rightresult));
297
			break;
298
		case and:    // T_AND:
299
			m_emitter.Append(leftcode.toString());
300
			m_emitter.Append(rightcode.toString());
301
			m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
302
					tmpVar, leftresult, "#/\\", rightresult));
303
			break;
304
		case or:     // T_OR:
305
			m_emitter.Append(leftcode.toString());
306
			m_emitter.Append(rightcode.toString());
307
			m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
308
					tmpVar, leftresult, "#\\/", rightresult));
309
			break;
310

  
311
		case implies:
312
			m_emitter.Append(leftcode.toString());
313
			m_emitter.AppendLine(String.format(" %s = (%s -> (%s%s); true), ", // {0} = (({1} -> ({2}{3}); true))
314
					tmpVar, leftresult, rightcode.toString(), rightresult));
315
			break;
316

  
317
		case equal:
318
			m_emitter.Append(leftcode.toString());
319
			m_emitter.Append(rightcode.toString());
320
			/*check if we have tupleconstructors as matchers*/
321
			TupleConstructor matcher = null;
322
			String aTuple = null;
323
			if (binaryOperator.left().kind() == ExpressionKind.TupleConstr &&
324
					((TupleConstructor)binaryOperator.left()).isMatcher())
325
			{
326
				matcher = (TupleConstructor)binaryOperator.left();
327
				aTuple = rightresult;
328
			}
329
			else if (binaryOperator.right().kind() == ExpressionKind.TupleConstr &&
330
					((TupleConstructor)binaryOperator.right()).isMatcher())
331
			{
332
				matcher = (TupleConstructor)binaryOperator.right();
333
				aTuple = leftresult;
334
			}
335

  
336
			if (matcher == null)
337
				m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
338
				tmpVar, leftresult, operatorString(binaryOperator, binaryOperator.left().type()), rightresult));
339
			else
340
			{
341
				m_emitter.Append(String.format("%s = unify(%s = [", tmpVar, aTuple));
342
				int cntr = 0;
343
				for (final Expression x: matcher.values())
344
				{
345
					if (cntr != 0)
346
						m_emitter.Append(", ");
347
					else
348
						cntr++;
349

  
350
					if (x.kind() != ExpressionKind.Identifier)
351
						throw new ArgumentException();
352

  
353
					final IdentifierExpression ident = (IdentifierExpression)x;
354
					final OoaPrologIdentifier avisitor = createIdentifierVisitor();
355
					ident.Accept(avisitor);
356
					m_emitter.Append(avisitor.toString());
357
				}
358
				m_emitter.AppendLine("]),");
359
			}
360
			break;
361

  
362

  
363

  
364
		case conc:
365
			m_emitter.Append(leftcode.toString());
366
			m_emitter.Append(rightcode.toString());
367
			m_emitter.AppendLine(String.format("ulyssesListConc(%s,%s,%s),", leftresult, rightresult, tmpVar));
368
			break;
369

  
370
		default:
371
			m_emitter.Append(leftcode.toString());
372
			m_emitter.Append(rightcode.toString());
373
			if (binaryOperator.left().type().kind() == TypeKind.QrType)
374
				m_emitter.Append("qEval");
375

  
376
			//do not use #= for assignments in the symbolic backend
377
			m_emitter.AppendLine(String.format(" %s = (%s %s %s), ",
378
					tmpVar, leftresult, operatorString(binaryOperator, binaryOperator.left().type()), rightresult));
379
			break;
380
		}
381
		assert(m_tmpVars.size() == 1);
382
	}
383

  
384

  
385

  
386
	protected OoaPrologSymbolicExpression(
387
			OoaPrologIdentifier.Factory idFactory,
388
			OoaPrologType.Factory typeFactory,
389
			Scratchbook scratchbook,
390
			OoaPrologExpression.Factory expressionFactory,
391
			boolean lhs)
392
	{
393
		super (idFactory, typeFactory, scratchbook, expressionFactory,  lhs);
394
	}
395

  
396
}

Also available in: Unified diff