asar coverage - build #272


src/asar/
File: src/asar/math_eval.cpp
Date: 2025-03-03 19:47:10
Lines:
174/210
82.9%
Functions:
28/28
100.0%
Branches:
263/426
61.7%

Line Branch Exec Source
1 #include "math_ast.h"
2 #include "asar.h"
3 #include "errors.h"
4
5 // TODO: make all these conversions print the current type aswell instead of just expected type
6 1154 double math_val::get_double() const {
7
4/6
✓ Branch 0 taken 141 times.
✓ Branch 1 taken 1149 times.
✓ Branch 2 taken 1015 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2311 switch(m_type) {
8 282 case math_val_type::floating:
9 282 return m_numeric_val.double_;
10 2018 case math_val_type::integer:
11 2018 return (double)m_numeric_val.int_;
12 11 case math_val_type::identifier:
13 11 return (double)get_integer();
14 case math_val_type::string:
15 throw_err_block(2, err_expected_number);
16 }
17 }
18 10122 int64_t math_val::get_integer() const {
19
4/6
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 9860 times.
✓ Branch 2 taken 10241 times.
✓ Branch 3 taken 266 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
20392 switch(m_type) {
20 50 case math_val_type::floating:
21 // TODO: throw error on overflow?
22 50 return (int64_t)m_numeric_val.double_;
23 19814 case math_val_type::integer:
24 19814 return m_numeric_val.int_;
25 528 case math_val_type::identifier:
26
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 262 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 266 times.
528 if(!labels.exists(m_string_val)) {
27 throw_err_block(pass, err_internal_error, "evaluating nonexistent label");
28 }
29 528 return labels.find(m_string_val).pos;
30 case math_val_type::string:
31 throw_err_block(2, err_expected_number);
32 }
33 }
34 142 const string &math_val::get_str() const {
35
2/3
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
142 if (m_type == math_val_type::string)
36 142 return m_string_val;
37 throw_err_block(2, err_expected_string);
38 }
39
40 400 const string &math_val::get_identifier() const {
41
2/3
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
400 if (m_type == math_val_type::identifier)
42 400 return m_string_val;
43 throw_err_block(2, err_expected_ident);
44 }
45 80 bool math_val::get_bool() const {
46
3/5
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 78 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
160 switch (m_type) {
47 4 case math_val_type::floating:
48 4 return get_double() != 0.0;
49 156 case math_val_type::integer:
50 case math_val_type::identifier:
51 156 return get_integer() != 0;
52 case math_val_type::string:
53 return get_str().length() != 0;
54 }
55 }
56
57 template<typename T>
58 5082 T evaluate_binop_arithmetic(T lhs, T rhs, math_binop_type type) {
59
3/4
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 1955 times.
✓ Branch 2 taken 532 times.
✗ Branch 3 not taken.
5082 switch(type) {
60 108 case math_binop_type::mul: return lhs * rhs;
61 3910 case math_binop_type::add: return lhs + rhs;
62 1064 case math_binop_type::sub: return lhs - rhs;
63 default:
64 throw_err_block(2, err_internal_error, "evaluate_binop_arithmetic with bad type");
65 }
66 }
67 template<typename T>
68 5000 bool evaluate_binop_compare(T lhs, T rhs, math_binop_type type) {
69
6/7
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 154 times.
✓ Branch 3 taken 1816 times.
✓ Branch 4 taken 466 times.
✓ Branch 5 taken 40 times.
✗ Branch 6 not taken.
5000 switch(type) {
70 24 case math_binop_type::comp_ge: return lhs >= rhs;
71 24 case math_binop_type::comp_le: return lhs <= rhs;
72 308 case math_binop_type::comp_gt: return lhs > rhs;
73 3632 case math_binop_type::comp_lt: return lhs < rhs;
74 932 case math_binop_type::comp_eq: return lhs == rhs;
75 80 case math_binop_type::comp_ne: return lhs != rhs;
76 default:
77 throw_err_block(2, err_internal_error, "evaluate_binop_compare with bad type");
78 }
79 }
80
81 2543 math_val evaluate_binop(math_val lhs, math_val rhs,
82 math_binop_type type) {
83 // todo: do this a bit smarter (bit_ops shouldn't cast int->float->int)
84
3/3
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 2543 times.
✓ Branch 2 taken 2515 times.
5089 if (lhs.m_type == math_val_type::floating)
85
2/3
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
62 rhs = math_val(rhs.get_double());
86
3/3
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2512 times.
✓ Branch 2 taken 2509 times.
5027 else if (rhs.m_type == math_val_type::floating)
87
2/3
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
12 lhs = math_val(lhs.get_double());
88
7/12
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2541 times.
✓ Branch 10 taken 2500 times.
✗ Branch 11 not taken.
5089 switch (type) {
89 12 case math_binop_type::pow:
90 12 return math_val(pow(lhs.get_double(), rhs.get_double()));
91 16 case math_binop_type::div:
92
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 12 times.
16 if (rhs.get_double() == 0.0)
93 4 throw_err_block(2, err_division_by_zero);
94 12 return math_val(lhs.get_double() / rhs.get_double());
95 case math_binop_type::mod:
96 if (rhs.get_double() == 0.0)
97 throw_err_block(2, err_division_by_zero);
98 // TODO: negative semantics
99 if (lhs.m_type == math_val_type::floating) {
100 return math_val(fmod(lhs.get_double(), rhs.get_double()));
101 } else {
102 return math_val(lhs.get_integer() % rhs.get_integer());
103 }
104 break;
105
106 6 case math_binop_type::shift_left: {
107 6 int64_t rhs_v = rhs.get_integer();
108
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (rhs_v < 0)
109 6 throw_err_block(2, err_negative_shift);
110 return math_val(lhs.get_integer() << (uint64_t)rhs_v);
111 }
112 12 case math_binop_type::shift_right: {
113 12 int64_t rhs_v = rhs.get_integer();
114
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rhs_v < 0)
115 6 throw_err_block(2, err_negative_shift);
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
6 return math_val(lhs.get_integer() >> (uint64_t)rhs_v);
117 }
118
119 case math_binop_type::bit_and:
120 return math_val(lhs.get_integer() & rhs.get_integer());
121 2 case math_binop_type::bit_or:
122 2 return math_val(lhs.get_integer() | rhs.get_integer());
123 case math_binop_type::bit_xor:
124 return math_val(lhs.get_integer() ^ rhs.get_integer());
125
126 case math_binop_type::logical_and:
127 case math_binop_type::logical_or:
128 throw_err_block(2, err_internal_error, "evaluate_binop() on logical ops loses short-circuiting");
129
130 2541 case math_binop_type::mul:
131 case math_binop_type::add:
132 case math_binop_type::sub:
133 // TODO error on string (also TODO support string +)
134
3/3
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1269 times.
✓ Branch 2 taken 1259 times.
2541 if (lhs.m_type == math_val_type::floating)
135 return math_val(evaluate_binop_arithmetic<double>(
136 26 lhs.get_double(), rhs.get_double(), type));
137 else
138 return math_val(evaluate_binop_arithmetic<int64_t>(
139 2515 lhs.get_integer(), rhs.get_integer(), type));
140
141 2500 case math_binop_type::comp_ge:
142 case math_binop_type::comp_le:
143 case math_binop_type::comp_gt:
144 case math_binop_type::comp_lt:
145 case math_binop_type::comp_eq:
146 case math_binop_type::comp_ne:
147
3/3
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1250 times.
✓ Branch 2 taken 1226 times.
2500 if (lhs.m_type == math_val_type::floating)
148 48 return math_val((int64_t)evaluate_binop_compare<double>(
149 48 lhs.get_double(), rhs.get_double(), type));
150 else
151 2452 return math_val((int64_t)evaluate_binop_compare<int64_t>(
152 2452 lhs.get_integer(), rhs.get_integer(), type));
153 }
154 }
155
156 5066 math_val math_ast_binop::evaluate(const eval_context &ctx) const {
157
2/4
✓ Branch 0 taken 2531 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2535 times.
✗ Branch 3 not taken.
5066 math_val lhs = m_left->evaluate(ctx);
158
159 // handle short-circuiting for || and &&
160
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2525 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2529 times.
5066 if (m_type == math_binop_type::logical_or) {
161
3/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
12 if (lhs.get_bool() == true)
162 6 return math_val((int64_t)true);
163
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 math_val rhs = m_right->evaluate(ctx);
164
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 return math_val((int64_t)rhs.get_bool());
165 6 }
166
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2516 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 2520 times.
5054 if (m_type == math_binop_type::logical_and) {
167
3/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 12 times.
18 if (lhs.get_bool() == false)
168 6 return math_val((int64_t)false);
169
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 math_val rhs = m_right->evaluate(ctx);
170
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 return math_val((int64_t)rhs.get_bool());
171 12 }
172
173
3/4
✓ Branch 0 taken 2516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2519 times.
✓ Branch 3 taken 1 times.
5036 math_val rhs = m_right->evaluate(ctx);
174
7/11
✓ Branch 0 taken 2516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2516 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5027 times.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2519 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2511 times.
✓ Branch 10 taken 8 times.
5075 return evaluate_binop(lhs, rhs, m_type);
175 5082 }
176
177 5111 int math_ast_binop::has_label() const {
178 5111 return m_left->has_label() | m_right->has_label();
179 }
180
181
182 90 int math_ast_binop::get_len(bool could_be_bank_ex) const {
183
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 60 times.
90 if(could_be_bank_ex) {
184 30 int want_rhs = 0;
185
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 9 times.
30 if(m_type == math_binop_type::div) {
186 12 want_rhs = 65536;
187
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
18 } else if(m_type == math_binop_type::shift_right) {
188 12 want_rhs = 16;
189 }
190
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 if(want_rhs) {
191 24 math_ast_node* right_ptr = m_right.get();
192
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 auto right_lit = dynamic_cast<math_ast_literal*>(right_ptr);
193
3/6
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
24 if(right_lit && right_lit->m_value.m_type == math_val_type::integer) {
194 24 int64_t right_val = right_lit->m_value.get_integer();
195
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if(right_val == want_rhs) return 1;
196 }
197 }
198 }
199
4/8
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 33 times.
✗ Branch 7 not taken.
66 return std::max(m_left->get_len(false), m_right->get_len(false));
200 }
201 35 math_val math_ast_unop::evaluate(const eval_context &ctx) const {
202
2/4
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
70 math_val arg = m_arg->evaluate(ctx);
203
4/8
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
70 switch (m_type) {
204 64 case math_unop_type::neg:
205
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 50 times.
64 if (arg.m_type == math_val_type::floating)
206
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 return math_val(-arg.get_double());
207 else
208
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 return math_val(-arg.get_integer());
209 case math_unop_type::bit_not:
210 return math_val(~arg.get_integer());
211 6 case math_unop_type::bank_extract:
212
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 return math_val(arg.get_integer() >> 16);
213 }
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 }
215
216 60 int math_ast_unop::has_label() const { return m_arg->has_label(); }
217
218 18 int math_ast_unop::get_len(bool could_be_bank_ex) const {
219
3/6
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
18 if (could_be_bank_ex && m_type == math_unop_type::bank_extract)
220 18 return 1;
221 return m_arg->get_len(false);
222 }
223
224 582 math_val math_ast_label::evaluate(const eval_context &ctx) const {
225
21/30
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 275 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 294 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 13 times.
✓ Branch 9 taken 275 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 278 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 10 times.
✓ Branch 19 taken 3 times.
✓ Branch 20 taken 13 times.
✓ Branch 21 taken 281 times.
✓ Branch 22 taken 13 times.
✓ Branch 23 taken 281 times.
✓ Branch 24 taken 10 times.
✓ Branch 25 taken 284 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
582 if (m_cur_ns && labels.exists(m_cur_ns + m_labelname)) {
226
4/8
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
40 return math_val::make_identifier(m_cur_ns + m_labelname);
227
4/4
✓ Branch 0 taken 277 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 281 times.
✓ Branch 3 taken 3 times.
562 } else if (labels.exists(m_labelname)) {
228
4/8
✓ Branch 0 taken 277 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 277 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 281 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 281 times.
✗ Branch 7 not taken.
558 return math_val::make_identifier(m_labelname);
229 } else {
230 // possibly forward label, assume without namespace.
231 // TODO: this assumption can cause moving labels :)))))
232
1/10
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
4 if(pass == 0) return math_val::make_identifier(m_labelname);
233 // if not pass 0, we know it's not a forward label and can throw the error
234 4 throw_err_block(2, err_label_not_found, m_labelname.data());
235 }
236 }
237
238 454 int math_ast_label::has_label() const {
239
19/30
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 219 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 227 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✓ Branch 9 taken 219 times.
✓ Branch 10 taken 8 times.
✓ Branch 11 taken 219 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 8 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 8 times.
✓ Branch 21 taken 219 times.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 219 times.
✓ Branch 24 taken 8 times.
✓ Branch 25 taken 219 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
454 if (m_cur_ns && labels.exists(m_cur_ns + m_labelname)) {
240
7/14
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 8 times.
16 return labels.find(m_cur_ns + m_labelname).is_static ? 1 : 3;
241
4/4
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 213 times.
✓ Branch 3 taken 6 times.
438 } else if (labels.exists(m_labelname)) {
242
5/6
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 135 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 213 times.
✓ Branch 4 taken 78 times.
✓ Branch 5 taken 135 times.
426 return labels.find(m_labelname).is_static ? 1 : 3;
243 }
244 // otherwise, non-static forward label
245 12 return 7;
246 }
247
248 744 int math_ast_label::get_len(bool could_be_bank_ex) const {
249 744 snes_label label;
250
21/30
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 354 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 375 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 10 times.
✓ Branch 8 taken 15 times.
✓ Branch 9 taken 354 times.
✓ Branch 10 taken 5 times.
✓ Branch 11 taken 364 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 15 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 15 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5 times.
✓ Branch 19 taken 10 times.
✓ Branch 20 taken 15 times.
✓ Branch 21 taken 360 times.
✓ Branch 22 taken 15 times.
✓ Branch 23 taken 360 times.
✓ Branch 24 taken 5 times.
✓ Branch 25 taken 370 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
744 if (m_cur_ns && labels.exists(m_cur_ns + m_labelname)) {
251
4/8
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
10 label = labels.find(m_cur_ns + m_labelname);
252
6/8
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 49 times.
✓ Branch 4 taken 370 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 320 times.
✓ Branch 7 taken 50 times.
734 } else if (labels.exists(m_labelname)) {
253
2/4
✓ Branch 0 taken 315 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 320 times.
✗ Branch 3 not taken.
635 label = labels.find(m_labelname);
254 99 } else return 2;
255
1/2
✓ Branch 0 taken 645 times.
✗ Branch 1 not taken.
645 return getlenforlabel(label, true);
256 }
257
258 math_function_ref
259 1060 math_ast_function_call::lookup_fname(string const &function_name) {
260
4/6
✓ Branch 0 taken 527 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 533 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✓ Branch 5 taken 516 times.
1593 if (auto it = user_functions.find(function_name);
261
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 510 times.
1060 it != user_functions.end()) {
262 34 return it->second;
263
3/6
✓ Branch 0 taken 510 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 516 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 516 times.
✗ Branch 5 not taken.
1542 } else if (auto it = builtin_functions.find(function_name);
264
1/2
✓ Branch 0 taken 510 times.
✗ Branch 1 not taken.
1026 it != builtin_functions.end()) {
265 1026 return it->second;
266 } else {
267 throw_err_block(2, err_function_not_found, function_name.data());
268 }
269 }
270 982 math_val math_ast_function_call::evaluate(const eval_context &ctx) const {
271 982 std::vector<math_val> arg_vals;
272
4/4
✓ Branch 0 taken 619 times.
✓ Branch 1 taken 488 times.
✓ Branch 2 taken 625 times.
✓ Branch 3 taken 494 times.
2226 for (auto const &p : m_arguments) {
273
4/7
✓ Branch 0 taken 619 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 619 times.
✓ Branch 3 taken 625 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 625 times.
✗ Branch 6 not taken.
1244 arg_vals.push_back(p->evaluate(ctx));
274 }
275
4/4
✓ Branch 0 taken 462 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 468 times.
✓ Branch 3 taken 26 times.
1912 return m_func.call(arg_vals);
276 982 }
277
278 974 int math_ast_function_call::has_label() const {
279 974 int out = m_func.has_label();
280
4/4
✓ Branch 0 taken 612 times.
✓ Branch 1 taken 484 times.
✓ Branch 2 taken 618 times.
✓ Branch 3 taken 490 times.
2204 for (auto const &p : m_arguments) {
281
2/4
✓ Branch 0 taken 612 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 618 times.
✗ Branch 3 not taken.
1230 out |= p->has_label();
282 }
283 974 return out;
284 }
285
286 96 int math_ast_function_call::get_len(bool could_be_bank_ex) const {
287 96 return m_func.get_len(m_arguments, could_be_bank_ex);
288 }
289
290 30 math_val math_user_function::call(const std::vector<math_val> &args) const {
291 30 math_ast_node::eval_context new_ctx;
292
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 new_ctx.userfunc_params = args;
293
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
30 if (args.size() != m_arg_count)
294 throw_err_block(2, err_argument_count, m_arg_count, (int)args.size());
295
2/4
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
60 return m_func_body->evaluate(new_ctx);
296 30 }
297
298 28 int math_user_function::has_label() const { return m_func_body->has_label(); }
299
300 6 int math_user_function::get_len(const std::vector<owned_node> &args,
301 bool could_be_bank_ex) const {
302 // TODO: this doesn't forward could_be_bank_ex to the fn call...
303 // supporting that properly would require stringing some context through all
304 // get_len calls supporting it less properly (making a special return value of
305 // get_len signify bankextract) could be viable tho...
306
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 int len = m_func_body->get_len(false);
307
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 for (auto &arg : args) {
308 len = std::max(len, arg->get_len(false));
309 }
310 6 return len;
311 }
312
313