• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ArkScript-lang / Ark / 11445793250

21 Oct 2024 05:51PM UTC coverage: 76.877% (+0.4%) from 76.499%
11445793250

push

github

SuperFola
refactor(macro): removing useless constructor

5130 of 6673 relevant lines covered (76.88%)

9379.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.33
/src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp
1
#include <Ark/Compiler/IntermediateRepresentation/IROptimizer.hpp>
2

3
#include <utility>
4
#include <Ark/Builtins/Builtins.hpp>
5

6
namespace Ark::internal
7
{
8
    struct EntityWithOffset
9
    {
10
        IR::Entity entity;
11
        std::size_t offset;
12
    };
13

14
    IROptimizer::IROptimizer(const unsigned debug) :
176✔
15
        m_logger("IROptimizer", debug)
88✔
16
    {}
176✔
17

18
    void IROptimizer::process(const std::vector<IR::Block>& pages, const std::vector<std::string>& symbols, const std::vector<ValTableElem>& values)
26✔
19
    {
26✔
20
        m_symbols = symbols;
26✔
21
        m_values = values;
26✔
22

23
        auto map = []<typename T>(const std::optional<T>& opt, auto&& lambda) -> decltype(std::optional(lambda(opt.value()))) {
14,738✔
24
            if (opt.has_value())
14,712✔
25
                return lambda(opt.value());
992✔
26
            return std::nullopt;
13,720✔
27
        };
14,712✔
28

29
        auto or_else = []<typename T>(const std::optional<T>& opt, auto&& lambda) -> std::optional<T> {
7,797✔
30
            if (!opt.has_value())
7,771✔
31
                return lambda();
6,824✔
32
            return opt;
947✔
33
        };
7,771✔
34

35
        for (const auto& block : pages)
155✔
36
        {
37
            m_ir.emplace_back();
129✔
38
            IR::Block& current_block = m_ir.back();
129✔
39

40
            std::size_t i = 0;
129✔
41
            const std::size_t end = block.size();
129✔
42

43
            while (i < end)
8,134✔
44
            {
45
                std::optional<EntityWithOffset> maybe_compacted = std::nullopt;
8,005✔
46

47
                if (i + 1 < end)
8,005✔
48
                    maybe_compacted = map(
15,776✔
49
                        compactEntities(block[i], block[i + 1]),
7,888✔
50
                        [](const auto& entity) {
8,847✔
51
                            return std::make_optional<EntityWithOffset>(entity, 2);
959✔
52
                        });
53
                if (i + 2 < end)
8,005✔
54
                    maybe_compacted = or_else(
7,771✔
55
                        maybe_compacted,
56
                        [&, this]() {
14,595✔
57
                            return map(
13,648✔
58
                                compactEntities(block[i], block[i + 1], block[i + 2]),
6,824✔
59
                                [](const auto& entity) {
6,857✔
60
                                    return std::make_optional<EntityWithOffset>(entity, 3);
33✔
61
                                });
62
                        });
63

64
                if (maybe_compacted.has_value())
8,005✔
65
                {
66
                    auto [entity, offset] = maybe_compacted.value();
992✔
67
                    current_block.emplace_back(entity);
992✔
68
                    i += offset;
992✔
69
                }
992✔
70
                else
71
                {
72
                    current_block.emplace_back(block[i]);
7,013✔
73
                    ++i;
7,013✔
74
                }
75
            }
8,005✔
76
        }
129✔
77
    }
26✔
78

79
    const std::vector<IR::Block>& IROptimizer::intermediateRepresentation() const noexcept
26✔
80
    {
26✔
81
        return m_ir;
26✔
82
    }
83

84
    std::optional<IR::Entity> IROptimizer::compactEntities(const IR::Entity& first, const IR::Entity& second)
7,888✔
85
    {
7,888✔
86
        if (first.primaryArg() > IR::MaxValueForDualArg || second.primaryArg() > IR::MaxValueForDualArg)
7,888✔
87
            return std::nullopt;
×
88

89
        // LOAD_CONST x
90
        // LOAD_CONST y
91
        // ---> LOAD_CONST_LOAD_CONST x y
92
        if (first.inst() == LOAD_CONST && second.inst() == LOAD_CONST)
7,888✔
93
            return IR::Entity(LOAD_CONST_LOAD_CONST, first.primaryArg(), second.primaryArg());
632✔
94
        // LOAD_CONST x
95
        // STORE / SET_VAL a
96
        // ---> LOAD_CONST_STORE x a ; LOAD_CONST_SET_VAL x a
97
        if (first.inst() == LOAD_CONST && second.inst() == STORE)
7,256✔
98
            return IR::Entity(LOAD_CONST_STORE, first.primaryArg(), second.primaryArg());
140✔
99
        if (first.inst() == LOAD_CONST && second.inst() == SET_VAL)
7,116✔
100
            return IR::Entity(LOAD_CONST_SET_VAL, first.primaryArg(), second.primaryArg());
4✔
101
        // LOAD_SYMBOL a
102
        // STORE / SET_VAL b
103
        // ---> STORE_FROM a b ; SET_VAL_FROM a b
104
        if (first.inst() == LOAD_SYMBOL && second.inst() == STORE)
7,112✔
105
            return IR::Entity(STORE_FROM, first.primaryArg(), second.primaryArg());
7✔
106
        if (first.inst() == LOAD_SYMBOL && second.inst() == SET_VAL)
7,105✔
107
            return IR::Entity(SET_VAL_FROM, first.primaryArg(), second.primaryArg());
4✔
108
        // BUILTIN i
109
        // CALL n
110
        // ---> CALL_BUILTIN i n
111
        if (first.inst() == BUILTIN && second.inst() == CALL && Builtins::builtins[first.primaryArg()].second.isFunction())
7,101✔
112
            return IR::Entity(CALL_BUILTIN, first.primaryArg(), second.primaryArg());
172✔
113

114
        return std::nullopt;
6,929✔
115
    }
7,888✔
116

117
    std::optional<IR::Entity> IROptimizer::compactEntities(const IR::Entity& first, const IR::Entity& second, const IR::Entity& third)
6,824✔
118
    {
6,824✔
119
        if (first.primaryArg() > IR::MaxValueForDualArg || second.primaryArg() > IR::MaxValueForDualArg || third.primaryArg() > IR::MaxValueForDualArg)
6,824✔
120
            return std::nullopt;
×
121

122
        // LOAD_SYMBOL a
123
        // LOAD_CONST n (1)
124
        // ADD / SUB
125
        // ---> INCREMENT / DECREMENT a
126
        if (third.inst() == ADD && first.inst() == LOAD_CONST && second.inst() == LOAD_SYMBOL && isNumber(first.primaryArg(), 1))
6,824✔
127
            return IR::Entity(INCREMENT, second.primaryArg());
25✔
128
        if (third.inst() == ADD && first.inst() == LOAD_SYMBOL && second.inst() == LOAD_CONST && isNumber(second.primaryArg(), 1))
6,799✔
129
            return IR::Entity(INCREMENT, first.primaryArg());
5✔
130
        if (third.inst() == SUB && first.inst() == LOAD_SYMBOL && second.inst() == LOAD_CONST && isNumber(second.primaryArg(), 1))
6,794✔
131
            return IR::Entity(DECREMENT, first.primaryArg());
3✔
132
        // LOAD_SYMBOL list
133
        // TAIL / HEAD
134
        // STORE / SET_VAL a
135
        // ---> STORE_TAIL list a ; STORE_HEAD ; SET_VAL_TAIL ; SET_VAL_HEAD
136
        if (first.inst() == LOAD_SYMBOL && second.inst() == TAIL && third.inst() == STORE)
6,791✔
137
            return IR::Entity(STORE_TAIL, first.primaryArg(), third.primaryArg());
×
138
        if (first.inst() == LOAD_SYMBOL && second.inst() == TAIL && third.inst() == SET_VAL)
6,791✔
139
            return IR::Entity(SET_VAL_TAIL, first.primaryArg(), third.primaryArg());
×
140
        if (first.inst() == LOAD_SYMBOL && second.inst() == HEAD && third.inst() == STORE)
6,791✔
141
            return IR::Entity(STORE_HEAD, first.primaryArg(), third.primaryArg());
×
142
        if (first.inst() == LOAD_SYMBOL && second.inst() == HEAD && third.inst() == SET_VAL)
6,791✔
143
            return IR::Entity(SET_VAL_HEAD, first.primaryArg(), third.primaryArg());
×
144

145
        return std::nullopt;
6,791✔
146
    }
6,824✔
147

148
    bool IROptimizer::isNumber(const uint16_t id, const double expected_number) const
33✔
149
    {
33✔
150
        return std::cmp_less(id, m_values.size()) && m_values[id].type == ValTableElemType::Number && std::get<double>(m_values[id].value) == expected_number;
33✔
151
    }
152
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc