asar coverage - build #


src/asar/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
217 of 230, 0 excluded
94.3%
Functions:
10 of 10, 0 excluded
100.0%
Branches:
622 of 1114, 0 excluded
55.8%

math_parse.cpp
Line Branch Exec Source
1 #include "asar.h"
2 #include "assembleblock.h"
3 #include "asar_math.h"
4 #include "table.h"
5 #include "unicode.h"
6 #include <cmath>
7
8 #include "math_ast.h"
9
10
11 bool foundlabel;
12 // WARNING: this flag is only correctly set in pass 0, as forward labels are
13 // always non-static but we don't know when we hit forward-labels past pass 0
14 bool foundlabel_static;
15 // only set in pass 0
16 bool forwardlabel;
17
18
19 std::unordered_map<string, math_user_function> user_functions;
20
21 // we don't need this struct to be exported
22 namespace {
23 // data necessary for parsing an expression, which might be an user function declaration
24 struct parse_context {
25 const char*& str;
26 // this map is empty unless declaring a function,
27 // in which case it maps argument name to argument index
28 const std::unordered_map<string, size_t> function_arg_names;
29 // these are methods to allow easier access to `str`
30 owned_node parse_atom();
31 owned_node parse_unops();
32 owned_node parse_binops(int depth = 0);
33 owned_node parse();
34 };
35 }
36
37
38 static const int8_t hextable[128] = {
39 // 0 1 2 3 4 5 6 7 8 9 a b c d e f
40 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
41 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
42 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
43 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
44 -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
45 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
46 -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
47 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
48 };
49
50 // "atom" = literal, parenthesized expression, or label reference
51 20729 owned_node parse_context::parse_atom() {
52
4/4
✓ Branch 2 → 3 taken 3200 times.
✓ Branch 2 → 16 taken 7094 times.
✓ Branch 5 → 6 taken 3287 times.
✓ Branch 5 → 58 taken 7148 times.
20729 if(*str == '$') {
53
2/9
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 8 taken 3200 times.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 263 not taken.
✗ Branch 5 → 264 not taken.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 17 taken 3287 times.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 648 not taken.
6487 if (!is_xdigit(*++str)) throw_err_block(2, err_invalid_hex_value);
54 6487 const char* start = str;
55 6487 int64_t ret = 0; // todo error on overflow?
56
6/8
✓ Branch 10 → 11 taken 13609 times.
✗ Branch 10 → 12 not taken.
✓ Branch 11 → 9 taken 10409 times.
✓ Branch 11 → 12 taken 3200 times.
✓ Branch 35 → 36 taken 14032 times.
✗ Branch 35 → 46 not taken.
✓ Branch 45 → 21 taken 10745 times.
✓ Branch 45 → 46 taken 3287 times.
27641 while ((unsigned char)*str < 0x80 && hextable[(unsigned char)*str] >= 0) {
57
1/2
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 10745 times.
21154 ret = (ret << 4) | hextable[(unsigned char)*str++];
58 }
59 6487 int len = str - start;
60 6487 int len_bytes = (len+1)/2;
61
2/5
✓ Branch 12 → 13 taken 3200 times.
✗ Branch 12 → 262 not taken.
✗ Branch 12 → 263 not taken.
✓ Branch 51 → 52 taken 3287 times.
✗ Branch 51 → 646 not taken.
6487 return std::make_unique<math_ast_literal>(ret, len_bytes);
62 }
63
16/16
✓ Branch 17 → 18 taken 6013 times.
✓ Branch 17 → 20 taken 1081 times.
✓ Branch 18 → 19 taken 5830 times.
✓ Branch 18 → 20 taken 183 times.
✓ Branch 19 → 20 taken 7 times.
✓ Branch 19 → 21 taken 5823 times.
✓ Branch 22 → 23 taken 1271 times.
✓ Branch 22 → 154 taken 5823 times.
✓ Branch 62 → 63 taken 6060 times.
✓ Branch 62 → 71 taken 1088 times.
✓ Branch 66 → 67 taken 5877 times.
✓ Branch 66 → 71 taken 183 times.
✓ Branch 70 → 71 taken 7 times.
✓ Branch 70 → 72 taken 5870 times.
✓ Branch 73 → 74 taken 1278 times.
✓ Branch 73 → 379 taken 5870 times.
14242 if (is_ualpha(*str) || *str=='.' || *str=='?') {
64 2549 const char * start=str;
65
16/16
✓ Branch 26 → 27 taken 1910 times.
✓ Branch 26 → 29 taken 8060 times.
✓ Branch 27 → 28 taken 1278 times.
✓ Branch 27 → 29 taken 632 times.
✓ Branch 28 → 29 taken 7 times.
✓ Branch 28 → 30 taken 1271 times.
✓ Branch 31 → 24 taken 8699 times.
✓ Branch 31 → 32 taken 1271 times.
✓ Branch 87 → 88 taken 1917 times.
✓ Branch 87 → 96 taken 8091 times.
✓ Branch 91 → 92 taken 1285 times.
✓ Branch 91 → 96 taken 632 times.
✓ Branch 95 → 96 taken 7 times.
✓ Branch 95 → 97 taken 1278 times.
✓ Branch 98 → 78 taken 8730 times.
✓ Branch 98 → 99 taken 1278 times.
19978 while (is_ualnum(*str) || *str == '.' || *str == '?') str++;
66 2549 int len=(int)(str-start);
67
4/4
✓ Branch 34 → 33 taken 40 times.
✓ Branch 34 → 35 taken 1271 times.
✓ Branch 110 → 102 taken 40 times.
✓ Branch 110 → 111 taken 1278 times.
2629 while (*str==' ') str++;
68
4/4
✓ Branch 35 → 36 taken 475 times.
✓ Branch 35 → 82 taken 796 times.
✓ Branch 114 → 115 taken 480 times.
✓ Branch 114 → 210 taken 798 times.
2549 if (*str=='(') {
69 955 str++;
70 955 string func_name;
71
2/5
✓ Branch 37 → 38 taken 475 times.
✗ Branch 37 → 271 not taken.
✗ Branch 37 → 272 not taken.
✓ Branch 121 → 122 taken 480 times.
✗ Branch 121 → 661 not taken.
955 func_name.assign(start, len);
72 955 std::vector<owned_node> arguments;
73
4/4
✓ Branch 54 → 40 taken 597 times.
✓ Branch 54 → 55 taken 475 times.
✓ Branch 165 → 125 taken 602 times.
✓ Branch 165 → 166 taken 480 times.
3109 while(*str != ')') {
74
4/4
✓ Branch 42 → 41 taken 1 time.
✓ Branch 42 → 43 taken 597 times.
✓ Branch 134 → 126 taken 1 time.
✓ Branch 134 → 135 taken 602 times.
1201 while (*str==' ') str++;
75
4/10
✓ Branch 43 → 44 taken 597 times.
✗ Branch 43 → 266 not taken.
✗ Branch 43 → 267 not taken.
✓ Branch 44 → 45 taken 597 times.
✗ Branch 44 → 264 not taken.
✗ Branch 44 → 265 not taken.
✓ Branch 136 → 137 taken 602 times.
✗ Branch 136 → 653 not taken.
✓ Branch 138 → 139 taken 602 times.
✗ Branch 138 → 651 not taken.
1199 arguments.emplace_back(parse_binops());
76 // is "invalid number" good here?
77
6/13
✓ Branch 46 → 47 taken 455 times.
✓ Branch 46 → 51 taken 142 times.
✗ Branch 47 → 48 not taken.
✓ Branch 47 → 51 taken 455 times.
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 269 not taken.
✗ Branch 48 → 270 not taken.
✓ Branch 144 → 145 taken 460 times.
✓ Branch 144 → 152 taken 142 times.
✗ Branch 148 → 149 not taken.
✓ Branch 148 → 152 taken 460 times.
✗ Branch 149 → 150 not taken.
✗ Branch 149 → 659 not taken.
1199 if(*str != ',' && *str != ')') throw_err_block(2, err_invalid_number);
78
4/4
✓ Branch 51 → 52 taken 142 times.
✓ Branch 51 → 54 taken 455 times.
✓ Branch 155 → 156 taken 142 times.
✓ Branch 155 → 162 taken 460 times.
1199 if(*str == ',') str++;
79 }
80 955 str++;
81 // ternary is basically just a function called "?"
82
4/4
✓ Branch 56 → 57 taken 4 times.
✓ Branch 56 → 73 taken 471 times.
✓ Branch 171 → 172 taken 4 times.
✓ Branch 171 → 196 taken 476 times.
955 if(func_name == "?") {
83
2/4
✗ Branch 58 → 59 not taken.
✓ Branch 58 → 63 taken 4 times.
✗ Branch 173 → 174 not taken.
✓ Branch 173 → 178 taken 4 times.
8 if(arguments.size() != 3) {
84 throw_err_block(2, err_argument_count, 3, (int)arguments.size());
85 }
86
2/5
✓ Branch 69 → 70 taken 4 times.
✗ Branch 69 → 267 not taken.
✗ Branch 69 → 268 not taken.
✓ Branch 191 → 192 taken 4 times.
✗ Branch 191 → 655 not taken.
28 return std::make_unique<math_ast_ternary_cond>(
87 8 std::move(arguments[0]),
88 8 std::move(arguments[1]),
89 16 std::move(arguments[2]));
90 }
91
2/5
✓ Branch 75 → 76 taken 471 times.
✗ Branch 75 → 268 not taken.
✗ Branch 75 → 269 not taken.
✓ Branch 201 → 202 taken 476 times.
✗ Branch 201 → 657 not taken.
947 return std::make_unique<math_ast_function_call>(std::move(arguments), std::move(func_name));
92 955 } else {
93
2/5
✓ Branch 82 → 83 taken 796 times.
✗ Branch 82 → 305 not taken.
✗ Branch 82 → 306 not taken.
✓ Branch 211 → 212 taken 798 times.
✗ Branch 211 → 713 not taken.
1594 string name_part(start, len);
94
4/4
✓ Branch 84 → 85 taken 176 times.
✓ Branch 84 → 93 taken 620 times.
✓ Branch 213 → 214 taken 176 times.
✓ Branch 213 → 229 taken 622 times.
1594 if(name_part == "...") {
95 // a tiny bit ugly, but whatever
96
6/15
✓ Branch 85 → 86 taken 176 times.
✗ Branch 85 → 278 not taken.
✗ Branch 85 → 279 not taken.
✓ Branch 86 → 87 taken 176 times.
✗ Branch 86 → 276 not taken.
✗ Branch 86 → 277 not taken.
✓ Branch 87 → 88 taken 176 times.
✗ Branch 87 → 274 not taken.
✗ Branch 87 → 275 not taken.
✓ Branch 217 → 218 taken 176 times.
✗ Branch 217 → 670 not taken.
✓ Branch 218 → 219 taken 176 times.
✗ Branch 218 → 668 not taken.
✓ Branch 220 → 221 taken 176 times.
✗ Branch 220 → 666 not taken.
352 return std::make_unique<math_ast_literal>(math_val::make_identifier(name_part));
97 }
98
4/4
✓ Branch 94 → 95 taken 27 times.
✓ Branch 94 → 105 taken 593 times.
✓ Branch 235 → 236 taken 27 times.
✓ Branch 235 → 268 taken 595 times.
1242 if(!function_arg_names.empty()) {
99
2/5
✓ Branch 95 → 96 taken 27 times.
✗ Branch 95 → 282 not taken.
✗ Branch 95 → 283 not taken.
✓ Branch 242 → 243 taken 27 times.
✗ Branch 242 → 678 not taken.
54 auto it = function_arg_names.find(name_part);
100
2/4
✓ Branch 98 → 99 taken 27 times.
✗ Branch 98 → 104 not taken.
✓ Branch 253 → 254 taken 27 times.
✗ Branch 253 → 265 not taken.
54 if(it != function_arg_names.end()) {
101
2/5
✓ Branch 100 → 101 taken 27 times.
✗ Branch 100 → 281 not taken.
✗ Branch 100 → 282 not taken.
✓ Branch 259 → 260 taken 27 times.
✗ Branch 259 → 676 not taken.
54 return std::make_unique<math_ast_function_argument>(it->second);
102 }
103 }
104
2/5
✓ Branch 105 → 106 taken 593 times.
✗ Branch 105 → 303 not taken.
✗ Branch 105 → 304 not taken.
✓ Branch 269 → 270 taken 595 times.
✗ Branch 269 → 711 not taken.
1188 string name = labelname(&start);
105 1188 str = start;
106
4/4
✓ Branch 106 → 107 taken 25 times.
✓ Branch 106 → 145 taken 568 times.
✓ Branch 275 → 276 taken 25 times.
✓ Branch 275 → 366 taken 570 times.
1188 if(*str == '[') {
107 // struct array indexing
108 50 str++;
109
2/5
✓ Branch 107 → 108 taken 25 times.
✗ Branch 107 → 299 not taken.
✗ Branch 107 → 300 not taken.
✓ Branch 281 → 282 taken 25 times.
✗ Branch 281 → 698 not taken.
50 auto index = parse_binops();
110
2/9
✗ Branch 108 → 109 not taken.
✓ Branch 108 → 112 taken 25 times.
✗ Branch 109 → 110 not taken.
✗ Branch 109 → 297 not taken.
✗ Branch 109 → 298 not taken.
✗ Branch 285 → 286 not taken.
✓ Branch 285 → 289 taken 25 times.
✗ Branch 286 → 287 not taken.
✗ Branch 286 → 696 not taken.
50 if(*str != ']') throw_err_block(2, err_invalid_label_missing_closer);
111 50 str++;
112
2/5
✓ Branch 112 → 113 taken 25 times.
✗ Branch 112 → 297 not taken.
✗ Branch 112 → 298 not taken.
✓ Branch 294 → 295 taken 25 times.
✗ Branch 294 → 696 not taken.
50 string subname = name;
113
4/4
✓ Branch 113 → 114 taken 24 times.
✓ Branch 113 → 122 taken 1 time.
✓ Branch 298 → 299 taken 24 times.
✓ Branch 298 → 318 taken 1 time.
50 if(*str == '.') {
114 // this part used to be in labelname... not sure where it really belongs....
115
12/12
✓ Branch 117 → 118 taken 48 times.
✓ Branch 117 → 119 taken 96 times.
✓ Branch 118 → 119 taken 24 times.
✓ Branch 118 → 120 taken 24 times.
✓ Branch 121 → 115 taken 120 times.
✓ Branch 121 → 122 taken 24 times.
✓ Branch 310 → 311 taken 48 times.
✓ Branch 310 → 315 taken 96 times.
✓ Branch 314 → 315 taken 24 times.
✓ Branch 314 → 316 taken 24 times.
✓ Branch 317 → 300 taken 120 times.
✓ Branch 317 → 318 taken 24 times.
288 while (is_ualnum(*str) || *str == '.') {
116
2/5
✓ Branch 115 → 116 taken 120 times.
✗ Branch 115 → 295 not taken.
✗ Branch 115 → 296 not taken.
✓ Branch 305 → 306 taken 120 times.
✗ Branch 305 → 694 not taken.
240 subname += *(str++);
117 }
118 }
119 // when doing base[index].sub:
120 // result = (base_addr + index*object_size(base)) + sub_offset
121 // = sub_addr + index*object_size(base)
122 // so we build a math node that represents this calculation
123
2/5
✓ Branch 122 → 123 taken 25 times.
✗ Branch 122 → 295 not taken.
✗ Branch 122 → 296 not taken.
✓ Branch 319 → 320 taken 25 times.
✗ Branch 319 → 694 not taken.
50 auto node_sub = std::make_unique<math_ast_label>(subname);
124
2/5
✓ Branch 123 → 124 taken 25 times.
✗ Branch 123 → 293 not taken.
✗ Branch 123 → 294 not taken.
✓ Branch 321 → 322 taken 25 times.
✗ Branch 321 → 692 not taken.
50 auto node_base = std::make_unique<math_ast_label>(name);
125 50 std::vector<owned_node> arg_list;
126
2/5
✓ Branch 126 → 127 taken 25 times.
✗ Branch 126 → 289 not taken.
✗ Branch 126 → 290 not taken.
✓ Branch 326 → 327 taken 25 times.
✗ Branch 326 → 688 not taken.
50 arg_list.emplace_back(std::move(node_base));
127
2/5
✓ Branch 128 → 129 taken 25 times.
✗ Branch 128 → 289 not taken.
✗ Branch 128 → 290 not taken.
✓ Branch 330 → 331 taken 25 times.
✗ Branch 330 → 688 not taken.
50 auto node_objsize = std::make_unique<math_ast_function_call>(std::move(arg_list), "objectsize");
128
2/5
✓ Branch 131 → 132 taken 25 times.
✗ Branch 131 → 283 not taken.
✗ Branch 131 → 284 not taken.
✓ Branch 338 → 339 taken 25 times.
✗ Branch 338 → 680 not taken.
50 auto node_mul = std::make_unique<math_ast_binop>(std::move(node_objsize), std::move(index), math_binop_type::mul);
129
2/5
✓ Branch 134 → 135 taken 25 times.
✗ Branch 134 → 284 not taken.
✗ Branch 134 → 285 not taken.
✓ Branch 347 → 348 taken 25 times.
✗ Branch 347 → 682 not taken.
50 auto node_add = std::make_unique<math_ast_binop>(std::move(node_mul), std::move(node_sub), math_binop_type::add);
130 50 return node_add;
131 50 } else {
132
2/5
✓ Branch 146 → 147 taken 568 times.
✗ Branch 146 → 300 not taken.
✗ Branch 146 → 301 not taken.
✓ Branch 369 → 370 taken 570 times.
✗ Branch 369 → 707 not taken.
1138 return std::make_unique<math_ast_label>(std::move(name));
133 }
134 1594 }
135 }
136
4/4
✓ Branch 154 → 155 taken 76 times.
✓ Branch 154 → 163 taken 5747 times.
✓ Branch 382 → 383 taken 76 times.
✓ Branch 382 → 403 taken 5794 times.
11693 if(*str == '(') {
137 152 str++;
138
2/5
✓ Branch 155 → 156 taken 76 times.
✗ Branch 155 → 309 not taken.
✗ Branch 155 → 310 not taken.
✓ Branch 388 → 389 taken 76 times.
✗ Branch 388 → 720 not taken.
152 auto res = parse_binops();
139
2/9
✗ Branch 156 → 157 not taken.
✓ Branch 156 → 160 taken 76 times.
✗ Branch 157 → 158 not taken.
✗ Branch 157 → 307 not taken.
✗ Branch 157 → 308 not taken.
✗ Branch 392 → 393 not taken.
✓ Branch 392 → 396 taken 76 times.
✗ Branch 393 → 394 not taken.
✗ Branch 393 → 718 not taken.
152 if(*str != ')') throw_err_block(2, err_mismatched_parentheses);
140 152 str++;
141 152 return res;
142 152 }
143
4/4
✓ Branch 163 → 164 taken 10 times.
✓ Branch 163 → 174 taken 5737 times.
✓ Branch 406 → 407 taken 10 times.
✓ Branch 406 → 445 taken 5784 times.
11541 if(*str == '%') {
144
2/8
✗ Branch 164 → 165 not taken.
✓ Branch 164 → 169 taken 10 times.
✗ Branch 165 → 166 not taken.
✗ Branch 165 → 169 not taken.
✗ Branch 411 → 412 not taken.
✓ Branch 411 → 420 taken 10 times.
✗ Branch 416 → 417 not taken.
✗ Branch 416 → 420 not taken.
20 if (str[1] != '0' && str[1] != '1') throw_err_block(2, err_invalid_binary_value);
145 20 const char* start = str+1;
146
1/2
✗ Branch 427 → 428 not taken.
✓ Branch 427 → 429 taken 10 times.
20 uint64_t res = strtoull(str+1, const_cast<char**>(&str), 2);
147 20 int len = str - start;
148
2/5
✓ Branch 170 → 171 taken 10 times.
✗ Branch 170 → 310 not taken.
✗ Branch 170 → 311 not taken.
✓ Branch 438 → 439 taken 10 times.
✗ Branch 438 → 722 not taken.
20 return std::make_unique<math_ast_literal>((int64_t)res, (len+7)/8);
149 }
150
4/4
✓ Branch 174 → 175 taken 112 times.
✓ Branch 174 → 200 taken 5625 times.
✓ Branch 448 → 449 taken 112 times.
✓ Branch 448 → 507 taken 5672 times.
11521 if (*str=='\'') {
151
2/9
✗ Branch 175 → 176 not taken.
✓ Branch 175 → 179 taken 112 times.
✗ Branch 176 → 177 not taken.
✗ Branch 176 → 318 not taken.
✗ Branch 176 → 319 not taken.
✗ Branch 453 → 454 not taken.
✓ Branch 453 → 457 taken 112 times.
✗ Branch 454 → 455 not taken.
✗ Branch 454 → 736 not taken.
224 if (!str[1]) throw_err_block(2, err_invalid_character);
152 112 int orig_val;
153 224 str++;
154
2/5
✓ Branch 179 → 180 taken 112 times.
✗ Branch 179 → 318 not taken.
✗ Branch 179 → 319 not taken.
✓ Branch 464 → 465 taken 112 times.
✗ Branch 464 → 736 not taken.
224 str += utf8_val(&orig_val, str);
155
2/9
✗ Branch 180 → 181 not taken.
✓ Branch 180 → 184 taken 112 times.
✗ Branch 181 → 182 not taken.
✗ Branch 181 → 318 not taken.
✗ Branch 181 → 319 not taken.
✗ Branch 470 → 471 not taken.
✓ Branch 470 → 474 taken 112 times.
✗ Branch 471 → 472 not taken.
✗ Branch 471 → 736 not taken.
224 if (orig_val == -1) throw_err_block(0, err_invalid_utf8);
156
2/9
✗ Branch 184 → 185 not taken.
✓ Branch 184 → 188 taken 112 times.
✗ Branch 185 → 186 not taken.
✗ Branch 185 → 318 not taken.
✗ Branch 185 → 319 not taken.
✗ Branch 477 → 478 not taken.
✓ Branch 477 → 481 taken 112 times.
✗ Branch 478 → 479 not taken.
✗ Branch 478 → 736 not taken.
224 if (*str != '\'') throw_err_block(2, err_invalid_character);
157
2/5
✓ Branch 188 → 189 taken 112 times.
✗ Branch 188 → 318 not taken.
✗ Branch 188 → 319 not taken.
✓ Branch 483 → 484 taken 112 times.
✗ Branch 483 → 736 not taken.
224 int64_t rval=thetable.get_val(orig_val);
158
2/4
✗ Branch 189 → 190 not taken.
✓ Branch 189 → 196 taken 112 times.
✗ Branch 484 → 485 not taken.
✓ Branch 484 → 492 taken 112 times.
224 if (rval == -1)
159 {
160 // RPG Hacker: Should be fine to not check return value of codepoint_to_utf8() here, because
161 // our error cases above already made sure that orig_val contains valid data at this point.
162 string u8_str;
163 codepoint_to_utf8(&u8_str, orig_val);
164 throw_err_block(2, err_undefined_char, u8_str.data());
165 }
166 224 str++;
167
2/5
✓ Branch 196 → 197 taken 112 times.
✗ Branch 196 → 316 not taken.
✗ Branch 196 → 317 not taken.
✓ Branch 499 → 500 taken 112 times.
✗ Branch 499 → 732 not taken.
224 return std::make_unique<math_ast_literal>(rval, 1);
168 }
169
4/5
✓ Branch 201 → 202 taken 5461 times.
✗ Branch 201 → 234 not taken.
✓ Branch 201 → 235 taken 164 times.
✓ Branch 511 → 512 taken 5502 times.
✓ Branch 511 → 571 taken 170 times.
11297 if (is_digit(*str)) {
170 10963 const char* end = str;
171 10963 bool is_float = false;
172
12/12
✓ Branch 207 → 208 taken 5501 times.
✓ Branch 207 → 209 taken 7062 times.
✓ Branch 208 → 209 taken 40 times.
✓ Branch 208 → 210 taken 5461 times.
✓ Branch 211 → 203 taken 7102 times.
✓ Branch 211 → 212 taken 5461 times.
✓ Branch 522 → 523 taken 5542 times.
✓ Branch 522 → 525 taken 7125 times.
✓ Branch 524 → 525 taken 40 times.
✓ Branch 524 → 526 taken 5502 times.
✓ Branch 527 → 515 taken 7165 times.
✓ Branch 527 → 528 taken 5502 times.
25230 while (is_digit(*end) || *end == '.') {
173
4/4
✓ Branch 203 → 204 taken 40 times.
✓ Branch 203 → 205 taken 7062 times.
✓ Branch 516 → 517 taken 40 times.
✓ Branch 516 → 518 taken 7125 times.
14267 if(*end == '.') is_float = true;
174 14267 end++;
175 }
176 10963 string number;
177
2/5
✓ Branch 213 → 214 taken 5461 times.
✗ Branch 213 → 323 not taken.
✗ Branch 213 → 324 not taken.
✓ Branch 534 → 535 taken 5502 times.
✗ Branch 534 → 748 not taken.
10963 number.assign(str, (int)(end - str));
178 10963 str = end;
179
4/5
✓ Branch 214 → 215 taken 40 times.
✗ Branch 214 → 220 not taken.
✓ Branch 214 → 221 taken 5421 times.
✓ Branch 537 → 538 taken 40 times.
✓ Branch 537 → 549 taken 5462 times.
10963 if(is_float) {
180
1/2
✗ Branch 540 → 541 not taken.
✓ Branch 540 → 542 taken 40 times.
80 double res = std::atof(number);
181
2/6
✗ Branch 216 → 217 not taken.
✗ Branch 216 → 319 not taken.
✓ Branch 217 → 218 taken 40 times.
✗ Branch 217 → 320 not taken.
✓ Branch 543 → 544 taken 40 times.
✗ Branch 543 → 739 not taken.
80 return std::make_unique<math_ast_literal>(res);
182 } else {
183
1/2
✗ Branch 551 → 552 not taken.
✓ Branch 551 → 553 taken 5462 times.
10883 int64_t res = strtoll(number, nullptr, 10);
184
8/11
✗ Branch 222 → 223 not taken.
✗ Branch 222 → 227 not taken.
✓ Branch 223 → 224 taken 5415 times.
✗ Branch 223 → 225 not taken.
✓ Branch 223 → 228 taken 6 times.
✓ Branch 224 → 225 taken 37 times.
✓ Branch 224 → 226 taken 5378 times.
✓ Branch 555 → 556 taken 5456 times.
✓ Branch 555 → 560 taken 6 times.
✓ Branch 556 → 557 taken 42 times.
✓ Branch 556 → 558 taken 5414 times.
10883 int len = (res >= 0x10000) ? 3 : (res >= 0x100) ? 2 : 1;
185
2/6
✗ Branch 228 → 229 not taken.
✗ Branch 228 → 321 not taken.
✓ Branch 229 → 230 taken 5421 times.
✗ Branch 229 → 322 not taken.
✓ Branch 562 → 563 taken 5462 times.
✗ Branch 562 → 743 not taken.
10883 return std::make_unique<math_ast_literal>(res, len);
186 }
187 10963 }
188
4/6
✗ Branch 234 → 235 not taken.
✗ Branch 234 → 258 not taken.
✓ Branch 235 → 236 taken 158 times.
✓ Branch 235 → 259 taken 6 times.
✓ Branch 574 → 575 taken 164 times.
✓ Branch 574 → 642 taken 6 times.
334 if(*str == '"') {
189 322 const char * strpos = str + 1;
190
1/2
✗ Branch 579 → 580 not taken.
✓ Branch 579 → 581 taken 164 times.
322 str = strchr(strpos, '"');
191
2/11
✗ Branch 235 → 236 not taken.
✗ Branch 235 → 239 not taken.
✗ Branch 236 → 237 not taken.
✓ Branch 236 → 240 taken 158 times.
✗ Branch 236 → 329 not taken.
✗ Branch 237 → 238 not taken.
✗ Branch 237 → 330 not taken.
✗ Branch 584 → 585 not taken.
✓ Branch 584 → 588 taken 164 times.
✗ Branch 585 → 586 not taken.
✗ Branch 585 → 756 not taken.
322 if(!str) throw_err_block(2, err_mismatched_quotes);
192
2/6
✗ Branch 239 → 240 not taken.
✗ Branch 239 → 329 not taken.
✓ Branch 240 → 241 taken 158 times.
✗ Branch 240 → 330 not taken.
✓ Branch 591 → 592 taken 164 times.
✗ Branch 591 → 756 not taken.
322 string output(strpos, str - strpos);
193
6/11
✗ Branch 247 → 248 not taken.
✗ Branch 247 → 249 not taken.
✗ Branch 248 → 241 not taken.
✓ Branch 248 → 249 taken 162 times.
✗ Branch 248 → 250 not taken.
✓ Branch 249 → 242 taken 4 times.
✓ Branch 249 → 250 taken 158 times.
✓ Branch 612 → 613 taken 168 times.
✗ Branch 612 → 618 not taken.
✓ Branch 617 → 593 taken 4 times.
✓ Branch 617 → 618 taken 164 times.
330 while(str && str[1] == '"') {
194 // we hit an escaped quote
195
2/6
✗ Branch 241 → 242 not taken.
✗ Branch 241 → 327 not taken.
✓ Branch 242 → 243 taken 4 times.
✗ Branch 242 → 328 not taken.
✓ Branch 593 → 594 taken 4 times.
✗ Branch 593 → 754 not taken.
8 output += '"';
196 8 strpos = str+2;
197
1/2
✗ Branch 598 → 599 not taken.
✓ Branch 598 → 600 taken 4 times.
8 str = strchr(strpos, '"');
198
2/11
✗ Branch 242 → 243 not taken.
✗ Branch 242 → 246 not taken.
✗ Branch 243 → 244 not taken.
✓ Branch 243 → 247 taken 4 times.
✗ Branch 243 → 327 not taken.
✗ Branch 244 → 245 not taken.
✗ Branch 244 → 328 not taken.
✗ Branch 603 → 604 not taken.
✓ Branch 603 → 607 taken 4 times.
✗ Branch 604 → 605 not taken.
✗ Branch 604 → 754 not taken.
8 if(!str) throw_err_block(2, err_mismatched_quotes);
199
2/6
✗ Branch 246 → 247 not taken.
✗ Branch 246 → 327 not taken.
✓ Branch 247 → 248 taken 4 times.
✗ Branch 247 → 328 not taken.
✓ Branch 609 → 610 taken 4 times.
✗ Branch 609 → 754 not taken.
8 output.append(strpos, 0, str - strpos);
200 }
201 322 str++;
202
4/6
✗ Branch 251 → 250 not taken.
✗ Branch 251 → 252 not taken.
✓ Branch 252 → 251 taken 12 times.
✓ Branch 252 → 253 taken 158 times.
✓ Branch 631 → 623 taken 12 times.
✓ Branch 631 → 632 taken 164 times.
346 while (*str==' ') str++; //eat space
203
2/6
✗ Branch 253 → 254 not taken.
✗ Branch 253 → 326 not taken.
✓ Branch 254 → 255 taken 158 times.
✗ Branch 254 → 327 not taken.
✓ Branch 635 → 636 taken 164 times.
✗ Branch 635 → 752 not taken.
322 return std::make_unique<math_ast_literal>(std::move(output));
204 322 }
205 12 throw_err_block(2, err_invalid_number);
206 }
207
208 20795 owned_node parse_context::parse_unops() {
209
4/4
✓ Branch 4 → 3 taken 1262 times.
✓ Branch 4 → 5 taken 10327 times.
✓ Branch 11 → 3 taken 1262 times.
✓ Branch 11 → 12 taken 10468 times.
23319 while(*str == ' ') str++;
210 // optimize for the common case
211 // TODO how much of an optimization is this really?
212
4/4
✓ Branch 5 → 6 taken 3200 times.
✓ Branch 5 → 7 taken 7127 times.
✓ Branch 15 → 16 taken 3287 times.
✓ Branch 15 → 18 taken 7181 times.
20795 if(*str == '$') return parse_atom();
213
214
4/4
✓ Branch 7 → 8 taken 20 times.
✓ Branch 7 → 14 taken 7107 times.
✓ Branch 21 → 22 taken 20 times.
✓ Branch 21 → 40 taken 7161 times.
14308 if(*str == '-') {
215 40 str++;
216
4/8
✓ Branch 8 → 9 taken 20 times.
✗ Branch 8 → 35 not taken.
✓ Branch 9 → 10 taken 20 times.
✗ Branch 9 → 33 not taken.
✓ Branch 30 → 31 taken 20 times.
✗ Branch 30 → 105 not taken.
✓ Branch 32 → 33 taken 20 times.
✗ Branch 32 → 103 not taken.
40 return std::make_unique<math_ast_unop>(parse_unops(), math_unop_type::neg);
217
4/4
✓ Branch 14 → 15 taken 4 times.
✓ Branch 14 → 21 taken 7103 times.
✓ Branch 43 → 44 taken 4 times.
✓ Branch 43 → 62 taken 7157 times.
14268 } else if(*str == '~') {
218 8 str++;
219
4/8
✓ Branch 15 → 16 taken 4 times.
✗ Branch 15 → 40 not taken.
✓ Branch 16 → 17 taken 4 times.
✗ Branch 16 → 38 not taken.
✓ Branch 52 → 53 taken 4 times.
✗ Branch 52 → 113 not taken.
✓ Branch 54 → 55 taken 4 times.
✗ Branch 54 → 111 not taken.
8 return std::make_unique<math_ast_unop>(parse_unops(), math_unop_type::bit_not);
220
8/8
✓ Branch 21 → 22 taken 15 times.
✓ Branch 21 → 29 taken 7088 times.
✓ Branch 22 → 23 taken 9 times.
✓ Branch 22 → 29 taken 6 times.
✓ Branch 65 → 66 taken 15 times.
✓ Branch 65 → 90 taken 7142 times.
✓ Branch 70 → 71 taken 9 times.
✓ Branch 70 → 90 taken 6 times.
14260 } else if(*str == '<' && str[1] == ':') {
221 18 str += 2;
222
4/8
✓ Branch 23 → 24 taken 9 times.
✗ Branch 23 → 45 not taken.
✓ Branch 24 → 25 taken 9 times.
✗ Branch 24 → 43 not taken.
✓ Branch 80 → 81 taken 9 times.
✗ Branch 80 → 121 not taken.
✓ Branch 82 → 83 taken 9 times.
✗ Branch 82 → 119 not taken.
18 return std::make_unique<math_ast_unop>(parse_unops(), math_unop_type::bank_extract);
223
2/4
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 7094 times.
✗ Branch 93 → 94 not taken.
✓ Branch 93 → 100 taken 7148 times.
14242 } else if(*str == '+') {
224 str++;
225 return parse_unops();
226 }
227 14242 else return parse_atom();
228 }
229
230 20765 owned_node parse_context::parse_binops(int depth) {
231 20765 const char* posneglabel = str;
232
4/4
✓ Branch 2 → 3 taken 10308 times.
✓ Branch 2 → 332 taken 1 time.
✓ Branch 6 → 7 taken 10455 times.
✓ Branch 6 → 803 taken 1 time.
20765 string posnegname = posneglabelname(&posneglabel, false);
233
8/8
✓ Branch 4 → 5 taken 31 times.
✓ Branch 4 → 8 taken 10277 times.
✓ Branch 8 → 9 taken 37 times.
✓ Branch 8 → 14 taken 10418 times.
✓ Branch 9 → 10 taken 14 times.
✓ Branch 9 → 14 taken 10294 times.
✓ Branch 15 → 16 taken 20 times.
✓ Branch 15 → 24 taken 10435 times.
20831 if (posnegname.length() > 0 &&
234
6/8
✓ Branch 5 → 6 taken 17 times.
✓ Branch 5 → 7 taken 14 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 17 times.
✓ Branch 10 → 11 taken 17 times.
✓ Branch 10 → 13 taken 20 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 17 times.
68 (*posneglabel == '\0' || *posneglabel == ')')) {
235 34 str = posneglabel;
236
2/4
✓ Branch 10 → 11 taken 14 times.
✗ Branch 10 → 266 not taken.
✓ Branch 19 → 20 taken 20 times.
✗ Branch 19 → 679 not taken.
34 return std::make_unique<math_ast_label>(posnegname);
237 }
238
239
2/4
✓ Branch 14 → 15 taken 10294 times.
✗ Branch 14 → 330 not taken.
✓ Branch 25 → 26 taken 10435 times.
✗ Branch 25 → 801 not taken.
20729 recurseblock rec;
240
241
4/4
✓ Branch 15 → 16 taken 10288 times.
✓ Branch 15 → 328 taken 6 times.
✓ Branch 27 → 28 taken 10429 times.
✓ Branch 27 → 799 taken 6 times.
20729 owned_node left = parse_unops();
242 20717 owned_node right;
243
4/4
✓ Branch 18 → 17 taken 1225 times.
✓ Branch 18 → 19 taken 10288 times.
✓ Branch 38 → 30 taken 1225 times.
✓ Branch 38 → 39 taken 10429 times.
23167 while(*str == ' ') str++;
244
16/16
✓ Branch 255 → 256 taken 3241 times.
✓ Branch 255 → 259 taken 9547 times.
✓ Branch 256 → 257 taken 2698 times.
✓ Branch 256 → 259 taken 543 times.
✓ Branch 257 → 258 taken 2556 times.
✓ Branch 257 → 259 taken 142 times.
✓ Branch 258 → 20 taken 2531 times.
✓ Branch 258 → 259 taken 25 times.
✓ Branch 655 → 656 taken 3250 times.
✓ Branch 655 → 668 taken 9682 times.
✓ Branch 659 → 660 taken 2701 times.
✓ Branch 659 → 668 taken 549 times.
✓ Branch 663 → 664 taken 2559 times.
✓ Branch 663 → 668 taken 142 times.
✓ Branch 667 → 40 taken 2534 times.
✓ Branch 667 → 668 taken 25 times.
25720 while (*str && *str != ')' && *str != ','&& *str != ']') {
245
2/4
✗ Branch 22 → 21 not taken.
✓ Branch 22 → 23 taken 2531 times.
✗ Branch 49 → 41 not taken.
✓ Branch 49 → 50 taken 2534 times.
5065 while(*str == ' ') str++;
246 // TODO can we make this macro a bit nicer???
247 #define oper(name, thisdepth, contents) \
248 if (!strncmp(str, name, strlen(name))) \
249 { \
250 if (depth<=thisdepth) \
251 { \
252 str += strlen(name); \
253 right = parse_binops(thisdepth+1); \
254 left = std::make_unique<math_ast_binop>(std::move(left), std::move(right), contents); \
255 continue; \
256 } \
257 else return left; \
258 }
259
11/18
✓ Branch 23 → 24 taken 6 times.
✓ Branch 23 → 35 taken 2525 times.
✓ Branch 24 → 25 taken 6 times.
✗ Branch 24 → 34 not taken.
✓ Branch 25 → 26 taken 6 times.
✗ Branch 25 → 267 not taken.
✓ Branch 30 → 31 taken 6 times.
✗ Branch 30 → 268 not taken.
✗ Branch 52 → 53 not taken.
✓ Branch 52 → 54 taken 2534 times.
✓ Branch 54 → 55 taken 6 times.
✓ Branch 54 → 82 taken 2528 times.
✓ Branch 55 → 56 taken 6 times.
✗ Branch 55 → 81 not taken.
✓ Branch 62 → 63 taken 6 times.
✗ Branch 62 → 681 not taken.
✓ Branch 74 → 75 taken 6 times.
✗ Branch 74 → 683 not taken.
5065 oper("**", 6, math_binop_type::pow);
260
10/16
✓ Branch 35 → 36 taken 18 times.
✓ Branch 35 → 47 taken 2507 times.
✓ Branch 36 → 37 taken 18 times.
✗ Branch 36 → 46 not taken.
✓ Branch 37 → 38 taken 18 times.
✗ Branch 37 → 270 not taken.
✓ Branch 42 → 43 taken 18 times.
✗ Branch 42 → 271 not taken.
✓ Branch 85 → 86 taken 18 times.
✓ Branch 85 → 113 taken 2510 times.
✓ Branch 86 → 87 taken 18 times.
✗ Branch 86 → 112 not taken.
✓ Branch 93 → 94 taken 18 times.
✗ Branch 93 → 687 not taken.
✓ Branch 105 → 106 taken 18 times.
✗ Branch 105 → 689 not taken.
5053 oper("*", 5, math_binop_type::mul);
261
10/16
✓ Branch 47 → 48 taken 14 times.
✓ Branch 47 → 59 taken 2493 times.
✓ Branch 48 → 49 taken 14 times.
✗ Branch 48 → 58 not taken.
✓ Branch 49 → 50 taken 14 times.
✗ Branch 49 → 273 not taken.
✓ Branch 54 → 55 taken 14 times.
✗ Branch 54 → 274 not taken.
✓ Branch 116 → 117 taken 14 times.
✓ Branch 116 → 144 taken 2496 times.
✓ Branch 117 → 118 taken 14 times.
✗ Branch 117 → 143 not taken.
✓ Branch 124 → 125 taken 14 times.
✗ Branch 124 → 693 not taken.
✓ Branch 136 → 137 taken 14 times.
✗ Branch 136 → 695 not taken.
5017 oper("/", 5, math_binop_type::div);
262
10/16
✓ Branch 59 → 60 taken 1 time.
✓ Branch 59 → 71 taken 2492 times.
✓ Branch 60 → 61 taken 1 time.
✗ Branch 60 → 70 not taken.
✓ Branch 61 → 62 taken 1 time.
✗ Branch 61 → 276 not taken.
✓ Branch 66 → 67 taken 1 time.
✗ Branch 66 → 277 not taken.
✓ Branch 147 → 148 taken 1 time.
✓ Branch 147 → 175 taken 2495 times.
✓ Branch 148 → 149 taken 1 time.
✗ Branch 148 → 174 not taken.
✓ Branch 155 → 156 taken 1 time.
✗ Branch 155 → 699 not taken.
✓ Branch 167 → 168 taken 1 time.
✗ Branch 167 → 701 not taken.
4989 oper("%", 5, math_binop_type::mod);
263
12/16
✓ Branch 71 → 72 taken 984 times.
✓ Branch 71 → 83 taken 1508 times.
✓ Branch 72 → 73 taken 974 times.
✓ Branch 72 → 82 taken 10 times.
✓ Branch 73 → 74 taken 974 times.
✗ Branch 73 → 279 not taken.
✓ Branch 78 → 79 taken 974 times.
✗ Branch 78 → 280 not taken.
✓ Branch 178 → 179 taken 987 times.
✓ Branch 178 → 206 taken 1508 times.
✓ Branch 179 → 180 taken 977 times.
✓ Branch 179 → 205 taken 10 times.
✓ Branch 186 → 187 taken 977 times.
✗ Branch 186 → 705 not taken.
✓ Branch 198 → 199 taken 977 times.
✗ Branch 198 → 707 not taken.
4987 oper("+", 4, math_binop_type::add);
264
10/16
✓ Branch 83 → 84 taken 267 times.
✓ Branch 83 → 95 taken 1241 times.
✓ Branch 84 → 85 taken 267 times.
✗ Branch 84 → 94 not taken.
✓ Branch 85 → 86 taken 267 times.
✗ Branch 85 → 282 not taken.
✓ Branch 90 → 91 taken 267 times.
✗ Branch 90 → 283 not taken.
✓ Branch 209 → 210 taken 267 times.
✓ Branch 209 → 237 taken 1241 times.
✓ Branch 210 → 211 taken 267 times.
✗ Branch 210 → 236 not taken.
✓ Branch 217 → 218 taken 267 times.
✗ Branch 217 → 711 not taken.
✓ Branch 229 → 230 taken 267 times.
✗ Branch 229 → 713 not taken.
3016 oper("-", 4, math_binop_type::sub);
265
11/18
✓ Branch 95 → 96 taken 1 time.
✓ Branch 95 → 107 taken 1240 times.
✓ Branch 96 → 97 taken 1 time.
✗ Branch 96 → 106 not taken.
✓ Branch 97 → 98 taken 1 time.
✗ Branch 97 → 285 not taken.
✓ Branch 102 → 103 taken 1 time.
✗ Branch 102 → 286 not taken.
✗ Branch 239 → 240 not taken.
✓ Branch 239 → 241 taken 1241 times.
✓ Branch 241 → 242 taken 1 time.
✓ Branch 241 → 269 taken 1240 times.
✓ Branch 242 → 243 taken 1 time.
✗ Branch 242 → 268 not taken.
✓ Branch 249 → 250 taken 1 time.
✗ Branch 249 → 717 not taken.
✓ Branch 261 → 262 taken 1 time.
✗ Branch 261 → 719 not taken.
2482 oper("<<", 3, math_binop_type::shift_left);
266
11/18
✓ Branch 107 → 108 taken 10 times.
✓ Branch 107 → 119 taken 1230 times.
✓ Branch 108 → 109 taken 10 times.
✗ Branch 108 → 118 not taken.
✓ Branch 109 → 110 taken 10 times.
✗ Branch 109 → 288 not taken.
✓ Branch 114 → 115 taken 10 times.
✗ Branch 114 → 289 not taken.
✗ Branch 271 → 272 not taken.
✓ Branch 271 → 273 taken 1240 times.
✓ Branch 273 → 274 taken 10 times.
✓ Branch 273 → 301 taken 1230 times.
✓ Branch 274 → 275 taken 10 times.
✗ Branch 274 → 300 not taken.
✓ Branch 281 → 282 taken 10 times.
✗ Branch 281 → 723 not taken.
✓ Branch 293 → 294 taken 10 times.
✗ Branch 293 → 725 not taken.
2480 oper(">>", 3, math_binop_type::shift_right);
267
268 //these two needed checked early to avoid bitwise from eating a operator
269
13/18
✓ Branch 119 → 120 taken 13 times.
✓ Branch 119 → 131 taken 1217 times.
✓ Branch 120 → 121 taken 7 times.
✓ Branch 120 → 130 taken 6 times.
✓ Branch 121 → 122 taken 7 times.
✗ Branch 121 → 291 not taken.
✓ Branch 126 → 127 taken 7 times.
✗ Branch 126 → 292 not taken.
✗ Branch 303 → 304 not taken.
✓ Branch 303 → 305 taken 1230 times.
✓ Branch 305 → 306 taken 13 times.
✓ Branch 305 → 333 taken 1217 times.
✓ Branch 306 → 307 taken 7 times.
✓ Branch 306 → 332 taken 6 times.
✓ Branch 313 → 314 taken 7 times.
✗ Branch 313 → 729 not taken.
✓ Branch 325 → 326 taken 7 times.
✗ Branch 325 → 731 not taken.
2460 oper("&&", 0, math_binop_type::logical_and);
270
13/18
✓ Branch 131 → 132 taken 7 times.
✓ Branch 131 → 143 taken 1210 times.
✓ Branch 132 → 133 taken 4 times.
✓ Branch 132 → 142 taken 3 times.
✓ Branch 133 → 134 taken 4 times.
✗ Branch 133 → 294 not taken.
✓ Branch 138 → 139 taken 4 times.
✗ Branch 138 → 295 not taken.
✗ Branch 335 → 336 not taken.
✓ Branch 335 → 337 taken 1217 times.
✓ Branch 337 → 338 taken 7 times.
✓ Branch 337 → 365 taken 1210 times.
✓ Branch 338 → 339 taken 4 times.
✓ Branch 338 → 364 taken 3 times.
✓ Branch 345 → 346 taken 4 times.
✗ Branch 345 → 735 not taken.
✓ Branch 357 → 358 taken 4 times.
✗ Branch 357 → 737 not taken.
2434 oper("||", 0, math_binop_type::logical_or);
271
2/16
✗ Branch 143 → 144 not taken.
✓ Branch 143 → 155 taken 1210 times.
✗ Branch 144 → 145 not taken.
✗ Branch 144 → 154 not taken.
✗ Branch 145 → 146 not taken.
✗ Branch 145 → 297 not taken.
✗ Branch 150 → 151 not taken.
✗ Branch 150 → 298 not taken.
✗ Branch 368 → 369 not taken.
✓ Branch 368 → 396 taken 1210 times.
✗ Branch 369 → 370 not taken.
✗ Branch 369 → 395 not taken.
✗ Branch 376 → 377 not taken.
✗ Branch 376 → 741 not taken.
✗ Branch 388 → 389 not taken.
✗ Branch 388 → 743 not taken.
2420 oper("&", 2, math_binop_type::bit_and);
272
10/16
✓ Branch 155 → 156 taken 3 times.
✓ Branch 155 → 167 taken 1207 times.
✓ Branch 156 → 157 taken 3 times.
✗ Branch 156 → 166 not taken.
✓ Branch 157 → 158 taken 3 times.
✗ Branch 157 → 300 not taken.
✓ Branch 162 → 163 taken 3 times.
✗ Branch 162 → 301 not taken.
✓ Branch 399 → 400 taken 3 times.
✓ Branch 399 → 427 taken 1207 times.
✓ Branch 400 → 401 taken 3 times.
✗ Branch 400 → 426 not taken.
✓ Branch 407 → 408 taken 3 times.
✗ Branch 407 → 747 not taken.
✓ Branch 419 → 420 taken 3 times.
✗ Branch 419 → 749 not taken.
2420 oper("|", 2,math_binop_type::bit_or);
273
2/16
✗ Branch 167 → 168 not taken.
✓ Branch 167 → 179 taken 1207 times.
✗ Branch 168 → 169 not taken.
✗ Branch 168 → 178 not taken.
✗ Branch 169 → 170 not taken.
✗ Branch 169 → 303 not taken.
✗ Branch 174 → 175 not taken.
✗ Branch 174 → 304 not taken.
✗ Branch 430 → 431 not taken.
✓ Branch 430 → 458 taken 1207 times.
✗ Branch 431 → 432 not taken.
✗ Branch 431 → 457 not taken.
✗ Branch 438 → 439 not taken.
✗ Branch 438 → 753 not taken.
✗ Branch 450 → 451 not taken.
✗ Branch 450 → 755 not taken.
2414 oper("^", 2, math_binop_type::bit_xor);
274
275
11/18
✓ Branch 179 → 180 taken 4 times.
✓ Branch 179 → 191 taken 1203 times.
✓ Branch 180 → 181 taken 4 times.
✗ Branch 180 → 190 not taken.
✓ Branch 181 → 182 taken 4 times.
✗ Branch 181 → 306 not taken.
✓ Branch 186 → 187 taken 4 times.
✗ Branch 186 → 307 not taken.
✗ Branch 460 → 461 not taken.
✓ Branch 460 → 462 taken 1207 times.
✓ Branch 462 → 463 taken 4 times.
✓ Branch 462 → 490 taken 1203 times.
✓ Branch 463 → 464 taken 4 times.
✗ Branch 463 → 489 not taken.
✓ Branch 470 → 471 taken 4 times.
✗ Branch 470 → 759 not taken.
✓ Branch 482 → 483 taken 4 times.
✗ Branch 482 → 761 not taken.
2414 oper(">=", 1, math_binop_type::comp_ge);
276
11/18
✓ Branch 191 → 192 taken 1 time.
✓ Branch 191 → 203 taken 1202 times.
✓ Branch 192 → 193 taken 1 time.
✗ Branch 192 → 202 not taken.
✓ Branch 193 → 194 taken 1 time.
✗ Branch 193 → 309 not taken.
✓ Branch 198 → 199 taken 1 time.
✗ Branch 198 → 310 not taken.
✗ Branch 492 → 493 not taken.
✓ Branch 492 → 494 taken 1203 times.
✓ Branch 494 → 495 taken 1 time.
✓ Branch 494 → 522 taken 1202 times.
✓ Branch 495 → 496 taken 1 time.
✗ Branch 495 → 521 not taken.
✓ Branch 502 → 503 taken 1 time.
✗ Branch 502 → 765 not taken.
✓ Branch 514 → 515 taken 1 time.
✗ Branch 514 → 767 not taken.
2406 oper("<=", 1, math_binop_type::comp_le);
277
10/16
✓ Branch 203 → 204 taken 70 times.
✓ Branch 203 → 215 taken 1132 times.
✓ Branch 204 → 205 taken 70 times.
✗ Branch 204 → 214 not taken.
✓ Branch 205 → 206 taken 70 times.
✗ Branch 205 → 312 not taken.
✓ Branch 210 → 211 taken 70 times.
✗ Branch 210 → 313 not taken.
✓ Branch 525 → 526 taken 70 times.
✓ Branch 525 → 553 taken 1132 times.
✓ Branch 526 → 527 taken 70 times.
✗ Branch 526 → 552 not taken.
✓ Branch 533 → 534 taken 70 times.
✗ Branch 533 → 771 not taken.
✓ Branch 545 → 546 taken 70 times.
✗ Branch 545 → 773 not taken.
2404 oper(">", 1, math_binop_type::comp_gt);
278
10/16
✓ Branch 215 → 216 taken 898 times.
✓ Branch 215 → 227 taken 234 times.
✓ Branch 216 → 217 taken 898 times.
✗ Branch 216 → 226 not taken.
✓ Branch 217 → 218 taken 898 times.
✗ Branch 217 → 315 not taken.
✓ Branch 222 → 223 taken 898 times.
✗ Branch 222 → 316 not taken.
✓ Branch 556 → 557 taken 898 times.
✓ Branch 556 → 584 taken 234 times.
✓ Branch 557 → 558 taken 898 times.
✗ Branch 557 → 583 not taken.
✓ Branch 564 → 565 taken 898 times.
✗ Branch 564 → 777 not taken.
✓ Branch 576 → 577 taken 898 times.
✗ Branch 576 → 779 not taken.
2264 oper("<", 1, math_binop_type::comp_lt);
279
13/18
✓ Branch 227 → 228 taken 209 times.
✓ Branch 227 → 239 taken 25 times.
✓ Branch 228 → 229 taken 207 times.
✓ Branch 228 → 238 taken 2 times.
✓ Branch 229 → 230 taken 207 times.
✗ Branch 229 → 318 not taken.
✓ Branch 234 → 235 taken 207 times.
✗ Branch 234 → 319 not taken.
✗ Branch 586 → 587 not taken.
✓ Branch 586 → 588 taken 234 times.
✓ Branch 588 → 589 taken 209 times.
✓ Branch 588 → 616 taken 25 times.
✓ Branch 589 → 590 taken 207 times.
✓ Branch 589 → 615 taken 2 times.
✓ Branch 596 → 597 taken 207 times.
✗ Branch 596 → 783 not taken.
✓ Branch 608 → 609 taken 207 times.
✗ Branch 608 → 785 not taken.
468 oper("==", 1, math_binop_type::comp_eq);
280
13/18
✓ Branch 239 → 240 taken 17 times.
✓ Branch 239 → 251 taken 8 times.
✓ Branch 240 → 241 taken 15 times.
✓ Branch 240 → 250 taken 2 times.
✓ Branch 241 → 242 taken 15 times.
✗ Branch 241 → 321 not taken.
✓ Branch 246 → 247 taken 15 times.
✗ Branch 246 → 322 not taken.
✗ Branch 618 → 619 not taken.
✓ Branch 618 → 620 taken 25 times.
✓ Branch 620 → 621 taken 17 times.
✓ Branch 620 → 648 taken 8 times.
✓ Branch 621 → 622 taken 15 times.
✓ Branch 621 → 647 taken 2 times.
✓ Branch 628 → 629 taken 15 times.
✗ Branch 628 → 789 not taken.
✓ Branch 640 → 641 taken 15 times.
✗ Branch 640 → 791 not taken.
50 oper("!=", 1, math_binop_type::comp_ne);
281
2/4
✓ Branch 251 → 252 taken 8 times.
✗ Branch 251 → 324 not taken.
✓ Branch 648 → 649 taken 8 times.
✗ Branch 648 → 795 not taken.
16 throw_err_block(2, err_unknown_operator);
282 #undef oper
283 }
284 20655 return left;
285 20823 }
286
287 14361 owned_node parse_context::parse() {
288 14361 auto res = parse_binops();
289
2/4
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 7096 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 18 taken 7235 times.
14331 if(*str) {
290 if(*str == ',') throw_err_block(2, err_invalid_input);
291 else throw_err_block(2, err_mismatched_parentheses);
292 }
293 14331 return res;
294 }
295
296 48 void createuserfunc(const char * name, const char * arguments, const char * content) {
297
17/47
✓ Branch 2 → 3 taken 24 times.
✗ Branch 2 → 79 not taken.
✓ Branch 3 → 4 taken 48 times.
✗ Branch 3 → 79 not taken.
✗ Branch 3 → 136 not taken.
✓ Branch 4 → 5 taken 24 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 48 times.
✗ Branch 5 → 79 not taken.
✗ Branch 5 → 136 not taken.
✓ Branch 6 → 7 taken 48 times.
✗ Branch 6 → 13 not taken.
✗ Branch 6 → 79 not taken.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 24 times.
✓ Branch 9 → 10 taken 24 times.
✗ Branch 9 → 136 not taken.
✓ Branch 10 → 11 taken 24 times.
✗ Branch 10 → 12 not taken.
✓ Branch 11 → 12 taken 24 times.
✗ Branch 11 → 136 not taken.
✓ Branch 12 → 13 taken 24 times.
✓ Branch 12 → 14 taken 24 times.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 18 taken 24 times.
✓ Branch 15 → 16 taken 24 times.
✗ Branch 15 → 17 not taken.
✓ Branch 17 → 18 taken 24 times.
✗ Branch 17 → 19 not taken.
✓ Branch 19 → 20 taken 24 times.
✗ Branch 19 → 21 not taken.
✓ Branch 21 → 22 taken 24 times.
✗ Branch 21 → 23 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 27 taken 24 times.
✗ Branch 79 → 80 not taken.
✗ Branch 79 → 81 not taken.
✗ Branch 83 → 84 not taken.
✗ Branch 83 → 85 not taken.
✗ Branch 136 → 137 not taken.
✗ Branch 136 → 138 not taken.
✗ Branch 139 → 140 not taken.
✗ Branch 139 → 141 not taken.
✗ Branch 142 → 143 not taken.
✗ Branch 142 → 144 not taken.
✗ Branch 145 → 146 not taken.
✗ Branch 145 → 147 not taken.
48 if(user_functions.count(name) != 0 || builtin_functions.count(name) != 0) {
298 throw_err_block(0, err_function_redefined, name);
299 }
300
2/5
✓ Branch 18 → 19 taken 24 times.
✗ Branch 18 → 109 not taken.
✗ Branch 18 → 110 not taken.
✓ Branch 28 → 29 taken 24 times.
✗ Branch 28 → 178 not taken.
48 string arguments_buf = arguments;
301 // TODO: if we want to be more lenient with spaces in the `function`
302 // command, then we need to handle spaces inside `arguments_buf`
303 24 int numargs;
304
2/5
✓ Branch 20 → 21 taken 24 times.
✗ Branch 20 → 107 not taken.
✗ Branch 20 → 108 not taken.
✓ Branch 32 → 33 taken 24 times.
✗ Branch 32 → 176 not taken.
48 autoptr<char**> spl = split(arguments_buf.raw(), ',', &numargs);
305 48 size_t arg_count = numargs;
306
20/28
✓ Branch 22 → 23 taken 15 times.
✓ Branch 22 → 28 taken 9 times.
✓ Branch 23 → 24 taken 15 times.
✗ Branch 23 → 87 not taken.
✓ Branch 26 → 27 taken 6 times.
✓ Branch 26 → 28 taken 9 times.
✓ Branch 29 → 30 taken 15 times.
✓ Branch 29 → 31 taken 9 times.
✓ Branch 31 → 32 taken 6 times.
✓ Branch 31 → 33 taken 18 times.
✓ Branch 34 → 35 taken 15 times.
✓ Branch 34 → 43 taken 9 times.
✓ Branch 36 → 37 taken 15 times.
✗ Branch 36 → 148 not taken.
✓ Branch 41 → 42 taken 6 times.
✓ Branch 41 → 43 taken 9 times.
✓ Branch 44 → 45 taken 15 times.
✓ Branch 44 → 46 taken 9 times.
✓ Branch 46 → 47 taken 15 times.
✓ Branch 46 → 48 taken 9 times.
✓ Branch 48 → 49 taken 6 times.
✓ Branch 48 → 50 taken 18 times.
✗ Branch 87 → 88 not taken.
✗ Branch 87 → 89 not taken.
✗ Branch 148 → 149 not taken.
✗ Branch 148 → 150 not taken.
✗ Branch 151 → 152 not taken.
✗ Branch 151 → 153 not taken.
48 if(numargs == 1 && spl[0] == string{""}) {
307 12 arg_count = 0;
308 }
309 48 std::unordered_map<string, size_t> arg_indices;
310
4/4
✓ Branch 54 → 35 taken 27 times.
✓ Branch 54 → 55 taken 24 times.
✓ Branch 78 → 54 taken 27 times.
✓ Branch 78 → 79 taken 24 times.
102 for(size_t i = 0; i < arg_count; i++) {
311
2/5
✓ Branch 36 → 37 taken 27 times.
✗ Branch 36 → 93 not taken.
✗ Branch 36 → 94 not taken.
✓ Branch 58 → 59 taken 27 times.
✗ Branch 58 → 156 not taken.
54 string argname = spl[i];
312
4/9
✓ Branch 37 → 38 taken 27 times.
✗ Branch 37 → 91 not taken.
✗ Branch 37 → 92 not taken.
✗ Branch 38 → 39 not taken.
✓ Branch 38 → 43 taken 27 times.
✓ Branch 59 → 60 taken 27 times.
✗ Branch 59 → 154 not taken.
✗ Branch 60 → 61 not taken.
✓ Branch 60 → 65 taken 27 times.
54 if(arg_indices.count(argname)) {
313 throw_err_block(0, err_duplicate_param_name, argname.data(), name);
314 }
315
4/9
✓ Branch 44 → 45 taken 27 times.
✗ Branch 44 → 91 not taken.
✗ Branch 44 → 92 not taken.
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 50 taken 27 times.
✓ Branch 66 → 67 taken 27 times.
✗ Branch 66 → 154 not taken.
✗ Branch 67 → 68 not taken.
✓ Branch 67 → 72 taken 27 times.
54 if(!confirmname(argname)) {
316 throw_err_block(0, err_invalid_param_name, argname.data());
317 }
318
2/4
✓ Branch 51 → 52 taken 27 times.
✗ Branch 51 → 91 not taken.
✓ Branch 74 → 75 taken 27 times.
✗ Branch 74 → 154 not taken.
54 arg_indices.emplace(std::move(argname), i);
319 54 }
320
321
2/5
✓ Branch 55 → 56 taken 24 times.
✗ Branch 55 → 103 not taken.
✗ Branch 55 → 104 not taken.
✓ Branch 81 → 82 taken 24 times.
✗ Branch 81 → 172 not taken.
48 parse_context ctx{ content, arg_indices };
322 // define the function name with a dummy function to allow recursive calls to it within its own body
323
2/5
✓ Branch 56 → 57 taken 24 times.
✗ Branch 56 → 95 not taken.
✗ Branch 56 → 96 not taken.
✓ Branch 87 → 88 taken 24 times.
✗ Branch 87 → 160 not taken.
48 math_user_function dummy_func = { std::make_unique<math_ast_literal>((int64_t)0), arg_count };
324
2/5
✓ Branch 62 → 63 taken 24 times.
✗ Branch 62 → 98 not taken.
✗ Branch 62 → 99 not taken.
✓ Branch 100 → 101 taken 24 times.
✗ Branch 100 → 166 not taken.
48 auto func_slot = user_functions.emplace(name, std::move(dummy_func)).first;
325
326
2/5
✓ Branch 63 → 64 taken 24 times.
✗ Branch 63 → 99 not taken.
✗ Branch 63 → 100 not taken.
✓ Branch 103 → 104 taken 24 times.
✗ Branch 103 → 168 not taken.
48 auto parsed = ctx.parse();
327 48 math_user_function userfunc = { std::move(parsed), arg_count };
328 48 func_slot->second = std::move(userfunc);
329 72 }
330
331 14313 owned_node parse_math_expr(const char * str) {
332 14313 parse_context parse_ctx { str, {}};
333
4/4
✓ Branch 3 → 4 taken 7072 times.
✓ Branch 3 → 8 taken 15 times.
✓ Branch 5 → 6 taken 7211 times.
✓ Branch 5 → 10 taken 15 times.
28596 return parse_ctx.parse();
334 14313 }
335
336 956 int64_t getnum(const char * str) {
337
2/4
✓ Branch 2 → 3 taken 478 times.
✗ Branch 2 → 22 not taken.
✓ Branch 3 → 4 taken 478 times.
✗ Branch 3 → 37 not taken.
956 owned_node parsed = parse_math_expr(str);
338
2/4
✓ Branch 4 → 5 taken 478 times.
✗ Branch 4 → 20 not taken.
✓ Branch 11 → 12 taken 478 times.
✗ Branch 11 → 35 not taken.
956 int haslabel = parsed->has_label();
339 956 foundlabel = haslabel > 0;
340 956 foundlabel_static = haslabel < 2;
341 956 forwardlabel = haslabel == 7;
342
2/4
✓ Branch 7 → 8 taken 478 times.
✗ Branch 7 → 15 not taken.
✓ Branch 19 → 20 taken 478 times.
✗ Branch 19 → 29 not taken.
1912 math_val rval = parsed->evaluate();
343
2/4
✓ Branch 9 → 10 taken 478 times.
✗ Branch 9 → 18 not taken.
✓ Branch 22 → 23 taken 478 times.
✗ Branch 22 → 33 not taken.
1912 return rval.get_integer();
344 1912 }
345
346 414 int getlen(const char * orgstr, bool optimizebankextraction) {
347
2/4
✓ Branch 2 → 3 taken 207 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 207 times.
✗ Branch 3 → 17 not taken.
414 owned_node parsed = parse_math_expr(orgstr);
348
2/4
✓ Branch 4 → 5 taken 207 times.
✗ Branch 4 → 8 not taken.
✓ Branch 11 → 12 taken 207 times.
✗ Branch 11 → 15 not taken.
414 int letgen = parsed->get_len(optimizebankextraction);
349 414 return letgen;
350 414 }
351
352 856 void initmathcore()
353 {
354 856 user_functions.clear();
355 856 }
356
357 846 void deinitmathcore()
358 {
359 //not needed
360 846 }
361