Project

General

Profile

Revision 7

Added by Willibald K. over 8 years ago

changing java, cpp, hpp files to unix line endings

View differences:

Expression.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.ast.expressions;
29

  
30
import java.util.ArrayList;
31
import java.util.List;
28
package org.momut.ooas.ast.expressions;
32 29

  
30
import java.util.ArrayList;
31
import java.util.List;
32

  
33 33
import org.momut.ooas.ast.AstNode;
34 34
import org.momut.ooas.ast.AstNodeTypeEnum;
35 35
import org.momut.ooas.ast.IAst;
......
52 52
import org.momut.ooas.utils.exceptions.ArgumentException;
53 53
import org.momut.ooas.utils.exceptions.NotImplementedException;
54 54
import org.momut.ooas.visitors.OoaPrintVisitor;
55

  
56
///////////////////////////////////////////////
57
///  Expressions
58
///
59
/// Note: Since we allow expression of the form
60
/// myTuple(a,b) = hd x, where a and b are newly
61
/// introduced placeholders, the expression knows
62
/// about local variables.
63
/// Scoping: Consider following expression
64
///     3 > a and myTuple(b,d) = hd e and b < 5
65
/// which gives
66
///             and
67
///          /       \
68
///         /         and
69
///        /        /     \
70
///       >        =        <
71
///      / \      /  \     /  \
72
///     3   a  (b,d)  e   b    5
73
///  the scope of b and d is defined by the binary
74
///  expression that has the leaf within its left child
75
///  (== the second 'and').
76
///  Local variables may only be introduced in constructors
77
///  of sets, lists, and tuples. Therefore the type is
78
///  known.
79

  
80

  
81
public abstract class Expression extends AstNode implements IAst
82
{
83
	protected ExpressionKind m_kind;
84
	protected UlyssesType m_type;
85
	protected int m_line;
86
	protected int m_pos;
87
	protected SymbolTable m_freeVariables;
88
	protected ArrayList<FunctionIdentifier> m_callTargets;
89

  
90
	public ExpressionKind kind() { return m_kind; }
91
	public UlyssesType type() { return m_type; }
92
	public int line() { return m_line; }
93
	public int pos() { return m_pos; }
94
	public SymbolTable freeVariables() { return m_freeVariables; }
95
	public List<FunctionIdentifier> callTargets() { return m_callTargets; }
96

  
97
	public Expression(ExpressionKind aKind, int line, int pos)
98
	{
99
		m_kind = aKind;
100
		m_line = line;
101
		m_pos = pos;
102
		m_callTargets = new ArrayList<FunctionIdentifier>();
103
	}
104

  
105
	public Expression(Expression toCopy)
106
	{
107
		m_kind = toCopy.m_kind;
108
		m_line = toCopy.m_line;
109
		m_pos = toCopy.m_pos;
110
		m_callTargets = new ArrayList<FunctionIdentifier>(toCopy.callTargets());
111
		m_type = toCopy.m_type;
112
		m_freeVariables = new SymbolTable(toCopy.m_freeVariables);
113
	}
114

  
115
	public /*virtual*/ Expression Clone()
116
	{
117
		throw new NotImplementedException();
118
	}
119

  
120
	public void SetType(UlyssesType aType)
121
	{
122
		if (aType == null)
123
			throw new ArgumentException();
124
		m_type = aType;
125
	}
126

  
127
	public void SetFreeVariables(SymbolTable aSymTab)
128
	{
129
		m_freeVariables = aSymTab;
130
	}
131

  
132
	public ArrayList<ExpressionVariableIdentifier> GetUninitializedFreeVariables()
133
	{
134
		final ArrayList<ExpressionVariableIdentifier> result = new ArrayList<ExpressionVariableIdentifier>();
135
		if (m_freeVariables != null)
136
			for(final Identifier v: m_freeVariables.symbolList())
137
			{
138
				final ExpressionVariableIdentifier id = (ExpressionVariableIdentifier)v;
139
				if (id.initialized() == false)
140
					result.add(id);
141
			}
142
		return result;
143
	}
144

  
145

  
146
	@Override
147
	public AstNodeTypeEnum nodeType() { return AstNodeTypeEnum.expression; }
148

  
149
	@Override
150
	public /*virtual*/ void Accept(IAstVisitor visitor)
151
	{
152
		throw new NotImplementedException();
153
	}
154

  
155

  
156
	/// <summary>
157
	/// Calculates the arithmetic cover, i.e. the return type of the operation, given two types.
158
	/// This is different from the cover-method defined at the type level.
159
	/// Note: We do saturating operations on the type boundaries.
160
	/// </summary>
161
	public static UlyssesType ArithmeticCover(UlyssesType type1, UlyssesType type2, ExpressionKind op)
162
	{
163
		if (!type1.IsNumeric() || (type2 != null && !type2.IsNumeric()))
164
			throw new ArgumentException();
165

  
166
		if (type1 instanceof ValuedEnumType)
167
			type1 = ((ValuedEnumType)type1).getIntType();
168
		if (type2 instanceof ValuedEnumType)
169
			type2 = ((ValuedEnumType)type2).getIntType();
170

  
171
		AbstractRange result;
172
		AbstractRange rangeType1 = null;
173
		AbstractRange rangeType2 = null;
174
		AbstractOperations operations;
175
		final boolean resultIsFloat = type1.kind() == TypeKind.FloatType
176
				|| op == ExpressionKind.div
177
				|| (type2 != null && type2.kind() == TypeKind.FloatType);
178
		if (resultIsFloat)
179
		{
180
			rangeType1 = new DoubleRange(
181
				type1.kind() == TypeKind.IntType ? ((IntType)type1).rangeHigh() : ((FloatType)type1).high(),
182
				type1.kind() == TypeKind.IntType ? ((IntType)type1).rangeLow() : ((FloatType)type1).low());
183
			if (type2 != null)
184
			{
185
				rangeType2 = new DoubleRange(
186
					type2.kind() == TypeKind.IntType ? ((IntType)type2).rangeHigh() : ((FloatType)type2).high(),
187
					type2.kind() == TypeKind.IntType ? ((IntType)type2).rangeLow() : ((FloatType)type2).low());
188
			}
189
			operations = new SaturatedDoubleOperations();
190
		}
191
		else
192
		{
193
			rangeType1 = new IntegerRange(((IntType)type1).rangeHigh(), ((IntType)type1).rangeLow());
194
			rangeType2 = new IntegerRange(((IntType)type2).rangeHigh(), ((IntType)type2).rangeLow());
195
			operations = new SaturatedIntegerOperations();
196
		}
197

  
198
		switch (op)
199
		{
200
			case pow:
201
			case prod:
202
			case unminus:
203
			case unplus:
204
			case minus:
205
			case sum:
206
			case div:
207
				result = operations.GenericArithmeticCover(rangeType1, rangeType2, op);
208
				break;
209

  
210
			case idiv:
211
				if (resultIsFloat)
212
					throw new ArgumentException();
213
				assert(type2 != null);
214
				result = operations.GenericArithmeticCover(rangeType1, rangeType2, op);
215
				break;
216

  
217
			case mod:
218
				if (resultIsFloat)
219
					throw new ArgumentException();
220
				assert(type2 != null);
221
				// FIXME: see http://mathforum.org/library/drmath/view/52343.html; LLVM only supports rem!
222
				final boolean isSigned = ((IntegerRange)rangeType2).min < 0 || ((IntegerRange)rangeType1).min < 0;
223
				result = new IntegerRange(((IntegerRange)rangeType2).max - 1, isSigned ? -((IntegerRange)rangeType2).max - 1 : 0);
224
				break;
225

  
226
			default:
227
				throw new NotImplementedException();
228
		}
229

  
230
		if (resultIsFloat)
231
			return new FloatType(
232
					((DoubleRange)result).min,
233
					((DoubleRange)result).max,
234
					FloatType.defaultPrecision(),
235
					null);
236
		else
237
			// this is crude, but see whether it works..
238
			return new IntType(
239
					((IntegerRange)result).min,
240
					((IntegerRange)result).max,
241
					null);
242
	}
243

  
244

  
245
	@Override
246
	public String toString()
247
	{
248
		return toString(new OoaPrintVisitor(null));
249
	}
250

  
251
	public String toString(OoaPrintVisitor aFormatter) {
252
		this.Accept(aFormatter);
253
		return aFormatter.toString();
254
	}
255
}
256

  
55

  
56
///////////////////////////////////////////////
57
///  Expressions
58
///
59
/// Note: Since we allow expression of the form
60
/// myTuple(a,b) = hd x, where a and b are newly
61
/// introduced placeholders, the expression knows
62
/// about local variables.
63
/// Scoping: Consider following expression
64
///     3 > a and myTuple(b,d) = hd e and b < 5
65
/// which gives
66
///             and
67
///          /       \
68
///         /         and
69
///        /        /     \
70
///       >        =        <
71
///      / \      /  \     /  \
72
///     3   a  (b,d)  e   b    5
73
///  the scope of b and d is defined by the binary
74
///  expression that has the leaf within its left child
75
///  (== the second 'and').
76
///  Local variables may only be introduced in constructors
77
///  of sets, lists, and tuples. Therefore the type is
78
///  known.
79

  
80

  
81
public abstract class Expression extends AstNode implements IAst
82
{
83
	protected ExpressionKind m_kind;
84
	protected UlyssesType m_type;
85
	protected int m_line;
86
	protected int m_pos;
87
	protected SymbolTable m_freeVariables;
88
	protected ArrayList<FunctionIdentifier> m_callTargets;
89

  
90
	public ExpressionKind kind() { return m_kind; }
91
	public UlyssesType type() { return m_type; }
92
	public int line() { return m_line; }
93
	public int pos() { return m_pos; }
94
	public SymbolTable freeVariables() { return m_freeVariables; }
95
	public List<FunctionIdentifier> callTargets() { return m_callTargets; }
96

  
97
	public Expression(ExpressionKind aKind, int line, int pos)
98
	{
99
		m_kind = aKind;
100
		m_line = line;
101
		m_pos = pos;
102
		m_callTargets = new ArrayList<FunctionIdentifier>();
103
	}
104

  
105
	public Expression(Expression toCopy)
106
	{
107
		m_kind = toCopy.m_kind;
108
		m_line = toCopy.m_line;
109
		m_pos = toCopy.m_pos;
110
		m_callTargets = new ArrayList<FunctionIdentifier>(toCopy.callTargets());
111
		m_type = toCopy.m_type;
112
		m_freeVariables = new SymbolTable(toCopy.m_freeVariables);
113
	}
114

  
115
	public /*virtual*/ Expression Clone()
116
	{
117
		throw new NotImplementedException();
118
	}
119

  
120
	public void SetType(UlyssesType aType)
121
	{
122
		if (aType == null)
123
			throw new ArgumentException();
124
		m_type = aType;
125
	}
126

  
127
	public void SetFreeVariables(SymbolTable aSymTab)
128
	{
129
		m_freeVariables = aSymTab;
130
	}
131

  
132
	public ArrayList<ExpressionVariableIdentifier> GetUninitializedFreeVariables()
133
	{
134
		final ArrayList<ExpressionVariableIdentifier> result = new ArrayList<ExpressionVariableIdentifier>();
135
		if (m_freeVariables != null)
136
			for(final Identifier v: m_freeVariables.symbolList())
137
			{
138
				final ExpressionVariableIdentifier id = (ExpressionVariableIdentifier)v;
139
				if (id.initialized() == false)
140
					result.add(id);
141
			}
142
		return result;
143
	}
144

  
145

  
146
	@Override
147
	public AstNodeTypeEnum nodeType() { return AstNodeTypeEnum.expression; }
148

  
149
	@Override
150
	public /*virtual*/ void Accept(IAstVisitor visitor)
151
	{
152
		throw new NotImplementedException();
153
	}
154

  
155

  
156
	/// <summary>
157
	/// Calculates the arithmetic cover, i.e. the return type of the operation, given two types.
158
	/// This is different from the cover-method defined at the type level.
159
	/// Note: We do saturating operations on the type boundaries.
160
	/// </summary>
161
	public static UlyssesType ArithmeticCover(UlyssesType type1, UlyssesType type2, ExpressionKind op)
162
	{
163
		if (!type1.IsNumeric() || (type2 != null && !type2.IsNumeric()))
164
			throw new ArgumentException();
165

  
166
		if (type1 instanceof ValuedEnumType)
167
			type1 = ((ValuedEnumType)type1).getIntType();
168
		if (type2 instanceof ValuedEnumType)
169
			type2 = ((ValuedEnumType)type2).getIntType();
170

  
171
		AbstractRange result;
172
		AbstractRange rangeType1 = null;
173
		AbstractRange rangeType2 = null;
174
		AbstractOperations operations;
175
		final boolean resultIsFloat = type1.kind() == TypeKind.FloatType
176
				|| op == ExpressionKind.div
177
				|| (type2 != null && type2.kind() == TypeKind.FloatType);
178
		if (resultIsFloat)
179
		{
180
			rangeType1 = new DoubleRange(
181
				type1.kind() == TypeKind.IntType ? ((IntType)type1).rangeHigh() : ((FloatType)type1).high(),
182
				type1.kind() == TypeKind.IntType ? ((IntType)type1).rangeLow() : ((FloatType)type1).low());
183
			if (type2 != null)
184
			{
185
				rangeType2 = new DoubleRange(
186
					type2.kind() == TypeKind.IntType ? ((IntType)type2).rangeHigh() : ((FloatType)type2).high(),
187
					type2.kind() == TypeKind.IntType ? ((IntType)type2).rangeLow() : ((FloatType)type2).low());
188
			}
189
			operations = new SaturatedDoubleOperations();
190
		}
191
		else
192
		{
193
			rangeType1 = new IntegerRange(((IntType)type1).rangeHigh(), ((IntType)type1).rangeLow());
194
			rangeType2 = new IntegerRange(((IntType)type2).rangeHigh(), ((IntType)type2).rangeLow());
195
			operations = new SaturatedIntegerOperations();
196
		}
197

  
198
		switch (op)
199
		{
200
			case pow:
201
			case prod:
202
			case unminus:
203
			case unplus:
204
			case minus:
205
			case sum:
206
			case div:
207
				result = operations.GenericArithmeticCover(rangeType1, rangeType2, op);
208
				break;
209

  
210
			case idiv:
211
				if (resultIsFloat)
212
					throw new ArgumentException();
213
				assert(type2 != null);
214
				result = operations.GenericArithmeticCover(rangeType1, rangeType2, op);
215
				break;
216

  
217
			case mod:
218
				if (resultIsFloat)
219
					throw new ArgumentException();
220
				assert(type2 != null);
221
				// FIXME: see http://mathforum.org/library/drmath/view/52343.html; LLVM only supports rem!
222
				final boolean isSigned = ((IntegerRange)rangeType2).min < 0 || ((IntegerRange)rangeType1).min < 0;
223
				result = new IntegerRange(((IntegerRange)rangeType2).max - 1, isSigned ? -((IntegerRange)rangeType2).max - 1 : 0);
224
				break;
225

  
226
			default:
227
				throw new NotImplementedException();
228
		}
229

  
230
		if (resultIsFloat)
231
			return new FloatType(
232
					((DoubleRange)result).min,
233
					((DoubleRange)result).max,
234
					FloatType.defaultPrecision(),
235
					null);
236
		else
237
			// this is crude, but see whether it works..
238
			return new IntType(
239
					((IntegerRange)result).min,
240
					((IntegerRange)result).max,
241
					null);
242
	}
243

  
244

  
245
	@Override
246
	public String toString()
247
	{
248
		return toString(new OoaPrintVisitor(null));
249
	}
250

  
251
	public String toString(OoaPrintVisitor aFormatter) {
252
		this.Accept(aFormatter);
253
		return aFormatter.toString();
254
	}
255
}
256

  

Also available in: Unified diff