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

ArkScript-lang / Ark / 11304355606

12 Oct 2024 08:53AM UTC coverage: 76.391% (+1.2%) from 75.225%
11304355606

push

github

SuperFola
feat(ir, compiler): implementing the IR optimizer

62 of 75 new or added lines in 3 files covered. (82.67%)

402 existing lines in 9 files now uncovered.

5054 of 6616 relevant lines covered (76.39%)

9231.22 hits per line

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

89.86
/src/arkscript/JsonCompiler.cpp
1
#include <CLI/JsonCompiler.hpp>
2

3
#include <string>
4
#include <vector>
5
#include <ranges>
6
#include <Ark/Exceptions.hpp>
7

8
#include <fmt/core.h>
9

10
using namespace Ark::internal;
11

12
JsonCompiler::JsonCompiler(unsigned debug, const std::vector<std::filesystem::path>& lib_env) :
9✔
13
    m_welder(debug, lib_env, Ark::DefaultFeatures & ~Ark::FeatureImportSolver)
9✔
14
{}
9✔
15

16
void JsonCompiler::feed(const std::string& filename)
9✔
17
{
9✔
18
    m_welder.computeASTFromFile(filename);
9✔
19
}
9✔
20

21
std::string JsonCompiler::compile()
9✔
22
{
9✔
23
    return _compile(m_welder.ast());
9✔
24
}
25

