GCC Code Coverage Report


Directory: ./
File: src/builtin/operators.inc
Date: 2023-04-27 00:55:30
Exec Total Coverage
Lines: 3 3 100.0%
Functions: 18 436 4.1%
Branches: 0 0 -%

Line Branch Exec Source
1 #pragma once
2
3 #include "ast/constant.h"
4 #include <cmath>
5
6 namespace lython {
7
8 // -
9 // Unary (T) -> T
10 // -
11
12 template <typename T, typename Implementation>
13 struct UnaryOperation {
14 struct Params {
15 T r;
16 T a;
17 };
18
19 static ConstantValue vm(ConstantValue const& a) {
20 6 return ConstantValue(Implementation::call(a.get<T>()));
21 }
22
23 static void call(Params& params) { params.r = Implementation::call(params.a); }
24
25 static T call(T a) { return Implementation::call(a); }
26 };
27
28 template <typename T>
29 struct Invert: public UnaryOperation<T, Invert<T>> {
30 static T call(T a) { return ~a; }
31 };
32
33 template <typename T>
34 struct Not: public UnaryOperation<T, Not<T>> {
35 static T call(T a) { return !a; }
36 };
37
38 template <typename T>
39 struct UAdd: public UnaryOperation<T, UAdd<T>> {
40 static T call(T a) { return +a; }
41 };
42
43 template <typename T>
44 struct USub: public UnaryOperation<T, USub<T>> {
45 static T call(T a) { return -a; }
46 };
47
48 template <>
49 struct USub<uint8>: public UnaryOperation<uint8, USub<uint8>> {
50 static int8 call(uint8 a) { return -int8(a); }
51 };
52
53 template <>
54 struct USub<uint16>: public UnaryOperation<uint16, USub<uint16>> {
55 static int16 call(uint16 a) { return -int16(a); }
56 };
57
58 template <>
59 struct USub<uint32>: public UnaryOperation<uint32, USub<uint32>> {
60 static int32 call(uint32 a) { return -int32(a); }
61 };
62
63 template <>
64 struct USub<uint64>: public UnaryOperation<uint64, USub<uint64>> {
65 static int64 call(uint64 a) { return -int64(a); }
66 };
67
68 // -
69 // Binary (T, T) -> T
70 // -
71 template <typename T, typename Implementation>
72 struct BinaryOperation {
73 struct Params {
74 T r;
75 T a;
76 T b;
77 };
78
79 static void call(Params& params) { params.r = Implementation::call(params.a, params.b); }
80
81 static ConstantValue vm(ConstantValue const& a, ConstantValue const& b) {
82 182 return ConstantValue(Implementation::call(a.get<T>(), b.get<T>()));
83 }
84
85 static T call(T a, T b) { return Implementation::call(a, b); }
86 };
87
88 template <typename T>
89 struct Add: public BinaryOperation<T, Add<T>> {
90 static T call(T a, T b) { return a + b; }
91 };
92
93 template <typename T>
94 struct Sub: public BinaryOperation<T, Sub<T>> {
95 static T call(T a, T b) { return a - b; }
96 };
97
98 template <typename T>
99 struct Pow: public BinaryOperation<T, Pow<T>> {
100 static T call(T a, T b) { return T(std::pow(a, b)); }
101 };
102
103 template <typename T>
104 struct LShift: public BinaryOperation<T, LShift<T>> {
105 static T call(T a, T b) { return a << b; }
106 };
107
108 template <typename T>
109 struct RShift: public BinaryOperation<T, RShift<T>> {
110 static T call(T a, T b) { return a >> b; }
111 };
112
113 template <typename T>
114 struct Mult: public BinaryOperation<T, Mult<T>> {
115 static T call(T a, T b) { return a * b; }
116 };
117
118 template <typename T>
119 struct Div: public BinaryOperation<T, Div<T>> {
120 static T call(T a, T b) { return a / b; }
121 };
122
123 template <typename T>
124 struct Mod: public BinaryOperation<T, Mod<T>> {
125 static T call(T a, T b) { return a % b; }
126 };
127
128 template <>
129 struct Mod<float>: public BinaryOperation<float, Mod<float>> {
130 static float call(float a, float b) { return fmodf(a, b); }
131 };
132
133 template <>
134 struct Mod<double>: public BinaryOperation<double, Mod<double>> {
135 static double call(double a, double b) { return fmod(a, b); }
136 };
137
138 template <typename T>
139 struct And: public BinaryOperation<T, And<T>> {
140 static T call(T a, T b) { return a && b; }
141 };
142
143 template <typename T>
144 struct Or: public BinaryOperation<T, Or<T>> {
145 static T call(T a, T b) { return a || b; }
146 };
147
148 template <typename T>
149 struct BitAnd: public BinaryOperation<T, BitAnd<T>> {
150 static T call(T a, T b) { return a & b; }
151 };
152
153 template <typename T>
154 struct BitOr: public BinaryOperation<T, BitOr<T>> {
155 static T call(T a, T b) { return a | b; }
156 };
157
158 template <typename T>
159 struct BitXor: public BinaryOperation<T, BitXor<T>> {
160 static T call(T a, T b) { return a ^ b; }
161 };
162
163 // -
164 // Comparison (T, T) -> bool
165 // -
166 template <typename T, typename Implementation>
167 struct ComparisonOperation {
168 struct Params {
169 bool r : 1;
170 T a;
171 T b;
172 };
173
174 static ConstantValue vm(ConstantValue const& a, ConstantValue const& b) {
175 110 return ConstantValue(Implementation::call(a.get<T>(), b.get<T>()));
176 }
177
178 static void call(Params& params) { params.r = Implementation::call(params.a, params.b); }
179
180 static T call(T a, T b) { return Implementation::call(a, b); }
181 };
182
183 template <typename T>
184 struct Eq: public ComparisonOperation<T, Eq<T>> {
185 static T call(T a, T b) { return a == b; }
186 };
187
188 template <typename T>
189 struct NotEq: public ComparisonOperation<T, NotEq<T>> {
190 static T call(T a, T b) { return a != b; }
191 };
192
193 template <typename T>
194 struct Lt: public ComparisonOperation<T, Lt<T>> {
195 static T call(T a, T b) { return a < b; }
196 };
197
198 template <typename T>
199 struct LtE: public ComparisonOperation<T, LtE<T>> {
200 static T call(T a, T b) { return a <= b; }
201 };
202
203 template <typename T>
204 struct Gt: public ComparisonOperation<T, Gt<T>> {
205 static T call(T a, T b) { return a > b; }
206 };
207
208 template <typename T>
209 struct GtE: public ComparisonOperation<T, GtE<T>> {
210 static T call(T a, T b) { return a >= b; }
211 };
212
213 template <typename T>
214 struct Is: public ComparisonOperation<T, Is<T>> {
215 static T call(T a, T b) { return a == b; }
216 };
217
218 template <typename T>
219 struct IsNot: public ComparisonOperation<T, IsNot<T>> {
220 static T call(T a, T b) { return a != b; }
221 };
222
223 template <typename T>
224 struct In: public ComparisonOperation<T, In<T>> {
225 static T call(T a, T b) { return a == b; }
226 };
227
228 template <typename T>
229 struct NotIn: public ComparisonOperation<T, NotIn<T>> {
230 static T call(T a, T b) { return a != b; }
231 };
232
233 } // namespace lython
234