Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / math / Operations.java @ 7

1
/**
2
  *
3
  *                      OOAS Compiler
4
  *
5
  *       Copyright 2015, AIT Austrian Institute of Technology.
6
  * This code is based on the C# Version of the OOAS Compiler, which is
7
  * copyright 2015 by the Institute of Software Technology, Graz University
8
  * of Technology with portions copyright by the AIT Austrian Institute of
9
  * Technology. All rights reserved.
10
  *
11
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
12
  *
13
  * If you modify the file please update the list of contributors below to in-
14
  * clude your name. Please also stick to the coding convention of using TABs
15
  * to do the basic (block-level) indentation and spaces for anything after
16
  * that. (Enable the display of special chars and it should be pretty obvious
17
  * what this means.) Also, remove all trailing whitespace.
18
  *
19
  * Contributors:
20
  *               Willibald Krenn (AIT)
21
  *               Stephan Zimmerer (AIT)
22
  *               Markus Demetz (AIT)
23
  *               Christoph Czurda (AIT)
24
  *
25
  */
26

    
27

    
28
package org.momut.ooas.math;
29

    
30
import org.momut.ooas.ast.expressions.ExpressionKind;
31
import org.momut.ooas.utils.exceptions.ArgumentException;
32
import org.momut.ooas.utils.exceptions.NotImplementedException;
33

    
34
public class Operations<T> extends AbstractOperations
35
{
36
        public static class BasicOps<T> {
37
                public T unMinus(T input) {throw new NotImplementedException();}
38

    
39
                public T minus(T inputA, T inputB) {throw new NotImplementedException();}
40
                public T plus(T inputA, T inputB) {throw new NotImplementedException();}
41
                public T div(T inputA, T inputB) {throw new NotImplementedException();}
42
                public T pow(T inputA, T inputB) {throw new NotImplementedException();}
43
                public T prod(T inputA, T inputB) {throw new NotImplementedException();}
44
                public T mod(T inputA, T inputB) {throw new NotImplementedException();}
45

    
46
                public boolean equal(T inputA, T intputB) {throw new NotImplementedException();}
47
                public boolean smaller(T inputA, T intputB) {throw new NotImplementedException();}
48
                public boolean greater(T inputA, T intputB){throw new NotImplementedException();}
49

    
50
                public T getDefaultValue() {throw new NotImplementedException();}
51
        }
52

    
53
        protected final BasicOps<T> m_basicOperations;
54

    
55

    
56
        @SuppressWarnings("unchecked")
57
        @Override
58
        public AbstractRange GenericArithmeticCover(AbstractRange type1, AbstractRange type2, ExpressionKind op)
59
        {
60
                Range<T> a = (Range<T>) type1;
61
                Range<T> b = (Range<T>) type2;
62

    
63
//                Range<T> a = type1 as Range<T>;
64
//                Range<T> b = type2 as Range<T>;
65

    
66
                if (a == null || b == null)
67
                        throw new ArgumentException();
68

    
69
                return GenericArithmeticCover(a, b, op);
70
        }
71

    
72
        public Range<T> GenericArithmeticCover(Range<T> type1, Range<T> type2, ExpressionKind op)
73
        {
74
                T defaultValue = m_basicOperations.getDefaultValue();
75
                Range<T> result = type1.Create(defaultValue, defaultValue);
76

    
77
                switch (op)
78
                {
79
                        case unminus:
80
                                result.min = m_basicOperations.unMinus(type1.max);
81
                                result.max = m_basicOperations.unMinus(type1.min);
82
                                break;
83
                        case unplus:
84
                                break;
85

    
86
                        case minus:
87
                                assert(type2 != null);
88
                                // we do some sort of resulttype = type1 - type2
89
                                // hence, do the unminus stuff with type 2
90
                                T spare = type2.max;
91
                                type2.max = m_basicOperations.unMinus(type2.min);
92
                                type2.min = m_basicOperations.unMinus(spare);
93
                                // now it's the same as with sum.. but c# does not let us fall through..
94
                                result.min = m_basicOperations.plus(type1.min, type2.min);
95
                                result.max = m_basicOperations.plus(type1.max, type2.max);
96
                                break;
97
                        case sum:
98
                                assert(type2 != null);
99
                                result.min = m_basicOperations.plus(type1.min, type2.min);
100
                                result.max = m_basicOperations.plus(type1.max, type2.max);
101
                                break;
102
                        case idiv:
103
                        case div:
104
                                assert(type2 != null);
105
                                type2.min = m_basicOperations.equal(type2.min, defaultValue) ?
106
                                                m_basicOperations.unMinus(type2.precision) : type2.min;
107
                                type2.max = m_basicOperations.equal(type2.max, defaultValue) ?
108
                                                type2.precision : type2.max;
109
                                // hmm, brute force.. is there some formula?
110
                                result.max = m_basicOperations.div(type1.min, type2.min);
111
                                result.min = result.max;
112

    
113
                                T tmp = m_basicOperations.div(type1.max, type2.min);
114
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
115
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
116

    
117
                                tmp = m_basicOperations.div(type1.min, type2.max);
118
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
119
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
120

    
121
                                tmp = m_basicOperations.div(type1.max, type2.max);
122
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
123
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
124
                                break;
125
                        case mod:
126
                                throw new ArgumentException(); // do this one level up
127
                        case pow:
128
                                // ok, this is bad. - just give up here
129
                                result.max = result.typemax;
130
                                result.min = result.typemin;
131
                                break;
132
                        case prod:
133
                                // hmm, brute force.. is there some formula?
134
                                result.max = m_basicOperations.prod(type1.min, type2.min);
135
                                result.min = result.max;
136

    
137
                                tmp = m_basicOperations.prod(type1.max, type2.min);
138
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
139
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
140

    
141
                                tmp = m_basicOperations.prod(type1.min, type2.max);
142
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
143
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
144

    
145
                                tmp = m_basicOperations.prod(type1.max, type2.max);
146
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
147
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
148
                                break;
149

    
150
                        default:
151
                                throw new NotImplementedException();
152
                }
153
                return result;
154
        }
155

    
156

    
157
        public Operations()
158
        {
159
                m_basicOperations = new BasicOps<T>();
160
        }
161

    
162
        public Operations(BasicOps<T> basicOperations)
163
        {
164
                m_basicOperations = basicOperations;
165
        }
166
}