asar coverage - build #


src/asar/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
39 of 40, 0 excluded
97.5%
Functions:
8 of 8, 0 excluded
100.0%
Branches:
21 of 37, 0 excluded
56.8%

asar_math.h
Line Branch Exec Source
1 #pragma once
2 #include <cstdint>
3 #include <memory>
4 #include <vector>
5 #include "assembleblock.h"
6 #include "errors.h"
7 #include "libstr.h"
8
9 // Public interface of the Asar mathematical subsystem //
10
11 // Asar's math is dynamically typed, this enum defines the possible types.
12 enum class math_val_type {
13 // 64-bit (double) floating point
14 floating,
15 // 64-bit signed int
16 integer,
17 // string
18 string,
19 // a resolved label with a name and value. used for datasize() and whatnot.
20 // auto-converts to integer when necessary.
21 identifier,
22 };
23
24 class math_val {
25 public:
26 math_val_type m_type;
27 union {
28 double double_;
29 int64_t int_;
30 } m_numeric_val;
31 // this is used for both labelname in case of
32 // m_type=identifier, and string value in case of m_type=string
33 string m_string_val;
34
35 math_val() {
36 m_type = math_val_type::integer;
37 m_numeric_val.int_ = 0;
38 }
39 158 math_val(double v) {
40 158 m_type = math_val_type::floating;
41 158 m_numeric_val.double_ = v;
42 158 }
43 23608 math_val(int64_t v) {
44 23608 m_type = math_val_type::integer;
45 23608 m_numeric_val.int_ = v;
46 23608 }
47 1352 math_val(string v) {
48 1352 m_type = math_val_type::string;
49
2/6
math_val::math_val(string):
✓ Branch 3 → 4 taken 670 times.
✗ Branch 3 → 5 not taken.
math_val::math_val(string):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✓ Branch 10 → 11 taken 682 times.
✗ Branch 10 → 12 not taken.
1352 m_string_val = v;
50 1352 }
51 963 static math_val make_identifier(string v) {
52
3/7
✓ Branch 2 → 3 taken 480 times.
✗ Branch 2 → 9 not taken.
✓ Branch 3 → 4 taken 963 times.
✗ Branch 3 → 7 not taken.
✗ Branch 3 → 12 not taken.
✓ Branch 4 → 5 taken 483 times.
✗ Branch 4 → 10 not taken.
963 math_val res(v);
53 963 res.m_type = math_val_type::identifier;
54 963 return res;
55 }
56
57 double get_double() const;
58 int64_t get_integer() const;
59 const string &get_str() const;
60 const string &get_identifier() const;
61 bool get_bool() const;
62 };
63
64 class math_ast_node {
65 public:
66 // any info that's necessary during evaluation.
67 // external callers shouldn't need to pass in anything other than the default-constructed one.
68 class eval_context {
69 public:
70 // TODO would it be faster to make this a reference? does that avoid any significant copies?
71 std::vector<math_val> userfunc_params;
72 };
73 // info necessary for static analysis.
74 // external callers shouldn't need to pass in anything other than the default-constructed one.
75 class static_context {
76 public:
77 // which user func (addr of math_user_function) we're in.
78 // sufficient to detect recursion since we don't allow mutually recursive definitions.
79 const void* current_user_func;
80 };
81
82 virtual math_val evaluate(const eval_context& = {}) const = 0;
83 // 0 - no label, 1 - static label, 3 - nonstatic label, 7 - forward label
84 virtual int has_label(const static_context& = {}) const = 0;
85 // how many bytes long should the result of this expression be?
86 virtual int get_len(bool could_be_bank_ex, const static_context& = {}) const = 0;
87 26280 virtual ~math_ast_node() = default;
88
89 // helper functions:
90
91 // evaluate an expression that doesn't allow non-static label references
92 5991 math_val evaluate_static() {
93
6/8
✓ Branch 2 → 3 taken 2994 times.
✗ Branch 2 → 12 not taken.
✓ Branch 3 → 4 taken 27 times.
✓ Branch 3 → 7 taken 2967 times.
✓ Branch 10 → 11 taken 2997 times.
✗ Branch 10 → 26 not taken.
✓ Branch 12 → 13 taken 27 times.
✓ Branch 12 → 16 taken 2970 times.
5991 if(has_label() > 1)
94 54 throw_err_block(0, err_no_labels_here);
95
2/4
✓ Branch 8 → 9 taken 2967 times.
✗ Branch 8 → 13 not taken.
✓ Branch 22 → 23 taken 2970 times.
✗ Branch 22 → 28 not taken.
8907 return evaluate();
96 5937 }
97 // evaluate an expression that doesn't allow forward label references
98 1929 math_val evaluate_non_forward() {
99
6/8
✓ Branch 2 → 3 taken 927 times.
✗ Branch 2 → 12 not taken.
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 7 taken 925 times.
✓ Branch 10 → 11 taken 1002 times.
✗ Branch 10 → 26 not taken.
✓ Branch 12 → 13 taken 2 times.
✓ Branch 12 → 16 taken 1000 times.
1929 if(has_label() > 3)
100 4 throw_err_block(0, err_label_forward);
101
2/4
✓ Branch 8 → 9 taken 925 times.
✗ Branch 8 → 13 not taken.
✓ Branch 22 → 23 taken 1000 times.
✗ Branch 22 → 28 not taken.
2925 return evaluate();
102 1925 }
103
104 // whether this expression is of the form "label +- offset", where offset is static
105 bool is_label_offset(snes_label& out_base, int64_t& out_offset);
106 };
107
108 void initmathcore();
109 void deinitmathcore();
110 void closecachedfiles();
111
112 void createuserfunc(const char * name, const char * arguments, const char * content);
113
114 std::unique_ptr<math_ast_node> parse_math_expr(const char * str);
115
116 // old interface: to be nuked in due time
117
118 int64_t getnum(const char * str);
119
120 // still used in arch-spc700... god that one's a proper mess
121 int getlen(const char * str, bool optimizebankextraction=false);
122 extern bool foundlabel;
123