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 |
|
✗ |
asar_throw_error(2, error_type_block, error_id_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 |
|
✗ |
asar_throw_error(pass, error_type_block, error_id_internal_error, "evaluating nonexistent label"); |
28 |
|
|
} |
29 |
|
528 |
return labels.find(m_string_val).pos; |
30 |
|
✗ |
case math_val_type::string: |
31 |
|
✗ |
asar_throw_error(2, error_type_block, error_id_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 |
|
✗ |
asar_throw_error(2, error_type_block, error_id_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 |
|
✗ |
asar_throw_error(2, error_type_block, error_id_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 |
|
✗ |
asar_throw_error(2, error_type_block, error_id_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 |
|
✗ |
asar_throw_error(2, error_type_block, error_id_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 |
asar_throw_error(2, error_type_block, error_id_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 |
|
✗ |
asar_throw_error(2, error_type_block, error_id_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 |
asar_throw_error(2, error_type_block, error_id_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 |
asar_throw_error(2, error_type_block, error_id_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 |
|
✗ |
asar_throw_error(2, error_type_block, error_id_internal_error, |
129 |
|
|
"evaluate_binop() on logical ops loses short-circuiting"); |
130 |
|
|
|
131 |
|
2541 |
case math_binop_type::mul: |
132 |
|
|
case math_binop_type::add: |
133 |
|
|
case math_binop_type::sub: |
134 |
|
|
// TODO error on string (also TODO support string +) |
135 |
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) |
136 |
|
|
return math_val(evaluate_binop_arithmetic<double>( |
137 |
|
26 |
lhs.get_double(), rhs.get_double(), type)); |
138 |
|
|
else |
139 |
|
|
return math_val(evaluate_binop_arithmetic<int64_t>( |
140 |
|
2515 |
lhs.get_integer(), rhs.get_integer(), type)); |
141 |
|
|
|
142 |
|
2500 |
case math_binop_type::comp_ge: |
143 |
|
|
case math_binop_type::comp_le: |
144 |
|
|
case math_binop_type::comp_gt: |
145 |
|
|
case math_binop_type::comp_lt: |
146 |
|
|
case math_binop_type::comp_eq: |
147 |
|
|
case math_binop_type::comp_ne: |
148 |
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) |
149 |
|
48 |
return math_val((int64_t)evaluate_binop_compare<double>( |
150 |
|
48 |
lhs.get_double(), rhs.get_double(), type)); |
151 |
|
|
else |
152 |
|
2452 |
return math_val((int64_t)evaluate_binop_compare<int64_t>( |
153 |
|
2452 |
lhs.get_integer(), rhs.get_integer(), type)); |
154 |
|
|
} |
155 |
|
✗ |
} |
156 |
|
|
|
157 |
|
5066 |
math_val math_ast_binop::evaluate(const eval_context &ctx) const { |
158 |
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); |
159 |
|
|
|
160 |
|
|
// handle short-circuiting for || and && |
161 |
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) { |
162 |
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) |
163 |
|
6 |
return math_val((int64_t)true); |
164 |
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); |
165 |
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 |
return math_val((int64_t)rhs.get_bool()); |
166 |
|
6 |
} |
167 |
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) { |
168 |
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) |
169 |
|
6 |
return math_val((int64_t)false); |
170 |
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); |
171 |
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 |
return math_val((int64_t)rhs.get_bool()); |
172 |
|
12 |
} |
173 |
|
|
|
174 |
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); |
175 |
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); |
176 |
|
5082 |
} |
177 |
|
|
|
178 |
|
5111 |
int math_ast_binop::has_label() const { |
179 |
|
5111 |
return m_left->has_label() | m_right->has_label(); |
180 |
|
|
} |
181 |
|
|
|
182 |
|
|
|
183 |
|
90 |
int math_ast_binop::get_len(bool could_be_bank_ex) const { |
184 |
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 60 times.
|
90 |
if(could_be_bank_ex) { |
185 |
|
30 |
int want_rhs = 0; |
186 |
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) { |
187 |
|
12 |
want_rhs = 65536; |
188 |
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) { |
189 |
|
12 |
want_rhs = 16; |
190 |
|
|
} |
191 |
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
|
30 |
if(want_rhs) { |
192 |
|
24 |
math_ast_node* right_ptr = m_right.get(); |
193 |
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 |
auto right_lit = dynamic_cast<math_ast_literal*>(right_ptr); |
194 |
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) { |
195 |
|
24 |
int64_t right_val = right_lit->m_value.get_integer(); |
196 |
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 |
if(right_val == want_rhs) return 1; |
197 |
|
|
} |
198 |
|
|
} |
199 |
|
|
} |
200 |
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)); |
201 |
|
|
} |
202 |
|
35 |
math_val math_ast_unop::evaluate(const eval_context &ctx) const { |
203 |
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); |
204 |
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) { |
205 |
|
64 |
case math_unop_type::neg: |
206 |
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 50 times.
|
64 |
if (arg.m_type == math_val_type::floating) |
207 |
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 |
return math_val(-arg.get_double()); |
208 |
|
|
else |
209 |
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
|
50 |
return math_val(-arg.get_integer()); |
210 |
|
✗ |
case math_unop_type::bit_not: |
211 |
|
✗ |
return math_val(~arg.get_integer()); |
212 |
|
6 |
case math_unop_type::bank_extract: |
213 |
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 |
return math_val(arg.get_integer() >> 16); |
214 |
|
|
} |
215 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
|
70 |
} |
216 |
|
|
|
217 |
|
60 |
int math_ast_unop::has_label() const { return m_arg->has_label(); } |
218 |
|
|
|
219 |
|
18 |
int math_ast_unop::get_len(bool could_be_bank_ex) const { |
220 |
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) |
221 |
|
18 |
return 1; |
222 |
|
✗ |
return m_arg->get_len(false); |
223 |
|
|
} |
224 |
|
|
|
225 |
|
582 |
math_val math_ast_label::evaluate(const eval_context &ctx) const { |
226 |
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)) { |
227 |
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); |
228 |
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)) { |
229 |
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); |
230 |
|
|
} else { |
231 |
|
|
// possibly forward label, assume without namespace. |
232 |
|
|
// TODO: this assumption can cause moving labels :))))) |
233 |
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); |
234 |
|
|
// if not pass 0, we know it's not a forward label and can throw the error |
235 |
|
4 |
asar_throw_error(2, error_type_block, error_id_label_not_found, |
236 |
|
|
m_labelname.data()); |
237 |
|
|
} |
238 |
|
|
} |
239 |
|
|
|
240 |
|
454 |
int math_ast_label::has_label() const { |
241 |
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)) { |
242 |
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; |
243 |
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)) { |
244 |
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; |
245 |
|
|
} |
246 |
|
|
// otherwise, non-static forward label |
247 |
|
12 |
return 7; |
248 |
|
|
} |
249 |
|
|
|
250 |
|
744 |
int math_ast_label::get_len(bool could_be_bank_ex) const { |
251 |
|
744 |
snes_label label; |
252 |
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)) { |
253 |
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); |
254 |
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)) { |
255 |
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); |
256 |
|
99 |
} else return 2; |
257 |
1/2
✓ Branch 0 taken 645 times.
✗ Branch 1 not taken.
|
645 |
return getlenforlabel(label, true); |
258 |
|
|
} |
259 |
|
|
|
260 |
|
|
math_function_ref |
261 |
|
1060 |
math_ast_function_call::lookup_fname(string const &function_name) { |
262 |
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); |
263 |
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 510 times.
|
1060 |
it != user_functions.end()) { |
264 |
|
34 |
return it->second; |
265 |
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); |
266 |
1/2
✓ Branch 0 taken 510 times.
✗ Branch 1 not taken.
|
1026 |
it != builtin_functions.end()) { |
267 |
|
1026 |
return it->second; |
268 |
|
|
} else { |
269 |
|
✗ |
asar_throw_error(2, error_type_block, error_id_function_not_found, |
270 |
|
|
function_name.data()); |
271 |
|
|
} |
272 |
|
|
} |
273 |
|
982 |
math_val math_ast_function_call::evaluate(const eval_context &ctx) const { |
274 |
|
982 |
std::vector<math_val> arg_vals; |
275 |
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) { |
276 |
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)); |
277 |
|
|
} |
278 |
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); |
279 |
|
982 |
} |
280 |
|
|
|
281 |
|
974 |
int math_ast_function_call::has_label() const { |
282 |
|
974 |
int out = m_func.has_label(); |
283 |
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) { |
284 |
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(); |
285 |
|
|
} |
286 |
|
974 |
return out; |
287 |
|
|
} |
288 |
|
|
|
289 |
|
96 |
int math_ast_function_call::get_len(bool could_be_bank_ex) const { |
290 |
|
96 |
return m_func.get_len(m_arguments, could_be_bank_ex); |
291 |
|
|
} |
292 |
|
|
|
293 |
|
30 |
math_val math_user_function::call(const std::vector<math_val> &args) const { |
294 |
|
30 |
math_ast_node::eval_context new_ctx; |
295 |
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
|
30 |
new_ctx.userfunc_params = args; |
296 |
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) |
297 |
|
✗ |
asar_throw_error(2, error_type_block, error_id_argument_count, m_arg_count, |
298 |
|
|
(int)args.size()); |
299 |
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); |
300 |
|
30 |
} |
301 |
|
|
|
302 |
|
28 |
int math_user_function::has_label() const { return m_func_body->has_label(); } |
303 |
|
|
|
304 |
|
6 |
int math_user_function::get_len(const std::vector<owned_node> &args, |
305 |
|
|
bool could_be_bank_ex) const { |
306 |
|
|
// TODO: this doesn't forward could_be_bank_ex to the fn call... |
307 |
|
|
// supporting that properly would require stringing some context through all |
308 |
|
|
// get_len calls supporting it less properly (making a special return value of |
309 |
|
|
// get_len signify bankextract) could be viable tho... |
310 |
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); |
311 |
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) { |
312 |
|
✗ |
len = std::max(len, arg->get_len(false)); |
313 |
|
|
} |
314 |
|
6 |
return len; |
315 |
|
|
} |
316 |
|
|
|
317 |
|
|
|