asar coverage - build #


src/asar/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
76 of 76, 0 excluded
100.0%
Functions:
34 of 34, 0 excluded
100.0%
Branches:
24 of 48, 0 excluded
50.0%

math_ast.h
Line Branch Exec Source
1 #include <memory>
2 #include <variant>
3 #include <vector>
4 #include <unordered_map>
5 #include "libstr.h"
6 #include "asar_math.h"
7 #include "assembleblock.h"
8
9 using owned_node = std::unique_ptr<math_ast_node>;
10
11 enum class math_binop_type {
12 pow, // **
13 mul, // *
14 div, // /
15 mod, // %
16 add, // +
17 sub, // -
18 shift_left, // <<
19 shift_right, // >>
20 bit_and, // &
21 bit_or, // |
22 bit_xor, // ^
23 logical_and, // &&
24 logical_or, // ||
25 comp_ge, // >=
26 comp_le, // <=
27 comp_gt, // >
28 comp_lt, // <
29 comp_eq, // ==
30 comp_ne, // !=
31 };
32
33 math_val evaluate_binop(math_val lhs, math_val rhs, math_binop_type type);
34
35 class math_ast_binop : public math_ast_node {
36 public:
37 owned_node m_left, m_right;
38 math_binop_type m_type;
39 5159 math_ast_binop(owned_node left_in, owned_node right_in, math_binop_type type_in)
40 5159 : m_left(std::move(left_in)), m_right(std::move(right_in)), m_type(type_in) {}
41
42 math_val evaluate(const eval_context &ctx) const;
43 int has_label(const static_context& ctx) const;
44 int get_len(bool could_be_bank_ex, const static_context& ctx) const;
45 };
46
47 enum class math_unop_type {
48 neg,
49 bit_not,
50 bank_extract,
51 };
52
53 class math_ast_unop : public math_ast_node {
54 public:
55 owned_node m_arg;
56 math_unop_type m_type;
57 66 math_ast_unop(owned_node arg_in, math_unop_type type_in)
58 66 : m_arg(std::move(arg_in)), m_type(type_in) {}
59 math_val evaluate(const eval_context &ctx) const;
60 int has_label(const static_context& ctx) const;
61 int get_len(bool could_be_bank_ex, const static_context& ctx) const;
62 };
63
64 class math_ast_ternary_cond : public math_ast_node {
65 owned_node m_cond, m_true, m_false;
66 public:
67 38 math_ast_ternary_cond(owned_node cond_in, owned_node true_in, owned_node false_in)
68 38 : m_cond(std::move(cond_in)), m_true(std::move(true_in)), m_false(std::move(false_in)) {}
69
70 math_val evaluate(const eval_context& ctx) const;
71 int has_label(const static_context& ctx) const;
72 int get_len(bool could_be_bank_ex, const static_context& ctx) const;
73 };
74
75 class math_ast_literal : public math_ast_node {
76 math_val m_value;
77 int m_len;
78 public:
79
2/6
math_ast_literal::math_ast_literal(math_val, int):
✓ Branch 3 → 4 taken 9212 times.
✗ Branch 3 → 5 not taken.
math_ast_literal::math_ast_literal(math_val, int):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✓ Branch 12 → 13 taken 9346 times.
✗ Branch 12 → 18 not taken.
18558 math_ast_literal(math_val value, int len=0) : m_value(value), m_len(len) {}
80 16596 math_val evaluate(const eval_context& ctx) const { return m_value; }
81 13734 int has_label(const static_context& ctx) const { return 0; }
82 2526 int get_len(bool could_be_bank_ex, const static_context& ctx) const { return m_len; }
83 friend int math_ast_binop::get_len(bool, const static_context&) const;
84 };
85
86 class math_ast_label : public math_ast_node {
87 string m_labelname;
88 // current namespace when this label was referenced
89 string m_cur_ns;
90 public:
91 // this should be the output of labelname() already
92 1284 math_ast_label(string labelname)
93
1/2
✓ Branch 11 → 12 taken 646 times.
✗ Branch 11 → 23 not taken.
2568 : m_labelname(labelname)
94 // this is initialized with the global ns
95
3/10
math_ast_label::math_ast_label(string):
✓ Branch 3 → 4 taken 638 times.
✗ Branch 3 → 8 not taken.
✓ Branch 4 → 5 taken 638 times.
✗ Branch 4 → 6 not taken.
math_ast_label::math_ast_label(string):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 8 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
✓ Branch 16 → 17 taken 646 times.
✗ Branch 16 → 18 not taken.
1930 , m_cur_ns(ns) {}
96 math_val evaluate(const eval_context &ctx) const;
97 int has_label(const static_context& ctx) const;
98 int get_len(bool could_be_bank_ex, const static_context& ctx) const;
99 };
100
101
102 class math_builtin_function {
103 using call_t = math_val(*)(const std::vector<math_val>& args);
104 using haslabel_t = int(*)(const math_ast_node::static_context& ctx);
105 using getlen_t = int(*)(const std::vector<owned_node>& args, bool could_be_bank_ex, const math_ast_node::static_context& ctx);
106 474 static int default_has_label(const math_ast_node::static_context& ctx) {
107 474 return 0;
108 }
109 84 static int default_get_len(const std::vector<owned_node>& args, bool could_be_bank_ex, const math_ast_node::static_context& ctx) {
110 84 int res = 0;
111
4/4
✓ Branch 10 → 4 taken 45 times.
✓ Branch 10 → 11 taken 42 times.
✓ Branch 27 → 9 taken 45 times.
✓ Branch 27 → 28 taken 42 times.
174 for(auto& v : args) {
112
2/4
✓ Branch 6 → 7 taken 45 times.
✗ Branch 6 → 13 not taken.
✓ Branch 20 → 21 taken 45 times.
✗ Branch 20 → 32 not taken.
90 res = std::max(res, v->get_len(false, ctx));
113 }
114 84 return res;
115 }
116 call_t m_call;
117 haslabel_t m_haslabel;
118 getlen_t m_getlen;
119 public:
120 420 math_builtin_function(call_t c, haslabel_t l = default_has_label, getlen_t gl = default_get_len)
121 420 : m_call(c), m_haslabel(l), m_getlen(gl) {}
122 6 math_builtin_function(call_t c, getlen_t gl)
123 6 : m_call(c), m_haslabel(default_has_label), m_getlen(gl) {}
124 927 math_val call(const std::vector<math_val>& args) const {
125 927 return m_call(args);
126 }
127 510 int has_label(const math_ast_node::static_context& ctx) const {
128 510 return m_haslabel(ctx);
129 }
130 108 int get_len(const std::vector<owned_node>& args, bool could_be_bank_ex, const math_ast_node::static_context& ctx) const {
131 108 return m_getlen(args, could_be_bank_ex, ctx);
132 }
133 };
134
135 class math_user_function {
136 size_t m_arg_count;
137 owned_node m_func_body;
138 public:
139 132 math_user_function(owned_node body, size_t arg_count)
140 132 : m_arg_count(arg_count), m_func_body(std::move(body)) {}
141 math_val call(const std::vector<math_val> &args) const;
142 int has_label(const math_ast_node::static_context& ctx) const;
143 int get_len(const std::vector<owned_node> &args, bool could_be_bank_ex, const math_ast_node::static_context& ctx) const;
144 };
145
146 class math_function_ref {
147 public:
148 std::variant<const math_builtin_function*, const math_user_function*> inner;
149 995 math_function_ref(const math_builtin_function& fn) : inner(&fn) {}
150 60 math_function_ref(const math_user_function& fn) : inner(&fn) {}
151 993 math_val call(const std::vector<math_val>& args) const {
152
4/4
✓ Branch 2 → 3 taken 479 times.
✓ Branch 2 → 6 taken 15 times.
✓ Branch 8 → 9 taken 484 times.
✓ Branch 8 → 12 taken 15 times.
2465 return std::visit([&](auto& i) { return i->call(args); }, inner);
153 }
154 534 int has_label(const math_ast_node::static_context& ctx) const {
155
2/4
✓ Branch 2 → 3 taken 267 times.
✗ Branch 2 → 6 not taken.
✓ Branch 7 → 8 taken 267 times.
✗ Branch 7 → 11 not taken.
1068 return std::visit([&](auto& i) { return i->has_label(ctx); }, inner);
156 }
157 138 int get_len(const std::vector<owned_node>& args, bool could_be_bank_ex, const math_ast_node::static_context& ctx) const {
158
4/8
math_function_ref::get_len(std::vector<std::unique_ptr<math_ast_node, std::default_delete<math_ast_node> >, std::allocator<std::unique_ptr<math_ast_node, std::default_delete<math_ast_node> > > > const&, bool, math_ast_node::static_context const&) const:
✓ Branch 2 → 3 taken 69 times.
✗ Branch 2 → 6 not taken.
✓ Branch 7 → 8 taken 69 times.
✗ Branch 7 → 11 not taken.
auto math_function_ref::get_len(std::vector<std::unique_ptr<math_ast_node, std::default_delete<math_ast_node> >, std::allocator<std::unique_ptr<math_ast_node, std::default_delete<math_ast_node> > > > const&, bool, math_ast_node::static_context const&) const::{lambda(auto:1&)#1}::operator()<math_user_function const* const>(math_user_function const* const&) const:
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 15 times.
auto math_function_ref::get_len(std::vector<std::unique_ptr<math_ast_node, std::default_delete<math_ast_node> >, std::allocator<std::unique_ptr<math_ast_node, std::default_delete<math_ast_node> > > > const&, bool, math_ast_node::static_context const&) const::{lambda(auto:1&)#1}::operator()<math_builtin_function const* const>(math_builtin_function const* const&) const:
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 54 times.
276 return std::visit([&](auto& i) { return i->get_len(args, could_be_bank_ex, ctx); }, inner);
159 }
160 };
161
162 extern std::unordered_map<string, math_user_function> user_functions;
163 extern const std::unordered_map<string, math_builtin_function> builtin_functions;
164
165 class math_ast_function_call : public math_ast_node {
166 std::vector<owned_node> m_arguments;
167 math_function_ref m_func;
168 static math_function_ref lookup_fname(string const &function_name);
169
170 public:
171 1055 math_ast_function_call(std::vector<owned_node> args, string function_name)
172 1585 : m_arguments(std::move(args))
173
2/6
math_ast_function_call::math_ast_function_call(std::vector<std::unique_ptr<math_ast_node, std::default_delete<math_ast_node> >, std::allocator<std::unique_ptr<math_ast_node, std::default_delete<math_ast_node> > > >, string):
✓ Branch 5 → 6 taken 525 times.
✗ Branch 5 → 7 not taken.
math_ast_function_call::math_ast_function_call(std::vector<std::unique_ptr<math_ast_node, std::default_delete<math_ast_node> >, std::allocator<std::unique_ptr<math_ast_node, std::default_delete<math_ast_node> > > >, string):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
✓ Branch 18 → 19 taken 530 times.
✗ Branch 18 → 20 not taken.
2110 , m_func(lookup_fname(function_name)) {}
174 math_val evaluate(const eval_context &ctx) const;
175 int has_label(const static_context& ctx) const;
176 int get_len(bool could_be_bank_ex, const static_context& ctx) const;
177 };
178
179 // only for use inside user function definitions
180 class math_ast_function_argument : public math_ast_node {
181 size_t m_arg_idx;
182 public:
183 120 math_ast_function_argument(size_t arg_idx) : m_arg_idx(arg_idx) {}
184
185 150 math_val evaluate(const eval_context& ctx) const {
186 150 return ctx.userfunc_params[m_arg_idx];
187 }
188
189 // if a function is called with a label as an argument, that gets checked by
190 // the function call node, not here
191 66 int has_label(const static_context& ctx) const { return 0; }
192 // i don't think these should ever have their len gotten?
193 18 int get_len(bool could_be_bank_ex, const static_context& ctx) const { return 0; }
194 };
195