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

ArkScript-lang / Ark / 11629993358

01 Nov 2024 01:18PM UTC coverage: 77.27% (-0.05%) from 77.319%
11629993358

push

github

SuperFola
feat(tests): adding first test for IR generation and optimization

5208 of 6740 relevant lines covered (77.27%)

9463.56 hits per line

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

76.07
/src/arkreactor/Compiler/Welder.cpp
1
#include <Ark/Constants.hpp>
2
#include <Ark/Compiler/Welder.hpp>
3

4
#include <Ark/Compiler/Package/ImportSolver.hpp>
5
#include <Ark/Compiler/AST/Optimizer.hpp>
6
#include <Ark/Compiler/Macros/Processor.hpp>
7
#include <Ark/Compiler/NameResolutionPass.hpp>
8
#include <Ark/Files.hpp>
9
#include <Ark/Exceptions.hpp>
10

11
#include <sstream>
12
#include <fmt/ostream.h>
13

14
namespace Ark
15
{
16
    Welder::Welder(const unsigned debug, const std::vector<std::filesystem::path>& lib_env, const uint16_t features) :
200✔
17
        m_lib_env(lib_env), m_features(features),
100✔
18
        m_computed_ast(internal::NodeType::Unused),
100✔
19
        m_parser(debug),
100✔
20
        m_import_solver(debug, lib_env),
100✔
21
        m_macro_processor(debug),
100✔
22
        m_ast_optimizer(debug),
100✔
23
        m_name_resolver(debug),
100✔
24
        m_logger("Welder", debug),
100✔
25
        m_ir_optimizer(debug),
100✔
26
        m_ir_compiler(debug),
100✔
27
        m_compiler(debug)
100✔
28
    {}
200✔
29

30
    void Welder::registerSymbol(const std::string& name)
4✔
31
    {
4✔
32
        m_name_resolver.addDefinedSymbol(name, /* is_mutable= */ false);
4✔
33
    }
4✔
34

35
    bool Welder::computeASTFromFile(const std::string& filename)
96✔
36
    {
96✔
37
        m_root_file = std::filesystem::path(filename);
96✔
38
        const std::string code = Utils::readFile(filename);
96✔
39

40
        return computeAST(filename, code);
96✔
41
    }
96✔
42

×
43
    bool Welder::computeASTFromString(const std::string& code)
4✔
44
    {
4✔
45
        m_root_file = std::filesystem::current_path();  // No filename given, take the current working directory
4✔
46

47
        return computeAST(ARK_NO_NAME_FILE, code);
4✔
48
    }
×
49

50
    bool Welder::generateBytecode()
41✔
51
    {
41✔
52
        try
×
53
        {
54
            m_compiler.process(m_computed_ast);
41✔
55
            m_ir = m_compiler.intermediateRepresentation();
×
56

57
            if ((m_features & FeatureIROptimizer) != 0)
27✔
58
            {
59
                m_ir_optimizer.process(m_ir, m_compiler.symbols(), m_compiler.values());
27✔
60
                m_ir = m_ir_optimizer.intermediateRepresentation();
27✔
61
            }
27✔
62

×
63
            m_ir_compiler.process(m_ir, m_compiler.symbols(), m_compiler.values());
27✔
64
            m_bytecode = m_ir_compiler.bytecode();
27✔
65

66
            if ((m_features & FeatureDumpIR) != 0)
×
67
                dumpIRToFile();
×
68

69
            return true;
×
70
        }
26✔
71
        catch (const CodeError& e)
72
        {
×
73
            if ((m_features & FeatureTestFailOnException) > 0)
13✔
74
                throw;
13✔
75

76
            Diagnostics::generate(e);
×
77
            return false;
×
78
        }
13✔
79
    }
108✔
80

×
81
    bool Welder::saveBytecodeToFile(const std::string& filename)
22✔
82
    {
22✔
83
        m_logger.info("Final bytecode size: {}B", m_bytecode.size() * sizeof(uint8_t));
22✔
84

85
        if (m_bytecode.empty())
22✔
86
            return false;
×
87

88
        std::ofstream output(filename, std::ofstream::binary);
22✔
89
        output.write(
44✔
90
            reinterpret_cast<char*>(&m_bytecode[0]),
22✔
91
            static_cast<std::streamsize>(m_bytecode.size() * sizeof(uint8_t)));
22✔
92
        output.close();
22✔
93
        return true;
22✔
94
    }
22✔
95

96
    const internal::Node& Welder::ast() const noexcept
9✔
97
    {
9✔
98
        return m_computed_ast;
9✔
99
    }
100

101
    std::string Welder::textualIR() const noexcept
1✔
102
    {
1✔
103
        std::stringstream stream;
1✔
104
        m_ir_compiler.dumpToStream(stream);
1✔
105
        return stream.str();
1✔
106
    }
1✔
107

108
    const bytecode_t& Welder::bytecode() const noexcept
4✔
109
    {
4✔
110
        return m_bytecode;
4✔
111
    }
112

113
    void Welder::dumpIRToFile() const
×
114
    {
×
115
        std::filesystem::path path = m_root_file;
×
116
        if (is_directory(m_root_file))
×
117
            path /= "output.ark.ir";
×
118
        else
119
            path.replace_extension(".ark.ir");
×
120

121
        std::ofstream output(path);
×
122
        m_ir_compiler.dumpToStream(output);
×
123
        output.close();
×
124
    }
×
125

126
    bool Welder::computeAST(const std::string& filename, const std::string& code)
53✔
127
    {
53✔
128
        try
×
129
        {
130
            m_parser.process(filename, code);
53✔
131
            m_computed_ast = m_parser.ast();
×
132

133
            if ((m_features & FeatureImportSolver) != 0)
72✔
134
            {
135
                m_import_solver.setup(m_root_file, m_parser.imports());
72✔
136
                m_import_solver.process(m_computed_ast);
72✔
137
                m_computed_ast = m_import_solver.ast();
72✔
138
            }
72✔
139

140
            if ((m_features & FeatureMacroProcessor) != 0)
72✔
141
            {
142
                m_macro_processor.process(m_computed_ast);
72✔
143
                m_computed_ast = m_macro_processor.ast();
51✔
144
            }
51✔
145

146
            if ((m_features & FeatureASTOptimizer) != 0)
51✔
147
            {
148
                m_ast_optimizer.process(m_computed_ast);
51✔
149
                m_computed_ast = m_ast_optimizer.ast();
51✔
150
            }
51✔
151

152
            if ((m_features & FeatureNameResolver) != 0)
51✔
153
            {
154
                // NOTE: ast isn't modified by the name resolver, no need to update m_computed_ast
155
                m_name_resolver.process(m_computed_ast);
51✔
156
            }
40✔
157

×
158
            return true;
40✔
159
        }
103✔
160
        catch (const CodeError& e)
161
        {
162
            if ((m_features & FeatureTestFailOnException) > 0)
51✔
163
                throw;
51✔
164

165
            Diagnostics::generate(e);
×
166
            return false;
×
167
        }
51✔
168
    }
248✔
169
}
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