26
std::string JsonCompiler::_compile(const Node& node)
542✔
27
{
542✔
28
    std::string json;
542✔
29

30
    switch (node.nodeType())
542✔
31
    {
209✔
32
        case NodeType::Symbol:
×
33
        {
34
            json += fmt::format(
418✔
35
                R"({{"type": "Symbol", "name": "{}"}})",
209✔
36
                node.string().c_str());
209✔
37
            break;
209✔
38
        }
5✔
39

40
        case NodeType::Capture:
×
41
        {
42
            json += fmt::format(
10✔
43
                R"({{"type": "Capture", "name": "{}"}})",
5✔
44
                node.string().c_str());
5✔
45
            break;
5✔
46
        }
4✔
47

48
        case NodeType::Field:
49
        {
50
            json += R"({"type": "Field", "children": )";
4✔
51
            json += toJsonList(node, 0) + "}";
4✔
52
            break;
4✔
53
        }
56✔
54

55
        case NodeType::String:
56
        {
57
            json += fmt::format(
112✔
58
                R"({{"type": "String", "value": "{}"}})",
56✔
59
                node.string().c_str());
56✔
60
            break;
56✔
61
        }
81✔
62

×
63
        case NodeType::Number:
64
        {
65
            json += fmt::format(
81✔
66
                R"({{"type": "Number", "value": {}}})",
81✔
67
                node.number());
81✔
68
            break;
81✔
69
        }
187✔
70

×
71
        case NodeType::List:
72
        {
×
73
            if (!node.constList().empty() && node.constList()[0].nodeType() == NodeType::Keyword)
187✔
74
            {
75
                Node keyword = node.constList()[0];
83✔
76
                switch (keyword.keyword())
83✔
77
                {
18✔
78
                    case Keyword::Fun:
79
                    {
80
                        // (fun (args) (body))
×
81
                        std::string args;
18✔
82
                        Node args_node = node.constList()[1];
18✔
83
                        for (std::size_t i = 0, end = args_node.constList().size(); i < end; ++i)
45✔
84
                        {
85
                            args += _compile(args_node.constList()[i]);
27✔
86
                            if (end > 1 && i != end - 1)
27✔
87
                                args += ", ";
10✔
88
                        }
27✔
89

90
                        json += fmt::format(
36✔
91
                            R"({{"type": "Fun", "args": [{}], "body": {}}})",
18✔
92
                            args.c_str(), _compile(node.constList()[2]).c_str());
18✔
93
                        break;
94
                    }
38✔
95

96
                    case Keyword::Let:
97
                    {
98
                        // (let name value)
99
                        json += fmt::format(
40✔
100
                            R"({{"type": "Let", "name": {}, "value": {}}})",
20✔
101
                            _compile(node.constList()[1]).c_str(), _compile(node.constList()[2]).c_str());
20✔
102
                        break;
20✔
103
                    }
3✔
104

105
                    case Keyword::Mut:
106
                    {
107
                        // (mut name value)
108
                        json += fmt::format(
6✔
109
                            R"({{"type": "Mut", "name": {}, "value": {}}})",
3✔
110
                            _compile(node.constList()[1]).c_str(), _compile(node.constList()[2]).c_str());
3✔
111
                        break;
3✔
112
                    }
5✔
113

114
                    case Keyword::Set:
115
                    {
116
                        // (set name value)
117
                        json += fmt::format(
10✔
118
                            R"({{"type": "Set", "name": {}, "value": {}}})",
5✔
119
                            _compile(node.constList()[1]).c_str(), _compile(node.constList()[2]).c_str());
5✔
120
                        break;
5✔
121
                    }
5✔
122

123
                    case Keyword::If:
124
                    {
125
                        // (if condition then else)
126
                        json += fmt::format(
10✔
127
                            R"({{"type": "If", "condition": {}, "then": {}, "else": {}}})",
5✔
128
                            _compile(node.constList()[1]).c_str(), _compile(node.constList()[2]).c_str(), _compile(node.constList()[3]).c_str());
5✔
129
                        break;
5✔
130
                    }
2✔
131

132
                    case Keyword::While:
133
                    {
134
                        // (while condition body)
135
                        json += fmt::format(
4✔
136
                            R"({{"type": "While", "condition": {}, "body": {}}})",
2✔
137
                            _compile(node.constList()[1]).c_str(), _compile(node.constList()[2]).c_str());
2✔
138
                        break;
2✔
139
                    }
25✔
140

141
                    case Keyword::Begin:
142
                    {
143
                        // (begin body)
144
                        json += R"({"type": "Begin", "children": )";
25✔
145
                        json += toJsonList(node, 1) + "}";
25✔
146
                        break;
25✔
147
                    }
4✔
148

149
                    case Keyword::Import:
150
                    {
151
                        // (import pkg.value)
152
                        // (import pkg.value :sym)
153
                        // (import pkg.value:*)
154
                        std::string package = node.constList()[1].constList().front().string();
4✔
155
                        for (const auto& sym : node.constList()[1].constList() | std::views::drop(1))
8✔
156
                            package += "." + sym.string();
4✔
UNCOV
157

×
158
                        bool is_glob = node.constList()[2].nodeType() == NodeType::Symbol && node.constList()[2].string() == "*";
4✔
159
                        std::vector<std::string> syms;
5✔
160
                        if (node.constList()[2].nodeType() == NodeType::List)
4✔
161
                        {
162
                            for (const auto& sym : node.constList()[2].constList())
5✔
163
                                syms.push_back('"' + sym.string() + '"');
2✔
164
                        }
3✔
165
                        json += fmt::format(
8✔
166
                            R"({{"type": "Import", "package": "{}", "glob": {}, "symbols": [{}]}})",
4✔
167
                            package,
168
                            is_glob,
169
                            fmt::join(syms, ", "));
4✔
170
                        break;
171
                    }
5✔
172

173
                    case Keyword::Del:
174
                    {
175
                        // (del value)
176
                        json += fmt::format(
2✔
177
                            R"({{"type": "Del", "value": {}}})",
1✔
178
                            _compile(node.constList()[1]).c_str());
1✔
179
                        break;
1✔
180
                    }
181
                }
83✔
182
            }
83✔
183
            else if (node.constList().size() > 1 && node.constList()[0].nodeType() == NodeType::Symbol)
104✔
184
            {
185
                // (foo bar 1)
186
                json += fmt::format(
198✔
187
                    R"({{"type": "FunctionCall", "name": {}, "args": )",
99✔
188
                    _compile(node.constList()[0]).c_str());
99✔
189
                json += toJsonList(node, 1) + "}";
99✔
190
            }
99✔
191
            else
192
                json += toJsonList(node, 0);
5✔
193

194
            break;
187✔
195
        }
×
196

197
        default:
198
            throw Ark::Error(fmt::format(
×
UNCOV
199
                "Not handled NodeType::{} ({} at {}:{}), please report this error on GitHub",
×
200
                nodeTypes[static_cast<std::size_t>(node.nodeType())].data(),
×
201
                node.filename().c_str(),
×
202
                node.line(),
×
203
                node.col()));
×
204
    }
542✔
205
    return json;
542✔
206
}
542✔
207

208
std::string JsonCompiler::toJsonList(const Node& node, std::size_t start)
133✔
209
{
133✔
210
    std::string json = "[";
133✔
211
    for (std::size_t i = start, end = node.constList().size(); i < end; ++i)
446✔
212
    {
213
        json += _compile(node.constList()[i]);
313✔
214
        if (i != end - 1)
313✔
215
            json += ", ";
181✔
216
    }
313✔
217
    json += "]";
133✔
218
    return json;
133✔
219
}
133✔
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

© 2025 Coveralls, Inc