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

ArkScript-lang / Ark / 17215213570

25 Aug 2025 04:52PM UTC coverage: 87.662% (+0.3%) from 87.348%
17215213570

push

github

SuperFola
feat(tests): adding double plugin loading test

7581 of 8648 relevant lines covered (87.66%)

133240.4 hits per line

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

93.01
/src/arkreactor/Compiler/AST/Node.cpp
1
#include <Ark/Compiler/Common.hpp>
2
#include <Ark/Compiler/AST/Node.hpp>
3

4
#include <Ark/Error/Exceptions.hpp>
5

6
#include <cassert>
7
#include <fmt/core.h>
8

9
namespace Ark::internal
10
{
11
    Node::Node(const NodeType node_type, const std::string& value) :
128,804✔
12
        m_type(node_type), m_value(value), m_pos()
64,402✔
13
    {}
64,402✔
14

15
    Node::Node(const NodeType node_type) :
244,640✔
16
        m_type(node_type), m_pos()
489,280✔
17
    {
244,640✔
18
        if (m_type == NodeType::List || m_type == NodeType::Macro || m_type == NodeType::Field)
244,640✔
19
            m_value = std::vector<Node>();
244,321✔
20
    }
244,640✔
21

22
    Node::Node(double value) :
70,688✔
23
        m_type(NodeType::Number), m_value(value), m_pos()
141,376✔
24
    {}
141,376✔
25

26
    Node::Node(const long value) :
106✔
27
        m_type(NodeType::Number), m_value(static_cast<double>(value)), m_pos()
212✔
28
    {}
212✔
29

30
    Node::Node(Keyword value) :
12,876✔
31
        m_type(NodeType::Keyword), m_value(value), m_pos()
25,752✔
32
    {}
25,752✔
33

34
    Node::Node(const Namespace& namespace_) :
250✔
35
        m_type(NodeType::Namespace), m_value(namespace_), m_pos()
125✔
36
    {}
125✔
37

38
    const std::string& Node::string() const noexcept
7,629,713✔
39
    {
7,629,713✔
40
        return std::get<std::string>(m_value);
7,629,713✔
41
    }
42

43
    double Node::number() const noexcept
7,512✔
44
    {
7,512✔
45
        return std::get<double>(m_value);
7,512✔
46
    }
47

48
    Keyword Node::keyword() const noexcept
112,060✔
49
    {
112,060✔
50
        return std::get<Keyword>(m_value);
112,060✔
51
    }
52

53
    Namespace& Node::arkNamespace() noexcept
430✔
54
    {
430✔
55
        return std::get<Namespace>(m_value);
430✔
56
    }
57

58
    const Namespace& Node::constArkNamespace() const noexcept
121✔
59
    {
121✔
60
        return std::get<Namespace>(m_value);
121✔
61
    }
62

63
    void Node::push_back(const Node& node) noexcept
176,637✔
64
    {
176,637✔
65
        list().push_back(node);
176,637✔
66
    }
176,637✔
67

68
    std::vector<Node>& Node::list() noexcept
1,206,362✔
69
    {
1,206,362✔
70
        return std::get<std::vector<Node>>(m_value);
1,206,362✔
71
    }
72

73
    const std::vector<Node>& Node::constList() const noexcept
1,968,415✔
74
    {
1,968,415✔
75
        return std::get<std::vector<Node>>(m_value);
1,968,415✔
76
    }
77

78
    NodeType Node::nodeType() const noexcept
4,087,756✔
79
    {
4,087,756✔
80
        return m_type;
4,087,756✔
81
    }
82

83
    bool Node::isListLike() const noexcept
14,615✔
84
    {
14,615✔
85
        return m_type == NodeType::List || m_type == NodeType::Macro;
14,615✔
86
    }
87

88
    bool Node::isStringLike() const noexcept
×
89
    {
×
90
        return m_type == NodeType::Symbol || m_type == NodeType::String || m_type == NodeType::Spread;
×
91
    }
92

93
    bool Node::isFunction() const noexcept
6,113✔
94
    {
6,113✔
95
        return m_type == NodeType::List &&
10,725✔
96
            !constList().empty() &&
4,612✔
97
            constList()[0].nodeType() == NodeType::Keyword &&
6,792✔
98
            constList()[0].keyword() == Keyword::Fun;
2,180✔
99
    }
100

101
    const std::optional<std::string>& Node::getUnqualifiedName() const noexcept
878✔
102
    {
878✔
103
        return m_unqualified_name;
878✔
104
    }
105

106
    void Node::updateValueAndType(const Node& source) noexcept
23,367✔
107
    {
23,367✔
108
        m_type = source.m_type;
23,367✔
109
        m_value = source.m_value;
23,367✔
110
    }
23,367✔
111

112
    void Node::setNodeType(const NodeType type) noexcept
296✔
113
    {
296✔
114
        m_type = type;
296✔
115
    }
296✔
116

117
    void Node::setUnqualifiedName(const std::string& name) noexcept
218✔
118
    {
218✔
119
        m_unqualified_name = name;
218✔
120
    }
218✔
121

122
    void Node::setString(const std::string& value) noexcept
99,900✔
123
    {
99,900✔
124
        m_value = value;
99,900✔
125
    }
99,900✔
126

127
    void Node::setPositionFrom(const Node& source) noexcept
161✔
128
    {
161✔
129
        m_filename = source.m_filename;
161✔
130
        m_pos = source.m_pos;
161✔
131
    }
161✔
132

133
    Node& Node::attachNearestCommentBefore(const std::string& comment)
160,529✔
134
    {
160,529✔
135
        m_comment = comment;
160,529✔
136
        return *this;
160,529✔
137
    }
138

139
    Node& Node::attachCommentAfter(const std::string& comment)
39,332✔
140
    {
39,332✔
141
        if (!m_after_comment.empty())
39,332✔
142
            m_after_comment += "\n";
37✔
143
        m_after_comment += comment;
39,332✔
144
        if (!m_after_comment.empty() && m_after_comment.back() == '\n')
39,332✔
145
            m_after_comment.pop_back();
107✔
146
        return *this;
39,332✔
147
    }
148

149
    void Node::setAltSyntax(const bool toggle)
2,827✔
150
    {
2,827✔
151
        m_alt_syntax = toggle;
2,827✔
152
    }
2,827✔
153

154
    void Node::setFunctionKind(const bool anonymous)
2,157✔
155
    {
2,157✔
156
        m_is_anonymous_function = anonymous;
2,157✔
157
    }
2,157✔
158

159
    bool Node::isAnonymousFunction() const noexcept
4,843✔
160
    {
4,843✔
161
        return m_is_anonymous_function;
4,843✔
162
    }
163

164
    FileSpan Node::position() const noexcept
110,212✔
165
    {
110,212✔
166
        return m_pos;
110,212✔
167
    }
168

169
    const std::string& Node::filename() const noexcept
50,910✔
170
    {
50,910✔
171
        return m_filename;
50,910✔
172
    }
173

174
    const std::string& Node::comment() const noexcept
15,647✔
175
    {
15,647✔
176
        return m_comment;
15,647✔
177
    }
178

179
    const std::string& Node::commentAfter() const noexcept
2,266✔
180
    {
2,266✔
181
        return m_after_comment;
2,266✔
182
    }
183

184
    std::string Node::repr() const noexcept
16,337✔
185
    {
16,337✔
186
        std::string data;
16,337✔
187
        switch (m_type)
16,337✔
188
        {
13,451✔
189
            case NodeType::Symbol:
190
                data += string();
13,451✔
191
                break;
13,451✔
192

193
            case NodeType::Capture:
194
                data += "&" + string();
×
195
                break;
60✔
196

197
            case NodeType::Keyword:
198
                data += keywords[static_cast<std::size_t>(keyword())];
60✔
199
                break;
482✔
200

201
            case NodeType::String:
202
                data += "\"" + string() + "\"";
422✔
203
                break;
1,581✔
204

205
            case NodeType::Number:
206
                data += fmt::format("{}", number());
1,159✔
207
                break;
2,250✔
208

209
            case NodeType::List:
210
                if (m_alt_syntax)
1,091✔
211
                {
212
                    const auto first = constList().front();
264✔
213
                    char open = 0;
264✔
214
                    if (first.nodeType() == NodeType::Keyword && first.keyword() == Keyword::Begin)
264✔
215
                        open = '{';
3✔
216
                    else if (first.nodeType() == NodeType::Symbol && first.string() == "list")
261✔
217
                        open = '[';
261✔
218
                    else
219
                        assert(false && "Alt syntax nodes can only be begin or list");
×
220

221
                    data += open;
264✔
222
                    for (std::size_t i = 1, end = constList().size(); i < end; ++i)
817✔
223
                    {
224
                        data += constList()[i].repr();
553✔
225
                        if (i < end - 1)
553✔
226
                            data += " ";
355✔
227
                    }
553✔
228

229
                    if (open == '{')
264✔
230
                        data += "}";
3✔
231
                    else if (open == '[')
261✔
232
                        data += "]";
261✔
233
                }
264✔
234
                else
235
                {
236
                    data += "(";
827✔
237
                    for (std::size_t i = 0, end = constList().size(); i < end; ++i)
3,012✔
238
                    {
239
                        data += constList()[i].repr();
2,185✔
240
                        if (i < end - 1)
2,185✔
241
                            data += " ";
1,362✔
242
                    }
2,185✔
243
                    data += ")";
827✔
244
                }
245
                break;
1,228✔
246

247
            case NodeType::Field:
248
                for (std::size_t i = 0, end = constList().size(); i < end; ++i)
425✔
249
                {
250
                    data += constList()[i].repr();
288✔
251
                    if (i < end - 1)
393,125✔
252
                        data += ".";
151✔
253
                }
288✔
254
                break;
153✔
255

256
            case NodeType::Macro:
257
                data += "(macro ";
392,853✔
258
                for (std::size_t i = 0, end = constList().size(); i < end; ++i)
392,913✔
259
                {
260
                    data += constList()[i].repr();
60✔
261
                    if (i < end - 1)
60✔
262
                        data += " ";
44✔
263
                }
60✔
264
                data += ")";
16✔
265
                break;
17✔
266

267
            case NodeType::Spread:
268
                data += "..." + string();
1✔
269
                break;
1✔
270

271
            // namespace node should not have a representation as it is purely internal,
272
            // and it can't be exploited by macros (unless you try passing an import node
273
            // to a macro, which should not happen?)
274
            case NodeType::Namespace:
275
                data += constArkNamespace().ast->repr();
×
276
                break;
×
277

278
            case NodeType::Unused:
279
                break;
×
280
        }
16,337✔
281
        return data;
16,337✔
282
    }
16,337✔
283

284
    std::ostream& Node::debugPrint(std::ostream& os) const noexcept
469✔
285
    {
469✔
286
        switch (m_type)
469✔
287
        {
143✔
288
            case NodeType::Symbol:
289
                os << "Symbol:" << string();
143✔
290
                break;
149✔
291

292
            case NodeType::Capture:
293
                os << "Capture:" << string();
6✔
294
                break;
84✔
295

296
            case NodeType::Keyword:
297
                os << "Keyword:";
78✔
298
                switch (keyword())
78✔
299
                {
14✔
300
                    case Keyword::Fun: os << "Fun"; break;
32✔
301
                    case Keyword::Let: os << "Let"; break;
21✔
302
                    case Keyword::Mut: os << "Mut"; break;
4✔
303
                    case Keyword::Set: os << "Set"; break;
16✔
304
                    case Keyword::If: os << "If"; break;
21✔
305
                    case Keyword::While: os << "While"; break;
15✔
306
                    case Keyword::Begin: os << "Begin"; break;
17✔
307
                    case Keyword::Import: os << "Import"; break;
12✔
308
                    case Keyword::Del: os << "Del"; break;
4✔
309
                }
78✔
310
                break;
86✔
311

312
            case NodeType::String:
313
                os << "String:" << string();
8✔
314
                break;
83✔
315

316
            case NodeType::Number:
317
                os << "Number:" << number();
75✔
318
                break;
215✔
319

320
            case NodeType::List:
321
                os << "( ";
140✔
322
                for (const auto& i : constList())
482✔
323
                    i.debugPrint(os) << " ";
342✔
324
                os << ")";
140✔
325
                break;
149✔
326

327
            case NodeType::Field:
328
                os << "( Field ";
9✔
329
                for (const auto& i : constList())
30✔
330
                    i.debugPrint(os) << " ";
21✔
331
                os << ")";
9✔
332
                break;
17✔
333

334
            case NodeType::Macro:
335
                os << "( Macro ";
8✔
336
                for (const auto& i : constList())
31✔
337
                    i.debugPrint(os) << " ";
23✔
338
                os << ")";
8✔
339
                break;
10✔
340

341
            case NodeType::Spread:
342
                os << "Spread:" << string();
2✔
343
                break;
2✔
344

345
            case NodeType::Namespace:
346
            {
347
                const auto details = constArkNamespace();
×
348
                os << "( Namespace:" << details.name << " ";
×
349
                details.ast->debugPrint(os) << " )";
×
350
                break;
351
            }
×
352

353
            case NodeType::Unused:
354
                break;
×
355
        }
469✔
356
        return os;
469✔
357
    }
358

359
    const Node& getTrueNode()
77✔
360
    {
77✔
361
        static const Node TrueNode(NodeType::Symbol, "true");
77✔
362
        return TrueNode;
77✔
363
    }
×
364

365
    const Node& getFalseNode()
59✔
366
    {
59✔
367
        static const Node FalseNode(NodeType::Symbol, "false");
59✔
368
        return FalseNode;
59✔
369
    }
×
370

371
    const Node& getNilNode()
51✔
372
    {
51✔
373
        static const Node NilNode(NodeType::Symbol, "nil");
51✔
374
        return NilNode;
51✔
375
    }
×
376

377
    const Node& getListNode()
1,128✔
378
    {
1,128✔
379
        static const Node ListNode(NodeType::Symbol, "list");
1,128✔
380
        return ListNode;
1,128✔
381
    }
×
382

383
    bool operator==(const Node& A, const Node& B)
414✔
384
    {
414✔
385
        if (A.m_type != B.m_type)  // should have the same types
414✔
386
            return false;
30✔
387

388
        if (A.m_type != NodeType::List)
384✔
389
            return A.m_value == B.m_value;
384✔
390
        return false;
×
391
    }
414✔
392

393
    bool operator<(const Node& A, const Node& B)
58✔
394
    {
58✔
395
        if (A.nodeType() != B.nodeType())
58✔
396
            return (static_cast<int>(A.nodeType()) - static_cast<int>(B.nodeType())) < 0;
18✔
397

398
        switch (A.nodeType())
40✔
399
        {
40✔
400
            case NodeType::Number:
401
                [[fallthrough]];
402
            case NodeType::Symbol:
403
                [[fallthrough]];
404
            case NodeType::String:
405
                return A.m_value < B.m_value;
40✔
406

407
            default:
408
                return false;
×
409
        }
410
    }
58✔
411
}
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