1
1
package com .regnosys .rosetta .interpreternew .visitors ;
2
2
3
- import java .util .List ;
3
+ import java .math .BigDecimal ;
4
+ import java .time .Duration ;
5
+ import java .time .LocalDate ;
6
+ import java .time .LocalDateTime ;
7
+ import java .time .format .DateTimeFormatter ;
4
8
5
9
import org .eclipse .emf .ecore .EObject ;
6
10
11
+ import com .regnosys .rosetta .interpreternew .values .RosettaInterpreterDateValue ;
7
12
import com .regnosys .rosetta .interpreternew .values .RosettaInterpreterEnvironment ;
8
13
import com .regnosys .rosetta .interpreternew .values .RosettaInterpreterError ;
9
14
import com .regnosys .rosetta .interpreternew .values .RosettaInterpreterErrorValue ;
@@ -36,77 +41,150 @@ public RosettaInterpreterValue interp(ArithmeticOperation expr,
36
41
RosettaInterpreterValue leftInterpreted = left .accept (visitor , env );
37
42
RosettaInterpreterValue rightInterpreted = right .accept (visitor , env );
38
43
39
- if (!(leftInterpreted instanceof RosettaInterpreterNumberValue
40
- || leftInterpreted instanceof RosettaInterpreterStringValue )
41
- || !(rightInterpreted instanceof RosettaInterpreterNumberValue
42
- || rightInterpreted instanceof RosettaInterpreterStringValue )) {
43
-
44
- // Check for errors in the left or right side of the binary operation
45
- RosettaInterpreterErrorValue leftErrors =
46
- checkForErrors (leftInterpreted , "Leftside" , expr );
47
- RosettaInterpreterErrorValue rightErrors =
48
- checkForErrors (rightInterpreted , "Rightside" , expr );
49
- return RosettaInterpreterErrorValue .merge (List .of (leftErrors , rightErrors ));
50
- }
51
44
52
- boolean sameType =
53
- (leftInterpreted instanceof RosettaInterpreterStringValue
54
- && rightInterpreted instanceof RosettaInterpreterStringValue )
55
- || (!(leftInterpreted instanceof RosettaInterpreterStringValue )
56
- && !(rightInterpreted instanceof RosettaInterpreterStringValue ));
57
- if (!sameType ) {
58
- return new RosettaInterpreterErrorValue (
59
- new RosettaInterpreterError (
60
- "The terms of the operation "
61
- + "are neither both strings nor both numbers" , expr ));
62
- }
63
-
45
+ // Check for errors in the left or right side of the binary operation
46
+ RosettaInterpreterErrorValue leftErrors =
47
+ checkForErrors (leftInterpreted , "Leftside" , expr );
48
+ RosettaInterpreterErrorValue rightErrors =
49
+ checkForErrors (rightInterpreted , "Rightside" , expr );
50
+ if (leftErrors .getErrors ().size () + rightErrors .getErrors ().size () > 0 ) {
51
+ return RosettaInterpreterErrorValue .merge (leftErrors , rightErrors );
52
+ }
53
+
54
+
55
+ //Interpret string concatenation
64
56
if (leftInterpreted instanceof RosettaInterpreterStringValue
65
57
&& rightInterpreted instanceof RosettaInterpreterStringValue ) {
66
- String leftString = ((RosettaInterpreterStringValue ) leftInterpreted )
67
- .getValue ();
68
- String rightString = ((RosettaInterpreterStringValue ) rightInterpreted )
69
- .getValue ();
70
- if (expr .getOperator ().equals ("+" )) {
71
- return new RosettaInterpreterStringValue (leftString + rightString );
72
- }
73
- else {
74
- return new RosettaInterpreterErrorValue (
75
- new RosettaInterpreterError (
76
- "The terms are strings but the operation "
77
- + "is not concatenation: not implemented" , expr ));
78
- }
58
+ return interpretString (leftInterpreted , rightInterpreted , expr );
59
+
60
+ //Interpret number operations
79
61
} else if (leftInterpreted instanceof RosettaInterpreterNumberValue
80
62
&& rightInterpreted instanceof RosettaInterpreterNumberValue ) {
81
- RosettaNumber leftNumber = ((RosettaInterpreterNumberValue ) leftInterpreted ).getValue ();
82
- RosettaNumber rightNumber = ((RosettaInterpreterNumberValue ) rightInterpreted ).getValue ();
63
+ return interpretNumber (leftInterpreted , rightInterpreted , expr );
64
+
65
+ //Interpret date subtraction
66
+ } else if (leftInterpreted instanceof RosettaInterpreterDateValue
67
+ && rightInterpreted instanceof RosettaInterpreterDateValue ) {
68
+ return interpretDate (leftInterpreted , rightInterpreted , expr );
83
69
84
- if (expr .getOperator ().equals ("+" )) {
85
- return new RosettaInterpreterNumberValue ((leftNumber
86
- .add (rightNumber )).bigDecimalValue ());
87
- } else if (expr .getOperator ().equals ("-" )) {
88
- return new RosettaInterpreterNumberValue ((leftNumber
89
- .subtract (rightNumber )).bigDecimalValue ());
90
- } else if (expr .getOperator ().equals ("*" )) {
91
- return new RosettaInterpreterNumberValue ((leftNumber
92
- .multiply (rightNumber )).bigDecimalValue ());
93
- } else {
94
- // Division by 0 is not allowed
95
- if (rightNumber .floatValue () == 0.0 ) {
96
- return new RosettaInterpreterErrorValue (
97
- new RosettaInterpreterError (
98
- "Division by 0 is not allowed" ));
99
- }
100
- return new RosettaInterpreterNumberValue ((leftNumber
101
- .divide (rightNumber )).bigDecimalValue ());
102
- }
103
70
} else {
104
71
return new RosettaInterpreterErrorValue (
105
72
new RosettaInterpreterError (
106
- "The terms of the operation are neither both strings nor both numbers" ));
73
+ "The terms of the operation are not both strings or both numbers or both dates" , expr ));
107
74
}
108
75
}
109
76
77
+ /**
78
+ * Helper method that contains the code for interpreting string concatenation.
79
+ *
80
+ * @param leftInterpreted the left term
81
+ * @param rightInterpreted the right term
82
+ * @param expr the arithmetic operation
83
+ * @return The interpreted result
84
+ */
85
+ private RosettaInterpreterValue interpretString (RosettaInterpreterValue leftInterpreted ,
86
+ RosettaInterpreterValue rightInterpreted , ArithmeticOperation expr ) {
87
+ String leftString = ((RosettaInterpreterStringValue ) leftInterpreted )
88
+ .getValue ();
89
+ String rightString = ((RosettaInterpreterStringValue ) rightInterpreted )
90
+ .getValue ();
91
+ if (expr .getOperator ().equals ("+" )) {
92
+ return new RosettaInterpreterStringValue (leftString + rightString );
93
+ }
94
+ else {
95
+ return new RosettaInterpreterErrorValue (
96
+ new RosettaInterpreterError (
97
+ "Both terms are strings but the operation "
98
+ + "is not concatenation: not implemented" , expr ));
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Helper method that contains the code for interpreting number operations.
104
+ *
105
+ * @param leftInterpreted the left term
106
+ * @param rightInterpreted the right term
107
+ * @param expr the arithmetic operation
108
+ * @return The interpreted result
109
+ */
110
+ private RosettaInterpreterValue interpretNumber (RosettaInterpreterValue leftInterpreted ,
111
+ RosettaInterpreterValue rightInterpreted , ArithmeticOperation expr ) {
112
+ RosettaNumber leftNumber = ((RosettaInterpreterNumberValue ) leftInterpreted ).getValue ();
113
+ RosettaNumber rightNumber = ((RosettaInterpreterNumberValue ) rightInterpreted ).getValue ();
114
+
115
+ if (expr .getOperator ().equals ("+" )) {
116
+ return new RosettaInterpreterNumberValue ((leftNumber
117
+ .add (rightNumber )).bigDecimalValue ());
118
+ } else if (expr .getOperator ().equals ("-" )) {
119
+ return new RosettaInterpreterNumberValue ((leftNumber
120
+ .subtract (rightNumber )).bigDecimalValue ());
121
+ } else if (expr .getOperator ().equals ("*" )) {
122
+ return new RosettaInterpreterNumberValue ((leftNumber
123
+ .multiply (rightNumber )).bigDecimalValue ());
124
+ } else {
125
+ // Division by 0 is not allowed
126
+ if (rightNumber .bigDecimalValue () == BigDecimal .valueOf (0 )) {
127
+ return new RosettaInterpreterErrorValue (
128
+ new RosettaInterpreterError (
129
+ "Division by 0 is not allowed" , expr ));
130
+ }
131
+ return new RosettaInterpreterNumberValue ((leftNumber
132
+ .divide (rightNumber )).bigDecimalValue ());
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Helper method that contains the code for interpreting date subtraction.
138
+ *
139
+ * @param leftInterpreted the left term
140
+ * @param rightInterpreted the right term
141
+ * @param expr the arithmetic operation
142
+ * @return The interpreted result
143
+ */
144
+ private RosettaInterpreterValue interpretDate (RosettaInterpreterValue leftInterpreted ,
145
+ RosettaInterpreterValue rightInterpreted , ArithmeticOperation expr ) {
146
+ RosettaInterpreterDateValue l = (RosettaInterpreterDateValue ) leftInterpreted ;
147
+ RosettaInterpreterDateValue r = (RosettaInterpreterDateValue ) rightInterpreted ;
148
+ if (expr .getOperator ().equals ("-" )) {
149
+ String dayL = appendZeroes (l .getDay ());
150
+ String monthL = appendZeroes (l .getMonth ());
151
+ String yearL = appendZeroes (l .getYear ());
152
+ String dayR = appendZeroes (r .getDay ());
153
+ String monthR = appendZeroes (r .getMonth ());
154
+ String yearR = appendZeroes (r .getYear ());
155
+
156
+ String inputString1 = dayL + " " + monthL + " " + yearL ;
157
+ String inputString2 = dayR + " " + monthR + " " + yearR ;
158
+
159
+ DateTimeFormatter dtf = DateTimeFormatter .ofPattern ("dd MM yyyy" );
160
+
161
+ LocalDateTime date1 = LocalDate .parse (inputString1 , dtf ).atStartOfDay ();
162
+ LocalDateTime date2 = LocalDate .parse (inputString2 , dtf ).atStartOfDay ();
163
+ long daysBetween = Duration .between (date1 , date2 ).toDays ();
164
+ return new RosettaInterpreterNumberValue (BigDecimal .valueOf (daysBetween ));
165
+ } else {
166
+ return new RosettaInterpreterErrorValue (
167
+ new RosettaInterpreterError (
168
+ "Both terms are dates but the operation "
169
+ + "is not subtraction: not implemented" , expr ));
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Helper method that adds a 0 to a day/month string in case it does not have it,
175
+ * to correspond to the proper format.
176
+ *
177
+ * @param d The day/month value as a RosettaInterpreterNumberValue
178
+ * @return The (optionally) modified string value.
179
+ */
180
+ private String appendZeroes (RosettaInterpreterNumberValue d ) {
181
+ String result = d .getValue ().bigDecimalValue ().toBigInteger ().toString ();
182
+ if (result .length () == 1 ) {
183
+ result = "0" + result ;
184
+ }
185
+ return result ;
186
+ }
187
+
110
188
111
189
/**
112
190
* Helper method that takes an interpretedValue and a string,
@@ -123,9 +201,9 @@ private RosettaInterpreterErrorValue checkForErrors(
123
201
RosettaInterpreterValue interpretedValue , String side ,
124
202
EObject associatedObject ) {
125
203
if (interpretedValue instanceof RosettaInterpreterNumberValue
126
- || interpretedValue instanceof RosettaInterpreterStringValue ) {
127
- // If the value satisfies the type conditions, we return an empty
128
- // error value so that the merger has two error values to merge
204
+ || interpretedValue instanceof RosettaInterpreterStringValue
205
+ || interpretedValue instanceof RosettaInterpreterDateValue ) {
206
+ // If the value satisfies the type conditions, return an empty error
129
207
return new RosettaInterpreterErrorValue ();
130
208
}
131
209
@@ -138,7 +216,7 @@ else if (RosettaInterpreterErrorValue.errorsExist(interpretedValue)) {
138
216
return new RosettaInterpreterErrorValue (
139
217
new RosettaInterpreterError (
140
218
"Arithmetic Operation: " + side
141
- + " is not of type Number/String" , associatedObject ));
219
+ + " is not of type Number/String/Date " , associatedObject ));
142
220
}
143
221
}
144
222
}
0 commit comments